feat: make single html and add schemas for socials

This commit is contained in:
Jet Pham 2026-03-09 17:13:43 -07:00
parent 4c09d416cf
commit a7ecb3a390
No known key found for this signature in database
7 changed files with 190 additions and 23 deletions

View file

@ -6,18 +6,77 @@
<meta name="theme-color" content="#000000" />
<meta name="apple-mobile-web-app-title" content="Jet Pham" />
<title>Jet Pham - Software Extremist</title>
<meta name="description" content="Jet Pham's personal website" />
<meta name="description" content="Jet Pham's personal website. Software extremist." />
<link rel="canonical" href="https://jetpham.com/" />
<link rel="manifest" href="/manifest.json" />
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link rel="preload" href="/Web437_IBM_VGA_8x16.woff" as="font" type="font/woff" crossorigin />
<meta property="og:title" content="Jet Pham - Software Extremist" />
<meta property="og:description" content="Jet Pham's personal website" />
<meta property="og:description" content="Jet Pham's personal website. Software extremist." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://jetpham.com" />
<meta property="og:url" content="https://jetpham.com/" />
<meta property="og:site_name" content="Jet Pham" />
<meta property="og:image" content="https://jetpham.com/web-app-manifest-512x512.png" />
<meta property="og:image:width" content="512" />
<meta property="og:image:height" content="512" />
<meta property="og:image:alt" content="Jet Pham" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Jet Pham - Software Extremist" />
<meta name="twitter:description" content="Jet Pham's personal website" />
<meta name="twitter:description" content="Jet Pham's personal website. Software extremist." />
<meta name="twitter:image" content="https://jetpham.com/web-app-manifest-512x512.png" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Jet Pham",
"givenName": "Jet",
"familyName": "Pham",
"description": "Software extremist.",
"url": "https://jetpham.com",
"jobTitle": "Software Extremist",
"hasOccupation": {
"@type": "Occupation",
"name": "Hacker"
},
"email": "jet@extremist.software",
"image": "https://jetpham.com/jet.svg",
"alumniOf": {
"@type": "CollegeOrUniversity",
"name": "University of San Francisco",
"url": "https://www.usfca.edu"
},
"hasCredential": {
"@type": "EducationalOccupationalCredential",
"credentialCategory": "degree",
"name": "Bachelor of Science in Computer Science"
},
"homeLocation": {
"@type": "City",
"name": "San Francisco, CA"
},
"workLocation": {
"@type": "City",
"name": "San Francisco, CA"
},
"memberOf": {
"@type": "Organization",
"name": "Noisebridge",
"url": "https://www.noisebridge.net"
},
"affiliation": {
"@type": "Organization",
"name": "Noisebridge",
"url": "https://www.noisebridge.net"
},
"sameAs": [
"https://github.com/jetpham",
"https://x.com/jetpham5",
"https://bsky.app/profile/jetpham.com",
"https://git.extremist.software"
]
}
</script>
</head>
<body style="background:#000">
<canvas id="canvas" class="fixed top-0 left-0 -z-10 h-screen w-screen" aria-hidden="true"></canvas>
@ -25,27 +84,28 @@
<div class="flex flex-col items-center justify-start px-4">
<!-- FrostedBox -->
<div class="relative px-[2ch] py-[2ch] my-[2ch] w-full max-w-[66.666667%] min-w-fit md:mt-[4ch]">
<!-- Frosted glass backdrop with mask -->
<div
class="pointer-events-none absolute inset-0 h-[200%]"
style="background-color: rgba(0, 0, 0, 0.75); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); mask-image: linear-gradient(to bottom, black 0% 50%, transparent 50% 100%); -webkit-mask-image: linear-gradient(to bottom, black 0% 50%, transparent 50% 100%);"
aria-hidden="true"
></div>
<!-- Border -->
<div class="absolute inset-0 border-2 border-white"></div>
<div class="absolute inset-0 border-2 border-white" aria-hidden="true"></div>
<!-- Content -->
<div class="relative z-10">
<div class="flex flex-col items-center justify-center gap-[2ch] md:flex-row">
<div class="order-1 flex flex-col items-center md:order-2">
<div id="ansi-art"></div>
<div class="mt-[2ch]">Software Extremist</div>
<h1 class="sr-only">Jet Pham</h1>
<div id="ansi-art" aria-hidden="true"></div>
<p class="mt-[2ch]">Software Extremist</p>
</div>
<div class="order-2 shrink-0 md:order-1">
<img
src="/jet.svg"
alt="Jet"
alt="A picture of Jet wearing a beanie in purple and blue lighting"
width="250"
height="250"
class="aspect-square w-full max-w-[250px] object-cover md:h-[263px] md:w-[175px] md:max-w-none"
style="background-color: #a604f3; color: transparent"
/>
</div>
</div>

