remove the need of an http server

This commit is contained in:
juancwu 2026-01-05 16:02:44 -05:00
commit b3224782cd
20 changed files with 567 additions and 1515 deletions

View file

@ -1,46 +0,0 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["node_modules", "assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html", "css"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = ["pnpm tw:dev"]
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
time = false
[misc]
clean_on_exit = false
[screen]
clear_on_rebuild = false
keep_scroll = true

4
.gitignore vendored
View file

@ -1,7 +1,9 @@
static/styles.css
.env
.env.*
node_modules
tmp
build
*.pem
*_templ.go
static/output.css
dist/

View file

@ -1,4 +0,0 @@
name: potoforio
bento_id: 69ee8dbe-2333-41f2-a21b-09ce9d2852b3
public_key_path: /home/jc/ghq/juancwu/potoforio/public.pem
private_key_path: /home/jc/ghq/juancwu/potoforio/private.pem

View file

@ -1,7 +0,0 @@
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": true,
"singleQuote": false,
"plugins": ["prettier-plugin-tailwindcss"]
}

View file

@ -1,29 +1,49 @@
version: '3'
tasks:
build:
desc: 'Builds the application'
cmds:
- task: build-css
- task: build-go
- task: build-views
- task: organize
build-css:
desc: 'Builds CSS with tailwind'
cmds:
- pnpm run tw:prod
build-go:
desc: 'Builds Go application'
- tailwindcss -i ./assets/css/input.css -o ./static/output.css --minify
build-views:
desc: 'Builds application views'
cmds:
- go build -o ./build/potoforio .
- go tool templ generate
- go run ./cmd/static-generator/main.go
organize:
desc: 'Organize built files into dist/'
cmds:
- rm -rf dist/
- mkdir dist/
- cp -r static dist
- mv index.html dist
# Development Tools
templ:
desc: Run templ with integrated server and hot reload
cmds:
- go tool templ generate --watch --cmd="go run ./cmd/server/main.go" --proxy="http://localhost:9000" --open-browser=false
tailwind-clean:
desc: Clean tailwind output
cmds:
- tailwindcss -i ./assets/css/input.css -o ./static/output.css --clean
tailwind-watch:
desc: Run tailwindcss in watch mode
cmds:
- tailwindcss -i ./assets/css/input.css -o ./static/output.css --watch
# Start development server
dev:
desc: Start development server with hot reload
deps:
- tailwind-clean
cmds:
- echo "Starting app..."
- task --parallel tailwind-watch templ
clean:
desc: 'Cleans up build artifacts'
desc: 'Clean up built files'
cmds:
- rm -f ./static/styles.css ./build/potoforio
run:
desc: 'Builds and runs the application'
cmds:
- task: build
- ./build/potoforio
- rm -rf dist/

106
assets/css/input.css Normal file
View file

@ -0,0 +1,106 @@
@import "tailwindcss";
@source "./page.go";
@source "./views/**/*.html";
@theme {
--font-inter: "Inter", sans-serif;
--breakpoint-3xl: 2048px;
--breakpoint-4xl: 2560px;
--breakpoint-5xl: 4096px;
}
@custom-variant retina {
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min--moz-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
@slot;
}
}
@custom-variant retina-sm {
@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 640px),
only screen and (min--moz-device-pixel-ratio: 2) and (min-width: 640px),
only screen and (-o-min-device-pixel-ratio: 2/1) and (min-width: 640px),
only screen and (min-device-pixel-ratio: 2) and (min-width: 640px),
only screen and (min-resolution: 192dpi) and (min-width: 640px),
only screen and (min-resolution: 2dppx) and (min-width: 640px) {
@slot;
}
}
@custom-variant retina-md {
@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 1024px),
only screen and (min--moz-device-pixel-ratio: 2) and (min-width: 1024px),
only screen and (-o-min-device-pixel-ratio: 2/1) and (min-width: 1024px),
only screen and (min-device-pixel-ratio: 2) and (min-width: 1024px),
only screen and (min-resolution: 192dpi) and (min-width: 1024px),
only screen and (min-resolution: 2dppx) and (min-width: 1024px) {
@slot;
}
}
@layer components {
.colourful-card {
@apply relative bg-white p-2 text-zinc-950 transition-all after:absolute after:-right-2 after:top-2 after:-z-10 after:h-full after:w-full after:bg-linear-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:bg-transparent hover:text-white hover:after:right-0 hover:after:top-0 focus:bg-transparent focus:text-white focus:after:right-0 focus:after:top-0;
}
.clip-me-from-grass {
clip-path: polygon(58.36% 5.19%,
52.34% 3.68%,
45.85% 3.05%,
37.74% 7.64%,
35.66% 12.39%,
34.82% 19.98%,
32.57% 27.81%,
29.87% 32.92%,
22.01% 37.14%,
17.02% 42.9%,
10.6% 53.43%,
8.22% 70.71%,
6.32% 80.67%,
10.69% 91.75%,
9.18% 99.36%,
47.27% 99.44%,
92.39% 99.2%,
91.85% 86.29%,
94.77% 74.28%,
88.08% 54.82%,
83.74% 45.14%,
78.61% 37.63%,
71.62% 34.03%,
64.62% 23.61%,
63.88% 18.13%,
62.23% 10.25%);
}
.grid-pattern {
width: 100%;
height: 100%;
background-size: cover;
background-position: center center;
background-repeat: repeat;
background-image: url("/static/grid.svg");
}
.radial-overlay {
background: radial-gradient(circle,
rgba(24, 24, 27, 0) 0%,
rgba(24, 24, 27, 1) 50%);
}
.polka-pattern {
background-color: #18181b;
opacity: 1;
background-image: radial-gradient(#27272a 1.3px, transparent 1.3px),
radial-gradient(#27272a 1.3px, #18181b 1.3px);
background-size: 52px 52px;
background-position:
0 0,
26px 26px;
}
}

29
cmd/server/main.go Normal file
View file

@ -0,0 +1,29 @@
package main
import (
"log"
"net/http"
"github.com/juancwu/potoforio/data"
"github.com/juancwu/potoforio/views"
)
func main() {
// Serve static files (images, manifest, etc.)
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
// Serve assets (compiled css)
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("./assets"))))
// Serve the Templ component
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
d := data.GetPageData()
component := views.Index(d)
component.Render(r.Context(), w)
})
log.Println("Dev server starting on :8080 (Proxy to :9000 via Templ)")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}

