feat: integrate art assets across all game panels (#43)
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m2s
CI / Lint, Build & Test (push) Successful in 1m6s

## Summary

- Adds `apps/web/src/utils/cdn.ts` with a `cdnImage(folder, id)` helper that builds URLs from `https://cdn.nhcarrigan.com/elysium/`
- Wires CDN art into all 13 game panels (bosses, quests, adventurers, companions, equipment, upgrades, prestige, transcendence, achievements, explorations, crafting, story, codex)
- Zone selector tabs now display 16:9 zone art thumbnails in place of emoji icons
- Adds a fixed background image at 15% opacity via `body::before`
- Documents the art generation and CDN upload process in `CLAUDE.md` for future expansions

Resolves #15

 This PR was created with help from Hikari~ 🌸

Reviewed-on: #43
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #43.
This commit is contained in:
2026-03-09 16:21:44 -07:00
committed by Naomi Carrigan
parent 7a1c57be9a
commit 11e97325cb
17 changed files with 217 additions and 25 deletions
+24 -1
View File
@@ -8,6 +8,7 @@
import { type JSX, useState } from "react";
import { useGame } from "../../context/gameContext.js";
import { CODEX_ENTRIES, ZONE_LABELS } from "../../data/codex.js";
import { cdnImage } from "../../utils/cdn.js";
import type { CodexEntry } from "@elysium/types";
/**
@@ -36,6 +37,18 @@ const sourceBadge: Record<CodexEntry["sourceType"], string> = {
zone: "🗺️",
};
const sourceTypeFolder: Record<CodexEntry["sourceType"], string> = {
adventurer: "adventurers",
boss: "bosses",
equipment: "equipment",
exploration: "explorations",
prestige: "prestige-upgrades",
quest: "quests",
recipe: "recipes",
upgrade: "upgrades",
zone: "zones",
};
/**
* Renders the codex panel with lore entries grouped by zone.
* @returns The JSX element.
@@ -155,7 +168,17 @@ const CodexPanel = (): JSX.Element => {
</span>
</div>
{isExpanded
? <p className="codex-entry-content">{entry.content}</p>
? <>
<img
alt={entry.title}
className="codex-entry-image"
src={cdnImage(
sourceTypeFolder[entry.sourceType],
entry.sourceId,
)}
/>
<p className="codex-entry-content">{entry.content}</p>
</>
: null}
</div>
);