make cv a markdown page
All checks were successful
Docker / run-tests (push) Successful in 3m5s
Docker / build-and-push-image (push) Successful in 2m39s

This commit is contained in:
Troy 2025-04-07 14:38:37 +01:00
parent a04446de76
commit 78b0780e12
Signed by: troy
GPG key ID: DFC06C02ED3B4711
13 changed files with 375 additions and 464 deletions

200
package-lock.json generated
View file

@ -9,22 +9,22 @@
"version": "0.0.1",
"dependencies": {
"@astrojs/check": "0.9.4",
"@astrojs/mdx": "^4.2.2",
"@astrojs/mdx": "^4.2.3",
"@astrojs/rss": "^4.0.11",
"@astrojs/sitemap": "3.3.0",
"@fontsource-variable/outfit": "^5.2.5",
"@fontsource-variable/red-hat-mono": "^5.2.5",
"@tailwindcss/vite": "^4.0.17",
"astro": "^5.5.5",
"@tailwindcss/vite": "^4.1.3",
"astro": "^5.6.1",
"astro-icon": "^1.1.5",
"rehype-external-links": "^3.0.0",
"tailwindcss": "^4.0.17",
"typescript": "^5.8.2"
"tailwindcss": "^4.1.3",
"typescript": "^5.8.3"
},
"devDependencies": {
"@iconify-json/mdi": "^1.2.3",
"@tailwindcss/typography": "^0.5.16",
"@types/node": "^22.13.13",
"@types/node": "^22.14.0",
"npm-check-updates": "^17.1.16",
"prettier": "^3.5.3",
"prettier-plugin-astro": "^0.14.1",
@ -154,9 +154,9 @@
}
},
"node_modules/@astrojs/mdx": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.2.2.tgz",
"integrity": "sha512-nWDvuCPenxoxbog3YK3yVWF3Jw7Lq1+ziWSAOc9fy6zAUbPDSr2bt3c6r6+oa1ll0miCQByj5UVts6eJvN/y+g==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.2.3.tgz",
"integrity": "sha512-oteB88udzzZmix5kWWUMeMJfeB2Dj8g7jy9LVNuTzGlBh3mEkGhQr6FsIR43p0JKCN11fl5J7P/Ev4Q0Nf0KQQ==",
"license": "MIT",
"dependencies": {
"@astrojs/markdown-remark": "6.3.1",
@ -1624,42 +1624,43 @@
"license": "MIT"
},
"node_modules/@tailwindcss/node": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.17.tgz",
"integrity": "sha512-LIdNwcqyY7578VpofXyqjH6f+3fP4nrz7FBLki5HpzqjYfXdF2m/eW18ZfoKePtDGg90Bvvfpov9d2gy5XVCbg==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.3.tgz",
"integrity": "sha512-H/6r6IPFJkCfBJZ2dKZiPJ7Ueb2wbL592+9bQEl2r73qbX6yGnmQVIfiUvDRB2YI0a3PWDrzUwkvQx1XW1bNkA==",
"license": "MIT",
"dependencies": {
"enhanced-resolve": "^5.18.1",
"jiti": "^2.4.2",
"tailwindcss": "4.0.17"
"lightningcss": "1.29.2",
"tailwindcss": "4.1.3"
}
},
"node_modules/@tailwindcss/oxide": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.17.tgz",
"integrity": "sha512-B4OaUIRD2uVrULpAD1Yksx2+wNarQr2rQh65nXqaqbLY1jCd8fO+3KLh/+TH4Hzh2NTHQvgxVbPdUDOtLk7vAw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.3.tgz",
"integrity": "sha512-t16lpHCU7LBxDe/8dCj9ntyNpXaSTAgxWm1u2XQP5NiIu4KGSyrDJJRlK9hJ4U9yJxx0UKCVI67MJWFNll5mOQ==",
"license": "MIT",
"engines": {
"node": ">= 10"
},
"optionalDependencies": {
"@tailwindcss/oxide-android-arm64": "4.0.17",
"@tailwindcss/oxide-darwin-arm64": "4.0.17",
"@tailwindcss/oxide-darwin-x64": "4.0.17",
"@tailwindcss/oxide-freebsd-x64": "4.0.17",
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.17",
"@tailwindcss/oxide-linux-arm64-gnu": "4.0.17",
"@tailwindcss/oxide-linux-arm64-musl": "4.0.17",
"@tailwindcss/oxide-linux-x64-gnu": "4.0.17",
"@tailwindcss/oxide-linux-x64-musl": "4.0.17",
"@tailwindcss/oxide-win32-arm64-msvc": "4.0.17",
"@tailwindcss/oxide-win32-x64-msvc": "4.0.17"
"@tailwindcss/oxide-android-arm64": "4.1.3",
"@tailwindcss/oxide-darwin-arm64": "4.1.3",
"@tailwindcss/oxide-darwin-x64": "4.1.3",
"@tailwindcss/oxide-freebsd-x64": "4.1.3",
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.3",
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.3",
"@tailwindcss/oxide-linux-arm64-musl": "4.1.3",
"@tailwindcss/oxide-linux-x64-gnu": "4.1.3",
"@tailwindcss/oxide-linux-x64-musl": "4.1.3",
"@tailwindcss/oxide-win32-arm64-msvc": "4.1.3",
"@tailwindcss/oxide-win32-x64-msvc": "4.1.3"
}
},
"node_modules/@tailwindcss/oxide-android-arm64": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.17.tgz",
"integrity": "sha512-3RfO0ZK64WAhop+EbHeyxGThyDr/fYhxPzDbEQjD2+v7ZhKTb2svTWy+KK+J1PHATus2/CQGAGp7pHY/8M8ugg==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.3.tgz",
"integrity": "sha512-cxklKjtNLwFl3mDYw4XpEfBY+G8ssSg9ADL4Wm6//5woi3XGqlxFsnV5Zb6v07dxw1NvEX2uoqsxO/zWQsgR+g==",
"cpu": [
"arm64"
],
@ -1673,9 +1674,9 @@
}
},
"node_modules/@tailwindcss/oxide-darwin-arm64": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.17.tgz",
"integrity": "sha512-e1uayxFQCCDuzTk9s8q7MC5jFN42IY7nzcr5n0Mw/AcUHwD6JaBkXnATkD924ZsHyPDvddnusIEvkgLd2CiREg==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.3.tgz",
"integrity": "sha512-mqkf2tLR5VCrjBvuRDwzKNShRu99gCAVMkVsaEOFvv6cCjlEKXRecPu9DEnxp6STk5z+Vlbh1M5zY3nQCXMXhw==",
"cpu": [
"arm64"
],
@ -1689,9 +1690,9 @@
}
},
"node_modules/@tailwindcss/oxide-darwin-x64": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.17.tgz",
"integrity": "sha512-d6z7HSdOKfXQ0HPlVx1jduUf/YtBuCCtEDIEFeBCzgRRtDsUuRtofPqxIVaSCUTOk5+OfRLonje6n9dF6AH8wQ==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.3.tgz",
"integrity": "sha512-7sGraGaWzXvCLyxrc7d+CCpUN3fYnkkcso3rCzwUmo/LteAl2ZGCDlGvDD8Y/1D3ngxT8KgDj1DSwOnNewKhmg==",
"cpu": [
"x64"
],
@ -1705,9 +1706,9 @@
}
},
"node_modules/@tailwindcss/oxide-freebsd-x64": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.17.tgz",
"integrity": "sha512-EjrVa6lx3wzXz3l5MsdOGtYIsRjgs5Mru6lDv4RuiXpguWeOb3UzGJ7vw7PEzcFadKNvNslEQqoAABeMezprxQ==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.3.tgz",
"integrity": "sha512-E2+PbcbzIReaAYZe997wb9rId246yDkCwAakllAWSGqe6VTg9hHle67hfH6ExjpV2LSK/siRzBUs5wVff3RW9w==",
"cpu": [
"x64"
],
@ -1721,9 +1722,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.17.tgz",
"integrity": "sha512-65zXfCOdi8wuaY0Ye6qMR5LAXokHYtrGvo9t/NmxvSZtCCitXV/gzJ/WP5ksXPhff1SV5rov0S+ZIZU+/4eyCQ==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.3.tgz",
"integrity": "sha512-GvfbJ8wjSSjbLFFE3UYz4Eh8i4L6GiEYqCtA8j2Zd2oXriPuom/Ah/64pg/szWycQpzRnbDiJozoxFU2oJZyfg==",
"cpu": [
"arm"
],
@ -1737,9 +1738,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.17.tgz",
"integrity": "sha512-+aaq6hJ8ioTdbJV5IA1WjWgLmun4T7eYLTvJIToiXLHy5JzUERRbIZjAcjgK9qXMwnvuu7rqpxzej+hGoEcG5g==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.3.tgz",
"integrity": "sha512-35UkuCWQTeG9BHcBQXndDOrpsnt3Pj9NVIB4CgNiKmpG8GnCNXeMczkUpOoqcOhO6Cc/mM2W7kaQ/MTEENDDXg==",
"cpu": [
"arm64"
],
@ -1753,9 +1754,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.17.tgz",
"integrity": "sha512-/FhWgZCdUGAeYHYnZKekiOC0aXFiBIoNCA0bwzkICiMYS5Rtx2KxFfMUXQVnl4uZRblG5ypt5vpPhVaXgGk80w==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.3.tgz",
"integrity": "sha512-dm18aQiML5QCj9DQo7wMbt1Z2tl3Giht54uVR87a84X8qRtuXxUqnKQkRDK5B4bCOmcZ580lF9YcoMkbDYTXHQ==",
"cpu": [
"arm64"
],
@ -1769,9 +1770,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.17.tgz",
"integrity": "sha512-gELJzOHK6GDoIpm/539Golvk+QWZjxQcbkKq9eB2kzNkOvrP0xc5UPgO9bIMNt1M48mO8ZeNenCMGt6tfkvVBg==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.3.tgz",
"integrity": "sha512-LMdTmGe/NPtGOaOfV2HuO7w07jI3cflPrVq5CXl+2O93DCewADK0uW1ORNAcfu2YxDUS035eY2W38TxrsqngxA==",
"cpu": [
"x64"
],
@ -1785,9 +1786,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.17.tgz",
"integrity": "sha512-68NwxcJrZn94IOW4TysMIbYv5AlM6So1luTlbYUDIGnKma1yTFGBRNEJ+SacJ3PZE2rgcTBNRHX1TB4EQ/XEHw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.3.tgz",
"integrity": "sha512-aalNWwIi54bbFEizwl1/XpmdDrOaCjRFQRgtbv9slWjmNPuJJTIKPHf5/XXDARc9CneW9FkSTqTbyvNecYAEGw==",
"cpu": [
"x64"
],
@ -1801,9 +1802,9 @@
}
},
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.17.tgz",
"integrity": "sha512-AkBO8efP2/7wkEXkNlXzRD4f/7WerqKHlc6PWb5v0jGbbm22DFBLbIM19IJQ3b+tNewQZa+WnPOaGm0SmwMNjw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.3.tgz",
"integrity": "sha512-PEj7XR4OGTGoboTIAdXicKuWl4EQIjKHKuR+bFy9oYN7CFZo0eu74+70O4XuERX4yjqVZGAkCdglBODlgqcCXg==",
"cpu": [
"arm64"
],
@ -1817,9 +1818,9 @@
}
},
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.17.tgz",
"integrity": "sha512-7/DTEvXcoWlqX0dAlcN0zlmcEu9xSermuo7VNGX9tJ3nYMdo735SHvbrHDln1+LYfF6NhJ3hjbpbjkMOAGmkDg==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.3.tgz",
"integrity": "sha512-T8gfxECWDBENotpw3HR9SmNiHC9AOJdxs+woasRZ8Q/J4VHN0OMs7F+4yVNZ9EVN26Wv6mZbK0jv7eHYuLJLwA==",
"cpu": [
"x64"
],
@ -1849,15 +1850,14 @@
}
},
"node_modules/@tailwindcss/vite": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.17.tgz",
"integrity": "sha512-HJbBYDlDVg5cvYZzECb6xwc1IDCEM3uJi3hEZp3BjZGCNGJcTsnCpan+z+VMW0zo6gR0U6O6ElqU1OoZ74Dhww==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.3.tgz",
"integrity": "sha512-lUI/QaDxLtlV52Lho6pu07CG9pSnRYLOPmKGIQjyHdTBagemc6HmgZxyjGAQ/5HMPrNeWBfTVIpQl0/jLXvWHQ==",
"license": "MIT",
"dependencies": {
"@tailwindcss/node": "4.0.17",
"@tailwindcss/oxide": "4.0.17",
"lightningcss": "1.29.2",
"tailwindcss": "4.0.17"
"@tailwindcss/node": "4.1.3",
"@tailwindcss/oxide": "4.1.3",
"tailwindcss": "4.1.3"
},
"peerDependencies": {
"vite": "^5.2.0 || ^6"
@ -1945,12 +1945,12 @@
}
},
"node_modules/@types/node": {
"version": "22.13.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.13.tgz",
"integrity": "sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ==",
"version": "22.14.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz",
"integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
"undici-types": "~6.21.0"
}
},
"node_modules/@types/sax": {
@ -2261,9 +2261,9 @@
}
},
"node_modules/astro": {
"version": "5.5.5",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.5.5.tgz",
"integrity": "sha512-fdnnK5dhWNIQT/cXzvaGs9il4T5noi4jafobdntbuNOrRxI1JnOxDfrtBadUo6cknCRCFhYrXh4VndCqj1a4Sg==",
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.6.1.tgz",
"integrity": "sha512-aQ2TV7wIf+q2Oi6gGWMINHWEAZqoP0eH6/mihodfTJYATPWyd03JIGVfjtYUJlkNdNSKxDXwEe/r/Zx4CZ1FPg==",
"license": "MIT",
"dependencies": {
"@astrojs/compiler": "^2.11.0",
@ -2302,26 +2302,26 @@
"neotraverse": "^0.6.18",
"p-limit": "^6.2.0",
"p-queue": "^8.1.0",
"package-manager-detector": "^1.0.0",
"package-manager-detector": "^1.1.0",
"picomatch": "^4.0.2",
"prompts": "^2.4.2",
"rehype": "^13.0.2",
"semver": "^7.7.1",
"shiki": "^3.0.0",
"shiki": "^3.2.1",
"tinyexec": "^0.3.2",
"tinyglobby": "^0.2.12",
"tsconfck": "^3.1.5",
"ultrahtml": "^1.5.3",
"ultrahtml": "^1.6.0",
"unist-util-visit": "^5.0.0",
"unstorage": "^1.15.0",
"vfile": "^6.0.3",
"vite": "^6.2.3",
"vite": "^6.2.4",
"vitefu": "^1.0.6",
"xxhash-wasm": "^1.1.0",
"yargs-parser": "^21.1.1",
"yocto-spinner": "^0.2.1",
"zod": "^3.24.2",
"zod-to-json-schema": "^3.24.3",
"zod-to-json-schema": "^3.24.5",
"zod-to-ts": "^1.2.0"
},
"bin": {
@ -2352,9 +2352,9 @@
}
},
"node_modules/astro/node_modules/package-manager-detector": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.0.0.tgz",
"integrity": "sha512-7elnH+9zMsRo7aS72w6MeRugTpdRvInmEB4Kmm9BVvPw/SLG8gXUGQ+4wF0Mys0RSWPz0B9nuBbDe8vFeA2sfg==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.1.0.tgz",
"integrity": "sha512-Y8f9qUlBzW8qauJjd/eu6jlpJZsuPJm2ZAV0cDVd420o4EdpH5RPdoCv+60/TdJflGatr4sDfpAL6ArWZbM5tA==",
"license": "MIT"
},
"node_modules/asynckit": {
@ -7163,9 +7163,9 @@
}
},
"node_modules/tailwindcss": {
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.17.tgz",
"integrity": "sha512-OErSiGzRa6rLiOvaipsDZvLMSpsBZ4ysB4f0VKGXUrjw2jfkJRd6kjRKV2+ZmTCNvwtvgdDam5D7w6WXsdLJZw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz",
"integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==",
"license": "MIT"
},
"node_modules/tapable": {
@ -7303,9 +7303,9 @@
"license": "MIT"
},
"node_modules/typescript": {
"version": "5.8.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@ -7331,9 +7331,9 @@
"license": "MIT"
},
"node_modules/ultrahtml": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.3.tgz",
"integrity": "sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz",
"integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==",
"license": "MIT"
},
"node_modules/uncrypto": {
@ -7352,9 +7352,9 @@
}
},
"node_modules/undici-types": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"license": "MIT"
},
"node_modules/unified": {
@ -7654,9 +7654,9 @@
}
},
"node_modules/vite": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz",
"integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==",
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz",
"integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==",
"license": "MIT",
"dependencies": {
"esbuild": "^0.25.0",
@ -8309,9 +8309,9 @@
}
},
"node_modules/zod-to-json-schema": {
"version": "3.24.3",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.3.tgz",
"integrity": "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==",
"version": "3.24.5",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz",
"integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==",
"license": "ISC",
"peerDependencies": {
"zod": "^3.24.1"

View file

@ -13,22 +13,22 @@
},
"dependencies": {
"@astrojs/check": "0.9.4",
"@astrojs/mdx": "^4.2.2",
"@astrojs/mdx": "^4.2.3",
"@astrojs/rss": "^4.0.11",
"@astrojs/sitemap": "3.3.0",
"@fontsource-variable/outfit": "^5.2.5",
"@fontsource-variable/red-hat-mono": "^5.2.5",
"@tailwindcss/vite": "^4.0.17",
"astro": "^5.5.5",
"@tailwindcss/vite": "^4.1.3",
"astro": "^5.6.1",
"astro-icon": "^1.1.5",
"rehype-external-links": "^3.0.0",
"tailwindcss": "^4.0.17",
"typescript": "^5.8.2"
"tailwindcss": "^4.1.3",
"typescript": "^5.8.3"
},
"devDependencies": {
"@iconify-json/mdi": "^1.2.3",
"@tailwindcss/typography": "^0.5.16",
"@types/node": "^22.13.13",
"@types/node": "^22.14.0",
"npm-check-updates": "^17.1.16",
"prettier": "^3.5.3",
"prettier-plugin-astro": "^0.14.1",

View file

@ -0,0 +1,91 @@
---
import Link from "@components/Link.astro";
import { createSlug } from "@lib/utils";
const projects = [
{
id: 1,
name: "MUST FIND BEANS",
description:
"A fast-paced first person shooter set following the realization that youre all out of beans. The problem is, youre nearing the end of cooking all the other items and you cant just not have them. Without beans, the day just wont be started off right.",
tags: ["Godot", "Blender", "GIMP", "Steamworks"],
link: "/projects/must-find-beans",
done: false,
},
{
id: 2,
name: "troylusty.com",
description:
"My personal website made using Astro as a way to show off my portfolio of work and display blog posts.",
tags: [
"Astro",
"Tailwind CSS",
"TypeScript",
"Self-hosted Forgejo Actions",
"Docker",
],
link: "https://code.troylusty.com/troy/troylusty.com",
done: true,
},
{
id: 3,
name: "Artwork",
description:
"A collection of digital artwork created with a variety of tools.",
tags: ["Blender", "Cinema 4D", "DaVinci Resolve"],
link: "/projects",
done: true,
},
{
id: 4,
name: "Packard",
description:
"Packard is a simple terminal based RSS aggregator meant to allow you to take a quick glance at whats occurring in topics you care about.",
tags: ["Rust", "Tokio", "Clap", "NixOS Flake"],
link: "https://code.troylusty.com/troy/packard",
done: true,
},
];
const sortedProjects = [...projects].sort((a, b) => a.id - b.id);
---
<ol class="grid grid-cols-1 gap-3 pl-0 md:grid-cols-2 print:grid-cols-2">
{
sortedProjects.map((project) => (
<li class="flex flex-col overflow-hidden pl-0">
<div class="flex flex-col space-y-1.5">
<div class="space-y-1">
<>
<h3 class="mt-0 text-base font-semibold tracking-tight">
<Link
href={project.link}
class="text-secondary inline-flex items-center gap-1 hover:underline"
>
{project.done ? (
<span class="mr-1 h-1 w-1 rounded-full bg-green-500" />
) : (
<span class="mr-1 h-1 w-1 rounded-full bg-amber-500" />
)}
{project.name}
</Link>
</h3>
<p class="text-secondary/70 text-xs">{project.description}</p>
</>
</div>
</div>
<div class="mt-auto flex text-sm text-pretty">
<div class="mt-2 flex flex-wrap gap-1">
{project.tags.map((tag) => (
<a
href={`/tags/${createSlug(tag)}`}
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full px-2 py-1 text-center font-sans text-[10px] font-light text-nowrap capitalize no-underline transition-colors duration-300"
>
{tag}
</a>
))}
</div>
</div>
</li>
))
}
</ol>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

View file

@ -1,35 +1,43 @@
---
title: "MUST FIND BEANS"
description: "What would you do if you awoke to find your breakfast entirely bean free, and how far would you go to make it right?"
date: 2026-01-01
updated: 2026-01-01
description: "What would you do if you realised your breakfast was going to be entirely free of beans, and how far would you go to make it right?"
date: 2025-05-08
updated: 2025-05-08
image: { url: "capsule.avif", alt: "MUST FIND BEANS Title Logo" }
tags: ["godot", "blender"]
tags: ["godot", "blender", "gimp"]
categories: ["personal"]
includeHero: true
draft: true
---
## Details
<div
class="border-l-4 border-orange-500 bg-orange-100 p-4 text-orange-700 dark:bg-orange-900 dark:text-orange-300"
role="alert"
>
<p class="m-0 mt-0 mb-0 font-bold">Please Note</p>
<p class="m-0 mt-0 mb-0">This game is very early in development.</p>
</div>
**THIS GAME IS VERY EARLY IN PRODUCTION**
![](capsule.avif)
Demonstrate your culinary combat skills in MUST FIND BEANS, a chaos driven FPS set in an endless arena full of enemies in an eat or be eaten situation.
[MUST FIND BEANS](https://store.steampowered.com/app/3012740/MUST_FIND_BEANS/) is a fast-paced first person shooter set following the realization that you're all out of beans. The problem is, you're nearing the end of cooking all the other items and you can't just not have them. Without beans, the day just won't be started off right.
### Culinary combat
Many will try to stop you as you race out in search of the final piece of your meal. But you must not let them. Find a can of beans by any means necessary before everything else you began cooking burns.
Prepare and serve up your opponents using a variety of cutlery and condiments, each fit for a different scenario!
Gameplay in MUST FIND BEANS aims to mimic games similar to the original Quake, and other modern “boomer shooters” such as ULTRAKILL, DUSK, or CRUEL. This extends not only to the fast and difficult yet predictable combat, but also the movement which has taken significant inspiration from that found within Source engine titles.
### Leaderboard
Go against players all around the world with the in-game leaderboard.
### Other key features
- Ultra-wide support
Visuals and imagery included imitate apartment and hotel interiors within and around Miami in the 1980s. This is will be most evident though the use of a combination of brutalist architecture along with collections of interior foliage. Whilst it might not be entirely present within the presented version of the game, each “enemy” will be styled after one of the breakfast items which have been left cooking as a way to visualise the characters paranoid and overly determined mental state.
## Early screenshots
![](Still2025-04-07111623_1.1.1.avif)
![](Still2025-04-07111623_1.1.6.avif)
![](Still2025-04-07111623_1.1.4.avif)
![](Still2025-04-07111623_1.1.2.avif)
![](Still2025-04-07111623_1.1.3.avif)
## Even earlier screenshots
![](ss_8340a3c02235371547350c557fefb830e6e2d067.avif)
![](ss_c578870d1c22722983b76c3effe7fba7f5d1cb5e.avif)
![](ss_b2dc5ca65e2f24088afac3faf79f450057e13383.avif)

88
src/layouts/Cv.astro Normal file
View file

@ -0,0 +1,88 @@
---
import Layout from "@layouts/Layout.astro";
import { SITE, CV } from "@consts";
import { Image } from "astro:assets";
import { Icon } from "astro-icon/components";
import Link from "@components/Link.astro";
import icon from "public/assets/icon.png";
---
<Layout title={CV.TITLE} description={CV.DESCRIPTION}>
<div class="animate-reveal flex items-center justify-between opacity-0">
<div class="flex-1 space-y-1.5">
<h1
class="animate-reveal text-start text-3xl font-semibold break-words opacity-0"
>
<span class="text-secondary">{CV.TITLE}</span><span
class="text-tertiary ml-2">{CV.DESCRIPTION}</span
>
</h1>
<p class="text-secondary/70 max-w-md text-pretty">Digital designer.</p><p
class="text-secondary/70 max-w-md items-center text-sm text-pretty"
>
<Link
class="inline-flex gap-x-1.5 align-baseline leading-none hover:underline"
href="https://www.google.com/maps/place/Devon"
>
<Icon name="mdi:earth" class="h-3 w-3" />
Devon, United Kingdom, GMT
</Link>
</p><div class="text-secondary/70 flex gap-x-1 pt-1 text-sm print:hidden">
<a
href={`mailto:${SITE.EMAIL}`}
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:email" title="Email" class="h-4 w-4" />
</a>
<Link
href="/"
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:link-variant" title="Website" class="h-4 w-4" />
</Link>
<Link
href="https://code.troylusty.com"
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:git" title="Git" class="h-4 w-4" />
</Link>
<Link
href="https://store.steampowered.com/developer/troy"
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:steam" title="Steamworks" class="h-4 w-4" />
</Link>
</div>
<p
class="text-secondary/70 hidden max-w-md items-center text-sm text-pretty print:flex"
>
<Link
class="inline-flex gap-x-1.5 align-baseline leading-none hover:underline"
href={`mailto:${SITE.EMAIL}`}
>
<Icon name="mdi:email" class="h-3 w-3" />
{SITE.EMAIL}
</Link>
</p>
</div><span
class="relative flex h-28 w-28 shrink-0 overflow-hidden rounded-xl"
>
<Image
src={icon}
alt="Troy Lusty"
class="aspect-square h-full w-full"
loading="eager"
/>
</span>
</div>
<div
class="animate-reveal mx-auto max-w-full opacity-0 [animation-delay:0.2s]"
>
<div
class="prose prose-neutral dark:prose-invert prose-sm prose-a:hover:no-underline prose-hr:my-4 prose-li:prose-p:my-0 prose-p:text-secondary/70 prose-li:text-secondary/70 max-w-full"
>
<slot />
</div>
</div>
</Layout>

View file

@ -10,20 +10,14 @@ import Button from "@components/Button.astro";
class="flex flex-col items-start justify-between gap-6 md:flex-row md:items-center"
>
<div>
<h2
class="animate-reveal text-2xl font-semibold break-words opacity-0"
id="featured-projects"
>
<h1 class="animate-reveal text-3xl font-semibold break-words opacity-0">
404
</h2>
<h3
</h1>
<h2
class="animate-reveal mt-2 font-bold opacity-0 [animation-delay:0.1s]"
>
Content not found
</h3>
</div>
<div class="animate-reveal opacity-0 [animation-delay:0.2s]">
<Button href="/" link="Go home" />
</h2>
</div>
</div>
</section>

View file

@ -1,332 +0,0 @@
---
import Layout from "@layouts/Layout.astro";
import { SITE, CV } from "@consts";
import { Image } from "astro:assets";
import { Icon } from "astro-icon/components";
import Link from "@components/Link.astro";
import icon from "public/assets/icon.png";
const skills = [
{ id: 1, name: "Python" },
{ id: 2, name: "Rust" },
{ id: 3, name: "TypeScript" },
{ id: 4, name: "Git" },
{ id: 5, name: "Docker" },
{ id: 6, name: "Linux" },
{ id: 7, name: "Shopify" },
{ id: 8, name: "Astro" },
{ id: 9, name: "Steamworks" },
{ id: 10, name: "Blender" },
{ id: 11, name: "Godot" },
{ id: 12, name: "Unreal Engine" },
{ id: 13, name: "Adobe Photoshop" },
{ id: 14, name: "GIMP" },
{ id: 15, name: "Inkscape" },
{ id: 16, name: "DaVinci Resolve" },
{ id: 17, name: "Pixelmator Pro" },
{ id: 99, name: "Full drivers licence (A & B)" },
];
const sortedSkills = [...skills].sort((a, b) => a.id - b.id);
const projects = [
{
id: 1,
name: "troylusty.com",
description: "My personal portfolio website made using Astro.",
tags: ["Astro", "Tailwind CSS", "TypeScript", "Actions", "Docker"],
link: "https://code.troylusty.com/troy/troylusty.com",
},
{
id: 2,
name: "Artwork",
description:
"A collection of digital artwork created with a variety of tools.",
tags: ["Blender"],
link: "/projects",
},
{
id: 3,
name: "Packard",
description: "Terminal based feed checker.",
tags: ["Rust", "Tokio", "Clap", "NixOS Flake"],
link: "https://code.troylusty.com/troy/packard",
},
];
const sortedProjects = [...projects].sort((a, b) => a.id - b.id);
const education = [
{
id: 1,
school: "University of Plymouth",
course: "BA (Hons) Game Arts and Design",
dates: "2024 - 2025",
description: ["1st year: Estimated completion May 2025"],
},
{
id: 2,
school: "University Centre South Devon",
course: "FdA Games and Interactive Design",
dates: "2022 - 2024",
description: [
"2nd year: 70.25% State Aggregate Mark",
"1st year: 69.43% State Aggregate Mark",
],
},
{
id: 3,
school: "South Devon College",
course:
"UAL Level 3 Extended Diploma in Creative Media Production and Technology",
dates: "2020 - 2022",
description: [
"2nd year: Extended Diploma - Distinction",
"1st year: Diploma - Distinction",
],
},
{
id: 4,
school: "Kennicott Sixth Form",
course: "BTEC & A-level",
dates: "2018 - 2020",
description: [
"Pearson BTEC Level 3 National Extended Diploma in Art and Design - Distinction Merit Merit",
"AQA GCE/A Computer Science ADV (Python) - C",
],
},
{
id: 5,
school: "King Edward VI Community College",
course: "GCSEs & Cambridge Nationals qualification",
dates: "2014 - 2018",
description: [
"10 GCSEs including Maths and English",
"OCR Cambridge Nationals Creative iMedia Level 1/2 Award/Certificate - Merit at Level 2",
],
},
];
const sortedEducation = [...education].sort((a, b) => a.id - b.id);
---
<Layout title={CV.TITLE} description={CV.DESCRIPTION}>
<div class="animate-reveal flex items-center justify-between opacity-0">
<div class="flex-1 space-y-1.5">
<h1 class="text-2xl font-bold">{SITE.AUTHOR}</h1><p
class="text-secondary/70 max-w-md font-mono text-sm text-pretty"
>
Digital designer.
</p><p
class="text-secondary/70 max-w-md items-center font-mono text-xs text-pretty"
>
<Link
class="inline-flex gap-x-1.5 align-baseline leading-none hover:underline"
href="https://www.google.com/maps/place/Devon"
>
<Icon name="mdi:earth" class="h-3 w-3" />
Devon, United Kingdom, GMT
</Link>
</p><div
class="text-secondary/70 flex gap-x-1 pt-1 font-mono text-sm print:hidden"
>
<a
href={`mailto:${SITE.EMAIL}`}
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:email" title="Email" class="h-4 w-4" />
</a>
<Link
href="/"
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:link-variant" title="Website" class="h-4 w-4" />
</Link>
<Link
href="https://code.troylusty.com"
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:git" title="Git" class="h-4 w-4" />
</Link>
<Link
href="https://store.steampowered.com/developer/troy"
class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full p-2 text-center text-sm text-nowrap capitalize transition-colors duration-300"
>
<Icon name="mdi:steam" title="Steamworks" class="h-4 w-4" />
</Link>
</div><div
class="text-secondary/70 hidden flex-col gap-x-1 font-mono text-sm print:flex"
>
<a href={`mailto:${SITE.EMAIL}`}
><span class="underline">{SITE.EMAIL}</span></a
>
</div>
</div><span
class="relative flex h-28 w-28 shrink-0 overflow-hidden rounded-xl"
>
<Image
src={icon}
alt="Troy Lusty"
class="aspect-square h-full w-full"
loading="eager"
/>
</span>
</div>
<section
class="animate-reveal flex min-h-0 flex-col gap-y-3 opacity-0 [animation-delay:0.1s]"
>
<h2 class="text-xl font-bold">About</h2><p
class="text-secondary/70 font-mono text-sm text-pretty"
>
My specific chosen area of focus is design, lighting, and rendering
focusing on 3D environments within software such as Blender and Unreal
Engine. Using either real-time or offline rendering techniques. In
addition to this I also have interests in web development and cyber
security. My portfolio of work can be found on my website at <a
href="/projects"
class="underline hover:no-underline">troylusty.com/projects</a
>.
</p>
</section>
<section
class="animate-reveal flex min-h-0 flex-col gap-y-3 opacity-0 [animation-delay:0.2s]"
>
<h2 class="text-xl font-bold">Experience</h2>
<div>
<div class="flex flex-col space-y-1.5">
<div class="flex items-center justify-between gap-x-2 text-base">
<h3
class="inline-flex items-center justify-center gap-x-1 leading-none font-semibold"
>
<Link
href="/projects/camouflage-store"
class="text-secondary inline-flex items-center gap-1 hover:underline"
>
<span class="mr-1 h-1 w-1 rounded-full bg-green-500"></span>
Camouflage Store
</Link>
</h3><div class="text-tertiary text-sm tabular-nums">
2020 - Current
</div>
</div><h4 class="font-mono text-sm leading-none">
E-commerce Business Management
</h4>
</div><div class="text-secondary/70 mt-2 font-mono text-xs text-pretty">
My role has me in charge of managing an online e-commerce store in
addition to creating, editing, and publishing informational YouTube and
social media content for a family run outdoors store. This includes the
recent redesign and also any maintenance and general upkeep of the site
with all its related systems.
<ul class="mt-2 list-inside list-disc">
<li>Migration of content to Shopify</li>
<li>Branding refresh and site redesign</li>
<li>VPS setup and self-hosted analytics platform</li>
</ul>
</div>
</div>
<div>
<div class="flex flex-col space-y-1.5">
<div class="flex items-center justify-between gap-x-2 text-base">
<h3
class="inline-flex items-center justify-center gap-x-1 leading-none font-semibold"
>
Smaller Roles
</h3>
</div>
<h4 class="font-mono text-sm leading-none">Production Assistant</h4>
</div><div class="text-secondary/70 mt-2 font-mono text-xs text-pretty">
SDC Radiant Rumble (2024)
</div>
<h4 class="mt-2 font-mono text-sm leading-none">Photogrammetrist</h4>
<div class="text-secondary/70 mt-2 font-mono text-xs text-pretty">
Paignton Picture House (2023)
</div>
</div>
</section>
<section
class="animate-reveal flex min-h-0 flex-col gap-y-3 opacity-0 [animation-delay:0.3s]"
>
<h2 class="text-xl font-bold">Education</h2>
{
sortedEducation.map((education) => (
<div>
<div class="flex flex-col space-y-1.5">
<div class="flex items-center justify-between gap-x-2 text-base">
<h3 class="leading-none font-semibold">{education.school}</h3>
<div class="text-tertiary text-sm tabular-nums">
{education.dates}
</div>
</div>
</div>
<div class="text-secondary mt-2 font-mono text-sm text-pretty">
{education.course}
<ul class="text-secondary/70 mt-2 list-inside list-disc text-xs">
{education.description.map((line) => (
<li>{line}</li>
))}
</ul>
</div>
</div>
))
}
</section>
<section
class="animate-reveal flex min-h-0 flex-col gap-y-3 opacity-0 [animation-delay:0.4s]"
>
<h2 class="text-xl font-bold">Skills & Tools</h2><ul
class="flex flex-wrap gap-1"
>
{
sortedSkills.map((skill) => (
<li class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full px-2 py-1 text-center text-xs text-nowrap capitalize transition-colors duration-300">
{skill.name}
</li>
))
}
</ul>
</section>
<section
class="animate-reveal flex min-h-0 scroll-mb-16 flex-col gap-y-3 opacity-0 [animation-delay:0.5s]"
>
<h2 class="text-xl font-bold">Projects</h2>
<ol
class="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3 print:grid-cols-3 print:gap-2"
>
{
sortedProjects.map((project) => (
<li class="flex flex-col overflow-hidden">
<div class="flex flex-col space-y-1.5">
<div class="space-y-1">
<>
<h3 class="text-base font-semibold tracking-tight">
<Link
href={project.link}
class="text-secondary inline-flex items-center gap-1 hover:underline"
>
<span class="mr-1 h-1 w-1 rounded-full bg-green-500" />
{project.name}
</Link>
</h3>
<div class="hidden font-mono text-xs underline print:visible">
{project.name}
</div>
<p class="text-secondary/70 font-mono text-xs">
{project.description}
</p>
</>
</div>
</div>
<div class="mt-auto flex font-mono text-sm text-pretty">
<div class="mt-2 flex flex-wrap gap-1">
{project.tags.map((tag) => (
<div class="bg-button text-secondary hover:bg-button-active flex w-fit flex-row items-center gap-1 justify-self-center rounded-full px-2 py-1 text-center font-sans text-[10px] font-light text-nowrap capitalize transition-colors duration-300">
{tag}
</div>
))}
</div>
</div>
</li>
))
}
</ol>
</section>
</Layout>

62
src/pages/cv.mdx Normal file
View file

@ -0,0 +1,62 @@
---
title: Troy Lusty
description: Curriculum Vitae
layout: "@layouts/Cv.astro"
---
import Projects from "@components/CvProjects.astro";
## About
I'm a [Game Arts and Design](#education) degree student with a chosen area of focus on the design, lighting, and rendering of 3D environments. Using either real-time or offline rendering techniques in software packages such as Blender and Unreal Engine. In addition to this I also have an interest in web development, graphic design, and cyber security which make up a large part of my hobbies. My current portfolio of work can be found on my website at [troylusty.com/projects](/projects).
---
## Experience
### **E-commerce Business Management**, [Camouflage Store](/projects/camouflage-store) <small class="font-light font-mono text-xs">(2020 - Current)</small>
My role has me in charge of managing an online e-commerce store in addition to creating, editing, and publishing informational YouTube and social media content for a family run outdoors store. This includes the recent branding redesign, migration of content to Shopify, and any maintenance or general upkeep of the site with all its related systems, such as the self-hosted analytics platform.
### Volunteering
- **Production Assistant**, SDC Radiant Rumble <small class="font-light font-mono text-xs">(2024)</small>
- **Photogrammetrist**, Paignton Picture House <small class="font-light font-mono text-xs">(2023)</small>
---
## Education
### **BA (Hons) Game Arts and Design**, University of Plymouth <small class="font-light font-mono text-xs">(2024 - 2025)</small>
- 1st year: Estimated completion May 2025
### **FdA Games and Interactive Design**, University Centre South Devon <small class="font-light font-mono text-xs">(2022 - 2024)</small>
- 2nd year: 70.25% State Aggregate Mark
- 1st year: 69.43% State Aggregate Mark
### **UAL Level 3 Extended Diploma in Creative Media Production and Technology**, South Devon College <small class="font-light font-mono text-xs">(2020 - 2022)</small>
- 2nd year: Extended Diploma - Distinction
- 1st year: Diploma - Distinction
### **BTEC & A-level**, Kennicott Sixth Form <small class="font-light font-mono text-xs">(2018 - 2020)</small>
- Pearson BTEC Level 3 National Extended Diploma in Art and Design - Distinction Merit Merit
- AQA GCE/A Computer Science ADV (Python) - C
### **GCSEs & Cambridge Nationals qualification**, King Edward VI Community College <small class="font-light font-mono text-xs">(2014 - 2018)</small>
- 10 GCSEs including Maths and English
- OCR Cambridge Nationals Creative iMedia Level 1/2 Award/Certificate - Merit at Level 2
### Additional
- Full drivers licence (A & B)
---
## Projects
<Projects />