View file

@ -0,0 +1,28 @@
package main
import (
"context"
"log"
"os"
"github.com/juancwu/potoforio/data"
"github.com/juancwu/potoforio/views"
)
func main() {
f, err := os.Create("index.html")
if err != nil {
log.Fatalf("failed to create output file: %v", err)
}
defer f.Close()
d := data.GetPageData()
component := views.Index(d)
err = component.Render(context.Background(), f)
if err != nil {
log.Fatalf("failed to render template: %v", err)
}
log.Println("Static site generated successfully to index.html")
}

131
data/data.go Normal file
View file

@ -0,0 +1,131 @@
package data
type Tech struct {
TechName string
TechURL string
TechClasses string
}
type Project struct {
Name string
URL string
Description string
TechList []Tech
Repo string
Classes string
}
type Page struct {
Projects []Project
}
func GetPageData() Page {
return Page{
Projects: []Project{
{
Name: "Hermes",
URL: "",
Description: "The user-friendly terminal API client for those who are in love and addicted to do everything on the terminal.",
Repo: "https://github.com/juancwu/hermes",
Classes: "border-orange-400",
TechList: []Tech{
{TechName: "Rust", TechURL: "https://www.rust-lang.org/", TechClasses: ""},
{TechName: "Ratatui", TechURL: "https://ratatui.rs/", TechClasses: ""},
},
},
{
Name: "Konbini",
URL: "",
Description: "A \"convenient store\" with API services to manage projects' secrets or environment variables with the ability to separate the variables into their own environment.",
Repo: "https://github.com/juancwu/konbini",
Classes: "border-sky-500",
TechList: []Tech{
{TechName: "Golang", TechURL: "https://go.dev/", TechClasses: "transition bg-zinc-950 text-zinc-100"},
{TechName: "Echo", TechURL: "https://echo.labstack.com/", TechClasses: "bg-zinc-950 text-zinc-100"},
{TechName: "PostgreSQL", TechURL: "https://www.postgresql.org/", TechClasses: "bg-zinc-950 text-zinc-100"},
},
},
{
Name: "EmojiScript",
URL: "https://emojiscript.juancwu.dev/",
Description: "A silly project started for a brain rot hackathon host by Audrey Chen. Please give it a shot if you are interested!",
Repo: "https://github.com/KonferCA/EmojiScript",
Classes: "border-green-400",
TechList: []Tech{
{TechName: "Typescript", TechURL: "https://www.typescriptlang.org/", TechClasses: ""},
{TechName: "Devpost", TechURL: "https://brainrot-jia-seed-hackathon.devpost.com/", TechClasses: ""},
},
},
{
Name: "Konfer Website",
URL: "https://konfer.ca",
Description: "The official landing site for Konfer Inc.",
Repo: "https://github.com/KonferCA/Konfer.ca",
Classes: "border-indigo-300",
TechList: []Tech{
{TechName: "React", TechURL: "https://react.dev/", TechClasses: ""},
{TechName: "Firebase", TechURL: "https://firebase.google.com/", TechClasses: ""},
{TechName: "TailwindCSS", TechURL: "https://tailwindcss.com/", TechClasses: ""},
},
},
{
Name: "HawkHacks Website",
URL: "https://hawkhacks.ca",
Description: "HawkHacks is a 36 hour in-person hackathon hosted at Wilfrid Laurier University.",
Repo: "https://github.com/LaurierHawkHacks/Landing",
Classes: "border-orange-300",
TechList: []Tech{
{TechName: "React", TechURL: "https://react.dev/", TechClasses: ""},
{TechName: "Firebase", TechURL: "https://firebase.google.com/", TechClasses: ""},
{TechName: "TailwindCSS", TechURL: "https://tailwindcss.com/", TechClasses: ""},
},
},
{
Name: "LCS Website",
URL: "https://lauriercs.ca",
Description: "The official Computer Science club at Wilfrid Laurier University website.",
Repo: "https://github.com/LaurierCS/Website",
Classes: "border-cyan-400",
TechList: []Tech{
{TechName: "React", TechURL: "https://react.dev/", TechClasses: ""},
{TechName: "Firebase", TechURL: "https://firebase.google.com/", TechClasses: ""},
{TechName: "Mantine UI", TechURL: "https://mantine.dev/", TechClasses: ""},
},
},
{
Name: "Shoto",
URL: "",
Description: "Simple and effective URL shortoner.",
Repo: "https://github.com/juancwu/shoto",
Classes: "border-indigo-500",
TechList: []Tech{
{TechName: "Next.js", TechURL: "https://nextjs.org/", TechClasses: "transition bg-zinc-950 text-zinc-100 hover:bg-zinc-100 hover:text-gray-950"},
{TechName: "Drizzle ORM", TechURL: "https://orm.drizzle.team/", TechClasses: "transition bg-zinc-950 text-zinc-100 hover:bg-green-600"},
{TechName: "Turso", TechURL: "https://turso.tech/", TechClasses: "transition bg-zinc-950 text-zinc-100 hover:bg-teal-600"},
},
},
{
Name: "Hachi-Bitto",
URL: "",
Description: "A general proramming language created just to satify YAPL, which stands for \"yet another programming language\".",
Repo: "https://github.com/juancwu/hachi-bitto",
Classes: "border-emerald-500",
TechList: []Tech{
{TechName: "Golang", TechURL: "https://go.dev/", TechClasses: "bg-zinc-950 text-zinc-100"},
},
},
{
Name: "This Site",
URL: "https://juancwu.dev",
Description: "My personal portolio site?",
Repo: "https://github.com/juancwu/potoforio",
Classes: "border-gray-600",
TechList: []Tech{
{TechName: "Golang", TechURL: "https://go.dev/", TechClasses: "bg-zinc-950 text-zinc-100"},
{TechName: "HTMX", TechURL: "https://htmx.org/", TechClasses: "bg-zinc-950 text-zinc-100"},
{TechName: "Hyperscript", TechURL: "https://hyperscript.org/", TechClasses: "bg-zinc-950 text-zinc-100"},
},
},
},
}
}

