Repository navigation
Conversation
A fixed SVG binary tree sits behind the page content. Its branch angle (the "degree") is the sum of date rules: day, month, season, weekday, hour, moon phase, full moon and Sabbat days. It refreshes every minute in the browser. Branches never overlap: the shrink ratio is 0.5 and the angle is clamped to a range the tests verify by brute force. The drawing is a faint ink impression (6% opacity, theme ink colour) and is hidden under prefers-contrast: more. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Replace the single bottom-rooted tree with an SVG pattern that covers the whole viewport. Each tree is scaled to sit inside its own padded cell and the cell width follows the tree's proportions, so trees pack tightly. Rows are offset by half a cell (brick layout) and cells never intersect, so neither branches nor neighbouring trees overlap. The wallpaper re-tiles on resize. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
Link each tree to its neighbours so the wallpaper reads as part fractal, part geometric pattern. Crowns meet their row neighbours at their outermost tips, and each trunk base forks to the two nearest crown tips in the next row, closing a triangle with the row link between them. Links leave each tree from its extreme left, right or base point, heading away from it, so they cannot cross a branch. Links that cross the tile edge are drawn in full plus a wrapped copy so the pattern is seamless. Cells are 1.5x the tree width (CELL_SPREAD) so the triangles are wide enough to read; tests cover non-crossing, connectivity, and fail against mutated links. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
Replace the fractal tree wallpaper with a geometric texture. Each cell holds concentric squares, each turned by the date-driven degree from the one outside it and scaled so its corners land exactly on its parent's edges. Lines therefore only meet at corners and never cross at any angle. Neighbouring cells turn in opposite directions (a 2x2 tile), and the tile is shifted half a pixel so the cell borders render crisp. The date rules (day, month, season, weekday, hour, Moon, Sabbats) are unchanged and still set the degree. Files are renamed fractal -> texture to match, and the tests cover the inscribed geometry, containment, and no crossings across a 3x3 block of tiles, and fail against deliberately broken geometry. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
The nested-square cells read as a grid. Replace them with Truchet-style arc tiles: each tile holds six quarter-circle arcs that meet every edge at the same three points, so curves run on unbroken across tiles and no cell borders are ever drawn. Each tile's flip is a fixed hash of its position. The date-driven degree now tilts the whole field by that many degrees and sets the share of flipped tiles, sliding the texture between long ordered diagonal waves and a looping maze. Arc spacing keeps opposite-corner arcs clear of each other, so no two arcs ever cross. Tiles are generated to cover the tilted window rather than repeated from an SVG pattern. Tests cover the edge points, continuity across tile edges, no crossing or near-touching between arcs, window coverage at any tilt, and the flip share, and fail against deliberately broken geometry. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
The degree jittered. Each rule was an on/off switch (day <= 15, hour < 12, moon waxing), so the degree jumped whenever one flipped, and tiles popped between orientations as the flip share crossed their hash. Rules are now smooth weights from 0 to 1 on continuous time. Each is a window on its own cycle whose edges ease along Perlin's smootherstep, so a rule keeps its original meaning inside its window and fades in and out at the edges. Windows that are opposites (season <= 2 / >= 3, hour < 12 / >= 12, moon waxing / waning) add up to exactly 1. The Sabbat rule is a swell that peaks on the day and fades within four days either side. The Moon's waxing/waning phase from getMoonIllumination jumps by up to about 0.03 at new and full moon (it picks a side from the sign of an angle that flips while the Moon is still off the Sun-Earth line). Add getMoonCycle, the difference of the Moon's and Sun's ecliptic longitudes, which never jumps. Tiles now cross-fade between orientations as the share passes their hash. A tile's two layers sum to full strength, so density stays steady. averageDegreeFor averages the degree over a span for time-lapse playback, where a weekly rule would otherwise flicker. Over a year at ten-minute steps the largest change fell from 4.5 degrees (769 steps over 0.2) to 0.095 degrees (none). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
Tiles had to pick an orientation, so even with a cross-fade a tile still flipped. Replace the tile arcs with the contour lines of one smooth field: a main wave plus two more at 60 and 120 degrees that fade in with the morph (all three make a hexagonal lattice of blobs), seen through a small domain warp. The degree tilts the field and sets the morph, from parallel wavy bands at the low end to closed loops at the high end. The field is a continuous function of the degree, so the texture can only transition. Lines come from marching squares on a grid, chained into polylines and drawn as smooth quadratic curves. Lines at different levels cannot cross, because the field has one value at each point; level 0, where the lattice's saddles sit, is not drawn, so lines meet only at the instant a band pinches off. There is no grid and no tile edge. The site component is one path. Tests: the field is bounded; a 0.01 degree change moves every point and every line by a hair (a hard switch in the morph fails this); no two lines cross at any degree in the range; every line sits on its level; open lines run off the window; the window is fully covered. Both a hard flip and a miswired marching-squares case fail the suite. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
The smoothed degree only ranged from 18.6 to 22.4 over a year, so the texture looked nearly the same all year. Strengthen the rules and widen the range. The slow rules (day of month, month, season, Sabbat) are six times stronger, so the year has a clear shape; the fast rules (weekday, hour, Moon) are only twice as strong, so they add life without making each day jerk. The base moves from 20 to 30 degrees, the tilt range widens to 0-60, and the morph from bands to loops now runs over 10-50 degrees. The rules still add up to a swing of -13 to +26, so the degree runs from the high teens to the mid fifties. Smoothed over a week, the degree now sweeps 21 to 44 degrees across the year (standard deviation 4.2, up from 0.8), and the morph covers most of its range. The largest change in ten minutes is 0.22 degrees (a step function would jump by at least a degree), which is under 0.03 degrees a minute. A new test pins the variety so it cannot quietly shrink again; it fails against the old strengths. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
The year now starts on 22 August and every month runs from one 22nd to the next, so the day-of-month, month and season rules all count from the anchor. The week, hour, Moon and Sabbats are real and do not move. The anchor is one constant (ANCHOR) in texture.ts. The season rules are quarters of the anchored year; the season labels shown in the preview stay the real northern-hemisphere ones. Positions are measured in milliseconds from the last 22nd, so they stay continuous across month and year boundaries (a month is 28 to 31 days; the windows wrap on the cycle length). The solstice and equinox Sabbats, which fall on the 21st, now land on the day-of-month rule's rising edge and stack with it, so the year has a regular rhythm of peaks. The smoothed degree still spans about 21 to 44 degrees, and the largest ten-minute change is unchanged. Tests cover the anchored positions (the year starts at midnight on 22 Aug, the second before is the end of the year before, every month starts on the 22nd) and move each rule's plateau dates onto the new months. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a full-spread background texture: flowing contour lines, like the lines of a relief map, behind the page. A date-driven "degree" tilts the whole field by that many degrees and sets how far it morphs, from long parallel wavy bands into a lattice of closed loops, as the day, month, season and Moon change. It is recalculated in the browser on load and every minute, and redrawn when the window is resized.
Nothing ever switches. The texture is a continuous function of the degree, so it can only transition: lines creep, bend, pinch off and merge. There are no tiles to flip, no grid, and no seams. Lines never cross.
The degree is varied. Over a year, smoothed over a week, it sweeps from about 21° to 44° (raw: about 19° to 51°), so the texture looks clearly different from season to season.
Everything is anchored on 22 August. The year starts on 22 Aug, and every "month" runs from one 22nd to the next. The day-of-month, month and season rules all count from that anchor, set by one constant,
ANCHOR, intexture.ts. The week, the hour, the Moon and the Sabbats are real and do not move. The solstice and equinox Sabbats (21 Mar, 21 Jun, 21 Sep, 21 Dec) fall on the day before a 22nd, so they land on the day-of-month rule's rising edge and stack with it, which gives the year a regular rhythm of peaks.Rules (start at 30°; each adds its delta × its weight; in
DEGREE_RULESinsrc/lib/utils/texture.ts):The slow rules (day of month, month, season, Sabbat) are strong, so the year has a clear shape; the fast ones (weekday, hour, Moon) are gentler, so they add life without making each day jerk. The rules add up to a swing of −13 to +26 around 30°. The "season" in a rule's name is a quarter of the anchored year; the season labels shown in the preview stay the real northern-hemisphere ones.
The texture
Low-key, part of the paper: drawn in the theme's
--inkat 6% opacity, so it reads as an impression in the paper in light and dark. It sits above the body paper but below.shell-main, ignores pointer events, and is hidden underprefers-contrast: moreand forced colours.This replaces the earlier fractal-tree, nested-square and arc-tile versions on this branch. The tile versions had to pick an orientation per tile, so even with a cross-fade a tile still flipped.
Smoothness
smoothWindowis a periodic window whose edges ease along Perlin's smootherstep (zero first and second derivatives at both ends, see Smoothstep). It depends only on distance from the window's centre, so it is continuous everywhere including where a cycle wraps. A rule keeps its original meaning inside its window; opposite windows sum to exactly 1.getMoonIllumination().phasejumps by up to about 0.03 at new and full moon (it picks waxing or waning from the sign of an angle that flips while the Moon is still a few degrees off the Sun–Earth line). This PR addsgetMoonCycletomoonPhase.ts(the Moon's ecliptic longitude minus the Sun's), which never jumps. The existing functions are untouched.averageDegreeForaverages the degree over a span (sampled every 6 hours) for fast playback, where a weekly rule would otherwise swing the degree more than once a second. A 7-day span cancels the weekly rhythm exactly. The live site uses the raw degree.At these strengths the largest change in the degree over ten minutes, across all of 2026, is 0.22° (a step function would jump by at least 1°), which is under 0.03° a minute at the site's one-minute refresh.
Changes
src/lib/utils/texture.ts: anchored calendar, smooth rules, the field, contour lines, averagingsrc/lib/utils/moonPhase.ts: addsgetMoonCycle(existing functions unchanged)src/lib/components/TextureBackground.svelte: the texture component (client-only, so no hydration mismatch)src/routes/+layout.svelte: mounts the componentsrc/lib/utils/texture.test.tsand atest:texturescriptTesting
pnpm test:texture: 22 tests pass in about two seconds. They cover smootherstep's flat ends; windows being 1 inside, 0 outside and continuous (including the wrap and half-period case); opposite windows summing to exactly 1; the anchored calendar (the year starts at midnight on 22 Aug, the second before is the end of the year before, every month starts on the 22nd, positions stay continuous); each rule keeping its original meaning mid-window; the degree never moving more than 0.3° in ten minutes through a whole year; the moon cycle moving steadily with no jump at new or full moon; a 7-day average cancelling the weekly rhythm; the degree being varied (more than 20° of smoothed range over the year, and most of the morph); the field staying within [−1, 1]; a 0.01° change in the degree moving every point of the field, and every contour line, by only a hair; no two contour lines crossing at any degree in the range; every line sitting on its level; open lines running off the window; and the window being fully covered.tsc --strictpasses on the module; new and changed files are Prettier-clean.pnpm checkandpnpm build, becausepnpm installcould not fetch theatmentionsGitHub dependency in my sandbox (403). Please let CI confirm these.+layout.sveltealready fails Prettier onmain, so I only added the two lines I needed rather than reformatting it.🤖 Generated with Claude Code
https://claude.ai/code/session_01VM4gJUQX6c2kEEuFLdEQW2