94
package-lock.json generated
View file

@ -22,6 +22,7 @@
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.1",
"vite": "^7.3.1",
"vite-plugin-singlefile": "^2.3.0",
"vite-plugin-top-level-await": "^1.6.0",
"vite-plugin-wasm": "^3.5.0"
}
@ -1899,6 +1900,19 @@
"node": "18 || 20 || >=22"
}
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cgol": {
"resolved": "cgol/pkg",
"link": true
@ -2234,6 +2248,19 @@
"node": ">=16.0.0"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@ -2350,6 +2377,16 @@
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -2699,6 +2736,33 @@
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/micromatch/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/minimatch": {
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
@ -3114,6 +3178,19 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/ts-api-utils": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
@ -3294,6 +3371,23 @@
}
}
},
"node_modules/vite-plugin-singlefile": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/vite-plugin-singlefile/-/vite-plugin-singlefile-2.3.0.tgz",
"integrity": "sha512-DAcHzYypM0CasNLSz/WG0VdKOCxGHErfrjOoyIPiNxTPTGmO6rRD/te93n1YL/s+miXq66ipF1brMBikf99c6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"micromatch": "^4.0.8"
},
"engines": {
"node": ">18.0.0"
},
"peerDependencies": {
"rollup": "^4.44.1",
"vite": "^5.4.11 || ^6.0.0 || ^7.0.0"
}
},
"node_modules/vite-plugin-top-level-await": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.6.0.tgz",

View file

@ -30,6 +30,7 @@
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.1",
"vite": "^7.3.1",
"vite-plugin-singlefile": "^2.3.0",
"vite-plugin-top-level-await": "^1.6.0",
"vite-plugin-wasm": "^3.5.0"
},

4
public/robots.txt Normal file
View file

@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://jetpham.com/sitemap.xml

8
public/sitemap.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://jetpham.com/</loc>
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
</urlset>

View file

@ -1,17 +1,8 @@
import "~/styles/globals.css";
import Jet from "~/assets/Jet.txt?ansi";
import init, { start } from "cgol";
document.getElementById("ansi-art")!.innerHTML = Jet;
import("cgol")
.then(async (cgolModule) => {
if (typeof cgolModule.default === "function") {
await cgolModule.default();
}
if (typeof cgolModule.start === "function") {
cgolModule.start();
}
})
.catch((error: unknown) => {
console.error("Failed to initialize CGOL WebAssembly module:", error);
});
await init();
start();

View file

@ -2,10 +2,17 @@ import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
import wasm from "vite-plugin-wasm";
import topLevelAwait from "vite-plugin-top-level-await";
import { viteSingleFile } from "vite-plugin-singlefile";
import ansi from "./vite-plugin-ansi";
export default defineConfig({
plugins: [ansi(), tailwindcss(), wasm(), topLevelAwait()],
plugins: [
ansi(),
tailwindcss(),
wasm(),
topLevelAwait(),
viteSingleFile({ useRecommendedBuildConfig: false }),
],
resolve: {
alias: {
"~": "/src",
@ -25,5 +32,7 @@ export default defineConfig({
},
build: {
target: "esnext",
assetsInlineLimit: 0,
cssCodeSplit: false,
},
});