32
go.mod
View file

@ -1,22 +1,24 @@
module github.com/juancwu/potoforio
go 1.21.3
go 1.23.0
require github.com/a-h/templ v0.3.977
require (
github.com/joho/godotenv v1.5.1
github.com/labstack/echo/v4 v4.11.2
)
require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cli/browser v1.3.0 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
github.com/natefinch/atomic v1.0.1 // indirect
golang.org/x/mod v0.26.0 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/tools v0.35.0 // indirect
)
tool github.com/a-h/templ/cmd/templ

66
go.sum
View file

@ -1,49 +1,43 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
github.com/a-h/templ v0.3.977 h1:kiKAPXTZE2Iaf8JbtM21r54A8bCNsncrfnokZZSrSDg=
github.com/a-h/templ v0.3.977/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/labstack/echo/v4 v4.11.2 h1:T+cTLQxWCDfqDEoydYm5kCobjmHwOwcv4OJAPHilmdE=
github.com/labstack/echo/v4 v4.11.2/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
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/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

93
main.go
View file

@ -1,93 +0,0 @@
package main
import (
"context"
"embed"
"fmt"
"html/template"
"io"
"io/fs"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
//go:embed static/*
var embeddedFiles embed.FS
//go:embed views/*.html
var embeddedTemplates embed.FS
type TemplateRenderer struct {
templates *template.Template
}
func main() {
// create a channel to listen for signals
sigChan := make(chan os.Signal, 1)
// listen to SIGTERM and SIGINT (ctrl-c)
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT, os.Interrupt)
templates, err := template.ParseFS(embeddedTemplates, "views/*.html")
if err != nil {
log.Fatalf("Error initializing templates: %v", err)
os.Exit(1)
}
e := echo.New()
e.Renderer = &TemplateRenderer{
templates: templates,
}
// serve server in a goroutine, allow the code to listen to ctrl-c
go func() {
e.Use(middleware.Logger())
staticFiles, err := fs.Sub(embeddedFiles, "static")
if err != nil {
panic(err)
}
e.StaticFS("/static", staticFiles)
e.GET("/", renderPage)
e.GET("/service/health-check", func(c echo.Context) error {
c.Response().Writer.WriteHeader(http.StatusOK)
c.Response().Write([]byte("APP VERSION: 1.0.0"))
return nil
})
port := os.Getenv("PORT")
if port == "" {
port = "5173"
}
e.Start(fmt.Sprintf(":%s", port))
}()
// block until a signal is received
sig := <-sigChan
log.Printf("Caught signal: %s\n", sig)
// start graceful shutdown with a timeout
// should stop everything and clean up within 10 seconds
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := e.Shutdown(ctx); err != nil {
log.Printf("Error during server shutdown: %v\n", err)
} else {
log.Println("Server shut down gracefully.")
}
}
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}

View file

@ -1,23 +0,0 @@
{
"name": "potoforio",
"version": "1.0.0",
"description": "JC's personal portfolio site",
"main": "index.js",
"scripts": {
"tw:dev": "tailwindcss -i ./views/styles.css -o ./static/styles.css",
"tw:prod": "tailwindcss -i ./views/styles.css -o ./static/styles.css --minify"
},
"keywords": [
"personal",
"porfolio",
"projects",
"resume"
],
"author": "JC",
"license": "MIT",
"dependencies": {
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3"
}
}

228
page.go
View file

