Compare commits

...

2 commits

Author SHA1 Message Date
9bc4df5d18
Oops
All checks were successful
Docker Deploy / build-and-push (push) Successful in 1m19s
2025-03-31 03:50:38 -06:00
0a5d5df468
No more building CSS 2025-03-31 03:49:05 -06:00
23 changed files with 1542 additions and 530 deletions

View file

@ -11,8 +11,7 @@ RUN go mod download && \
COPY . .
# Install required tools and make scripts executable
RUN apk add --no-cache upx make bash && \
chmod +x /app/lib/stylegen/gen.sh
RUN apk add --no-cache upx make bash
# Create necessary directories
RUN mkdir -p /app/public/css

View file

@ -3,7 +3,6 @@ CHECK := ✅
BUILD := 🔨
CLEAN := 🧹
RUN := 🚀
CSS := 🎨
TEST := 🧪
DOCKER := 🐳
WARN := ⚠️
@ -13,8 +12,6 @@ DOCS := 📚
BINARY_NAME := atri.dad
DOCKER_IMAGE := atri-dot-dad
GO_FILES := $(wildcard *.go)
CSS_INPUT := lib/stylegen/base.css
CSS_OUTPUT := public/css/styles.css
# Docker detection
DOCKER_ENV := $(shell if [ -f /.dockerenv ]; then echo true; else echo false; fi)
@ -24,13 +21,12 @@ else
BASE_PATH := $(CURDIR)
endif
.PHONY: all build clean run dev stylegen docker-dev docker-build docker-run test help reset ensure-swag
.PHONY: all build clean run dev docker-dev docker-build docker-run test help reset ensure-swag
help:
@echo "Available commands:"
@echo "make clean - Remove build artifacts"
@echo "make reset - Clean and reset the project to initial state"
@echo "make build - Generate CSS, docs, and build Go binary"
@echo "make build - Generate docs and build Go binary"
@echo "make run - Build and run the binary"
@echo "make dev - Run in development mode"
@echo "make docker-dev - Run development environment in Docker"
@ -45,37 +41,12 @@ ensure-swag:
go install github.com/swaggo/swag/cmd/swag@latest; \
}
reset:
@echo "$(CLEAN) Performing complete project reset..."
clean:
@echo "$(CLEAN) Cleaning project..."
@rm -f $(BINARY_NAME)
@rm -f $(CSS_OUTPUT)
@rm -rf public/css/*
@rm -f tailwind.config.js
@rm -rf docs/docs.go docs/swagger.json docs/swagger.yaml
@go clean -cache -testcache -modcache
@rm -rf $(BASE_PATH)/tw # Remove the 'tw' directory
@echo "$(CHECK) Project reset complete"
clean:
@echo "$(CLEAN) Cleaning build artifacts..."
@rm -f $(BINARY_NAME)
@rm -f $(CSS_OUTPUT)
@rm -rf $(BASE_PATH)/lib/stylegen/tw # Remove the 'tw' directory
@echo "$(CHECK) Cleanup complete"
stylegen:
@echo "$(CSS) Generating CSS styles..."
@echo "Current working directory: $$(pwd)"
@echo "Contents of current directory:"
@ls -la
@echo "\nContents of lib/stylegen:"
@ls -la lib/stylegen
@chmod +x $(BASE_PATH)/lib/stylegen/gen.sh
@$(BASE_PATH)/lib/stylegen/gen.sh \
-e "html" \
-d "$(BASE_PATH)/pages/templates" \
-o "$(BASE_PATH)/public/css"
@echo "$(CHECK) CSS generation complete"
@echo "$(CHECK) Project clean complete"
swaggergen: ensure-swag
@echo "$(DOCS) Generating Swagger documentation..."
@ -83,7 +54,7 @@ swaggergen: ensure-swag
@echo "$(CHECK) Swagger docs generated"
# Combined generation target
generate: stylegen swaggergen
generate: swaggergen
build: generate
@echo "$(BUILD) Building binary..."

29
lib/stylegen/base.css vendored
View file

@ -1,29 +0,0 @@
@import "tailwindcss";
@layer base {
html,
container,
body {
height: 100% !important;
width: 100% !important;
overflow-y: auto !important;
position: fixed !important;
}
main {
margin-left: auto !important;
margin-right: auto !important;
width: 100% !important;
max-width: 100% !important;
text-align: center !important;
}
.container {
margin-left: auto !important;
margin-right: auto !important;
display: flex !important;
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
}
}

View file

@ -1,112 +0,0 @@
#!/usr/bin/env bash
# Define the version of the binary to download
VERSION="v4.0.9"
# Parse command-line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-e|--extensions)
EXTENSIONS="$2"
shift; shift
;;
-d|--directory)
DIRECTORY="$2"
shift; shift
;;
-o|--output-dir)
OUTPUT_DIR="$2"
shift; shift
;;
*)
echo "Unknown argument: $1"
exit 1
;;
esac
done
# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "Script directory: $SCRIPT_DIR"
OS=$(uname -s)
ARCH=$(uname -m)
# Normalize OS and ARCH identifiers
case $OS in
"Darwin")
OS="macos"
;;
"Linux")
OS="linux"
;;
"CYGWIN"*|"MINGW"*|"MSYS"*)
OS="windows"
;;
*)
echo "Unknown operating system: $OS"
exit 1
;;
esac
case $ARCH in
"x86_64")
ARCH="x64"
;;
"arm64"|"aarch64")
ARCH="arm64"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
echo "Detected OS: $OS"
echo "Detected Architecture: $ARCH"
# Function to construct the binary download URL based on version, OS, and architecture
get_binary_url() {
echo "https://github.com/tailwindlabs/tailwindcss/releases/download/$VERSION/tailwindcss-$OS-$ARCH"
}
# Create the 'tw' directory for storing the downloaded binary
TW_DIR="${SCRIPT_DIR}/tw"
mkdir -p "$TW_DIR"
# Set the binary path
BINARY="${TW_DIR}/tailwindcss-${OS}-${ARCH}"
# Check if the binary is already downloaded, otherwise download it
if [ ! -f "$BINARY" ]; then
echo "Binary not found, downloading version $VERSION..."
DOWNLOAD_URL=$(get_binary_url)
if [ -z "$DOWNLOAD_URL" ]; then
echo "No suitable release found for this OS and architecture."
exit 1
fi
# Download the binary
curl -L "$DOWNLOAD_URL" -o "$BINARY"
echo "Downloaded binary to: $BINARY"
fi
# Make the binary executable
chmod +x "$BINARY"
echo "Using binary: $BINARY"
echo "Extensions: $EXTENSIONS"
echo "Directory: $DIRECTORY"
echo "Output Directory: $OUTPUT_DIR"
# Generate the minified version for production
echo "Generating minified CSS for production..."
"$BINARY" -i "${SCRIPT_DIR}/base.css" -o "${OUTPUT_DIR}/styles.css" --minify
# Create empty daisyui.css and themes.css files if they don't exist
touch "${OUTPUT_DIR}/daisyui.css"
touch "${OUTPUT_DIR}/themes.css"
echo "All CSS files generated"

View file

@ -20,7 +20,7 @@ func Home(c echo.Context) error {
{
Name: "Email",
Href: "mailto:me@atri.dad",
Icon: template.HTML(`<svg xmlns="http://www.w3.org/2000/svg" height="32" width="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>`),
Icon: template.HTML(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" height="32" width="32"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48L48 64zM0 176L0 384c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-208L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z"/></svg>`),
},
{
Name: "RSS",
@ -75,11 +75,6 @@ func Home(c echo.Context) error {
Href: "https://docker.com",
Icon: template.HTML(`<svg role="img" viewBox="0 0 24 24" height="32" width="32" xmlns="http://www.w3.org/2000/svg"><title>Docker</title><path d="M13.983 11.078h2.119a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.119a.185.185 0 00-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 00.186-.186V3.574a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 00.186-.186V6.29a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 00.184-.186V6.29a.185.185 0 00-.185-.185H8.1a.185.185 0 00-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 00.185-.186V6.29a.185.185 0 00-.185-.185H5.136a.186.186 0 00-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 00.185-.185V9.006a.185.185 0 00-.184-.186h-2.12a.186.186 0 00-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51-.338.001-.676.03-1.01.087-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199-.226.327c-.284.438-.49.922-.612 1.43-.23.97-.09 1.882.403 2.661-.595.332-1.55.413-1.744.42H.751a.751.751 0 00-.75.748 11.376 11.376 0 00.692 4.062c.545 1.428 1.355 2.48 2.41 3.124 1.18.723 3.1 1.137 5.275 1.137.983.003 1.963-.086 2.93-.266a12.248 12.248 0 003.823-1.389c.98-.567 1.86-1.288 2.61-2.136 1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009.309-.293.55-.65.707-1.046l.098-.288Z"/></svg>`),
},
{
Name: "NixOS",
Href: "https://nixos.org",
Icon: template.HTML(`<svg role="img" viewBox="0 0 24 24" height="32" width="32" xmlns="http://www.w3.org/2000/svg"><title>NixOS</title><path d="M7.352 1.592l-1.364.002L5.32 2.75l1.557 2.713-3.137-.008-1.32 2.34H14.11l-1.353-2.332-3.192-.006-2.214-3.865zm6.175 0l-2.687.025 5.846 10.127 1.341-2.34-1.59-2.765 2.24-3.85-.683-1.182h-1.336l-1.57 2.705-1.56-2.72zm6.887 4.195l-5.846 10.125 2.696-.008 1.601-2.76 4.453.016.682-1.183-.666-1.157-3.13-.008L21.778 8.1l-1.365-2.313zM9.432 8.086l-2.696.008-1.601 2.76-4.453-.016L0 12.02l.666 1.157 3.13.008-1.575 2.71 1.365 2.315L9.432 8.086zM7.33 12.25l-.006.01-.002-.004-1.342 2.34 1.59 2.765-2.24 3.85.684 1.182H7.35l.004-.006h.001l1.567-2.698 1.558 2.72 2.688-.026-.004-.006h.01L7.33 12.25zm2.55 3.93l1.354 2.332 3.192.006 2.215 3.865 1.363-.002.668-1.156-1.557-2.713 3.137.008 1.32-2.34H9.881Z"/></svg>`),
},
}
buttons := []lib.ButtonLink{

View file

@ -14,18 +14,18 @@ Atridad Lahiji // Root
{{end}}
{{define "main"}}
<h1 class="text-4xl font-extrabold text-white sm:text-8xl">
<span class="bg-gradient-to-r from-pink-500 to-blue-500 bg-clip-text text-transparent">{{.Title}}</span>
<div class="home-page text-center">
<h1 class="text-4xl font-extrabold sm:text-8xl">
<span class="gradient-text">{{.Title}}</span>
</h1>
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
<h2 class="text-2xl font-extrabold tracking-tight sm:text-[2rem]">
{{.Subtitle}}
</h2>
<span>
<h2 class="mb-2 text-xl text-white sm:text-[1.5rem]">Places I exist:</h2>
<div class="flex flex-row flex-wrap items-center justify-center gap-4 text-center">
<h2 class="mb-2 text-xl sm:text-[1.5rem]">Places I exist:</h2>
<div class="flex flex-row flex-wrap items-center justify-center gap-4">
{{range .Socials}}
{{template "iconlinks" .}}
{{end}}
@ -33,20 +33,21 @@ Atridad Lahiji // Root
</span>
<span>
<h2 class="mb-2 text-xl text-white sm:text-[1.5rem]">Stuff I Use:</h2>
<h2 class="mb-2 text-xl sm:text-[1.5rem]">Stuff I Use:</h2>
<div class="flex flex-row flex-wrap items-center justify-center gap-4 text-center">
<div class="flex flex-row flex-wrap items-center justify-center gap-4">
{{range .Tech}}
{{template "iconlinks" .}}
{{end}}
</div>
</span>
<div class="flex flex-row flex-wrap gap-2 mx-auto justify-center">
<div class="home-buttons-container">
{{range .ButtonsLinks}}
{{template "buttonlinks" .}}
{{end}}
</div>
</div>
{{end}}
{{define "foot"}}

View file

@ -8,16 +8,14 @@
<title>{{template "title" .}}</title>
<meta name="description" content="{{template "description" .}}">
<script defer src="https://analytics.atri.dad/script.js" data-website-id="0206740c-245f-402a-b433-125d6d48945a"></script>
<link href="/public/css/daisyui.css" rel="stylesheet" type="text/css" />
<link href="/public/css/themes.css" rel="stylesheet" type="text/css" />
<link href="/public/css/styles.css" rel="stylesheet" type="text/css" />
{{template "head" .}}
</head>
<body class="block h-[100%]" hx-ext="preload">
<body>
{{template "header" .}}
<main class="container flex flex-col items-center justify-center gap-3 sm:gap-6 p-4 text-center min-h-[calc(100%-64px)]">
<main class="container flex flex-col items-center justify-center gap-3 sm:gap-6 p-4 text-center">
{{template "main" .}}
</main>
<script src="/public/js/htmx.base.js"></script>

View file

@ -9,24 +9,21 @@
<title>{{template "title" .}}</title>
<meta name="description" content="{{template "description" .}}">
<script defer src="https://analytics.atri.dad/script.js" data-website-id="0206740c-245f-402a-b433-125d6d48945a"></script>
<link href="/public/css/daisyui.css" rel="stylesheet" type="text/css" />
<link href="/public/css/styles.css" rel="stylesheet" type="text/css" />
<link href="/public/css/themes.css" rel="stylesheet" type="text/css" />
<link href="/public/css/markdown.css" rel="stylesheet" type="text/css" />
{{template "head" .}}
</head>
<body class="block h-[100%]">
<body>
{{template "header" .}}
<main class="mx-auto p-4 max-w-3xl">
<main class="container mx-auto pt-6 pb-12 px-4 max-w-2xl">
<article>
<h1 class="mx-auto text-2xl sm:text-4xl font-bold tracking-tight text-center mb-4 max-w-[65ch]">{{.Name}}</h1>
<div class="flex flex-row flex-wrap justify-center gap-4 mb-6">
<h1 class="text-3xl font-bold tracking-tight text-center mb-4">{{.Name}}</h1>
<div class="flex flex-row justify-center items-center gap-2">
{{if .Date}}
<p>
<div class="flex flex-row flex-wrap items-center gap-1 text-md">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<div class="flex flex-row items-center gap-1 text-sm">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-clock-4">
<circle cx="12" cy="12" r="10" />
@ -34,19 +31,18 @@
</svg>
{{.Date}}
</div>
</p>
{{end}}
{{if .Tags}}
<div class="flex flex-row flex-wrap text-center items-center justify-center gap-1">
<div class="flex flex-row items-center gap-1">
{{range .Tags}}
<div class="badge badge-accent">#{{.}}</div>
<span class="project-tag">#{{.}}</span>
{{end}}
</div>
{{end}}
<div id="svgContainer" style="display: none;">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-check-circle">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
@ -54,29 +50,33 @@
</svg>
</div>
<button id="copyButton" aria-label="Copy Link to Post" hx-get="/api/post/copy" hx-swap="innerHTML"
hx-trigger="click delay:3s"
_='on click put #svgContainer.innerHTML into me.innerHTML then call navigator.clipboard.writeText(window.location.href)'>
<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-copy">
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
</svg>
</button>
<div class="flex items-center gap-2">
<button id="copyButton" aria-label="Copy Link to Post" hx-get="/api/post/copy" hx-swap="innerHTML"
class="post-icon-button"
hx-trigger="click delay:3s"
_='on click put #svgContainer.innerHTML into me.innerHTML then call navigator.clipboard.writeText(window.location.href)'>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-copy">
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
</svg>
</button>
<a href="/posts" class="btn btn-primary btn-outline" preload="mouseover">
<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-undo-2">
<path d="M9 14 4 9l5-5" />
<path d="M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5v0a5.5 5.5 0 0 1-5.5 5.5H11" />
</svg>
Back
</a>
<a href="/posts" class="post-back-button" preload="mouseover">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-undo-2">
<path d="M9 14 4 9l5-5" />
<path d="M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5v0a5.5 5.5 0 0 1-5.5 5.5H11" />
</svg>
Back
</a>
</div>
</div>
<hr class="my-6 border-t border-white w-full max-w-2xl mx-auto" />
<div class="markdown text-left mx-auto max-w-2xl">
<hr class="mb-6 mt-2 border-t border-white opacity-20 w-full mx-auto" />
<div class="markdown text-left mx-auto">
{{template "main" .}}
</div>
</article>

View file

@ -16,19 +16,23 @@ Atridad Lahiji // Papers
{{define "main"}}
{{if .Papers}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
{{range .Papers}}
{{template "cardlinks" .}}
{{end}}
</section>
<div class="card-grid-container">
<section class="card-grid">
{{range .Papers}}
{{template "cardlinks" .}}
{{end}}
</section>
</div>
{{end}}
{{if not .Papers}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
<div class="card-grid-container">
<section class="card-grid">
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
Nothing to see here (yet)!
</h2>
</section>
</section>
</div>
{{end}}
{{end}}

View file

@ -1,51 +1,51 @@
{{define "cardlinks"}}
<div class="card card-compact w-64 bg-secondary shadow-xl">
<div class="card-body text-base-100 flex flex-col">
<h2 class="card-title text-base-100">{{.Name}}</h2>
<div class="project-card">
<div class="project-card-content">
<h2 class="project-card-title">{{.Name}}</h2>
{{if .Description}}
<p>{{.Description}}</p>
<p class="project-card-description">{{.Description}}</p>
{{end}}
{{if .Date}}
<p>
<p class="project-card-date">
<div class="flex flex-row flex-wrap items-center gap-1 text-md">
<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-clock-4"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clock-4"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
{{.Date}}
</div>
</p>
{{end}}
{{if .Tags}}
<div class="flex flex-row flex-wrap text-center items-center justify-center gap-1">
<div class="project-card-tags">
{{range .Tags}}
<div class="badge badge-accent">#{{.}}</div>
<span class="project-tag">#{{.}}</span>
{{end}}
</div>
{{end}}
{{if .Href}}
<div class="card-actions justify-end">
<div class="project-card-link">
{{if eq true .Internal}}
<a
role="button"
href={{.Href}}
aria-label={{.Name}}
class="btn btn-circle btn-base-100 btn-outline"
class="project-link-button"
preload="mouseover"
>
<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-arrow-right"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
</a>
{{else}}
<a
role="button"
href={{.Href}}
aria-label={{.Name}}
class="btn btn-circle btn-base-100 btn-outline"
class="project-link-button"
target="_blank"
rel="noopener noreferrer"
>
<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-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
</a>
{{end}}
</div>

View file

@ -1,21 +1,49 @@
{{define "header"}}
<header class="navbar bg-base-100">
<header class="navbar">
<div class="navbar-start">
<a class="btn btn-ghost normal-case text-lg sm:text-xl text-white" href="/">{{template "navcontent".}}</a>
<a class="btn btn-ghost normal-case text-xl" href="/">{{template "navcontent".}}</a>
</div>
<div class="navbar-end z-50">
<div class="navbar-end">
<div class="dropdown dropdown-end">
<label tabindex="0" class="btn btn-sm btn-ghost text-white">
<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-menu"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
<label tabindex="0" class="btn btn-ghost" id="navbar-toggle">
<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="menu-icon"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
</label>
<ul
tabindex="0"
class="menu menu-sm dropdown-content gap-2 mt-3 p-2 shadow-md bg-base-100 rounded-box"
preload="mouseover"
class="menu dropdown-content mt-3 shadow-md rounded-box z-50 nav-menu"
id="nav-menu"
>
{{template "navitems" .}}
</ul>
</div>
</div>
</header>
<script>
document.addEventListener('DOMContentLoaded', function() {
const navbarToggle = document.getElementById('navbar-toggle');
const navMenu = document.getElementById('nav-menu');
// Toggle menu on hamburger click
navbarToggle.addEventListener('click', function(e) {
e.stopPropagation();
navMenu.classList.toggle('show');
});
// Close menu when clicking outside
document.addEventListener('click', function(e) {
if (!navMenu.contains(e.target) && !navbarToggle.contains(e.target)) {
navMenu.classList.remove('show');
}
});
// Close menu when clicking on a menu item
const menuItems = navMenu.querySelectorAll('a');
menuItems.forEach(item => {
item.addEventListener('click', function() {
navMenu.classList.remove('show');
});
});
});
</script>
{{end}}

View file

@ -1,5 +1,5 @@
{{define "iconlinks"}}
<a class="fill-white hover:fill-pink-500" href={{.Href}} target="_blank" rel="me" aria-label={{.Name}}>
<a class="icon-link" href={{.Href}} target="_blank" rel="me" aria-label={{.Name}}>
{{.Icon}}
</a>
{{end}}

View file

@ -1,20 +1,8 @@
{{define "navitems"}}
<li>
<a class="no-underline" href="/"> Home </a>
</li>
<li>
<a class="no-underline" href="/projects"> Projects </a>
</li>
<li>
<a class="no-underline" href="/papers"> Papers </a>
</li>
<li>
<a class="no-underline" href="/talks"> Talks </a>
</li>
<li>
<a class="no-underline" href="/posts"> Posts </a>
</li>
<li>
<a class="no-underline" href="/tools"> Tools </a>
</li>
<li><a href="/">Home</a></li>
<li><a href="/projects">Projects</a></li>
<li><a href="/papers">Papers</a></li>
<li><a href="/talks">Talks</a></li>
<li><a href="/posts">Posts</a></li>
<li><a href="/tools">Tools</a></li>
{{end}}

View file

@ -16,19 +16,23 @@ Atridad Lahiji // Posts
{{define "main"}}
{{if .Posts}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
{{range .Posts}}
{{template "cardlinks" .}}
{{end}}
</section>
<div class="card-grid-container">
<section class="card-grid">
{{range .Posts}}
{{template "cardlinks" .}}
{{end}}
</section>
</div>
{{end}}
{{if not .Posts}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
<div class="card-grid-container">
<section class="card-grid">
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
Nothing to see here (yet)!
</h2>
</section>
</section>
</div>
{{end}}
{{end}}

View file

@ -16,19 +16,23 @@ Atridad Lahiji // Projects
{{define "main"}}
{{if .Projects}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
<div class="card-grid-container">
<section class="card-grid">
{{range .Projects}}
{{template "cardlinks" .}}
{{end}}
</section>
</section>
</div>
{{end}}
{{if not .Projects}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
<div class="card-grid-container">
<section class="card-grid">
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
Nothing to see here (yet)!
</h2>
</section>
</section>
</div>
{{end}}
{{end}}

View file

@ -16,19 +16,23 @@ Atridad Lahiji // Talks
{{define "main"}}
{{if .Talks}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
{{range .Talks}}
{{template "cardlinks" .}}
{{end}}
</section>
<div class="card-grid-container">
<section class="card-grid">
{{range .Talks}}
{{template "cardlinks" .}}
{{end}}
</section>
</div>
{{end}}
{{if not .Talks}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
<div class="card-grid-container">
<section class="card-grid">
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
Nothing to see here (yet)!
</h2>
</section>
</section>
</div>
{{end}}
{{end}}

View file

@ -15,21 +15,27 @@ Atridad Lahiji // Tools
{{define "main"}}
{{if .Tools}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
{{range .Tools}}
{{template "cardlinks" .}}
{{end}}
</section>
{{end}}
<div class="tools-page">
{{if .Tools}}
<div class="card-grid-container">
<section class="card-grid">
{{range .Tools}}
{{template "cardlinks" .}}
{{end}}
</section>
</div>
{{end}}
{{if not .Tools}}
<section class="flex flex-row flex-wrap gap-2 justify-center align-middle">
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
Nothing to see here (yet)!
</h2>
</section>
{{end}}
{{if not .Tools}}
<div class="card-grid-container">
<section class="card-grid">
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
Nothing to see here (yet)!
</h2>
</section>
</div>
{{end}}
</div>
{{end}}

View file

@ -14,20 +14,30 @@ Atridad Lahiji // Tools // Resizer
{{end}}
{{define "main"}}
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">Image Resizer</h2>
<form action="/api/tools/resize" method="post" enctype="multipart/form-data" class="flex-col flex gap-4">
Select image to resize:
<input type="file" name="image" accept=".png,.jpg,.jpeg"
class="file-input file-input-bordered file-input-secondary w-full max-w-xs" required />
<br>
New width (px):
<input type="number" id="newWidth" name="width" min="1" class="input input-bordered w-full max-w-xs" required>
<br>
New height (px):
<input type="number" id="newHeight" name="height" min="1" class="input input-bordered w-full max-w-xs" required>
<br>
<button type="submit" class="btn btn-secondary">Resize Image</button>
</form>
<div class="tool-page">
<h1>Image Resizer</h1>
<p>Upload and resize your images quickly and easily. Select an image file, specify dimensions, and get a resized version instantly.</p>
<form action="/api/tools/resize" method="post" enctype="multipart/form-data" class="form-group">
<div class="form-group">
<label for="image">Select image to resize:</label>
<input type="file" id="image" name="image" accept=".png,.jpg,.jpeg" required />
</div>
<div class="form-group">
<label for="newWidth">New width (px):</label>
<input type="number" id="newWidth" name="width" min="1" required />
</div>
<div class="form-group">
<label for="newHeight">New height (px):</label>
<input type="number" id="newHeight" name="height" min="1" required />
</div>
<button type="submit" class="tool-button">Resize Image</button>
</form>
</div>
{{end}}
{{define "foot"}}

View file

@ -14,25 +14,26 @@ A demo of my SSE implementation.
{{end}}
{{define "main"}}
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">Server Sent Events Demo</h2>
<div class="tool-page">
<h1>Server Sent Events Demo</h1>
<p class="text-lg">This page demonstrates the use of the <a href="https://htmx.org/extensions/sse/">HTMX SSE
Extension</a> to receive Server Sent Events on the "default" channel.</p>
<p class="text-lg">Any events received on the "default" channel will appear below:</p>
<div hx-ext="sse" sse-connect="/api/sse" sse-swap="message">
Waiting for SSE Message...
</div>
<p class="text-lg">Here you can send messages on the default channel:</p>
<form hx-post="/api/tools/sendsse" hx-trigger="submit" hx-swap="none" class="flex-col flex gap-2">
<div class="label">
<span class="label-text">Message</span>
<p>This page demonstrates the use of the <a href="https://htmx.org/extensions/sse/" class="tool-link">HTMX SSE
Extension</a> to receive Server Sent Events on the "default" channel.</p>
<p>Any events received on the "default" channel will appear below:</p>
<div hx-ext="sse" sse-connect="/api/sse" sse-swap="message" class="sse-message-container">
Waiting for SSE Message...
</div>
<input type="text" name="message" value="Hello world!" placeholder="Enter your message here"
class="input input-bordered input-primary w-full max-w-xs" />
<button type="submit" class="btn btn-primary">Send Event</button>
</form>
<p>Here you can send messages on the default channel:</p>
<form hx-post="/api/tools/sendsse" hx-trigger="submit" hx-swap="none" class="form-group">
<div class="form-group">
<label for="message">Message</label>
<input type="text" id="message" name="message" value="Hello world!" placeholder="Enter your message here" />
</div>
<button type="submit" class="tool-button">Send Event</button>
</form>
</div>
{{end}}
{{define "foot"}}

File diff suppressed because one or more lines are too long

View file

@ -1,180 +0,0 @@
/* Markdown styling */
.markdown {
color: #fff;
line-height: 1.6;
}
/* Headings */
.markdown h1,
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
font-weight: 700;
margin-top: 1.5rem;
margin-bottom: 1rem;
color: #fff;
}
.markdown h1 {
font-size: 1.875rem;
line-height: 2.25rem;
}
.markdown h2 {
font-size: 1.5rem;
line-height: 2rem;
}
.markdown h3 {
font-size: 1.25rem;
line-height: 1.75rem;
}
.markdown h4 {
font-size: 1.125rem;
line-height: 1.75rem;
}
/* Paragraphs */
.markdown p {
margin-top: 1rem;
margin-bottom: 1rem;
}
/* Links */
.markdown a {
color: #60a5fa;
text-decoration: none;
}
.markdown a:hover {
text-decoration: underline;
}
/* Strong/Bold */
.markdown strong,
.markdown b {
font-weight: 700;
color: #fff;
}
/* Code blocks and inline code */
.markdown code {
background-color: rgba(55, 65, 81, 0.5);
border-radius: 0.25rem;
padding: 0.125rem 0.25rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 0.875rem;
}
.markdown pre {
background-color: rgba(55, 65, 81, 0.5);
border-radius: 0.375rem;
padding: 1rem;
margin: 1rem 0;
overflow-x: auto;
}
.markdown pre code {
background-color: transparent;
padding: 0;
font-size: 0.875rem;
color: #f1f5f9;
display: block;
}
/* Lists */
.markdown ul {
list-style-type: disc;
padding-left: 1.5rem;
margin: 1rem 0;
}
.markdown ol {
list-style-type: decimal;
padding-left: 1.5rem;
margin: 1rem 0;
}
.markdown li {
margin: 0.25rem 0;
}
.markdown li > ul,
.markdown li > ol {
margin: 0;
}
/* Blockquotes */
.markdown blockquote {
border-left: 4px solid #60a5fa;
padding-left: 1rem;
margin: 1rem 0;
font-style: italic;
color: #d1d5db;
}
/* Images */
.markdown img {
max-width: 100%;
height: auto;
margin: 1rem auto;
border-radius: 0.375rem;
display: block;
}
/* Horizontal rule */
.markdown hr {
border: 0;
border-top: 1px solid #fff;
margin: 1.5rem 0;
}
/* Tables */
.markdown table {
width: 100%;
border-collapse: collapse;
margin: 1rem 0;
}
.markdown th {
background-color: rgba(55, 65, 81, 0.5);
padding: 0.5rem;
border: 1px solid #4b5563;
text-align: left;
}
.markdown td {
padding: 0.5rem;
border: 1px solid #4b5563;
}
.markdown tr:nth-child(even) {
background-color: rgba(55, 65, 81, 0.3);
}
/* Adjustments for code with line numbers */
.markdown .chroma {
background-color: rgba(55, 65, 81, 0.5);
border-radius: 0.375rem;
}
.markdown .lntable {
width: 100%;
border: none;
}
.markdown .lntd {
padding: 0;
border: none;
}
.markdown .lntd:first-child {
width: 10px;
text-align: right;
padding-right: 10px;
color: #6b7280;
user-select: none;
}

1332
public/css/styles.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long