diff --git a/.gitignore b/.gitignore
index ab5afb2..3194a2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -174,3 +174,4 @@ dist
# Finder (MacOS) folder config
.DS_Store
+html
\ No newline at end of file
diff --git a/README.md b/README.md
index 882a947..3da9110 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ https://art.mekanoe.com
## Artworks
- [./001-platform-provenance](https://art.mekanoe.com/001-platform-provenance)
-- [./002-rainbow-trinity](https://art.mekanoe.com/002-rainbow-trinity)
+- [./002-enter-the-third](https://art.mekanoe.com/002-enter-the-third)
## Development
diff --git a/build.ts b/build.ts
new file mode 100644
index 0000000..f9887e5
--- /dev/null
+++ b/build.ts
@@ -0,0 +1,30 @@
+import chalk from "chalk";
+import { generate } from "./generate";
+import { globSync } from "glob";
+import { rmSync, mkdirSync, cpSync } from "node:fs";
+
+console.log(chalk.green`>> Cleaing up ./html ...`);
+rmSync("html", { recursive: true, force: true });
+mkdirSync("html");
+
+const works = globSync("src/*/main.ts");
+
+console.log(chalk.green`>> Building ...`);
+console.log(chalk.yellow(` Found ${works.length} works.`));
+
+await Bun.build({
+ entrypoints: works,
+ outdir: "html",
+ splitting: true,
+});
+
+console.log(chalk.green`>> Generating HTML and Markdown ...`);
+await generate(works);
+
+console.log(chalk.green`>> Copying public files ...`);
+const publics = globSync("src/public/*");
+for (const file of publics) {
+ const dest = file.replace("src/public/", "html/");
+ cpSync(file, dest);
+ console.log(chalk.yellow(` -> html/${dest}...`));
+}
diff --git a/bun.lockb b/bun.lockb
index c72ae5c..01b6040 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/generate.ts b/generate.ts
new file mode 100644
index 0000000..e2a395f
--- /dev/null
+++ b/generate.ts
@@ -0,0 +1,37 @@
+import indexTemplate from "./generators/index.html.txt";
+import workTemplate from "./generators/work.html.txt";
+import readmeTemplate from "./generators/README.md.txt";
+import chalk from "chalk";
+
+export const generate = async (works: string[]) => {
+ const allWorks = works
+ .map((file) => file.replace("src/", "").replace("/main.ts", ""))
+ .sort()
+ .reverse();
+
+ for (const work of allWorks) {
+ const html = `${workTemplate}`.replace(/##name##/g, work);
+
+ await Bun.write(`html/${work}/index.html`, html);
+ console.log(chalk.yellow(` -> html/${work}/index.html...`));
+ }
+
+ const index = indexTemplate.replace(
+ "",
+ allWorks
+ .map((work) => `
./${work}`)
+ .join("\n ")
+ );
+ await Bun.write("html/index.html", index);
+ console.log(chalk.yellow(` -> html/index.html...`));
+
+ const readme = readmeTemplate.replace(
+ "",
+ allWorks
+ .reverse()
+ .map((work) => `- [./${work}](https://art.mekanoe.com/${work})`)
+ .join("\n")
+ );
+ await Bun.write("README.md", readme);
+ console.log(chalk.yellow(` -> README.md...`));
+};
diff --git a/generators/generate.ts b/generators/generate.ts
deleted file mode 100644
index f5aee09..0000000
--- a/generators/generate.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { unlinkSync } from "node:fs";
-import { globSync } from "glob";
-import indexTemplate from "./index.html.txt";
-import workTemplate from "./work.html.txt";
-import readmeTemplate from "./README.md.txt";
-
-const allHtmls = globSync("html/*.html").filter(
- (file) => file !== "html/index.html"
-);
-for (const htmlFile of allHtmls) {
- unlinkSync(htmlFile);
-}
-
-const allWorks = globSync("html/*.js")
- .map((file) => file.replace("html/", "").replace(".js", ""))
- .sort()
- .reverse();
-
-console.log({ allWorks });
-
-for (const work of allWorks) {
- const html = `${workTemplate}`.replace(/##name##/g, work);
-
- await Bun.write(`html/${work}.html`, html);
-}
-
-const index = indexTemplate.replace(
- "",
- allWorks
- .map((work) => `./${work}`)
- .join("\n ")
-);
-await Bun.write("html/index.html", index);
-
-const readme = readmeTemplate.replace(
- "",
- allWorks
- .reverse()
- .map((work) => `- [./${work}](https://art.mekanoe.com/${work})`)
- .join("\n")
-);
-await Bun.write("README.md", readme);
-
-console.log(
- `index.html & README.md generated. ${allWorks.length} works found.`
-);
diff --git a/generators/index.html.txt b/generators/index.html.txt
index bfc50d2..76a8408 100644
--- a/generators/index.html.txt
+++ b/generators/index.html.txt
@@ -16,8 +16,60 @@
line-height: 1.5;
text-shadow: 1px 1px 3px hsl(38, 45%, 22%);
}
+
+ * {
+ box-sizing: border-box;
+ transition: all 0.2s ease-in-out;
+ }
+
+ header {
+ display: flex;
+ font-size: 2.5rem;
+ align-items: center;
+
+ & .subtext {
+ font-size: 1rem;
+ margin-left: 0.5rem;
+ color: hsl(39, 68.6%, 31.2%);
+ & a:hover {
+ color: hsl(39, 100%, 80%);
+ }
+ }
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ padding-left: 3rem;
+ display: flex;
+ flex-direction: column;
+ font-size: 1.5rem;
+ }
+
+ li {
+ & a {
+ text-decoration: underline;
+ text-decoration-color: transparent;
+ }
+ &:hover {
+ color: hsl(39, 100%, 80%);
+ & a {
+ text-decoration-color: inherit;
+ }
+ }
+
+ &::before {
+ content: "▸";
+ margin-right: 0.5rem;
+ }
+ }
-