@ -1,228 +0,0 @@
package main
import (
"github.com/labstack/echo/v4"
)
type Tech struct {
TechName string
TechURL string
TechClasses string
}
type Project struct {
Name string
URL string
Description string
TechList []Tech
Repo string
Classes string
}
type Page struct {
Projects []Project
}
func renderPage(c echo.Context) error {
data := Page{}
data.Projects = []Project{
{
Name: "Hermes",
URL: "",
Description: "The user-friendly terminal API client for those who are in love and addicted to do everything on the terminal.",
Repo: "https://github.com/juancwu/hermes",
Classes: "border-orange-400",
TechList: []Tech{
{
TechName: "Rust",
TechURL: "https://www.rust-lang.org/",
TechClasses: "",
},
{
TechName: "Ratatui",
TechURL: "https://ratatui.rs/",
TechClasses: "",
},
},
},
{
Name: "Konbini",
URL: "",
Description: "A \"convenient store\" with API services to manage projects' secrets or environment variables with the ability to separate the variables into their own environment.",
Repo: "https://github.com/juancwu/konbini",
Classes: "border-sky-500",
TechList: []Tech{
{
TechName: "Golang",
TechURL: "https://go.dev/",
TechClasses: "transition bg-zinc-950 text-zinc-100",
},
{
TechName: "Echo",
TechURL: "https://echo.labstack.com/",
TechClasses: "bg-zinc-950 text-zinc-100",
},
{
TechName: "PostgreSQL",
TechURL: "https://www.postgresql.org/",
TechClasses: "bg-zinc-950 text-zinc-100",
},
},
},
{
Name: "EmojiScript",
URL: "https://emojiscript.juancwu.dev/",
Description: "A silly project started for a brain rot hackathon host by Audrey Chen. Please give it a shot if you are interested!",
Repo: "https://github.com/KonferCA/EmojiScript",
Classes: "border-green-400",
TechList: []Tech{
{
TechName: "Typescript",
TechURL: "https://www.typescriptlang.org/",
TechClasses: "",
},
{
TechName: "Devpost",
TechURL: "https://brainrot-jia-seed-hackathon.devpost.com/",
TechClasses: "",
},
},
},
{
Name: "Konfer Website",
URL: "https://konfer.ca",
Description: "The official landing site for Konfer Inc.",
Repo: "https://github.com/KonferCA/Konfer.ca",
Classes: "border-indigo-300",
TechList: []Tech{
{
TechName: "React",
TechURL: "https://react.dev/",
TechClasses: "",
},
{
TechName: "Firebase",
TechURL: "https://firebase.google.com/",
TechClasses: "",
},
{
TechName: "TailwindCSS",
TechURL: "https://tailwindcss.com/",
TechClasses: "",
},
},
},
{
Name: "HawkHacks Website",
URL: "https://hawkhacks.ca",
Description: "HawkHacks is a 36 hour in-person hackathon hosted at Wilfrid Laurier University.",
Repo: "https://github.com/LaurierHawkHacks/Landing",
Classes: "border-orange-300",
TechList: []Tech{
{
TechName: "React",
TechURL: "https://react.dev/",
TechClasses: "",
},
{
TechName: "Firebase",
TechURL: "https://firebase.google.com/",
TechClasses: "",
},
{
TechName: "TailwindCSS",
TechURL: "https://tailwindcss.com/",
TechClasses: "",
},
},
},
{
Name: "LCS Website",
URL: "https://lauriercs.ca",
Description: "The official Computer Science club at Wilfrid Laurier University website.",
Repo: "https://github.com/LaurierCS/Website",
Classes: "border-cyan-400",
TechList: []Tech{
{
TechName: "React",
TechURL: "https://react.dev/",
TechClasses: "",
},
{
TechName: "Firebase",
TechURL: "https://firebase.google.com/",
TechClasses: "",
},
{
TechName: "Mantine UI",
TechURL: "https://mantine.dev/",
TechClasses: "",
},
},
},
{
Name: "Shoto",
URL: "",
Description: "Simple and effective URL shortoner.",
Repo: "https://github.com/juancwu/shoto",
Classes: "border-indigo-500",
TechList: []Tech{
{
TechName: "Next.js",
TechURL: "https://nextjs.org/",
TechClasses: "transition bg-zinc-950 text-zinc-100 hover:bg-zinc-100 hover:text-gray-950",
},
{
TechName: "Drizzle ORM",
TechURL: "https://orm.drizzle.team/",
TechClasses: "transition bg-zinc-950 text-zinc-100 hover:bg-green-600",
},
{
TechName: "Turso",
TechURL: "https://turso.tech/",
TechClasses: "transition bg-zinc-950 text-zinc-100 hover:bg-teal-600",
},
},
},
{
Name: "Hachi-Bitto",
URL: "",
Description: "A general proramming language created just to satify YAPL, which stands for \"yet another programming language\".",
Repo: "https://github.com/juancwu/hachi-bitto",
Classes: "border-emerald-500",
TechList: []Tech{
{
TechName: "Golang",
TechURL: "https://go.dev/",
TechClasses: "bg-zinc-950 text-zinc-100",
},
},
},
{
Name: "This Site",
URL: "https://juancwu.dev",
Description: "My personal portolio site?",
Repo: "https://github.com/juancwu/potoforio",
Classes: "border-gray-600",
TechList: []Tech{
{
TechName: "Golang",
TechURL: "https://go.dev/",
TechClasses: "bg-zinc-950 text-zinc-100",
},
{
TechName: "HTMX",
TechURL: "https://htmx.org/",
TechClasses: "bg-zinc-950 text-zinc-100",
},
{
TechName: "Hyperscript",
TechURL: "https://hyperscript.org/",
TechClasses: "bg-zinc-950 text-zinc-100",
},
},
},
}
return c.Render(200, "index.html", data)
}

717
pnpm-lock.yaml generated
View file

