@latimer-woods-tech/constellation
v0.3.0
Published
The personal-sky renderer + data catalogs — a pure, runtime-agnostic SVG-string generator (no DOM, no Node built-ins). Parallel to `@latimer-woods-tech/bodygraph`: bodygraph = the body (microcosm); constellation = the sky (macrocosm). Deterministic from a
Downloads
2,141
Readme
@latimer-woods-tech/constellation
The personal-sky renderer + data catalogs — a pure, runtime-agnostic
SVG-string generator (no DOM, no Node built-ins). Parallel to
@latimer-woods-tech/bodygraph: bodygraph = the body (microcosm);
constellation = the sky (macrocosm). Deterministic from a seed — every
person's sky is unique but stable across renders. Safe in Cloudflare
Workers, Node.js, and Remotion (the default motion: 'none' is the static
frame-driven path there).
Motion modes
Both render entry points take motion: 'none' | 'smil' | 'css'. 'css' emits
a seed-scoped <style> block with @keyframes on opacity/transform only —
GPU-composited, and governed by the CSS animation model, so a host page's
universal prefers-reduced-motion nullifier actually reaches it; the SVG also
carries its own @media (prefers-reduced-motion: reduce) block, keeping it
motion-safe even embedded standalone (OG images, downloads). 'smil' is the
legacy <animate> output — SMIL escapes CSS reduced-motion nullifiers (this
shipped a real accessibility defect, HD#1416), so prefer 'css' on the web.
'none' is fully static. The animate flag is deprecated: animate: true
maps to 'smil', animate: false or omitted maps to 'none', and an
explicit motion always wins.
Positions-first usage (API consumers)
Render straight from raw ecliptic body positions — the shape any ephemeris emits. No selfprime synthesis focus nodes required.
import { renderPersonalSky } from '@latimer-woods-tech/constellation';
const svg = renderPersonalSky({
positions: {
sun: { longitude: 132.91 },
moon: { longitude: 245.3 },
mercury: { longitude: 155.2, retrograde: true }, // label renders "Mercury ℞"
// … venus, mars, jupiter, saturn, uranus, neptune, pluto,
// chiron, northNode, southNode, lilith, ascendant, midheaven
},
seed: 'user-or-chart-id', // same person → same sky
name: 'YOU', // centre label
motion: 'css', // 'css' on the web · 'none' (default) for static/OG/video
fixedStarOrb: 1.5, // conjunction orb for the fixed-stars lens (0 disables)
});Each known body is placed into its natural life-theme (from the
CELESTIAL_BODIES catalog) as a glyph-marked anchor; any fixed star from the
FIXED_STARS catalog conjunct a supplied position lights up with its name.
Unknown body keys are ignored, so you can pass an ephemeris output map
directly. positionsToThemes(positions, orb?) is exported separately if you
want to post-process the theme nodes before rendering.
Focus-node usage (synthesis consumers)
The original entry point, unchanged: six life-theme constellations fed by resolved focus nodes (convergence / voices / tensions layers as light).
import { renderConstellation } from '@latimer-woods-tech/constellation';
const svg = renderConstellation({
forge: 'self',
seed: 'user-id',
themes: { purpose: { stars: [{ role: 'anchor', system: 'astrology', magnitude: 3 }] } },
pulse: { timing: true }, // themes lit by a live transit
motion: 'css', // reduced-motion-governable twinkle/pulse
});Catalogs & lenses
CELESTIAL_BODIES,BODY_ORDER,bodiesByTheme— planets, luminaries, angles: glyph, colour, magnitude, life-theme affinity.FIXED_STARS,activeFixedStars,magTier,SPECTRAL_COLOR— the Behenian 15 + bright navigational stars, conjunction matching.activeTransitThemes,pulseThemes,transitCaption— the living sky.kuaNumber,eightMansions,fengShuiByTheme,WU_XING— Feng Shui lens.
