# francominelli11/keistars architecture

> Architecture diagram of the GitHub repository francominelli11/keistars, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/francominelli11/keistars
- Repository: https://github.com/francominelli11/keistars

## Overview

KeiStars is a browser-only commemorative star-map poster designer. A visitor enters the editor, sets a place and local date/time, chooses a theme, text, colors and print size, then previews and exports a PNG or print-ready PDF; designs can be autosaved locally or shared in a URL fragment. The graph covers the documented landing, place search, celestial rendering, poster composition and export stages. Some component wiring is supported by the SOURCE INDEX or README rather than sampled implementation, so uncertain connections are omitted.

Main entry points: [`src/components/PosterStage.tsx`](https://github.com/francominelli11/keistars/blob/main/src/components/PosterStage.tsx) (Poster stage), [`src/components/ControlPanel.tsx`](https://github.com/francominelli11/keistars/blob/main/src/components/ControlPanel.tsx) (Control panel), [`src/App.tsx`](https://github.com/francominelli11/keistars/blob/main/src/App.tsx) (Editor shell), [`src/lib/posterRender.ts`](https://github.com/francominelli11/keistars/blob/main/src/lib/posterRender.ts) (Canvas composition)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_site["Site and entry"]
  node_navigation["Route dispatch<br/>[main.tsx]"]
  node_landing["Commercial landing<br/>[Landing.tsx]"]
end

subgraph group_design["Design editor"]
  node_editor["Editor shell<br/>[App.tsx]"]
  node_controls["Control panel<br/>[ControlPanel.tsx]"]
  node_place["Place search"]
  node_moment["Date and time<br/>[MomentSection.tsx]"]
  node_copy["Poster text<br/>[CopySection.tsx]"]
  node_skycontrols["Sky options<br/>[SkySection.tsx]"]
  node_themes["Themes and colors<br/>[themes.ts]"]
  node_posterstate["Poster state<br/>[poster.ts]"]
  node_searchhook["City search hook<br/>[useCitySearch.ts]"]
end

subgraph group_sky["Celestial map"]
  node_maphook["Celestial map hook<br/>[useCelestialMap.ts]"]
  node_mapconfig["Map configuration<br/>[celestialConfig.ts]"]
  node_celestial["Celestial map runtime<br/>[celestialMap.ts]"]
  node_celestialloader["Engine loader<br/>[celestialLoader.ts]"]
end

subgraph group_poster["Poster output"]
  node_mapstage["Poster stage<br/>[PosterStage.tsx]"]
  node_preview["Poster preview<br/>[PreviewModal.tsx]"]
  node_layout["Poster layout<br/>[posterLayout.ts]"]
  node_render["Canvas composition<br/>[posterRender.ts]"]
  node_sizes["Print sizes<br/>[posterSizes.ts]"]
  node_png["PNG export<br/>[exportPoster.ts]"]
  node_pdf["PDF export<br/>[exportPosterPdf.ts]"]
  node_fonts["Poster fonts<br/>[fonts.ts]"]
end

subgraph group_services["Persistence and services"]
  node_geocoder["Place geocoding<br/>[nominatim.ts]"]
  node_storage["Save and share<br/>[storage.ts]"]
end

node_visitor(("Visitor"))
node_geocoders["Geocoding services"]
node_localstorage[("Browser storage")]
node_sharedlink["Share URL fragment"]

node_visitor -->|"opens site"| node_navigation
node_navigation -->|"routes to"| node_landing
node_navigation -->|"lazy loads"| node_editor
node_visitor -->|"designs poster"| node_editor
node_editor -->|"renders"| node_controls
node_editor -->|"renders"| node_mapstage
node_controls -->|"renders"| node_place
node_controls -.->|"renders"| node_moment
node_controls -.->|"renders"| node_copy
node_controls -.->|"renders"| node_skycontrols
node_controls -->|"updates"| node_posterstate
node_place -.->|"searches with"| node_searchhook
node_searchhook -->|"calls"| node_geocoder
node_geocoder -->|"queries Nominatim and Photon"| node_geocoders
node_editor -->|"creates actions"| node_posterstate
node_editor -->|"loads and saves"| node_storage
node_storage -->|"hydrates"| node_posterstate
node_storage -.->|"persists design"| node_localstorage
node_storage -->|"encodes state"| node_sharedlink
node_mapstage -->|"uses"| node_maphook
node_maphook -->|"computes geometry"| node_mapconfig
node_maphook -->|"initializes and updates"| node_celestial
node_celestial -->|"loads engine"| node_celestialloader
node_mapconfig -->|"builds theme style"| node_themes
node_mapstage -->|"opens"| node_preview
node_mapstage -->|"exports PNG"| node_png
node_mapstage -->|"exports PDF"| node_pdf
node_mapstage -->|"renders poster"| node_render
node_preview -->|"renders preview"| node_render
node_render -->|"gets geometry"| node_layout
node_render -->|"uses font specs"| node_fonts
node_png -->|"composes canvas"| node_render
node_pdf -->|"composes canvas"| node_render
node_png -->|"uses dimensions"| node_sizes
node_pdf -->|"uses print dimensions"| node_sizes
node_mapstage -->|"selects print format"| node_sizes
node_mapstage -.->|"selects theme"| node_themes

click node_navigation "https://github.com/francominelli11/keistars/blob/main/src/main.tsx"
click node_landing "https://github.com/francominelli11/keistars/blob/main/src/pages/Landing.tsx"
click node_editor "https://github.com/francominelli11/keistars/blob/main/src/App.tsx"
click node_controls "https://github.com/francominelli11/keistars/blob/main/src/components/ControlPanel.tsx"
click node_place "https://github.com/francominelli11/keistars/blob/main/src/components/LocationSection.tsx"
click node_moment "https://github.com/francominelli11/keistars/blob/main/src/components/MomentSection.tsx"
click node_copy "https://github.com/francominelli11/keistars/blob/main/src/components/CopySection.tsx"
click node_skycontrols "https://github.com/francominelli11/keistars/blob/main/src/components/SkySection.tsx"
click node_themes "https://github.com/francominelli11/keistars/blob/main/src/lib/themes.ts"
click node_posterstate "https://github.com/francominelli11/keistars/blob/main/src/state/poster.ts"
click node_searchhook "https://github.com/francominelli11/keistars/blob/main/src/hooks/useCitySearch.ts"
click node_geocoder "https://github.com/francominelli11/keistars/blob/main/src/lib/nominatim.ts"
click node_mapstage "https://github.com/francominelli11/keistars/blob/main/src/components/PosterStage.tsx"
click node_maphook "https://github.com/francominelli11/keistars/blob/main/src/hooks/useCelestialMap.ts"
click node_mapconfig "https://github.com/francominelli11/keistars/blob/main/src/lib/celestialConfig.ts"
click node_celestial "https://github.com/francominelli11/keistars/blob/main/src/lib/celestialMap.ts"
click node_celestialloader "https://github.com/francominelli11/keistars/blob/main/src/lib/celestialLoader.ts"
click node_preview "https://github.com/francominelli11/keistars/blob/main/src/components/PreviewModal.tsx"
click node_layout "https://github.com/francominelli11/keistars/blob/main/src/lib/posterLayout.ts"
click node_render "https://github.com/francominelli11/keistars/blob/main/src/lib/posterRender.ts"
click node_sizes "https://github.com/francominelli11/keistars/blob/main/src/lib/posterSizes.ts"
click node_png "https://github.com/francominelli11/keistars/blob/main/src/lib/exportPoster.ts"
click node_pdf "https://github.com/francominelli11/keistars/blob/main/src/lib/exportPosterPdf.ts"
click node_fonts "https://github.com/francominelli11/keistars/blob/main/src/lib/fonts.ts"
click node_storage "https://github.com/francominelli11/keistars/blob/main/src/lib/storage.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_navigation,node_landing toneBlue
class node_editor,node_controls,node_place,node_moment,node_copy,node_skycontrols,node_themes,node_posterstate,node_searchhook,node_localstorage toneAmber
class node_maphook,node_mapconfig,node_celestial,node_celestialloader toneMint
class node_mapstage,node_preview,node_layout,node_render,node_sizes,node_png,node_pdf,node_fonts toneRose
class node_geocoder,node_storage,node_visitor,node_geocoders,node_sharedlink toneIndigo
```

## Components

### Site and entry

- [Route dispatch](https://github.com/francominelli11/keistars/blob/main/src/main.tsx): `src/main.tsx`
- [Commercial landing](https://github.com/francominelli11/keistars/blob/main/src/pages/Landing.tsx): `src/pages/Landing.tsx`

### Design editor

- [Editor shell](https://github.com/francominelli11/keistars/blob/main/src/App.tsx): `src/App.tsx`
- [Control panel](https://github.com/francominelli11/keistars/blob/main/src/components/ControlPanel.tsx): `src/components/ControlPanel.tsx`
- [Place search](https://github.com/francominelli11/keistars/blob/main/src/components/LocationSection.tsx): `src/components/LocationSection.tsx`
- [Date and time](https://github.com/francominelli11/keistars/blob/main/src/components/MomentSection.tsx): `src/components/MomentSection.tsx`
- [Poster text](https://github.com/francominelli11/keistars/blob/main/src/components/CopySection.tsx): `src/components/CopySection.tsx`
- [Sky options](https://github.com/francominelli11/keistars/blob/main/src/components/SkySection.tsx): `src/components/SkySection.tsx`
- [Themes and colors](https://github.com/francominelli11/keistars/blob/main/src/lib/themes.ts): `src/lib/themes.ts`
- [Poster state](https://github.com/francominelli11/keistars/blob/main/src/state/poster.ts): `src/state/poster.ts`
- [City search hook](https://github.com/francominelli11/keistars/blob/main/src/hooks/useCitySearch.ts): `src/hooks/useCitySearch.ts`

### Celestial map

- [Celestial map hook](https://github.com/francominelli11/keistars/blob/main/src/hooks/useCelestialMap.ts): `src/hooks/useCelestialMap.ts`
- [Map configuration](https://github.com/francominelli11/keistars/blob/main/src/lib/celestialConfig.ts): `src/lib/celestialConfig.ts`
- [Celestial map runtime](https://github.com/francominelli11/keistars/blob/main/src/lib/celestialMap.ts): `src/lib/celestialMap.ts`
- [Engine loader](https://github.com/francominelli11/keistars/blob/main/src/lib/celestialLoader.ts): `src/lib/celestialLoader.ts`

### Poster output

- [Poster stage](https://github.com/francominelli11/keistars/blob/main/src/components/PosterStage.tsx): `src/components/PosterStage.tsx`
- [Poster preview](https://github.com/francominelli11/keistars/blob/main/src/components/PreviewModal.tsx): `src/components/PreviewModal.tsx`
- [Poster layout](https://github.com/francominelli11/keistars/blob/main/src/lib/posterLayout.ts): `src/lib/posterLayout.ts`
- [Canvas composition](https://github.com/francominelli11/keistars/blob/main/src/lib/posterRender.ts): `src/lib/posterRender.ts`
- [Print sizes](https://github.com/francominelli11/keistars/blob/main/src/lib/posterSizes.ts): `src/lib/posterSizes.ts`
- [PNG export](https://github.com/francominelli11/keistars/blob/main/src/lib/exportPoster.ts): `src/lib/exportPoster.ts`
- [PDF export](https://github.com/francominelli11/keistars/blob/main/src/lib/exportPosterPdf.ts): `src/lib/exportPosterPdf.ts`
- [Poster fonts](https://github.com/francominelli11/keistars/blob/main/src/lib/fonts.ts): `src/lib/fonts.ts`

### Persistence and services

- [Place geocoding](https://github.com/francominelli11/keistars/blob/main/src/lib/nominatim.ts): `src/lib/nominatim.ts`
- [Save and share](https://github.com/francominelli11/keistars/blob/main/src/lib/storage.ts): `src/lib/storage.ts`

### Other components

- **Visitor**
- **Geocoding services**
- **Browser storage**
- **Share URL fragment**

## Connections

- Visitor → Route dispatch: opens site (evidence: `README.md`)
- Route dispatch → Commercial landing: routes to (evidence: `src/main.tsx`)
- Route dispatch → Editor shell: lazy loads (evidence: `README.md`)
- Visitor → Editor shell: designs poster (evidence: `README.md`)
- Editor shell → Control panel: renders (evidence: `src/App.tsx`)
- Editor shell → Poster stage: renders (evidence: `src/App.tsx`)
- Control panel → Place search: renders (evidence: `src/components/ControlPanel.tsx`)
- Control panel → Date and time: renders (evidence: `src/components/ControlPanel.tsx`)
- Control panel → Poster text: renders (evidence: `src/components/ControlPanel.tsx`)
- Control panel → Sky options: renders (evidence: `src/components/ControlPanel.tsx`)
- Control panel → Poster state: updates (evidence: `src/components/ControlPanel.tsx`)
- Place search → City search hook: searches with
- City search hook → Place geocoding: calls (evidence: `src/hooks/useCitySearch.ts`)
- Place geocoding → Geocoding services: queries Nominatim and Photon (evidence: `README.md`)
- Editor shell → Poster state: creates actions (evidence: `src/App.tsx`)
- Editor shell → Save and share: loads and saves (evidence: `src/App.tsx`)
- Save and share → Poster state: hydrates (evidence: `src/lib/storage.ts`)
- Save and share → Browser storage: persists design
- Save and share → Share URL fragment: encodes state (evidence: `src/lib/storage.ts`)
- Poster stage → Celestial map hook: uses (evidence: `src/components/PosterStage.tsx`)
- Celestial map hook → Map configuration: computes geometry (evidence: `src/hooks/useCelestialMap.ts`)
- Celestial map hook → Celestial map runtime: initializes and updates (evidence: `src/hooks/useCelestialMap.ts`)
- Celestial map runtime → Engine loader: loads engine (evidence: `src/lib/celestialMap.ts`)
- Map configuration → Themes and colors: builds theme style (evidence: `src/lib/celestialConfig.ts`)
- Poster stage → Poster preview: opens (evidence: `src/components/PosterStage.tsx`)
- Poster stage → PNG export: exports PNG (evidence: `src/components/PosterStage.tsx`)
- Poster stage → PDF export: exports PDF (evidence: `src/components/PosterStage.tsx`)
- Poster stage → Canvas composition: renders poster (evidence: `src/components/PosterStage.tsx`)
- Poster preview → Canvas composition: renders preview (evidence: `src/components/PreviewModal.tsx`)
- Canvas composition → Poster layout: gets geometry (evidence: `src/lib/posterRender.ts`)
- Canvas composition → Poster fonts: uses font specs (evidence: `src/lib/posterRender.ts`)
- PNG export → Canvas composition: composes canvas (evidence: `src/lib/exportPoster.ts`)
- PDF export → Canvas composition: composes canvas (evidence: `src/lib/exportPosterPdf.ts`)
- PNG export → Print sizes: uses dimensions (evidence: `src/lib/exportPoster.ts`)
- PDF export → Print sizes: uses print dimensions (evidence: `src/lib/exportPosterPdf.ts`)
- Poster stage → Print sizes: selects print format (evidence: `src/components/PosterStage.tsx`)
- Poster stage → Themes and colors: selects theme
