diff options
Diffstat (limited to 'website.templ')
| -rw-r--r-- | website.templ | 416 |
1 files changed, 74 insertions, 342 deletions
diff --git a/website.templ b/website.templ index bec1453..53992f7 100644 --- a/website.templ +++ b/website.templ @@ -1,7 +1,5 @@ package main -import "flag" - templ HeadComponent(title string, description string) { <head> <meta charset="UTF-8"/> @@ -142,7 +140,7 @@ templ Nav(path string) { <span>{ path }</span> <span class="flex gap-[1ch]"> @NavLink("/", "home") - for _, dir := range []string{"skills", "projects", "blogs"} { + for _, dir := range []string{"projects", "info", "blogs"} { @NavLink("/"+dir, dir) } @NavLink("/shell", "shell") @@ -250,8 +248,8 @@ func footerClass(connected bool) string { return style } -templ SkillsPage(style Style) { - @TerminalLayout(style, "/home/kyren/skills.md") { +templ InfoPage(style Style) { + @TerminalLayout(style, "/home/kyren/info.md") { @TerminalStack(false, "") { @TerminalBorder("Info", "", "") { <span> @@ -264,15 +262,13 @@ templ SkillsPage(style Style) { } type Project struct { - Slug string // e.g. "my-game" - Title string // e.g. "MyGame" - Category string // e.g. "Game written in Zig" - Desc string // 1-2 line description/pitch - Tags []ProjectTag // ["Zig", "OpenGL", "Linux"] - Status string - Icon templ.Component - CgitURL string // e.g. "https://cgit.yourdomain.com/my-game" - GithubURL string // Fallback mirror link + Slug string + Title string + Category string + Desc string + Icon templ.Component + Tags []ProjectTag + Links []ProjectLink } type ProjectTag struct { @@ -281,8 +277,9 @@ type ProjectTag struct { } type ProjectLink struct { - URL string - Icon templ.Component + Icon templ.Component + Label string + URL string } type FlagshipInfo struct { @@ -303,43 +300,6 @@ type Stat struct { Value string } -var p Project = Project{ - Slug: "krypton", - Title: "Krypton", - Category: "Programming Language Compiler", - Desc: "A modern Minecraft creator event. As a developer, I helped with minor improvements to the cosmetics system. ", - Icon: IconCpu("text-[#F5A670] self-center"), - // Icon: IconKrypton(), - Status: "ON", - Tags: []ProjectTag{ - // {"Programming Language", Color("--extra")}, - // {"Compiler", Color("--extra")}, - {"C", Color("text-[#5874FF]")}, - {"LLVM", Color("text-[#FFFFFF]")}, - // {"Java", Color("#F5A670")}, - }, - CgitURL: "https://whatever", - GithubURL: "", -} - -var flagship FlagshipInfo = FlagshipInfo{ - Version: "Sprout.0 2026-08-13", - Downloads: []Download{ - {"linux-amd64", "https://foobar", "23 MB"}, - // {"linux-arm64", "https://foobar", "52 MB"}, - // {"macos-arm64", "https://fooshit", "47 MB"}, - {"windows-amd64", "https://fooshit", "65.7 MB"}, - }, - // Stats: []Stat{{"lines of code", "18.7k"}}, - Snippet: ` -io :: import "core/io"; - -main :: proc() { - io.printf("Hello, %s", "world"); -} -`, -} - var versionBeforeDownloads = false const flagshipClasses = "[--border-py:1.25rem] border-(--accent)! bg-white/[0.03] shadow-[0_0_1.5rem_color-mix(in_srgb,var(--accent)_25%,transparent)]" @@ -356,14 +316,10 @@ templ FlagshipProject(project Project, extra string) { <code class={ "text-[75%] px-[0.4rem] inline-block rounded-[0.3rem] border-[0.01rem] bg-(--alt)/25" + " " + tag.Color }>{ tag.Name }</code> } <span class="ml-auto flex items-center self-center"> - @IconLink("https://git.example.com/foo", "git", "") { - @IconGit("text-(--primary)") - } - @IconLink("https://github.com/foo", "github", "") { - @IconGithub("text-(--secondary)") - } - @IconLink("https://example.com", "website", "") { - @IconExternal("text-(--accent)") + for _, link := range project.Links { + @IconLink(link.URL, link.Label, "") { + @link.Icon + } } </span> </div> @@ -431,271 +387,6 @@ templ IconArchive(color string) { } } -const flagshipClassesV4 = "[--border-py:1.25rem] border-(--accent)! bg-white/[0.03] shadow-[0_0_1.5rem_color-mix(in_srgb,var(--accent)_25%,transparent)]" - -templ FlagshipProjectV4(project Project, extra string) { - @TerminalBorder("", "", flagshipClasses+" "+extra) { - <div class="flex gap-[2rem] w-full"> - <div class="flex flex-col gap-[1rem] flex-1 min-w-0"> - <div class="flex flex-wrap items-baseline gap-x-[1ch] gap-y-[0.4rem]"> - @project.Icon - <a href={ templ.SafeURL("/projects/" + project.Slug) } class="text-[170%] font-bold text-(--accent) hover:underline">{ project.Title }</a> - <span class="text-[85%] text-(--primary)">{ project.Category }</span> - for _, tag := range project.Tags { - <code class={ "text-[75%] px-[0.4rem] inline-block rounded-[0.3rem] border-[0.01rem] bg-(--alt)/25" + " " + tag.Color }>{ tag.Name }</code> - } - <span class="ml-auto flex items-center self-center"> - @IconLink("https://git.example.com/foo", "git", "") { - @IconGit("text-(--primary)") - } - @IconLink("https://github.com/foo", "github", "") { - @IconGithub("text-(--secondary)") - } - @IconLink("https://example.com", "website", "") { - @IconExternal("text-(--accent)") - } - </span> - </div> - <p class="leading-relaxed max-w-3xl">{ project.Desc }</p> - if len(project.Downloads) > 0 || project.Version != "" { - <div class="flex flex-wrap items-center gap-x-[1rem] gap-y-[0.5rem]"> - for _, d := range project.Downloads { - @DownloadButton(d) - } - if project.Version != "" { - <code class="text-[85%] text-(--alt)">{ project.Version }</code> - } - </div> - } - if len(project.Stats) > 0 { - <div class="flex flex-wrap gap-x-[2rem] gap-y-[0.4rem] text-[85%]"> - for _, stat := range project.Stats { - <span class="flex gap-[1ch]"> - <span class="font-bold text-(--primary)">{ stat.Value }</span> - <span class="text-(--alt)">{ stat.Label }</span> - </span> - } - </div> - } - </div> - if project.Snippet != "" { - <div class="shrink-0 self-start flex flex-col gap-[0.5rem] p-[1rem] rounded-[0.4rem] bg-black/30"> - <span class="text-[75%] text-(--alt)">example</span> - @CopyPre(project.Snippet, "text-[80%] leading-[normal]") { - { project.Snippet } - } - </div> - } - </div> - } -} - -templ DownloadButtonV4(d Download) { - <a href={ templ.SafeURL(d.URL) } class="inline-flex items-center gap-[1ch] px-[0.8rem] py-[0.3rem] rounded-[0.4rem] border-[0.1rem] border-solid border-(--alt) text-(--primary) transition-colors hover:bg-(--alt)/25"> - @IconDownload("text-(--primary)") - { d.Label } - </a> -} - -templ IconDownload(color string) { - @Icon(color) { - <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path> - <polyline points="7 10 12 15 17 10"></polyline> - <line x1="12" x2="12" y1="15" y2="3"></line> - } -} - -const flagshipClassesV3 = "[--border-py:1.25rem] border-(--primary)! bg-white/[0.03] shadow-[0_0_1.5rem_color-mix(in_srgb,var(--primary)_25%,transparent)]" - -templ FlagshipProjectV3(project Project, extra string) { - @TerminalBorder("", "", flagshipClasses+" "+extra) { - <div class="flex gap-[2rem] w-full"> - <div class="flex flex-col gap-[1rem] flex-1 min-w-0"> - <div class="flex flex-wrap items-baseline gap-x-[1ch] gap-y-[0.4rem]"> - @project.Icon - <a href={ templ.SafeURL("/projects/" + project.Slug) } class="text-[170%] font-bold text-(--accent) hover:underline">{ project.Title }</a> - <code class="px-[0.5rem] rounded-[0.3rem] border-[0.1rem] border-(--accent)/50 text-[85%] text-(--accent)">{ project.Version }</code> - <span class="text-[85%] text-(--primary)">{ project.Category }</span> - for _, tag := range project.Tags { - <code class={ "text-[75%] px-[0.4rem] inline-block rounded-[0.3rem] border-[0.01rem] bg-(--alt)/25" + " " + tag.Color }>{ tag.Name }</code> - } - <span class="ml-auto flex items-center self-center"> - @IconLink("https://git.example.com/foo", "git", "") { - @IconGit("text-(--primary)") - } - @IconLink("https://github.com/foo", "github", "") { - @IconGithub("text-(--secondary)") - } - @IconLink("https://example.com", "website", "") { - @IconExternal("text-(--accent)") - } - </span> - </div> - <p class="leading-relaxed max-w-3xl">{ project.Desc }</p> - if project.Install != "" { - @CopyPre(project.Install, "text-[85%] leading-[normal]") { - { "$ " + project.Install } - } - } - if project.Devlog != nil { - <a href={ templ.SafeURL("/blogs/" + project.Devlog.Slug) } class="text-[85%] text-(--secondary) hover:underline"> - { "latest devlog: " + project.Devlog.Title } - </a> - } - </div> - if project.Snippet != "" { - <div class="shrink-0 self-start flex flex-col gap-[0.5rem] p-[1rem] rounded-[0.4rem] bg-black/30"> - <span class="text-[75%] text-(--alt)">example</span> - @CopyPre(project.Snippet, "text-[80%] leading-[normal]") { - { project.Snippet } - } - </div> - } - </div> - } -} - -templ FlagshipProjectV2(project Project, extra string) { - @TerminalBorder(project.Version, "", flagshipClasses+" "+extra) { - <div class="flex gap-[2rem] w-full"> - <div class="flex flex-col gap-[1rem] flex-1 min-w-0"> - <div class="flex flex-wrap items-baseline gap-x-[1ch] gap-y-[0.4rem]"> - @project.Icon - <a href={ templ.SafeURL("/projects/" + project.Slug) } class="text-[170%] font-bold text-(--primary) hover:underline">{ project.Title }</a> - <span class="text-[85%] text-(--secondary)">{ project.Category }</span> - for _, tag := range project.Tags { - <code class={ "text-[75%] px-[0.4rem] inline-block rounded-[0.3rem] border-[0.01rem] bg-(--alt)/25" + " " + tag.Color }>{ tag.Name }</code> - } - <span class="ml-auto flex items-center self-center"> - @IconLink("https://git.example.com/foo", "git", "") { - @IconGit("text-(--primary)") - } - @IconLink("https://github.com/foo", "github", "") { - @IconGithub("text-(--secondary)") - } - @IconLink("https://example.com", "website", "") { - @IconExternal("text-(--accent)") - } - </span> - </div> - <p class="leading-relaxed max-w-3xl">{ project.Desc }</p> - <div class="flex flex-wrap items-center gap-[0.5ch] pt-[1rem] border-t border-white/10 text-[85%]"> - for i, stage := range project.Pipeline { - if i > 0 { - <span class="text-(--alt)">→</span> - } - <code class="px-[0.4rem] rounded-[0.3rem] bg-(--alt)/25 text-(--accent)">{ stage }</code> - } - </div> - <div class="flex flex-wrap gap-x-[2.5rem] gap-y-[0.75rem]"> - for _, stat := range project.Stats { - <div class="flex flex-col"> - <span class="text-[150%] font-bold text-(--primary)">{ stat.Value }</span> - <span class="text-[75%] text-(--alt)">{ stat.Label }</span> - </div> - } - </div> - </div> - if project.Snippet != "" { - <div class="shrink-0 self-start flex flex-col gap-[0.5rem] p-[1rem] rounded-[0.4rem] bg-black/30"> - <span class="text-[75%] text-(--alt)">example</span> - @CopyPre(project.Snippet, "text-[80%] leading-[normal]") { - { project.Snippet } - } - </div> - } - </div> - } -} - -templ FlagshipProjectV1(project Project) { - <div class="relative border border-[var(--primary)]/40 rounded bg-white/[0.03] p-6 mb-10 shadow-[0_0_15px_rgba(0,0,0,0.3)]"> - <!-- Header Bar --> - <div class="flex items-center justify-between pb-3 mb-4 border-b border-white/10 font-mono text-xs"> - <div class="flex items-center gap-2"> - <span class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></span> - <span class="text-[var(--accent)] font-bold">FLAGSHIP BUILD</span> - <span class="text-zinc-500">|</span> - <span class="text-zinc-400">{ project.Status }</span> - </div> - <div class="flex gap-3 text-zinc-400"> - if project.CgitURL != "" { - <a href={ templ.URL(project.CgitURL) } target="_blank" class="hover:text-[var(--primary)] transition-colors">[cgit]</a> - } - if project.GithubURL != "" { - <a href={ templ.URL(project.GithubURL) } target="_blank" class="hover:text-[var(--primary)] transition-colors">[github]</a> - } - </div> - </div> - <!-- Title & Category Line --> - <div class="flex items-baseline gap-3 mb-2"> - <h2 class="text-2xl font-bold text-[var(--primary)]"> - <a href={ templ.URL("/projects/" + project.Slug) } class="hover:underline">{ project.Title }</a> - </h2> - <span class="text-sm text-zinc-400 font-mono">{ project.Category }</span> - </div> - <!-- 1-2 Line Pitch --> - <p class="text-zinc-300 text-sm leading-relaxed mb-6 max-w-3xl">{ project.Desc }</p> - <!-- Tech Tags & Detail Link --> - <div class="flex flex-wrap items-center justify-between gap-4 pt-4 border-t border-white/5 font-mono text-xs"> - <div class="flex flex-wrap gap-2"> - for _, tag := range project.Tags { - <span class="px-2 py-0.5 rounded bg-white/5 border border-white/10 text-zinc-300">{ tag.Name }</span> - } - </div> - <a href={ templ.URL("/projects/" + project.Slug) } class="text-[var(--primary)] hover:translate-x-1 transition-transform inline-flex items-center gap-1"> - View Project Details → - </a> - </div> - </div> -} - -templ PinnedGrid(projects []Project) { - <div class="mb-12"> - <div class="text-xs font-mono text-zinc-500 uppercase tracking-wider mb-4"> - // Notable Projects</div> - <div class="grid grid-cols-1 md:grid-cols-6 gap-4"> - for i, project := range projects { - <!-- Top 2 items take col-span-3 (50%), Bottom 3 items take col-span-2 (33%) --> - <div - class={ "group border border-white/10 rounded bg-white/[0.02] hover:bg-white/[0.05] hover:border-white/20 transition-all p-5 flex flex-col justify-between", - templ.KV("md:col-span-3", i < 2), - templ.KV("md:col-span-2", i >= 2) } - > - <div> - <!-- Title + Description/Type Line --> - <div class="flex items-baseline justify-between gap-2 mb-2"> - <h3 class="font-bold text-[var(--primary)] group-hover:text-[var(--accent)] transition-colors"> - <a href={ templ.URL("/projects/" + project.Slug) } class="hover:underline">{ project.Title }</a> - </h3> - <span class="text-xs text-zinc-400 font-mono shrink-0">{ project.Category }</span> - </div> - <!-- Pitch --> - <p class="text-xs text-zinc-300 mb-4 line-clamp-2 leading-relaxed">{ project.Desc }</p> - </div> - <!-- Footer: Tags & Outbound Links --> - <div class="flex items-center justify-between pt-3 border-t border-white/5 text-[11px] font-mono"> - <div class="flex flex-wrap gap-1"> - for _, tag := range project.Tags { - <span class="text-zinc-400 bg-white/5 px-1.5 py-0.5 rounded border border-white/5">{ tag.Name }</span> - } - </div> - <div class="flex gap-2 text-zinc-400"> - if project.CgitURL != "" { - <a href={ templ.URL(project.CgitURL) } target="_blank" class="hover:text-white">[cgit]</a> - } - if project.GithubURL != "" { - <a href={ templ.URL(project.GithubURL) } target="_blank" class="hover:text-white">[gh]</a> - } - </div> - </div> - </div> - } - </div> - </div> - </div> -} - templ IconLink(href string, label string, extra string) { <a href={ templ.SafeURL(href) } target="_blank" rel="noopener noreferrer" aria-label={ label } title={ label } class={ "text-[90%] block p-[0.2rem] rounded-[0.4rem] transition-colors hover:bg-(--alt)/25" + " " + extra }> { children... } @@ -748,14 +439,10 @@ templ ProjectItem(project Project, extra string) { // <code class="text-[75%] px-[0.4rem] inline-block rounded-[0.3rem] bg-(--extra)/70 text-(--background)">{ tag }</code> // } <span class="ml-auto flex items-center self-center"> - @IconLink("https://git.example.com/foo", "git", "") { - @IconGit("text-(--primary)") - } - @IconLink("https://github.com/foo", "github", "") { - @IconGithub("text-(--secondary)") - } - @IconLink("https://example.com", "website", "") { - @IconExternal("text-(--accent)") + for _, link := range project.Links { + @IconLink(link.URL, link.Label, "") { + @link.Icon + } } </span> </div> @@ -790,7 +477,7 @@ templ ProjectsPage(style Style, projects []Project, pinned int) { } templ NotFoundPage(style Style, path string) { - @TerminalLayout(style, "404") { + @TerminalLayout(style, path) { @TerminalStack(true, "") { @TerminalBorder("Shell", "", "") { <span> @@ -920,18 +607,63 @@ templ IconUptime(color string) { } } +templ IconEko(color string) { + @Icon(color) { + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wifi preview-icon"><path d="M12 20h.01"></path><path d="M2 8.82a15 15 0 0 1 20 0"></path><path d="M5 12.859a10 10 0 0 1 14 0"></path><path d="M8.5 16.429a5 5 0 0 1 7 0"></path></svg> + } +} + +templ IconTrident(color string) { + @Icon(color) { + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide preview-icon"> + <path d="m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8"></path> + <path d="M19 5 2.1 21.9"></path> + </svg> + } +} + +templ IconDotfiles(color string) { + @Icon(color) { + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings preview-icon"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle></svg> + } +} + +templ IconVideo(color string) { + @Icon(color) { + // <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-play preview-icon"><path d="M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z"></path><circle cx="12" cy="12" r="10"></circle></svg> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-monitor-play preview-icon"><path d="M15.033 9.44a.647.647 0 0 1 0 1.12l-4.065 2.352a.645.645 0 0 1-.968-.56V7.648a.645.645 0 0 1 .967-.56z"></path><path d="M12 17v4"></path><path d="M8 21h8"></path><rect x="2" y="3" width="20" height="14" rx="2"></rect></svg> + } +} + +templ IconJetbrains(color string) { + @Icon(color) { + <svg fill="none" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="_R_34j5_" x1="0.85" x2="62.62" y1="62.72" y2="1.81" gradientUnits="userSpaceOnUse"> + <stop stop-color="#FF9419"></stop> + <stop offset="0.43" stop-color="#FF021D"></stop> + <stop offset="0.99" stop-color="#E600FF"></stop> + </linearGradient> + </defs> + <path fill="url(#_R_34j5_)" d="M20.34 3.66 3.66 20.34A12.5 12.5 0 0 0 0 29.18V59c0 2.76 2.24 5 5 5h29.82c3.32 0 6.49-1.32 8.84-3.66l16.68-16.68c2.34-2.34 3.66-5.52 3.66-8.84V5c0-2.76-2.24-5-5-5H29.18c-3.32 0-6.49 1.32-8.84 3.66"></path> + <path fill="#000" d="M48 16H8v40h40z"></path> + <path fill="#fff" d="M30 47H13v4h17z"></path> + </svg> + } +} + func row(icon func(color string) templ.Component, color, label, value string) FetchRow { return FetchRow{Icon: icon(color), Color: color, Label: label, Value: value} } var fetchRows = []FetchRow{ // row(IconTerminal, "text-(--secondary)", "Terminal", "Ghostty & Zsh"), - row(IconCode, "--accent", "Main Language", "C"), - row(IconScriptLang, "--accent", "Scripting Langs", "Go and Python"), - row(IconDebugger, "#F16265", "Debugger", "Raddebugger"), - row(IconMonitor, "#54D7A9", "Operating System", "Fedora KDE Linux"), - row(IconEditor, "#54D7A9", "Text Editor", "Neovim"), - row(IconUptime, "#D8C44B", "Uptime", "Asleep"), + row(IconCode, "text-(--accent)", "Main Language", "C"), + row(IconScriptLang, "text-(--accent)", "Scripting Langs", "Go and Python"), + row(IconDebugger, "text-[#F16265]", "Debugger", "Raddebugger"), + row(IconMonitor, "text-[#54D7A9]", "Operating System", "Fedora KDE Linux"), + row(IconEditor, "text-[#54D7A9]", "Text Editor", "Neovim"), + row(IconUptime, "text-[#D8C44B]", "Uptime", "Asleep"), // row(IconCpu, "--extra", "Hardware", "..."), } @@ -968,7 +700,7 @@ templ Fastfetch(rows []FetchRow) { } templ Icon(color string) { - <svg width="1.1em" height="1.1em" class={ "shrink-0", Color(color) } viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> + <svg width="1.1em" height="1.1em" class={ "shrink-0", Color(color), "self-center" } viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> { children... } </svg> } |