@ -1,717 +0,0 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
autoprefixer:
specifier: ^10.4.16
version: 10.4.16(postcss@8.4.31)
postcss:
specifier: ^8.4.31
version: 8.4.31
tailwindcss:
specifier: ^3.3.3
version: 3.3.3
packages:
'@alloc/quick-lru@5.2.0':
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
'@jridgewell/gen-mapping@0.3.3':
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
engines: {node: '>=6.0.0'}
'@jridgewell/resolve-uri@3.1.1':
resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
engines: {node: '>=6.0.0'}
'@jridgewell/set-array@1.1.2':
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.4.15':
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
'@jridgewell/trace-mapping@0.3.20':
resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
'@nodelib/fs.stat@2.0.5':
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
'@nodelib/fs.walk@1.2.8':
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
autoprefixer@10.4.16:
resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
peerDependencies:
postcss: ^8.1.0
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
binary-extensions@2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
braces@3.0.2:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'}
browserslist@4.22.1:
resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
camelcase-css@2.0.1:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
caniuse-lite@1.0.30001686:
resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==}
chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'}
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
hasBin: true
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
dlv@1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
electron-to-chromium@1.4.561:
resolution: {integrity: sha512-eS5t4ulWOBfVHdq9SW2dxEaFarj1lPjvJ8PaYMOjY0DecBaj/t4ARziL2IPpDr4atyWwjLFGQ2vo/VCgQFezVQ==}
escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
fast-glob@3.3.1:
resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
engines: {node: '>=8.6.0'}
fastq@1.15.0:
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
glob@7.1.6:
resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
has@1.0.4:
resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
engines: {node: '>= 0.4.0'}
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-core-module@2.13.0:
resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
jiti@1.20.0:
resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==}
hasBin: true
lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
nanoid@3.3.6:
resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
node-releases@2.0.13:
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
normalize-range@0.1.2:
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
engines: {node: '>=0.10.0'}
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
postcss-import@15.1.0:
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'}
peerDependencies:
postcss: ^8.0.0
postcss-js@4.0.1:
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
peerDependencies:
postcss: ^8.4.21
postcss-load-config@4.0.1:
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
postcss-nested@6.0.1:
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
postcss-selector-parser@6.0.13:
resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
engines: {node: '>=4'}
postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
postcss@8.4.31:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
sucrase@3.34.0:
resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
engines: {node: '>=8'}
hasBin: true
supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
tailwindcss@3.3.3:
resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==}
engines: {node: '>=14.0.0'}
hasBin: true
thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
update-browserslist-db@1.0.13:
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
yaml@2.3.3:
resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==}
engines: {node: '>= 14'}
snapshots:
'@alloc/quick-lru@5.2.0': {}
'@jridgewell/gen-mapping@0.3.3':
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.20
'@jridgewell/resolve-uri@3.1.1': {}
'@jridgewell/set-array@1.1.2': {}
'@jridgewell/sourcemap-codec@1.4.15': {}
'@jridgewell/trace-mapping@0.3.20':
dependencies:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0
'@nodelib/fs.stat@2.0.5': {}
'@nodelib/fs.walk@1.2.8':
dependencies:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
any-promise@1.3.0: {}
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
arg@5.0.2: {}
autoprefixer@10.4.16(postcss@8.4.31):
dependencies:
browserslist: 4.22.1
caniuse-lite: 1.0.30001686
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.0.0
postcss: 8.4.31
postcss-value-parser: 4.2.0
balanced-match@1.0.2: {}
binary-extensions@2.2.0: {}
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
braces@3.0.2:
dependencies:
fill-range: 7.0.1
browserslist@4.22.1:
dependencies:
caniuse-lite: 1.0.30001686
electron-to-chromium: 1.4.561
node-releases: 2.0.13
update-browserslist-db: 1.0.13(browserslist@4.22.1)
camelcase-css@2.0.1: {}
caniuse-lite@1.0.30001686: {}
chokidar@3.5.3:
dependencies:
anymatch: 3.1.3
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
commander@4.1.1: {}
concat-map@0.0.1: {}
cssesc@3.0.0: {}
didyoumean@1.2.2: {}
dlv@1.1.3: {}
electron-to-chromium@1.4.561: {}
escalade@3.1.1: {}
fast-glob@3.3.1:
dependencies:
'@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.5
fastq@1.15.0:
dependencies:
reusify: 1.0.4
fill-range@7.0.1:
dependencies:
to-regex-range: 5.0.1
fraction.js@4.3.7: {}
fs.realpath@1.0.0: {}
fsevents@2.3.3:
optional: true
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
glob-parent@6.0.2:
dependencies:
is-glob: 4.0.3
glob@7.1.6:
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
has@1.0.4: {}
inflight@1.0.6:
dependencies:
once: 1.4.0
wrappy: 1.0.2
inherits@2.0.4: {}
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.2.0
is-core-module@2.13.0:
dependencies:
has: 1.0.4
is-extglob@2.1.1: {}
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
is-number@7.0.0: {}
jiti@1.20.0: {}
lilconfig@2.1.0: {}
lines-and-columns@1.2.4: {}
merge2@1.4.1: {}
micromatch@4.0.5:
dependencies:
braces: 3.0.2
picomatch: 2.3.1
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
mz@2.7.0:
dependencies:
any-promise: 1.3.0
object-assign: 4.1.1
thenify-all: 1.6.0
nanoid@3.3.6: {}
node-releases@2.0.13: {}
normalize-path@3.0.0: {}
normalize-range@0.1.2: {}
object-assign@4.1.1: {}
object-hash@3.0.0: {}
once@1.4.0:
dependencies:
wrappy: 1.0.2
path-is-absolute@1.0.1: {}
path-parse@1.0.7: {}
picocolors@1.0.0: {}
picomatch@2.3.1: {}
pify@2.3.0: {}
pirates@4.0.6: {}
postcss-import@15.1.0(postcss@8.4.31):
dependencies:
postcss: 8.4.31
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.8
postcss-js@4.0.1(postcss@8.4.31):
dependencies:
camelcase-css: 2.0.1
postcss: 8.4.31
postcss-load-config@4.0.1(postcss@8.4.31):
dependencies:
lilconfig: 2.1.0
yaml: 2.3.3
optionalDependencies:
postcss: 8.4.31
postcss-nested@6.0.1(postcss@8.4.31):
dependencies:
postcss: 8.4.31
postcss-selector-parser: 6.0.13
postcss-selector-parser@6.0.13:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
postcss-value-parser@4.2.0: {}
postcss@8.4.31:
dependencies:
nanoid: 3.3.6
picocolors: 1.0.0
source-map-js: 1.0.2
queue-microtask@1.2.3: {}
read-cache@1.0.0:
dependencies:
pify: 2.3.0
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
resolve@1.22.8:
dependencies:
is-core-module: 2.13.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
reusify@1.0.4: {}
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
source-map-js@1.0.2: {}
sucrase@3.34.0:
dependencies:
'@jridgewell/gen-mapping': 0.3.3
commander: 4.1.1
glob: 7.1.6
lines-and-columns: 1.2.4
mz: 2.7.0
pirates: 4.0.6
ts-interface-checker: 0.1.13
supports-preserve-symlinks-flag@1.0.0: {}
tailwindcss@3.3.3:
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
chokidar: 3.5.3
didyoumean: 1.2.2
dlv: 1.1.3
fast-glob: 3.3.1
glob-parent: 6.0.2
is-glob: 4.0.3
jiti: 1.20.0
lilconfig: 2.1.0
micromatch: 4.0.5
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.0.0
postcss: 8.4.31
postcss-import: 15.1.0(postcss@8.4.31)
postcss-js: 4.0.1(postcss@8.4.31)
postcss-load-config: 4.0.1(postcss@8.4.31)
postcss-nested: 6.0.1(postcss@8.4.31)
postcss-selector-parser: 6.0.13
resolve: 1.22.8
sucrase: 3.34.0
transitivePeerDependencies:
- ts-node
thenify-all@1.6.0:
dependencies:
thenify: 3.3.1
thenify@3.3.1:
dependencies:
any-promise: 1.3.0
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
ts-interface-checker@0.1.13: {}
update-browserslist-db@1.0.13(browserslist@4.22.1):
dependencies:
browserslist: 4.22.1
escalade: 3.1.1
picocolors: 1.0.0
util-deprecate@1.0.2: {}
wrappy@1.0.2: {}
yaml@2.3.3: {}

View file

@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View file

@ -1,48 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./page.go", "./views/**/*.html"],
theme: {
extend: {
fontFamily: {
inter: ["Inter", "sans-serif"],
},
screens: {
"3xl": "2048px",
"4xl": "2560px",
"5xl": "4096px",
// for mac users
retina: {
raw: `@media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min--moz-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx)
`,
},
"retina-sm": {
raw: `@media
only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 640px),
only screen and (min--moz-device-pixel-ratio: 2) and (min-width: 640px),
only screen and (-o-min-device-pixel-ratio: 2/1) and (min-width: 640px),
only screen and (min-device-pixel-ratio: 2) and (min-wdith: 640px),
only screen and (min-resolution: 192dpi) and (min-width: 640px),
only screen and (min-resolution: 2dppx) and (min-width: 640px)
`,
},
"retina-md": {
raw: `@media
only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 1024px),
only screen and (min--moz-device-pixel-ratio: 2) and (min-width: 1024px),
only screen and (-o-min-device-pixel-ratio: 2/1) and (min-width: 1024px),
only screen and (min-device-pixel-ratio: 2) and (min-wdith: 1024px),
only screen and (min-resolution: 192dpi) and (min-width: 1024px),
only screen and (min-resolution: 2dppx) and (min-width: 1024px)
`,
},
},
},
},
plugins: [],
};

