# lhosk/portfolio architecture

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

- Interactive diagram: https://gitdiagram.com/lhosk/portfolio
- Repository: https://github.com/lhosk/portfolio

## Overview

This React portfolio serves a visitor-facing route flow: visitors navigate the site, browse project and paper catalogs or photo collections, and open detailed write-ups and interactive demos. Its main domain branches are biographical pages, project/paper content, photo discovery, and standalone WebGL demonstrations. The photo workflow also has an offline indexing stage that prepares image variants and metadata. The graph reflects documented routes and sampled component usage; some detail-page wiring and photo-index implementation are documented but not sampled.

Main entry points: [`src/App.js`](https://github.com/lhosk/portfolio/blob/main/src/App.js) (Router and layout), [`src/pages/Photos.js`](https://github.com/lhosk/portfolio/blob/main/src/pages/Photos.js) (Photo gallery), [`src/components/DetailPage.js`](https://github.com/lhosk/portfolio/blob/main/src/components/DetailPage.js) (Shared page UI), [`src/pages/Projects.js`](https://github.com/lhosk/portfolio/blob/main/src/pages/Projects.js) (Project catalog)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_shell["Site shell"]
  node_app["Router and layout<br/>[App.js]"]
  node_home["Home page<br/>[HomePage.js]"]
  node_career["Career page<br/>[Career.js]"]
  node_about["About page<br/>[About.js]"]
  node_site_data["Site links and contact<br/>[site.js]"]
  node_shared_ui["Shared page UI<br/>[DetailPage.js]"]
  node_styles["Shared styles<br/>[styles.js]"]
  node_nav["Navigation<br/>[NavBar.js]"]
  node_footer["Footer<br/>[Footer.js]"]
end

subgraph group_catalog["Projects and papers"]
  node_project_catalog["Project catalog<br/>[Projects.js]"]
  node_paper_catalog["Paper catalog<br/>[Papers.js]"]
  node_filter_grid["Catalog filters<br/>[FilterGrid.js]"]
  node_catalog_data["Project and paper data<br/>[projects.js]"]
  node_project_details["Project write-ups"]
  node_thorium["Thorium study<br/>[thorium.js]"]
  node_paper_details["Paper write-ups"]
  node_phonon_paper["Phonon article<br/>[phononintro.js]"]
  node_phonon_animations["Phonon animations"]
end

subgraph group_photos["Photo gallery"]
  node_photo_page["Photo gallery<br/>[Photos.js]"]
  node_photo_metadata["Photo index<br/>[photoIndex.json]"]
  node_photo_filters["Gallery filters<br/>[FilterBar.js]"]
  node_time_slider["Time range control<br/>[TimeSlider.js]"]
  node_photo_format["Photo formatting<br/>[format.js]"]
  node_photo_modal["Photo viewer<br/>[PhotoModal.js]"]
  node_photo_indexer["Photo index builder<br/>[buildPhotoIndex.js]"]
  node_photo_sources["Original photos"]
end

subgraph group_demos["WebGL demos"]
  node_webgl_pages["WebGL project pages"]
  node_webgl_layout["Demo page layout<br/>[GlDemo.js]"]
  node_webgl_files["Standalone demos"]
end

node_visitor(("Visitor"))

node_visitor -->|"opens"| node_app
node_app -->|"routes to"| node_home
node_app -->|"routes to"| node_career
node_app -->|"routes to"| node_about
node_app -->|"routes to"| node_project_catalog
node_app -->|"routes to"| node_paper_catalog
node_app -->|"routes to"| node_photo_page
node_app -->|"routes to"| node_project_details
node_app -->|"routes to"| node_paper_details
node_app -->|"renders"| node_nav
node_app -->|"renders"| node_footer
node_nav -->|"reads links"| node_site_data
node_footer -->|"reads contact"| node_site_data
node_project_catalog -->|"renders"| node_filter_grid
node_paper_catalog -->|"renders"| node_filter_grid
node_project_catalog -->|"reads entries"| node_catalog_data
node_paper_catalog -->|"reads entries"| node_catalog_data
node_project_details -.->|"uses layout"| node_shared_ui
node_paper_details -.->|"uses layout"| node_shared_ui
node_shared_ui -->|"looks up page entry"| node_catalog_data
node_phonon_paper -->|"renders animations"| node_phonon_animations
node_thorium -->|"renders layout"| node_shared_ui
node_photo_page -->|"reads metadata"| node_photo_metadata
node_photo_page -->|"renders filters"| node_photo_filters
node_photo_page -->|"opens viewer"| node_photo_modal
node_photo_page -->|"formats thumbnails"| node_photo_format
node_photo_filters -->|"renders control"| node_time_slider
node_photo_filters -->|"uses month names"| node_photo_format
node_photo_modal -->|"formats details"| node_photo_format
node_photo_sources -->|"provides originals"| node_photo_indexer
node_photo_indexer -->|"writes index"| node_photo_metadata
node_photo_indexer -->|"reads images"| node_photo_sources
node_webgl_pages -->|"uses shared layout"| node_webgl_layout
node_webgl_layout -->|"embeds demo"| node_webgl_files
node_webgl_layout -->|"renders detail layout"| node_shared_ui

click node_app "https://github.com/lhosk/portfolio/blob/main/src/App.js"
click node_home "https://github.com/lhosk/portfolio/blob/main/src/pages/HomePage.js"
click node_career "https://github.com/lhosk/portfolio/blob/main/src/pages/Career.js"
click node_about "https://github.com/lhosk/portfolio/blob/main/src/pages/About.js"
click node_site_data "https://github.com/lhosk/portfolio/blob/main/src/data/site.js"
click node_shared_ui "https://github.com/lhosk/portfolio/blob/main/src/components/DetailPage.js"
click node_styles "https://github.com/lhosk/portfolio/blob/main/src/components/styles.js"
click node_project_catalog "https://github.com/lhosk/portfolio/blob/main/src/pages/Projects.js"
click node_paper_catalog "https://github.com/lhosk/portfolio/blob/main/src/pages/Papers.js"
click node_filter_grid "https://github.com/lhosk/portfolio/blob/main/src/components/FilterGrid.js"
click node_catalog_data "https://github.com/lhosk/portfolio/blob/main/src/data/projects.js"
click node_project_details "https://github.com/lhosk/portfolio/tree/main/src/pages/projects"
click node_thorium "https://github.com/lhosk/portfolio/blob/main/src/pages/projects/thorium.js"
click node_paper_details "https://github.com/lhosk/portfolio/tree/main/src/pages/papers"
click node_phonon_paper "https://github.com/lhosk/portfolio/blob/main/src/pages/papers/phononintro.js"
click node_phonon_animations "https://github.com/lhosk/portfolio/tree/main/src/pages/papers/phanimations"
click node_photo_page "https://github.com/lhosk/portfolio/blob/main/src/pages/Photos.js"
click node_photo_metadata "https://github.com/lhosk/portfolio/blob/main/src/data/photoIndex.json"
click node_photo_filters "https://github.com/lhosk/portfolio/blob/main/src/pages/photos/FilterBar.js"
click node_time_slider "https://github.com/lhosk/portfolio/blob/main/src/pages/photos/TimeSlider.js"
click node_photo_format "https://github.com/lhosk/portfolio/blob/main/src/pages/photos/format.js"
click node_photo_modal "https://github.com/lhosk/portfolio/blob/main/src/pages/photos/PhotoModal.js"
click node_photo_indexer "https://github.com/lhosk/portfolio/blob/main/scripts/buildPhotoIndex.js"
click node_webgl_pages "https://github.com/lhosk/portfolio/tree/main/src/pages/projects/gl"
click node_webgl_layout "https://github.com/lhosk/portfolio/blob/main/src/pages/projects/gl/GlDemo.js"
click node_webgl_files "https://github.com/lhosk/portfolio/tree/main/public/files"
click node_nav "https://github.com/lhosk/portfolio/blob/main/src/components/NavBar.js"
click node_footer "https://github.com/lhosk/portfolio/blob/main/src/components/Footer.js"

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_app,node_home,node_career,node_about,node_site_data,node_shared_ui,node_styles,node_nav,node_footer toneBlue
class node_project_catalog,node_paper_catalog,node_filter_grid,node_catalog_data,node_project_details,node_thorium,node_paper_details,node_phonon_paper,node_phonon_animations toneAmber
class node_photo_page,node_photo_metadata,node_photo_filters,node_time_slider,node_photo_format,node_photo_modal,node_photo_indexer,node_photo_sources toneMint
class node_webgl_pages,node_webgl_layout,node_webgl_files toneRose
class node_visitor toneIndigo
```

## Components

### Site shell

- [Router and layout](https://github.com/lhosk/portfolio/blob/main/src/App.js): `src/App.js`
- [Home page](https://github.com/lhosk/portfolio/blob/main/src/pages/HomePage.js): `src/pages/HomePage.js`
- [Career page](https://github.com/lhosk/portfolio/blob/main/src/pages/Career.js): `src/pages/Career.js`
- [About page](https://github.com/lhosk/portfolio/blob/main/src/pages/About.js): `src/pages/About.js`
- [Site links and contact](https://github.com/lhosk/portfolio/blob/main/src/data/site.js): `src/data/site.js`
- [Shared page UI](https://github.com/lhosk/portfolio/blob/main/src/components/DetailPage.js): `src/components/DetailPage.js`
- [Shared styles](https://github.com/lhosk/portfolio/blob/main/src/components/styles.js): `src/components/styles.js`
- [Navigation](https://github.com/lhosk/portfolio/blob/main/src/components/NavBar.js): `src/components/NavBar.js`
- [Footer](https://github.com/lhosk/portfolio/blob/main/src/components/Footer.js): `src/components/Footer.js`

### Projects and papers

- [Project catalog](https://github.com/lhosk/portfolio/blob/main/src/pages/Projects.js): `src/pages/Projects.js`
- [Paper catalog](https://github.com/lhosk/portfolio/blob/main/src/pages/Papers.js): `src/pages/Papers.js`
- [Catalog filters](https://github.com/lhosk/portfolio/blob/main/src/components/FilterGrid.js): `src/components/FilterGrid.js`
- [Project and paper data](https://github.com/lhosk/portfolio/blob/main/src/data/projects.js): `src/data/projects.js`
- [Project write-ups](https://github.com/lhosk/portfolio/tree/main/src/pages/projects): `src/pages/projects`
- [Thorium study](https://github.com/lhosk/portfolio/blob/main/src/pages/projects/thorium.js): `src/pages/projects/thorium.js`
- [Paper write-ups](https://github.com/lhosk/portfolio/tree/main/src/pages/papers): `src/pages/papers`
- [Phonon article](https://github.com/lhosk/portfolio/blob/main/src/pages/papers/phononintro.js): `src/pages/papers/phononintro.js`
- [Phonon animations](https://github.com/lhosk/portfolio/tree/main/src/pages/papers/phanimations): `src/pages/papers/phanimations`

### Photo gallery

- [Photo gallery](https://github.com/lhosk/portfolio/blob/main/src/pages/Photos.js): `src/pages/Photos.js`
- [Photo index](https://github.com/lhosk/portfolio/blob/main/src/data/photoIndex.json): `src/data/photoIndex.json`
- [Gallery filters](https://github.com/lhosk/portfolio/blob/main/src/pages/photos/FilterBar.js): `src/pages/photos/FilterBar.js`
- [Time range control](https://github.com/lhosk/portfolio/blob/main/src/pages/photos/TimeSlider.js): `src/pages/photos/TimeSlider.js`
- [Photo formatting](https://github.com/lhosk/portfolio/blob/main/src/pages/photos/format.js): `src/pages/photos/format.js`
- [Photo viewer](https://github.com/lhosk/portfolio/blob/main/src/pages/photos/PhotoModal.js): `src/pages/photos/PhotoModal.js`
- [Photo index builder](https://github.com/lhosk/portfolio/blob/main/scripts/buildPhotoIndex.js): `scripts/buildPhotoIndex.js`
- **Original photos**

### WebGL demos

- [WebGL project pages](https://github.com/lhosk/portfolio/tree/main/src/pages/projects/gl): `src/pages/projects/gl`
- [Demo page layout](https://github.com/lhosk/portfolio/blob/main/src/pages/projects/gl/GlDemo.js): `src/pages/projects/gl/GlDemo.js`
- [Standalone demos](https://github.com/lhosk/portfolio/tree/main/public/files): `public/files`

### Other components

- **Visitor**

## Connections

- Visitor → Router and layout: opens (evidence: `README.md`)
- Router and layout → Home page: routes to (evidence: `src/App.js`)
- Router and layout → Career page: routes to (evidence: `src/App.js`)
- Router and layout → About page: routes to (evidence: `src/App.js`)
- Router and layout → Project catalog: routes to (evidence: `src/App.js`)
- Router and layout → Paper catalog: routes to (evidence: `src/App.js`)
- Router and layout → Photo gallery: routes to (evidence: `src/App.js`)
- Router and layout → Project write-ups: routes to (evidence: `src/App.js`)
- Router and layout → Paper write-ups: routes to (evidence: `src/App.js`)
- Router and layout → Navigation: renders (evidence: `src/App.js`)
- Router and layout → Footer: renders (evidence: `src/App.js`)
- Navigation → Site links and contact: reads links (evidence: `src/components/NavBar.js`)
- Footer → Site links and contact: reads contact (evidence: `src/components/Footer.js`)
- Project catalog → Catalog filters: renders (evidence: `src/pages/Projects.js`)
- Paper catalog → Catalog filters: renders (evidence: `src/pages/Papers.js`)
- Project catalog → Project and paper data: reads entries (evidence: `src/pages/Projects.js`)
- Paper catalog → Project and paper data: reads entries (evidence: `src/pages/Papers.js`)
- Project write-ups → Shared page UI: uses layout (evidence: `README.md`)
- Paper write-ups → Shared page UI: uses layout (evidence: `README.md`)
- Shared page UI → Project and paper data: looks up page entry (evidence: `src/components/DetailPage.js`)
- Phonon article → Phonon animations: renders animations (evidence: `src/pages/papers/phononintro.js`)
- Thorium study → Shared page UI: renders layout (evidence: `src/pages/projects/thorium.js`)
- Photo gallery → Photo index: reads metadata (evidence: `src/pages/Photos.js`)
- Photo gallery → Gallery filters: renders filters (evidence: `src/pages/Photos.js`)
- Photo gallery → Photo viewer: opens viewer (evidence: `src/pages/Photos.js`)
- Photo gallery → Photo formatting: formats thumbnails (evidence: `src/pages/Photos.js`)
- Gallery filters → Time range control: renders control (evidence: `src/pages/photos/FilterBar.js`)
- Gallery filters → Photo formatting: uses month names (evidence: `src/pages/photos/FilterBar.js`)
- Photo viewer → Photo formatting: formats details (evidence: `src/pages/photos/PhotoModal.js`)
- Original photos → Photo index builder: provides originals (evidence: `README.md`)
- Photo index builder → Photo index: writes index (evidence: `README.md`)
- Photo index builder → Original photos: reads images (evidence: `README.md`)
- WebGL project pages → Demo page layout: uses shared layout (evidence: `src/pages/projects/gl/perspective.js`)
- Demo page layout → Standalone demos: embeds demo (evidence: `src/pages/projects/gl/GlDemo.js`)
- Demo page layout → Shared page UI: renders detail layout (evidence: `src/pages/projects/gl/GlDemo.js`)
