Static portfolio hosting documentation for three independent projects. No build system, framework, or package manager — pure HTML, CSS, and vanilla JavaScript. All media is optimized via an automated Python pipeline for maximum performance.
- Local Development & Environment
- Image Optimization Pipeline
- Directory Structure
- Managing Photos
- Adding a New Photo Category
- Theme System
- Backup
ProjectWebSites/
├── index.html Main landing page with gallery
├── impressum.html Legal notice
├── theme.css Shared color tokens for all pages
├── theme-switcher.js Floating theme-picker UI
├── build-gallery.py ← unified script for all galleries
├── manifest.js Auto-generated — DO NOT edit manually
├── favicon.ico
├── images/ Shared site images (e.g. avatar)
├── gallery/ Main page gallery gallery (created when needed)
│
├── SnoreDoctor/
│ ├── index.html App guide page (sidebar + dynamic gallery)
│ ├── style.css
│ └── gallery/
│ ├── manifest.js Auto-generated — DO NOT edit manually
│ ├── main/
│ ├── session-detail/
│ ├── analysis/
│ ├── calendar/
│ ├── anti-snoring/
│ ├── learn/
│ └── settings/
│
├── LichtLabor/
│ ├── index.html Project page (sidebar + filtered gallery)
│ ├── style.css
│ ├── manifest.js Auto-generated — DO NOT edit manually
│ └── gallery/
│ ├── software/
│ │ ├── designer/
│ │ └── livePlayer/
│ ├── hardware-setup/
│ ├── led-installations/
│ ├── live-shows/
│ └── mobile/
│
└── sinitintro/ Legacy Bootstrap 2.x template (do not edit)
Serve the site using any static HTTP server:
python3 -m http.server 8000Or with live-reload:
npx live-serverNo build step, no npm install, no compilation.
To manage image optimization without installing libraries globally, use the provided setup_env.sh script:
- Make it executable: Run
chmod +x setup_env.shin your terminal. - Run it: Execute
./setup_env.sh. This creates a.venvdirectory containing all necessary dependencies (Pillow, HEIF, and AVIF support).
Whenever you want to run the gallery builder or any image processing scripts, activate the environment first:
source .venv/bin/activate
python3 build-gallery.pyWhile the environment is active, your terminal prompt will usually show (.venv), indicating that any python or pip commands are local to this project. When finished, simply type deactivate.
The galleries are driven by manifest.js files generated from the gallery/ directories.
This file is auto-generated — you never edit it by hand.
The page reads it on load and builds the photo grid dynamically.
-
Create the gallery directory (if it doesn't exist):
mkdir -p gallery
-
Create category subfolders for your projects:
mkdir -p gallery/lumo mkdir -p gallery/lichtlabor mkdir -p gallery/snore-doctor mkdir -p gallery/electronics mkdir -p gallery/software
-
Drop images into the appropriate category folder:
gallery/lumo/puppet-show.jpg gallery/lichtlabor/hardware-setup.png gallery/snore-doctor/screenshot.png gallery/electronics/circuit-board.jpgSupported formats:
.png.jpg.jpeg.webp.gif -
Regenerate the manifest from the project root:
source .venv/bin/activate python3 build-gallery.py deactivateThe script prints a summary so you can verify counts look right.
-
Reload the page — the gallery will show your new gallery with filter buttons.
Delete the file from the category folder and re-run build-gallery.py.
The unified build script supports different configurations:
# Generate manifest.js (default for galleries)
python3 build-gallery.py --format js-
Create the folder:
mkdir SnoreDoctor/gallery/my-new-section
-
Register it in the page so it gets a title, description, and icon. Open
SnoreDoctor/index.htmland find theCATEGORIESobject (look forconst CATEGORIES). Add an entry:"my-new-section": { title: "My New Section", icon: "🔔", description: "What this section covers.", tags: [ { label: "Feature A", color: "blue" }, { label: "Feature B", color: "green" }, ] },
Available tag colors:
bluegreenorangepurple -
Drop images into the folder and run the build script:
python3 build-gallery.py --dir SnoreDoctor
-
Create the category folder:
mkdir LichtLabor/gallery/my-category
-
Add metadata: Create
LichtLabor/gallery/my-category/description.txt. Line 1 should be the title, Line 2 the description. -
Drop images and regenerate:
python3 build-gallery.py --dir LichtLabor
All pages share theme.css which defines CSS custom properties (--bg, --accent, etc.).
A floating palette button (bottom-right corner on every page) lets you switch themes live.
The choice is saved in localStorage and persists across page loads.
| Name | Style |
|---|---|
| Default | Purple / Cyan (light) |
| Dark | Purple / Cyan (dark) |
| Power Grid | Cyan / Violet (dark, high-tech) |
| Amber Glow | Amber / Orange (dark, hardware) |
| Ocean | Blue / Teal (light) |
| Forest | Green (light) |
| Sunset | Orange / Rose (light) |
| Earth Tech | Green / Brown (light, organic) |
| Mono | Near-black (light) |
| Titanium | Black on white (high contrast) |
| Ghost | Blue on off-white (minimal) |
| Apple Light | Silver (Apple-inspired) |
| Apple Dark | Space Gray (Apple-inspired) |
Open theme.css and add a new block at the bottom:
[data-theme="my-theme"] {
--bg: #ffffff;
--bg2: #f5f5f5;
--surface: #ffffff;
--accent: #e63946;
--accent2: #457b9d;
--text: #1d1d1d;
--muted: #6b6b6b;
--border: rgba(0,0,0,0.1);
--hero-glow: rgba(230,57,70,0.1);
}Then register it in theme-switcher.js by adding an entry to the THEMES array:
{ id: "my-theme", label: "My Theme", swatch: "#e63946" },Run from the project root to create a timestamped .tar.gz archive:
bash backup.shOutput: backup_YYYYMMDD_HHMMSS.tar.gz in the parent directory.