View file

@ -1,210 +0,0 @@
<!doctype html>
<html lang="en" class="relative h-full w-full scroll-smooth bg-zinc-900 font-inter text-white">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Juan Wu software developer portfolio site" />
<meta name="author" content="Juan Wu" />
<meta name="keywords" content="software developer, fullstack developer, portfolio" />
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png" />
<link rel="manifest" href="/static/site.webmanifest" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/static/styles.css" />
<link rel="preload" fetchpriority="high" as="image" href="/static/touching-grass-pic.jpg" type="image/jpeg" />
<link rel="preload" fetchpriority="high" as="image" href="/static/grid.svg" type="image/svg+xml" />
<link rel="canonical" href="https://juancwu.dev" />
<script src="https://unpkg.com/htmx.org@1.9.6"
integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<title>Juan Wu | Portfolio</title>
</head>
<body class="h-full w-full">
<div class="polka-pattern fixed inset-0 -z-10" aria-hidden="true"></div>
<header class="border-b border-white/10 bg-zinc-900 px-8 lg:px-16">
<div class="flex items-center py-6 font-medium">
<div>
<span class="text-white"> JUAN WU </span>
<div class="group relative text-sm text-teal-400 hover:line-through">
SOFTWARE DEVELOPER
<span aria-hidden="true"
class="absolute left-0 top-full hidden text-red-500 group-hover:inline">CHROOT</span>
</div>
</div>
<button class="ml-auto lg:hidden" aria-label="Open mobile navigation menu"
_="on click remove .translate-x-full from <nav /> then add .overflow-hidden to <body />">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" aria-hidden="true" class="h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round"
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
<nav
class="fixed inset-0 z-10 translate-x-full items-center bg-zinc-900 transition-transform lg:relative lg:ml-auto lg:flex lg:translate-x-0 lg:bg-transparent">
<div class="flex justify-end p-8">
<button class="block lg:hidden" aria-label="close mobile navigation menu"
_="on click add .translate-x-full to <nav /> then remove .overflow-hidden from <body />">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="h-6 w-6 text-red-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<ul class="flex flex-col items-center justify-center gap-8 uppercase text-white lg:flex-row lg:gap-4">
<li>
<a href="#projects"
class="relative z-0 p-2 after:absolute after:left-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:bg-gradient-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:after:w-full focus:after:w-full">
Projects
</a>
</li>
<li aria-hidden="true">
<span aria-hidden="true" class="hidden select-none font-normal text-fuchsia-400 lg:inline">
-
</span>
</li>
<li>
<a href="https://github.com/juancwu"
class="relative z-0 p-2 after:absolute after:left-1/2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:-translate-x-1/2 after:-translate-y-1/2 after:scale-75 after:bg-white after:opacity-0 after:transition-all hover:text-gray-950 hover:after:scale-100 hover:after:opacity-100 focus:text-gray-950 focus:after:scale-100 focus:after:opacity-100">GitHub</a>
</li>
<li aria-hidden="true">
<span aria-hidden="true" class="hidden select-none font-normal text-fuchsia-400 lg:inline">
-
</span>
</li>
<li>
<a href="https://linkedin.com/in/juancwu"
class="relative z-0 p-2 after:absolute after:-left-2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:bg-gradient-to-r after:from-sky-500 after:to-indigo-500 after:opacity-0 after:transition-all hover:after:left-0 hover:after:top-0 hover:after:translate-y-[15%] hover:after:opacity-100 focus:after:left-0 focus:after:top-0 focus:after:translate-y-[15%] focus:after:opacity-100">LinkedIn</a>
</li>
<!--
<li aria-hidden="true">
<span
aria-hidden="true"
class="hidden select-none font-normal text-fuchsia-400 lg:inline"
>
-
</span>
</li>
<li>
<a
href="https://linkedin.com/in/juancwu"
class="relative z-0 p-2 after:absolute after:right-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:-scale-x-100 after:bg-gradient-to-r after:from-orange-500 after:to-yellow-500 after:transition-all hover:after:w-full focus:after:w-full"
>RESUME</a
>
</li>
-->
</ul>
</nav>
</div>
</header>
<main class="relative z-0 px-16 py-24">
<div class="grid-pattern absolute inset-0" aria-hidden="true"></div>
<div class="radial-overlay absolute inset-0" aria-hidden="true"></div>
<section id="hero" aria-label="Hero Section" class="flex h-full w-full items-center justify-center">
<div class="flex items-center justify-center gap-16">
<div class="relative z-10 space-y-4 text-white">
<p class="text-md text-zinc-300 lg:text-xl">
Hello there <span aria-hidden="true">👋</span>,
</p>
<p class="text-4xl font-bold text-zinc-100 lg:text-5xl xl:text-7xl">
I am Juan,
</p>
<p class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl">
a computer science student who <br> <span class="font-bold text-zinc-200">loves software development</span> <br> and <br> <span class="font-bold text-zinc-200">tinkers with hardware</span>!
</p>
<p class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl">
I currently work at
<a href="https://konfer.ca" target="_blank" rel="noopener noreferrer"
class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">Konfer</a>
and
<a href="https://hawkhacks.ca" target="_blank" rel="noopener noreferrer"
class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-0 after:w-full after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:h-full focus:text-white focus:decoration-sky-500 focus:after:h-full">HawkHacks</a>.
</p>
<div class="h-4" aria-hidden="true"></div>
<p class="text-4xl font-medium md:inline-block lg:text-5xl">
Check out my
</p>
<a href="#projects"
class="colourful-card inline-block text-4xl font-semibold focus:outline-offset-2 md:ml-2 lg:mt-4 lg:text-5xl">
PROJECTS
</a>
</div>
<div
class="clip-me-from-grass hidden bg-gray-200 p-2 opacity-100 drop-shadow-lg lg:block lg:max-w-lg retina:h-auto retina:w-96">
<img class="clip-me-from-grass z-0 h-full w-full" src="/static/touching-grass-pic.jpg"
alt="Juan's portrait photo of him touching grass (figuratively)" />
</div>
</div>
</section>
</main>
<div class="hidden h-12 lg:block" aria-hidden="true"></div>
<section id="projects" aria-label="Juan's Projects" class="relative px-8">
<div class="relative flex items-center justify-center pt-8">
<div class="flex flex-col items-center">
<h1 class="flex flex-col gap-2 p-8 text-3xl font-bold uppercase md:text-5xl">
<span class="relative text-xl font-medium text-zinc-300 md:text-2xl">Welcome to</span>
<span
class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:scale-90 before:bg-gradient-to-r before:from-purple-500 before:to-pink-500 before:opacity-60 before:transition-all hover:before:scale-100">
<span class="group relative"> Project Backyard </span>
</h1>
<a href="https://github.com/juancwu" target="_blank" rel="noopener noreferrer"
class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">
Checkout my GitHub for more projects!
</a>
</div>
</div>
<div class="h-16" aria-hidden="true"></div>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2 2xl:grid-cols-3">
{{ range .Projects }}
<div
class="flex w-full flex-col justify-between gap-4 rounded border-2 p-6 shadow-lg backdrop-blur-[2px] transition border-opacity-60 hover:border-opacity-100 {{ .Classes }}">
<div>
<div class="flex flex-col items-center justify-between gap-4 md:flex-row md:gap-0">
{{ if gt (len .URL) 1 }}
<a href="{{ .URL }}" target="_blank" rel="noopener noreferrer"
class="relative flex items-center gap-2 transition-colors hover:text-sky-400">
<h3 class="text-2xl font-medium">
{{ .Name }}
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="-mt-1 inline-block h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round"
d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
</svg>
</h3>
</a>
{{ else }}
<h3 class="text-2xl font-medium">{{ .Name }}</h3>
{{ end }}
<ul class="flex gap-2">
{{ range .TechList }}
<li>
<a href="{{ .TechURL }}" target="_blank" rel="noopener noreferrer"
class="relative text-sm underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full md:text-base">{{
.TechName }}</a>
</li>
{{ end }}
</ul>
</div>
<div class="h-4" aria-hidden="true"></div>
<hr class="border-white/25" />
<div class="h-4" aria-hidden="true"></div>
<p>{{ .Description }}</p>
</div>
<p>
Checkout the code in
<a href="{{ .Repo }}" target="_blank" rel="noopener noreferrer"
class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">GitHub</a>
</p>
</div>
{{ end }}
</div>
</section>
<div class="h-64" aria-hidden="true"></div>
</body>
</html>

