- Svelte
- SvelteKit
- Biome
- GSAP - For smooth animations
- Sass - For enhanced styling
- TypeScript - For type safety
- Zod - For runtime type validation
The website is automatically deployed using GitHub Actions. On every push to the main branch:
- The code is checked out
- The changes are pulled on the VPS
- Dependencies are installed
- The application is built
- The PM2 process is restarted
-
The changing button rotates on hover and fully rotates on click. The issue was that if the button hover was exited before the rotation was complete,the button would rotate back to its original positio, in a very jarring way.
-
The SVG external link icon was cool to tweak in order to animate it on hover.
-
A configurable magnetic field effect that attracts elements towards the mouse cursor. Features adjustable field size and force, with a debug mode that visualizes the magnetic field boundaries.
-
A spring physics-based custom cursor that smoothly follows mouse movement. Fully customizable with support for scaling, opacity, blur effects, and the ability to display SVGs or text inside it on hover. Includes its own actions (
use:cursorEnteranduse:cursorLeave) for easily adding hover interactions to any element, with configurable parameters for scale, opacity, and content changes. It only appears on desktop devices and when the mouse has moved to avoid appearing on page load. -
A WebGL-powered interactive background featuring Bayer dithering effects. Click anywhere on the background to generate expanding wave rings with retro pixelated aesthetics. Uses fragment shaders for GPU-accelerated rendering and supports up to 10 simultaneous wave effects with configurable speed, thickness, and attenuation parameters.
Inspired by the techniques described in Interactive WebGL Backgrounds: A Quick Guide to Bayer Dithering on Codrops.
-
A reactive composable that elegantly tracks scroll state using Svelte 5's runes system. It monitors both the current scroll position and whether the page can be scrolled, then derives a boolean indicating if the scroll position has exceeded a defined trigger threshold. The composable automatically manages event listeners for scroll and resize events, providing a clean API for scroll-based UI changes like header styling or element visibility. Perfect for implementing smooth scroll-triggered animations and responsive design patterns.
The website is powered by two custom Rust services:
API Server (vps-back)
- Built with Rocket.rs framework
- Provides RESTful API endpoints
- Handles CORS and static file serving
- Serves data for the music section
LastFM Integration (vps-lastfm)
A dedicated service that:
- Fetches real-time LastFM listening data
- Tracks currently playing song (5-second intervals)
- Stores last 100 played tracks (1-minute intervals)
- Outputs structured JSON data consumed by the API server
The architecture diagram is generated using D2.
