commit 83fdf3134c8b50fedf8aa51d21348ab50c05c223 Author: kokopi Date: Sun Mar 8 02:22:40 2026 +0900 init diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..83cc66d --- /dev/null +++ b/.air.toml @@ -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 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..87b8e33 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +tmp/ +.dev.pids +.env +static/css/app.css +*_templ.go +server +node_modules/ +bun.lock diff --git a/components/icons/icons.templ b/components/icons/icons.templ new file mode 100644 index 0000000..9c021fe --- /dev/null +++ b/components/icons/icons.templ @@ -0,0 +1,14 @@ +package icons + +templ ArrowUpRight(className string) { + + + +} diff --git a/components/layout.templ b/components/layout.templ new file mode 100644 index 0000000..9620cc8 --- /dev/null +++ b/components/layout.templ @@ -0,0 +1,75 @@ +package components + +import ( + "fmt" + "personal-site/constants" + "time" +) + +templ navbar(params *constants.LayoutParams) { +
+ +
+} + +templ MainLayout(params *constants.LayoutParams) { + + + + + + + { params.Title } + + +
+ @navbar(params) + // base container +
+ { children... } +
+
+

+ © { fmt.Sprintf("%d", time.Now().Year()) } derrickgee.dev - Built + with Golang +

+
+
+ + +} diff --git a/constants/layout_parameters.go b/constants/layout_parameters.go new file mode 100644 index 0000000..fa0f3f8 --- /dev/null +++ b/constants/layout_parameters.go @@ -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", + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..169cb7d --- /dev/null +++ b/go.mod @@ -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 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..97218c5 --- /dev/null +++ b/go.sum @@ -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= diff --git a/main.go b/main.go new file mode 100644 index 0000000..2d52e79 --- /dev/null +++ b/main.go @@ -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") + +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..860ad73 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "@tailwindcss/cli": "^4.2.1", + "tailwindcss": "^4.2.1" + } +} \ No newline at end of file diff --git a/pages/index.templ b/pages/index.templ new file mode 100644 index 0000000..ddcc8e9 --- /dev/null +++ b/pages/index.templ @@ -0,0 +1,271 @@ +package pages + +import "personal-site/components" +import "personal-site/constants" +import "personal-site/components/icons" + +templ heroSection() { +
+

+ available for work +

+

+ Derrick Gee +

+

Full Stack Software Engineer

+

+ + + + + Japan · US Citizen +

+

+ I build full-stack web applications with a focus on developer experience and real-world impact. Python, C# + Blazor, Go — and everything in between. +

+ +
+} + +templ aboutSection() { +
+ +
+

+ 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. +

+

+ When I'm not coding, I'm exploring new technologies that solve real-world problems. Currently based in + Japan, working remotely. +

+
+ Python + + C# + / Blazor + + Golang + FastAPI + Hugo + Tailwindcss + Javascript + Lua + Neovim + Linux +
+
+
+} + +templ expSection() { +
+ +
+ // westbold +
+
+
+

+ + Westbold · Remote +

+

Full Stack Software Engineer

+
+ Jul 2021 — Present +
+

+ Full-stack development across customer-facing + workflows, frontend architecture, and internal tooling. Focused on improving usability, reducing + friction, and modernizing the codebase. +

+
+ C# + Blazor + Tailwindcss + Hugo + Javascript + Python +
+
+ // tenchijin +
+
+
+

+ + Tenchijin · Remote +

+

Full Stack Software Engineer

+
+ Dec 2020 — Sep 2021 +
+

+ Backend development with some frontend on an + enterprise satellite data platform. Improved performance, rewrote core services, and documented + workflows for faster onboarding. +

+
+ Python + Django + VueJS +
+
+ // hennge +
+
+
+

+ + Hennge · Hybrid +

+

Software Engineer Intern

+
+ Sep 2020 — Nov 2020 +
+

+ Contributed to a production enterprise email platform + and built internal proof-of-concept projects to explore cloud infrastructure. +

+
+ Python + VueJS + Terraform + AWS +
+
+
+
+} + +templ Index() { + {{ params := constants.NewLayoutParams("Home") }} + @components.MainLayout(params) { + + @heroSection() + @aboutSection() + @expSection() + } +} diff --git a/scripts/dev.sh b/scripts/dev.sh new file mode 100755 index 0000000..3562313 --- /dev/null +++ b/scripts/dev.sh @@ -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 + diff --git a/scripts/tw.sh b/scripts/tw.sh new file mode 100755 index 0000000..85def58 --- /dev/null +++ b/scripts/tw.sh @@ -0,0 +1,3 @@ +#!/bin/bash +bun run tailwindcss -i ../tailwind.css -o ../static/css/app.css --watch + diff --git a/static/fonts/Geist.woff2 b/static/fonts/Geist.woff2 new file mode 100644 index 0000000..bb6885b Binary files /dev/null and b/static/fonts/Geist.woff2 differ diff --git a/static/fonts/OFL.txt b/static/fonts/OFL.txt new file mode 100644 index 0000000..b48941f --- /dev/null +++ b/static/fonts/OFL.txt @@ -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. diff --git a/static/fonts/README.txt b/static/fonts/README.txt new file mode 100644 index 0000000..78e0564 --- /dev/null +++ b/static/fonts/README.txt @@ -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. diff --git a/static/fonts/static/Geist-Black.ttf b/static/fonts/static/Geist-Black.ttf new file mode 100644 index 0000000..5552d16 Binary files /dev/null and b/static/fonts/static/Geist-Black.ttf differ diff --git a/static/fonts/static/Geist-Bold.ttf b/static/fonts/static/Geist-Bold.ttf new file mode 100644 index 0000000..71dc002 Binary files /dev/null and b/static/fonts/static/Geist-Bold.ttf differ diff --git a/static/fonts/static/Geist-ExtraBold.ttf b/static/fonts/static/Geist-ExtraBold.ttf new file mode 100644 index 0000000..5327eb0 Binary files /dev/null and b/static/fonts/static/Geist-ExtraBold.ttf differ diff --git a/static/fonts/static/Geist-ExtraLight.ttf b/static/fonts/static/Geist-ExtraLight.ttf new file mode 100644 index 0000000..943cb76 Binary files /dev/null and b/static/fonts/static/Geist-ExtraLight.ttf differ diff --git a/static/fonts/static/Geist-Light.ttf b/static/fonts/static/Geist-Light.ttf new file mode 100644 index 0000000..cd3835d Binary files /dev/null and b/static/fonts/static/Geist-Light.ttf differ diff --git a/static/fonts/static/Geist-Medium.ttf b/static/fonts/static/Geist-Medium.ttf new file mode 100644 index 0000000..97712e5 Binary files /dev/null and b/static/fonts/static/Geist-Medium.ttf differ diff --git a/static/fonts/static/Geist-Regular.ttf b/static/fonts/static/Geist-Regular.ttf new file mode 100644 index 0000000..88c6d70 Binary files /dev/null and b/static/fonts/static/Geist-Regular.ttf differ diff --git a/static/fonts/static/Geist-SemiBold.ttf b/static/fonts/static/Geist-SemiBold.ttf new file mode 100644 index 0000000..42d34ff Binary files /dev/null and b/static/fonts/static/Geist-SemiBold.ttf differ diff --git a/static/fonts/static/Geist-Thin.ttf b/static/fonts/static/Geist-Thin.ttf new file mode 100644 index 0000000..79ee487 Binary files /dev/null and b/static/fonts/static/Geist-Thin.ttf differ diff --git a/tailwind.css b/tailwind.css new file mode 100644 index 0000000..b9f6341 --- /dev/null +++ b/tailwind.css @@ -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; + } +}