186
views/index.templ Normal file
View file

@ -0,0 +1,186 @@
package views
import "github.com/juancwu/potoforio/data"
templ Index(d data.Page) {
<!DOCTYPE html>
<html lang="en" class="relative h-full w-full scroll-smooth bg-zinc-900 font-inter text-white">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="Juan Wu software developer portfolio site"/>
<meta name="author" content="Juan Wu"/>
<meta name="keywords" content="software developer, fullstack developer, portfolio"/>
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png"/>
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png"/>
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png"/>
<link rel="manifest" href="/static/site.webmanifest"/>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="/static/output.css"/>
<link rel="preload" fetchpriority="high" as="image" href="/static/touching-grass-pic.jpg" type="image/jpeg"/>
<link rel="preload" fetchpriority="high" as="image" href="/static/grid.svg" type="image/svg+xml"/>
<script src="https://unpkg.com/htmx.org@1.9.6" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<title>Juan Wu | Portfolio</title>
</head>
<body class="h-full w-full">
<div class="polka-pattern fixed inset-0 -z-10" aria-hidden="true"></div>
<header class="border-b border-white/10 bg-zinc-900 px-8 lg:px-16">
<div class="flex items-center py-6 font-medium">
<div>
<span class="text-white">JUAN WU </span>
<div class="group relative text-sm text-teal-400 hover:line-through">
SOFTWARE DEVELOPER
<span aria-hidden="true" class="absolute left-0 top-full hidden text-red-500 group-hover:inline">CHROOT</span>
</div>
</div>
<button
class="ml-auto lg:hidden"
aria-label="Open mobile navigation menu"
_="on click remove .translate-x-full from <nav /> then add .overflow-hidden to <body />"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" class="h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path>
</svg>
</button>
<nav class="fixed inset-0 z-10 translate-x-full items-center bg-zinc-900 transition-transform lg:relative lg:ml-auto lg:flex lg:translate-x-0 lg:bg-transparent">
<div class="flex justify-end p-8">
<button
class="block lg:hidden"
aria-label="close mobile navigation menu"
_="on click add .translate-x-full to <nav /> then remove .overflow-hidden from <body />"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-6 w-6 text-red-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
<ul class="flex flex-col items-center justify-center gap-8 uppercase text-white lg:flex-row lg:gap-4">
<li>
<a href="#projects" class="relative z-0 p-2 after:absolute after:left-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:bg-gradient-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:after:w-full focus:after:w-full">
Projects
</a>
</li>
<li aria-hidden="true">
<span aria-hidden="true" class="hidden select-none font-normal text-fuchsia-400 lg:inline">
-
</span>
</li>
<li>
<a href="https://github.com/juancwu" class="relative z-0 p-2 after:absolute after:left-1/2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:-translate-x-1/2 after:-translate-y-1/2 after:scale-75 after:bg-white after:opacity-0 after:transition-all hover:text-gray-950 hover:after:scale-100 hover:after:opacity-100 focus:text-gray-950 focus:after:scale-100 focus:after:opacity-100">GitHub</a>
</li>
<li aria-hidden="true">
<span aria-hidden="true" class="hidden select-none font-normal text-fuchsia-400 lg:inline">
-
</span>
</li>
<li>
<a href="https://linkedin.com/in/juancwu" class="relative z-0 p-2 after:absolute after:-left-2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:bg-gradient-to-r after:from-sky-500 after:to-indigo-500 after:opacity-0 after:transition-all hover:after:left-0 hover:after:top-0 hover:after:translate-y-[15%] hover:after:opacity-100 focus:after:left-0 focus:after:top-0 focus:after:translate-y-[15%] focus:after:opacity-100">LinkedIn</a>
</li>
</ul>
</nav>
</div>
</header>
<main class="relative z-0 px-16 py-24">
<div class="grid-pattern absolute inset-0" aria-hidden="true"></div>
<div class="radial-overlay absolute inset-0" aria-hidden="true"></div>
<section id="hero" aria-label="Hero Section" class="flex h-full w-full items-center justify-center">
<div class="flex items-center justify-center gap-16">
<div class="relative z-10 space-y-4 text-white">
<p class="text-md text-zinc-300 lg:text-xl">
Hello there <span aria-hidden="true">👋</span>,
</p>
<p class="text-4xl font-bold text-zinc-100 lg:text-5xl xl:text-7xl">
I am Juan,
</p>
<p class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl">
a computer science student who
<br/>
<span class="font-bold text-zinc-200">loves software development</span>
<br/>
and
<br/>
<span class="font-bold text-zinc-200">tinkers with hardware</span>!
</p>
<p class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl">
I currently work at
<a href="https://konfer.ca" target="_blank" rel="noopener noreferrer" class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">Konfer</a>
and
<a href="https://hawkhacks.ca" target="_blank" rel="noopener noreferrer" class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-0 after:w-full after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:h-full focus:text-white focus:decoration-sky-500 focus:after:h-full">HawkHacks</a>.
</p>
<div class="h-4" aria-hidden="true"></div>
<p class="text-4xl font-medium md:inline-block lg:text-5xl">
Check out my
</p>
<a href="#projects" class="colourful-card inline-block text-4xl font-semibold focus:outline-offset-2 md:ml-2 lg:mt-4 lg:text-5xl">
PROJECTS
</a>
</div>
<div class="clip-me-from-grass hidden bg-gray-200 p-2 opacity-100 drop-shadow-lg lg:block lg:max-w-lg retina:h-auto retina:w-96">
<img class="clip-me-from-grass z-0 h-full w-full" src="/static/touching-grass-pic.jpg" alt="Juan's portrait photo of him touching grass (figuratively)"/>
</div>
</div>
</section>
</main>
<div class="hidden h-12 lg:block" aria-hidden="true"></div>
<section id="projects" aria-label="Juan's Projects" class="relative px-8">
<div class="relative flex items-center justify-center pt-8">
<div class="flex flex-col items-center">
<h1 class="flex flex-col gap-2 p-8 text-3xl font-bold uppercase md:text-5xl">
<span class="relative text-xl font-medium text-zinc-300 md:text-2xl">Welcome to</span>
<span class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:scale-90 before:bg-gradient-to-r before:from-purple-500 before:to-pink-500 before:opacity-60 before:transition-all hover:before:scale-100">
<span class="group relative">Project Backyard </span>
</span>
</h1>
<a href="https://github.com/juancwu" target="_blank" rel="noopener noreferrer" class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">
Checkout my GitHub for more projects!
</a>
</div>
</div>
<div class="h-16" aria-hidden="true"></div>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2 2xl:grid-cols-3">
for _, p := range d.Projects {
<div class={ "flex w-full flex-col justify-between gap-4 rounded border-2 p-6 shadow-lg backdrop-blur-[2px] transition border-opacity-60 hover:border-opacity-100", p.Classes }>
<div>
<div class="flex flex-col items-center justify-between gap-4 md:flex-row md:gap-0">
if len(p.URL) > 1 {
<a href={ templ.SafeURL(p.URL) } target="_blank" rel="noopener noreferrer" class="relative flex items-center gap-2 transition-colors hover:text-sky-400">
<h3 class="text-2xl font-medium">
{ p.Name }
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="-mt-1 inline-block h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"></path>
</svg>
</h3>
</a>
} else {
<h3 class="text-2xl font-medium">{ p.Name }</h3>
}
<ul class="flex gap-2">
for _, t := range p.TechList {
<li>
<a href={ templ.SafeURL(t.TechURL) } target="_blank" rel="noopener noreferrer" class={ "relative text-sm underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full md:text-base", t.TechClasses }>
{ t.TechName }
</a>
</li>
}
</ul>
</div>
<div class="h-4" aria-hidden="true"></div>
<hr class="border-white/25"/>
<div class="h-4" aria-hidden="true"></div>
<p>{ p.Description }</p>
</div>
<p>
Checkout the code in
<a href={ templ.SafeURL(p.Repo) } target="_blank" rel="noopener noreferrer" class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">GitHub</a>
</p>
</div>
}
</div>
</section>
<div class="h-64" aria-hidden="true"></div>
</body>
</html>
}

