beastereotype.com).404.html acts as the project loader for clean /work/project-slug paths.projects.js to ensure instant loading without a "loading" state./ (Root)
├── index.html <-- Home (Featured grid + Bio snippet) [SEO Priority]
├── 404.html <-- Project Loader (Clone of index.html with Router script)
├── about/
│ └── index.html <-- About Page (Full text bio) [SEO Priority]
├── work/
│ └── index.html <-- Filterable Gallery (All projects)
├── digital-art/
│ └── index.html <-- Filterable Gallery (Digital Art)
├── data/
│ ├── projects.js <-- Source of Truth: const works & const digitalArt
│ └── dictionary.js <-- UI Dictionary & Translations (en, pt, fr)
├── js/
│ ├── app.js <-- Orchestrator (Entry point)
│ ├── router.js <-- URL parser & navigation logic
│ ├── renderer.js <-- HTML Template builders (Cards, Heros, Grids)
│ ├── ui.js <-- Interactions (Filters, Menu, Lang Toggle)
│ └── utils.js <-- Helpers (Category generators, Slug cleaners)
└── css/
└── main.css <-- Modular CSS (Variables, Layout, Components)
All project entries in data/projects.js must follow this hybrid quoting style for a balance of URL flexibility and clean code:
const works = {
"project-slug": { // Quotes for IDs (allows dashes for URLs)
year: 2026, // No quotes for standard properties
categories: ["3d", "motion"],
thumbnail: "<https://r2>.../thumb.webp",
preview: "<https://r2>.../preview.mp4",
title: {
en: "Title Name",
pt: "Nome do Titulo"
fr: "Titulo em frances"
},
credits: {
agency: "Name",
direction: "Name"
},
content: [
{ type: "video", url: "youtube-link", caption: { en: "Text", pt: "Texto", fr: "Text"}},
{ type: "image", url: "r2-link", caption: { en: null, pt: null, fr: null } }
]
}
};
/ (e.g., <script src="/js/app.js">) to prevent broken links on deep project paths.404.html must extract the slug from window.location.pathname and call renderProject(slug). If specified slug does not exist, show 404 page not found message./js/)