init
This commit is contained in:
54
.air.toml
Normal file
54
.air.toml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
root = "."
|
||||||
|
testdata_dir = "testdata"
|
||||||
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
args_bin = []
|
||||||
|
bin = "./tmp/main"
|
||||||
|
cmd = "templ generate && bun run tailwindcss -i ./tailwind.css -o ./static/css/app.css --minify && go build -o ./tmp/main ."
|
||||||
|
delay = 2000
|
||||||
|
exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules", ".git", "static", "scripts", "migrations"]
|
||||||
|
exclude_file = []
|
||||||
|
exclude_regex = ["_test.go", "_templ.go"]
|
||||||
|
exclude_unchanged = true
|
||||||
|
follow_symlink = false
|
||||||
|
full_bin = ""
|
||||||
|
include_dir = []
|
||||||
|
include_ext = ["go", "tpl", "tmpl", "html", "templ"]
|
||||||
|
include_file = []
|
||||||
|
log = "build-errors.log"
|
||||||
|
poll = false
|
||||||
|
poll_interval = 0
|
||||||
|
post_cmd = []
|
||||||
|
pre_cmd = []
|
||||||
|
rerun = false
|
||||||
|
rerun_delay = 500
|
||||||
|
send_interrupt = true
|
||||||
|
kill_delay = "2s"
|
||||||
|
stop_on_error = true
|
||||||
|
stop_on_root = true
|
||||||
|
|
||||||
|
[color]
|
||||||
|
app = ""
|
||||||
|
build = "yellow"
|
||||||
|
main = "magenta"
|
||||||
|
runner = "green"
|
||||||
|
watcher = "cyan"
|
||||||
|
|
||||||
|
[log]
|
||||||
|
main_only = false
|
||||||
|
silent = false
|
||||||
|
time = false
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
clean_on_exit = true
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
app_port = 0
|
||||||
|
enabled = false
|
||||||
|
proxy_port = 0
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
clear_on_rebuild = true
|
||||||
|
keep_scroll = false
|
||||||
|
|
||||||
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
tmp/
|
||||||
|
.dev.pids
|
||||||
|
.env
|
||||||
|
static/css/app.css
|
||||||
|
*_templ.go
|
||||||
|
server
|
||||||
|
node_modules/
|
||||||
|
bun.lock
|
||||||
14
components/icons/icons.templ
Normal file
14
components/icons/icons.templ
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package icons
|
||||||
|
|
||||||
|
templ ArrowUpRight(className string) {
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class={ className }
|
||||||
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 19.5 15-15m0 0H8.25m11.25 0v11.25"></path>
|
||||||
|
</svg>
|
||||||
|
}
|
||||||
75
components/layout.templ
Normal file
75
components/layout.templ
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package components
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"personal-site/constants"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
templ navbar(params *constants.LayoutParams) {
|
||||||
|
<header class="sticky top-0 z-50 w-full border-b border-zinc-800 bg-bg-100/80 backdrop-blur-sm">
|
||||||
|
<div class="max-w-3xl mx-auto h-12 flex items-center justify-between">
|
||||||
|
<a
|
||||||
|
href="/"
|
||||||
|
class="font-mono text-xs text-fg-200 tracking-widest uppercase hover:text-fg-100 transition-colors duration-150"
|
||||||
|
>
|
||||||
|
{ params.NavTitle }
|
||||||
|
</a>
|
||||||
|
<nav class="flex items-center gap-5">
|
||||||
|
<a
|
||||||
|
href="/projects"
|
||||||
|
class="text-xs text-fg-300 hover:text-fg-100 transition-colors duration-150"
|
||||||
|
>projects</a>
|
||||||
|
<a
|
||||||
|
href="https://github.com"
|
||||||
|
class="text-xs text-fg-300 hover:text-fg-100 transition-colors duration-150 flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<svg width="12" height="12" viewBox="0 0 32 32" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M16 0C7.163 0 0 7.163 0 16c0 8.836 7.163 16 16 16 8.836 0 16-7.163 16-16C32 7.163 24.837 0 16 0zm7.68 21.155a1.06 1.06 0 01-1.458.387l-4.514-2.607a1.842 1.842 0 01-.638.223v4.017a1.06 1.06 0 01-2.12 0v-4.017a1.842 1.842 0 01-1.3-1.787 1.843 1.843 0 011.842-1.842c.347 0 .671.097.948.264l4.418-2.551a1.06 1.06 0 011.457.387 1.06 1.06 0 01-.387 1.457l-4.418 2.551c.01.09.016.181.016.274 0 .093-.006.184-.016.274l4.514 2.607a1.06 1.06 0 01.387 1.457l-.731-.695zm-13.512-8.24a1.06 1.06 0 011.457-.387l4.418 2.551c.277-.167.601-.264.948-.264.347 0 .671.097.948.264l4.418-2.551a1.06 1.06 0 011.457.387 1.06 1.06 0 01-.387 1.457l-4.418 2.551c.01.09.016.181.016.274a1.843 1.843 0 01-1.842 1.842 1.843 1.843 0 01-1.842-1.842c0-.093.006-.184.016-.274l-4.418-2.551a1.06 1.06 0 01-.387-1.457h.616z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
gitea
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://github.com"
|
||||||
|
class="text-xs text-fg-300 hover:text-fg-100 transition-colors duration-150 flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
github
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ MainLayout(params *constants.LayoutParams) {
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<link rel="stylesheet" href={ fmt.Sprintf("/static/css/app.css?v=%d", time.Now().Unix()) }/>
|
||||||
|
<title>{ params.Title }</title>
|
||||||
|
</head>
|
||||||
|
<body class="relative bg-linear-to-b from-bg-400 to-bg-100 text-fg-100 overflow-hidden font-sans">
|
||||||
|
<div class="h-screen grid grid-rows-[auto_1fr_auto] overflow-y-auto overflow-x-hidden">
|
||||||
|
@navbar(params)
|
||||||
|
// base container
|
||||||
|
<div class="p-4 mt-6 flex flex-col gap-6 max-w-3xl mx-auto">
|
||||||
|
{ children... }
|
||||||
|
</div>
|
||||||
|
<footer class="w-full text-center py-4">
|
||||||
|
<p class="text-xs text-secondary text-fg-200">
|
||||||
|
© { fmt.Sprintf("%d", time.Now().Year()) } derrickgee.dev - Built
|
||||||
|
with Golang
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
}
|
||||||
13
constants/layout_parameters.go
Normal file
13
constants/layout_parameters.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package constants
|
||||||
|
|
||||||
|
type LayoutParams struct {
|
||||||
|
Title string
|
||||||
|
NavTitle string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLayoutParams(title string) *LayoutParams {
|
||||||
|
return &LayoutParams{
|
||||||
|
Title: title,
|
||||||
|
NavTitle: "derrickgee.dev",
|
||||||
|
}
|
||||||
|
}
|
||||||
38
go.mod
Normal file
38
go.mod
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
module personal-site
|
||||||
|
|
||||||
|
go 1.25.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/a-h/templ v0.3.1001 // indirect
|
||||||
|
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||||
|
github.com/bytedance/sonic v1.15.0 // indirect
|
||||||
|
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||||
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||||
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
|
github.com/gin-gonic/gin v1.12.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
|
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||||
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
|
github.com/quic-go/qpack v0.6.0 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||||
|
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
|
||||||
|
golang.org/x/arch v0.24.0 // indirect
|
||||||
|
golang.org/x/crypto v0.48.0 // indirect
|
||||||
|
golang.org/x/net v0.51.0 // indirect
|
||||||
|
golang.org/x/sys v0.41.0 // indirect
|
||||||
|
golang.org/x/text v0.34.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
|
)
|
||||||
82
go.sum
Normal file
82
go.sum
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
github.com/a-h/templ v0.3.1001 h1:yHDTgexACdJttyiyamcTHXr2QkIeVF1MukLy44EAhMY=
|
||||||
|
github.com/a-h/templ v0.3.1001/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
|
||||||
|
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||||
|
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||||
|
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||||
|
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||||
|
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||||
|
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||||
|
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||||
|
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
|
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||||
|
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||||
|
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
|
||||||
|
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||||
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||||
|
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||||
|
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||||
|
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||||
|
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||||
|
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||||
|
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
|
||||||
|
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
|
||||||
|
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
|
||||||
|
golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||||
|
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||||
|
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||||
|
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
|
||||||
|
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||||
|
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||||
|
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||||
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
69
main.go
Normal file
69
main.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"personal-site/pages"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupRoutesAndMiddleware() *gin.Engine {
|
||||||
|
r := gin.Default()
|
||||||
|
r.Static("/static", "./static")
|
||||||
|
r.GET("/", func(c *gin.Context) {
|
||||||
|
page := pages.Index()
|
||||||
|
page.Render(c.Request.Context(), c.Writer)
|
||||||
|
})
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if err := godotenv.Load(); err != nil {
|
||||||
|
log.Println("No .env file found")
|
||||||
|
} else {
|
||||||
|
log.Println(".env loaded successfully")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
router := setupRoutesAndMiddleware()
|
||||||
|
|
||||||
|
// dev env
|
||||||
|
router.SetTrustedProxies(nil)
|
||||||
|
|
||||||
|
// prod env
|
||||||
|
// router.SetTrustedProxies([]string{"127.0.0.1"})
|
||||||
|
// router.TrustedPlatform = gin.PlatformCloudflare
|
||||||
|
|
||||||
|
srv := &http.Server{
|
||||||
|
Addr: ":3500",
|
||||||
|
Handler: router,
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
log.Println("Server starting on :3500")
|
||||||
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
|
log.Fatal("Failed to start server:", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
quit := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
<-quit
|
||||||
|
|
||||||
|
log.Println("Shutting down server...")
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := srv.Shutdown(ctx); err != nil {
|
||||||
|
log.Fatal("Server forced to shutdown:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Server exited")
|
||||||
|
|
||||||
|
}
|
||||||
6
package.json
Normal file
6
package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"@tailwindcss/cli": "^4.2.1",
|
||||||
|
"tailwindcss": "^4.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
271
pages/index.templ
Normal file
271
pages/index.templ
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
package pages
|
||||||
|
|
||||||
|
import "personal-site/components"
|
||||||
|
import "personal-site/constants"
|
||||||
|
import "personal-site/components/icons"
|
||||||
|
|
||||||
|
templ heroSection() {
|
||||||
|
<section id="hero" class="pb-5">
|
||||||
|
<p
|
||||||
|
class="hero-eyebrow fade-up font-mono text-xs font-medium text-fg-200 tracking-[0.08em] uppercase flex items-center gap-2 mb-5"
|
||||||
|
>
|
||||||
|
available for work
|
||||||
|
</p>
|
||||||
|
<h1 class="fade-up delay-1 text-[clamp(2.25rem,6vw,3.25rem)] font-bold tracking-[-0.04em] leading-[1.05] mb-3">
|
||||||
|
Derrick Gee
|
||||||
|
</h1>
|
||||||
|
<p class="fade-up delay-2 text-base font-normal text-fg-200 mb-2">Full Stack Software Engineer</p>
|
||||||
|
<p class="fade-up delay-2 font-mono text-xs text-fg-300 flex items-center gap-1.5 mb-8">
|
||||||
|
<svg width="12" height="12" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"></path>
|
||||||
|
<path d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
||||||
|
</svg>
|
||||||
|
Japan · US Citizen
|
||||||
|
</p>
|
||||||
|
<p class="fade-up delay-3 text-[0.9375rem] text-fg-200 max-w-120 leading-[1.7] mb-9">
|
||||||
|
I build full-stack web applications with a focus on developer experience and real-world impact. Python, C#
|
||||||
|
Blazor, Go — and everything in between.
|
||||||
|
</p>
|
||||||
|
<div class="fade-up delay-4 flex items-center gap-3 flex-wrap">
|
||||||
|
<a
|
||||||
|
href="#projects"
|
||||||
|
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium bg-fg-100 text-bg-100 border border-transparent no-underline transition-opacity duration-150 hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring-100"
|
||||||
|
>
|
||||||
|
View Projects
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="#experience"
|
||||||
|
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium bg-transparent text-fg-100 border border-border-100 no-underline transition-all duration-150 hover:bg-bg-300 hover:border-border-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring-100"
|
||||||
|
>
|
||||||
|
Experience
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://git.kokopi.dev/kokopi"
|
||||||
|
target="_blank"
|
||||||
|
class="inline-flex items-center gap-2 p-1.5 rounded-lg text-[0.8125rem] font-medium bg-transparent text-fg-200 no-underline transition-all duration-150 hover:text-fg-100 hover:bg-bg-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring-100"
|
||||||
|
>
|
||||||
|
<svg width="15" height="15" viewBox="0 0 32 32" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M16 0C7.163 0 0 7.163 0 16c0 8.836 7.163 16 16 16 8.836 0 16-7.163 16-16C32 7.163 24.837 0 16 0zm7.68 21.155a1.06 1.06 0 01-1.458.387l-4.514-2.607a1.842 1.842 0 01-.638.223v4.017a1.06 1.06 0 01-2.12 0v-4.017a1.842 1.842 0 01-1.3-1.787 1.843 1.843 0 011.842-1.842c.347 0 .671.097.948.264l4.418-2.551a1.06 1.06 0 011.457.387 1.06 1.06 0 01-.387 1.457l-4.418 2.551c.01.09.016.181.016.274 0 .093-.006.184-.016.274l4.514 2.607a1.06 1.06 0 01.387 1.457l-.731-.695zm-13.512-8.24a1.06 1.06 0 011.457-.387l4.418 2.551c.277-.167.601-.264.948-.264.347 0 .671.097.948.264l4.418-2.551a1.06 1.06 0 011.457.387 1.06 1.06 0 01-.387 1.457l-4.418 2.551c.01.09.016.181.016.274a1.843 1.843 0 01-1.842 1.842 1.843 1.843 0 01-1.842-1.842c0-.093.006-.184.016-.274l-4.418-2.551a1.06 1.06 0 01-.387-1.457h.616z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
Gitea
|
||||||
|
@icons.ArrowUpRight("size-3")
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://github.com/kokopi-dev"
|
||||||
|
target="_blank"
|
||||||
|
class="inline-flex items-center gap-2 p-1.5 rounded-lg text-[0.8125rem] font-medium bg-transparent text-fg-200 no-underline transition-all duration-150 hover:text-fg-100 hover:bg-bg-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring-100"
|
||||||
|
>
|
||||||
|
<svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
GitHub
|
||||||
|
@icons.ArrowUpRight("size-3")
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ aboutSection() {
|
||||||
|
<section id="about" class="py-5">
|
||||||
|
<p
|
||||||
|
class="section-label font-mono text-[0.6875rem] font-semibold tracking-widest uppercase text-fg-300 mb-5 flex items-center gap-3"
|
||||||
|
>
|
||||||
|
about
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="fade-up bg-bg-200 border border-border-100 rounded-lg p-5 transition-all duration-200 hover:border-border-200 hover:bg-bg-300"
|
||||||
|
>
|
||||||
|
<p class="text-[0.9375rem] text-fg-200 leading-[1.75] mb-5">
|
||||||
|
I'm a Python and C# Blazor full-stack software engineer. I work across the whole stack — backend APIs,
|
||||||
|
server-side rendering, and polished frontends. I'm also a Linux and Neovim enthusiast who enjoys tinkering
|
||||||
|
with configs as much as shipping features.
|
||||||
|
</p>
|
||||||
|
<p class="text-[0.9375rem] text-fg-200 leading-[1.75] mb-6">
|
||||||
|
When I'm not coding, I'm exploring new technologies that solve real-world problems. Currently based in
|
||||||
|
Japan, working remotely.
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-wrap gap-1.5">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Python</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>
|
||||||
|
C#
|
||||||
|
/ Blazor
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Golang</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>FastAPI</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Hugo</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Tailwindcss</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Javascript</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Lua</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Neovim</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100 whitespace-nowrap"
|
||||||
|
>Linux</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ expSection() {
|
||||||
|
<section id="experience" class="py-5">
|
||||||
|
<p
|
||||||
|
class="section-label font-mono text-[0.6875rem] font-semibold tracking-widest uppercase text-fg-300 mb-5 flex items-center gap-3"
|
||||||
|
>
|
||||||
|
experience
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-col gap-3">
|
||||||
|
// westbold
|
||||||
|
<div
|
||||||
|
class="fade-up bg-bg-200 border border-border-100 rounded-lg p-5 transition-colors duration-200 hover:border-border-200"
|
||||||
|
>
|
||||||
|
<div class="flex justify-between items-start gap-4 flex-wrap mb-1.5">
|
||||||
|
<div>
|
||||||
|
<p class="text-xs font-medium text-fg-200 mb-1 flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
class="status-live inline-block w-1.5 h-1.5 rounded-full bg-[oklch(0.72_0.15_145)] mr-1"
|
||||||
|
></span>
|
||||||
|
Westbold · Remote
|
||||||
|
</p>
|
||||||
|
<p class="text-[0.9375rem] font-semibold mb-2">Full Stack Software Engineer</p>
|
||||||
|
</div>
|
||||||
|
<span class="font-mono text-[0.6875rem] text-fg-300 whitespace-nowrap pt-0.5">Jul 2021 — Present</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-fg-200 mb-3.5 leading-relaxed">
|
||||||
|
Full-stack development across customer-facing
|
||||||
|
workflows, frontend architecture, and internal tooling. Focused on improving usability, reducing
|
||||||
|
friction, and modernizing the codebase.
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-wrap gap-1.5">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>C#</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Blazor</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Tailwindcss</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Hugo</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Javascript</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Python</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
// tenchijin
|
||||||
|
<div
|
||||||
|
class="fade-up delay-1 bg-bg-200 border border-border-100 rounded-lg p-5 transition-colors duration-200 hover:border-border-200"
|
||||||
|
>
|
||||||
|
<div class="flex justify-between items-start gap-4 flex-wrap mb-1.5">
|
||||||
|
<div>
|
||||||
|
<p class="text-xs font-medium text-fg-200 mb-1 flex items-center gap-2">
|
||||||
|
<span class="inline-block w-1.5 h-1.5 rounded-full bg-[oklch(0.75_0_0)] mr-1"></span>
|
||||||
|
Tenchijin · Remote
|
||||||
|
</p>
|
||||||
|
<p class="text-[0.9375rem] font-semibold mb-2">Full Stack Software Engineer</p>
|
||||||
|
</div>
|
||||||
|
<span class="font-mono text-[0.6875rem] text-fg-300 whitespace-nowrap pt-0.5">Dec 2020 — Sep 2021</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-fg-200 mb-3.5 leading-relaxed">
|
||||||
|
Backend development with some frontend on an
|
||||||
|
enterprise satellite data platform. Improved performance, rewrote core services, and documented
|
||||||
|
workflows for faster onboarding.
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-wrap gap-1.5">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Python</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Django</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>VueJS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
// hennge
|
||||||
|
<div
|
||||||
|
class="fade-up delay-2 bg-bg-200 border border-border-100 rounded-lg p-5 transition-colors duration-200 hover:border-border-200"
|
||||||
|
>
|
||||||
|
<div class="flex justify-between items-start gap-4 flex-wrap mb-1.5">
|
||||||
|
<div>
|
||||||
|
<p class="text-xs font-medium text-fg-200 mb-1 flex items-center gap-2">
|
||||||
|
<span class="inline-block w-1.5 h-1.5 rounded-full bg-[oklch(0.75_0_0)] mr-1"></span>
|
||||||
|
Hennge · Hybrid
|
||||||
|
</p>
|
||||||
|
<p class="text-[0.9375rem] font-semibold mb-2">Software Engineer Intern</p>
|
||||||
|
</div>
|
||||||
|
<span class="font-mono text-[0.6875rem] text-fg-300 whitespace-nowrap pt-0.5">Sep 2020 — Nov 2020</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-fg-200 mb-3.5 leading-relaxed">
|
||||||
|
Contributed to a production enterprise email platform
|
||||||
|
and built internal proof-of-concept projects to explore cloud infrastructure.
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-wrap gap-1.5">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Python</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>VueJS</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>Terraform</span>
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2 py-0.5 rounded-md font-mono text-[0.6875rem] font-medium bg-bg-300 text-fg-200 border border-border-100"
|
||||||
|
>AWS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ Index() {
|
||||||
|
{{ params := constants.NewLayoutParams("Home") }}
|
||||||
|
@components.MainLayout(params) {
|
||||||
|
<style>
|
||||||
|
.hero-eyebrow::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-fg-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-label::after {
|
||||||
|
content: '';
|
||||||
|
flex: 1;
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-border-100);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@heroSection()
|
||||||
|
@aboutSection()
|
||||||
|
@expSection()
|
||||||
|
}
|
||||||
|
}
|
||||||
77
scripts/dev.sh
Executable file
77
scripts/dev.sh
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cd ..
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ ! -d "/tmp/firefox-dev" ]; then
|
||||||
|
echo "Creating firefox profile"
|
||||||
|
mkdir -p /tmp/firefox-dev
|
||||||
|
firefox -CreateProfile "dev-profile /tmp/firefox-dev"
|
||||||
|
cat >> /tmp/firefox-dev/prefs.js << EOF
|
||||||
|
user_pref("browser.download.dir", "~/downloads");
|
||||||
|
user_pref("browser.download.folderList", 2);
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# PID file to track processes
|
||||||
|
PIDFILE=".dev.pids"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
echo -e "\n${YELLOW}🛑 Shutting down development servers...${NC}"
|
||||||
|
|
||||||
|
if [ -f "$PIDFILE" ]; then
|
||||||
|
while read -r pid name; do
|
||||||
|
if kill -0 "$pid" 2>/dev/null; then
|
||||||
|
echo -e "${BLUE} Stopping $name (PID: $pid)${NC}"
|
||||||
|
kill "$pid" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
done <"$PIDFILE"
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n${YELLLOW}Killing dev-profile browser"
|
||||||
|
pkill -f "dev-profile"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ All processes stopped${NC}"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set up signal handlers
|
||||||
|
trap cleanup SIGINT SIGTERM EXIT
|
||||||
|
|
||||||
|
# Clear any existing PID file
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
|
||||||
|
echo -e "${GREEN}🚀 Starting development environment...${NC}"
|
||||||
|
|
||||||
|
# Start Templ watcher
|
||||||
|
# echo -e "${BLUE}📝 Starting Templ watcher...${NC}"
|
||||||
|
# templ generate --watch &
|
||||||
|
# TEMPL_PID=$!
|
||||||
|
# echo "$TEMPL_PID templ" >>"$PIDFILE"
|
||||||
|
|
||||||
|
# Wait a moment for templ to start
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Start Air for Go hot reloading
|
||||||
|
echo -e "${BLUE}🔥 Starting Air (Go hot reload)...${NC}"
|
||||||
|
air &
|
||||||
|
AIR_PID=$!
|
||||||
|
echo "$AIR_PID air" >>"$PIDFILE"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ Development environment ready!${NC}"
|
||||||
|
echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}"
|
||||||
|
|
||||||
|
# wait for gin to start
|
||||||
|
sleep 2
|
||||||
|
firefox -P dev-profile -private-window http://localhost:3500 &
|
||||||
|
|
||||||
|
# Wait for Air process (main process)
|
||||||
|
wait $AIR_PID
|
||||||
|
|
||||||
3
scripts/tw.sh
Executable file
3
scripts/tw.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
bun run tailwindcss -i ../tailwind.css -o ../static/css/app.css --watch
|
||||||
|
|
||||||
BIN
static/fonts/Geist.woff2
Normal file
BIN
static/fonts/Geist.woff2
Normal file
Binary file not shown.
93
static/fonts/OFL.txt
Normal file
93
static/fonts/OFL.txt
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font.git)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
71
static/fonts/README.txt
Normal file
71
static/fonts/README.txt
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
Geist Variable Font
|
||||||
|
===================
|
||||||
|
|
||||||
|
This download contains Geist as both a variable font and static fonts.
|
||||||
|
|
||||||
|
Geist is a variable font with this axis:
|
||||||
|
wght
|
||||||
|
|
||||||
|
This means all the styles are contained in a single file:
|
||||||
|
Geist-VariableFont_wght.ttf
|
||||||
|
|
||||||
|
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||||
|
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||||
|
in those cases you can use the static font files for Geist:
|
||||||
|
static/Geist-Thin.ttf
|
||||||
|
static/Geist-ExtraLight.ttf
|
||||||
|
static/Geist-Light.ttf
|
||||||
|
static/Geist-Regular.ttf
|
||||||
|
static/Geist-Medium.ttf
|
||||||
|
static/Geist-SemiBold.ttf
|
||||||
|
static/Geist-Bold.ttf
|
||||||
|
static/Geist-ExtraBold.ttf
|
||||||
|
static/Geist-Black.ttf
|
||||||
|
|
||||||
|
Get started
|
||||||
|
-----------
|
||||||
|
|
||||||
|
1. Install the font files you want to use
|
||||||
|
|
||||||
|
2. Use your app's font picker to view the font family and all the
|
||||||
|
available styles
|
||||||
|
|
||||||
|
Learn more about variable fonts
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||||
|
https://variablefonts.typenetwork.com
|
||||||
|
https://medium.com/variable-fonts
|
||||||
|
|
||||||
|
In desktop apps
|
||||||
|
|
||||||
|
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||||
|
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||||
|
|
||||||
|
Online
|
||||||
|
|
||||||
|
https://developers.google.com/fonts/docs/getting_started
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||||
|
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||||
|
|
||||||
|
Installing fonts
|
||||||
|
|
||||||
|
MacOS: https://support.apple.com/en-us/HT201749
|
||||||
|
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||||
|
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||||
|
|
||||||
|
Android Apps
|
||||||
|
|
||||||
|
https://developers.google.com/fonts/docs/android
|
||||||
|
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Please read the full license text (OFL.txt) to understand the permissions,
|
||||||
|
restrictions and requirements for usage, redistribution, and modification.
|
||||||
|
|
||||||
|
You can use them in your products & projects – print or digital,
|
||||||
|
commercial or otherwise.
|
||||||
|
|
||||||
|
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||||
|
license for all details.
|
||||||
BIN
static/fonts/static/Geist-Black.ttf
Normal file
BIN
static/fonts/static/Geist-Black.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-Bold.ttf
Normal file
BIN
static/fonts/static/Geist-Bold.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-ExtraBold.ttf
Normal file
BIN
static/fonts/static/Geist-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-ExtraLight.ttf
Normal file
BIN
static/fonts/static/Geist-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-Light.ttf
Normal file
BIN
static/fonts/static/Geist-Light.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-Medium.ttf
Normal file
BIN
static/fonts/static/Geist-Medium.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-Regular.ttf
Normal file
BIN
static/fonts/static/Geist-Regular.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-SemiBold.ttf
Normal file
BIN
static/fonts/static/Geist-SemiBold.ttf
Normal file
Binary file not shown.
BIN
static/fonts/static/Geist-Thin.ttf
Normal file
BIN
static/fonts/static/Geist-Thin.ttf
Normal file
Binary file not shown.
44
tailwind.css
Normal file
44
tailwind.css
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Geist";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100 900; /* Variable font supports full range */
|
||||||
|
font-display: swap;
|
||||||
|
src: url("/static/fonts/Geist.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: "Geist", system-ui, sans-serif;
|
||||||
|
|
||||||
|
--color-bg-100: oklch(0.09 0 0);
|
||||||
|
--color-bg-200: oklch(0.12 0 0);
|
||||||
|
--color-bg-300: oklch(0.15 0 0);
|
||||||
|
--color-bg-400: oklch(0.18 0 0);
|
||||||
|
|
||||||
|
--color-fg-100: oklch(0.97 0 0);
|
||||||
|
--color-fg-200: oklch(0.6 0 0);
|
||||||
|
--color-fg-300: oklch(0.4 0 0);
|
||||||
|
|
||||||
|
--color-border-100: oklch(1 0 0 / 9%);
|
||||||
|
--color-border-200: oklch(1 0 0 / 30%);
|
||||||
|
|
||||||
|
--color-ring-100: oklch(0.55 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
@keyframes fadeUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(16px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fade-up {
|
||||||
|
animation: fadeUp 0.4s ease forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user