View file

@ -1,64 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.colourful-card {
@apply relative bg-white p-2 text-zinc-950 transition-all after:absolute after:-right-2 after:top-2 after:-z-10 after:h-full after:w-full after:bg-gradient-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:bg-transparent hover:text-white hover:after:right-0 hover:after:top-0 focus:bg-transparent focus:text-white focus:after:right-0 focus:after:top-0;
}
.clip-me-from-grass {
clip-path: polygon(58.36% 5.19%,
52.34% 3.68%,
45.85% 3.05%,
37.74% 7.64%,
35.66% 12.39%,
34.82% 19.98%,
32.57% 27.81%,
29.87% 32.92%,
22.01% 37.14%,
17.02% 42.9%,
10.6% 53.43%,
8.22% 70.71%,
6.32% 80.67%,
10.69% 91.75%,
9.18% 99.36%,
47.27% 99.44%,
92.39% 99.2%,
91.85% 86.29%,
94.77% 74.28%,
88.08% 54.82%,
83.74% 45.14%,
78.61% 37.63%,
71.62% 34.03%,
64.62% 23.61%,
63.88% 18.13%,
62.23% 10.25%);
}
.grid-pattern {
width: 100%;
height: 100%;
background-size: cover;
background-position: center center;
background-repeat: repeat;
background-image: url("/static/grid.svg");
}
.radial-overlay {
background: radial-gradient(circle,
rgba(24, 24, 27, 0) 0%,
rgba(24, 24, 27, 1) 50%);
}
.polka-pattern {
background-color: #18181b;
opacity: 1;
background-image: radial-gradient(#27272a 1.3px, transparent 1.3px),
radial-gradient(#27272a 1.3px, #18181b 1.3px);
background-size: 52px 52px;
background-position:
0 0,
26px 26px;
}
}