Site Map

A constellation-themed directory for my personal projects.


What it is

A landing page for my subdomain projects on sophs.world. Each project is a star in an interactive constellation. It has two modes: a dark sky with twinkling stars and occasional shooting stars, and a vintage style star chart that looks like something pulled out of an old astronomy textbook.

Why I built it

I had a growing number of little projects scattered across subdomains and no central place to find them. I wanted to go with something fun to make and fun to look at.

The stack

SvelteKit with Svelte 5 runes, Tailwind CSS v4, deployed to Cloudflare Pages. Entirely static — no backend, no API calls. The star field uses a canvas with a requestAnimationFrame loop, while the constellation and interactive elements are all SVG.

How it works

The dark mode background randomly generates 300 stars on page load, each with its own twinkle speed and base brightness. Twinkle is a sine wave per star — cheap and effective. Shooting stars spawn on a random timer (~every 25 seconds on average) with a gradient trail that fades in and out over about half a second.

Both dark and light mode layers for every element exist in the DOM at all times. Theme switching just animates opacity — nothing is created or destroyed, which avoids the pop-in glitch you get with conditional rendering. The whole page cross-fades smoothly on toggle.

The four background constellations (Lepus, Cassiopeia, Big Dipper, Crux) are plotted from real star positions in the Hipparcos catalog. RA/Dec coordinates are projected to flat x/y with a simple formula — good enough at this scale — and the stick-figure line data comes from Stellarium's constellation definitions.

Clicking a project star zooms the SVG via a CSS transform (not viewBox animation, which can't transition). On desktop the constellation shifts right to make room for a detail card on the left. On mobile the card centers over a subtle background zoom.

The challenges

Theme transitions. Early versions used {#if dark} blocks to swap between dark and light star elements. This caused visible glitches during the toggle — elements would pop in and out instead of smoothly transitioning. The fix was rendering both sets of elements permanently and animating their opacity, which made the switch seamless.

Constellation accuracy. Getting the background constellations to look right was harder than expected. Initial attempts with estimated coordinates looked noticeably wrong, especially Lepus. Ended up pulling real RA/Dec data from the Hipparcos catalog via Stellarium's stick-figure definitions and projecting them mathematically.

Light mode contrast. The vintage star chart aesthetic looks great in theory but is easy to make too faint. Went through several rounds of bumping opacity and darkening ink colours before the grid lines, coordinate labels, and decorative elements were actually readable against the parchment background.

To revisit / To do

  • Mobile layout — the side-by-side zoom + detail card doesn't have a great narrow-screen story yet. Probably needs a bottom sheet or full-screen takeover on mobile.
  • Preview images — the detail cards have a placeholder where site screenshots should go. Need to capture and add these.
  • Write-ups — each project should link to a short technical write-up. The template first version is ready, the content might take a little longer.
  • Deterministic stars — the background star field regenerates randomly on every page load. Could seed a PRNG for consistency, but honestly the randomness might be a feature.