From 1dd84c980a2831aebf9cdd996be39a1d4bd8dae1 Mon Sep 17 00:00:00 2001 From: Adam Jeniski Date: Fri, 2 Jan 2026 01:08:12 -0500 Subject: [PATCH] vibe some styles --- CLAUDE.md | 58 +++++++++++++++++++++ resources/public/css/style.css | 92 ++++++++++++++++++++++++++++++++-- src/ajet/www/core.clj | 58 ++++++++++----------- 3 files changed, 177 insertions(+), 31 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..fbfa3d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,58 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a simple Clojure web application serving a personal dashboard at ajet.fyi. It uses Ring, Compojure, and Hiccup to generate and serve a static HTML page with links to various services. + +## Development Commands + +**Start the server (development):** +```bash +clj -M:repl +``` +Then in the REPL: +```clojure +(require 'user) +(in-ns 'user) +server ; inspect the server +(. server stop) ; stop server +(. server start) ; start server +``` + +**Start the server (production):** +```bash +./start.sh +# or directly: +clj -M -m ajet.www.core +``` + +**Restart systemd service:** +```bash +./restart.sh +``` + +## Architecture + +- **Entry point**: `src/ajet/www/core.clj` - defines the web app, routes, and server +- **Development REPL**: `src/dev/user.clj` - provides a convenient REPL environment with server control +- **Static resources**: `resources/public/` - CSS and other static files served via Ring's `wrap-resource` +- **Dependencies**: `deps.edn` - uses Clojure CLI tools (deps.edn) + +The application: +1. Generates HTML using Hiccup (in-memory, not template files) +2. Serves on port 80 in production, random port in development +3. Serves static resources from `resources/public/` +4. Uses Ring middleware for content-type and not-modified headers + +## Deployment + +Deployment is automated via Gitea Actions (`.gitea/workflows/deploy.yaml`). On push to `main`, it triggers a service restart via curl to the service-manager endpoint. + +## Code Organization + +- The entire app logic is in `src/ajet/www/core.clj` +- The HTML content is defined as a Hiccup data structure in the `index` var +- Routes are minimal: just a single GET "/" endpoint +- The app is wrapped with Ring middleware for serving static files and proper headers diff --git a/resources/public/css/style.css b/resources/public/css/style.css index 9b1a172..b61b6af 100644 --- a/resources/public/css/style.css +++ b/resources/public/css/style.css @@ -1,4 +1,90 @@ -body { - font-face: sans-serif; - padding-left: 20px; +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif; + background: #f5f5f5; + color: #1a1a1a; + line-height: 1.6; + padding: 2rem 1rem; + max-width: 900px; + margin: 0 auto; +} + +h1 { + font-size: 2rem; + font-weight: 700; + margin-bottom: 2rem; + color: #1a1a1a; +} + +h2 { + font-size: 1.25rem; + font-weight: 600; + margin: 2rem 0 1rem 0; + color: #2c2c2c; + border-bottom: 2px solid #e0e0e0; + padding-bottom: 0.5rem; +} + +h2:first-of-type { + margin-top: 0; +} + +ul { + list-style: none; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 0.75rem; + margin-bottom: 1.5rem; +} + +li { + background: white; + border-radius: 8px; + border: 1px solid #e0e0e0; + transition: all 0.2s ease; +} + +li:hover { + border-color: #3b82f6; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + transform: translateY(-1px); +} + +a { + display: block; + padding: 0.875rem 1rem; + color: #1a1a1a; + text-decoration: none; + font-weight: 500; + transition: color 0.2s ease; +} + +li:hover a { + color: #3b82f6; +} + +img { + display: block; + max-width: 100%; + height: auto; + margin-top: 1rem; + border-radius: 8px; + border: 1px solid #e0e0e0; + background: white; + padding: 1rem; +} + +@media (max-width: 640px) { + ul { + grid-template-columns: 1fr; + } + + body { + padding: 1rem 0.75rem; + } } diff --git a/src/ajet/www/core.clj b/src/ajet/www/core.clj index 8d4352d..e29c3b4 100644 --- a/src/ajet/www/core.clj +++ b/src/ajet/www/core.clj @@ -9,34 +9,36 @@ (:gen-class)) (def index - (str (h/html [:title "Ajet Dashboard"] - [:link {:rel "stylesheet", :href "/css/style.css"}] - [:link - {:rel "icon", - :type "image/x-icon", - :href - "https://data-star.dev/cdn-cgi/image/format=auto/static/images/rocket-48x48-4c739bfaffe86a6ffcc3a6d77e3c5547730f03d74c11aa460209596d1811f7a3.png"}] - [:h2 "Public Services:"] - [:ul - [:li [:a {:href "https://git.ajet.fyi/"} "git"]] - [:li [:a {:href "https://status.ajet.fyi/"} "status"]] - [:li [:a {:href "https://blog.ajet.fyi/"} "blog"]]] - [:h2 "Personal Quicklist:"] - [:ul - [:li [:a {:href "https://devbox.ajet.fyi"} "devbox"]] - [:li [:a {:href "https://git.ajet.fyi/ajet-industries"} "Ajet Industries"]] - [:li [:a {:href "https://git.ajet.fyi/explore/repos"} "repos"]] - [:li [:a {:href "https://ebooks.ajet.fyi"} "ebooks"]] - [:li [:a {:href "https://uptime.ajet.fyi"} "uptime"]] - [:li [:a {:href "https://service-manager.ajet.fyi"} "ci"]] - [:li [:a {:href "https://mini:8006"} "cluster"]] - [:li [:a {:href "http://192.168.1.124:8081"} "mp4"]] - [:li [:a {:href "http://24.97.151.11/aca/index.html#view"} "upstate live feed"]]] - [:h2 "Keymap:"] - [:img {:src "https://git.ajet.fyi/ajet/zmk-corne-rotary-pad/media/branch/main/keymap-drawer/eyelash_corne.svg" - :width "60%"}] - [:script {:src "https://cdn.jsdelivr.net/npm/eruda"}] - [:script "eruda.init()"]))) + (str (h/html [:head + [:meta {:charset "utf-8"}] + [:meta {:name "viewport" :content "width=device-width, initial-scale=1"}] + [:title "Ajet Dashboard"] + [:link {:rel "stylesheet", :href "/css/style.css"}] + [:link + {:rel "icon", + :type "image/x-icon", + :href + "https://data-star.dev/cdn-cgi/image/format=auto/static/images/rocket-48x48-4c739bfaffe86a6ffcc3a6d77e3c5547730f03d74c11aa460209596d1811f7a3.png"}]] + [:body + [:h1 "Ajet Dashboard"] + [:h2 "Public Services"] + [:ul + [:li [:a {:href "https://git.ajet.fyi/"} "git"]] + [:li [:a {:href "https://status.ajet.fyi/"} "status"]] + [:li [:a {:href "https://blog.ajet.fyi/"} "blog"]]] + [:h2 "Personal Quicklist"] + [:ul + [:li [:a {:href "https://devbox.ajet.fyi"} "devbox"]] + [:li [:a {:href "https://git.ajet.fyi/ajet-industries"} "Ajet Industries"]] + [:li [:a {:href "https://git.ajet.fyi/explore/repos"} "repos"]] + [:li [:a {:href "https://ebooks.ajet.fyi"} "ebooks"]] + [:li [:a {:href "https://uptime.ajet.fyi"} "uptime"]] + [:li [:a {:href "https://service-manager.ajet.fyi"} "ci"]] + [:li [:a {:href "https://mini:8006"} "cluster"]] + [:li [:a {:href "http://192.168.1.124:8081"} "mp4"]] + [:li [:a {:href "http://24.97.151.11/aca/index.html#view"} "upstate live feed"]]] + [:h2 "Keymap"] + [:img {:src "https://git.ajet.fyi/ajet/zmk-corne-rotary-pad/media/branch/main/keymap-drawer/eyelash_corne.svg"}]]))) (defroutes approutes (GET "/" [] index))