Add Images section — hub + 4 collection galleries, wire nav star

- Images/images.html: hub page linking all 4 collections
- Images/wayback.html, nomad-soul.html, myster-wizzard.html, exopraxist.html: collection galleries
- 429 thumbnails (360px) committed across 4 collections
- Gallery renders from baked filename arrays (no on-load fetch)
- Lightbox lazy-fetches FileBrowser for full-res on click, falls back to thumbnail
- .gitignore: allow Images/*/thumbnails/, anchor /GEMINI.md to root only, add .venv/
- index.html: wire Images star node to Images/images.html

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-27 20:06:19 +02:00
parent 8242492712
commit e57d2b0a72
433 changed files with 2249 additions and 2 deletions

13
.gitignore vendored
View File

@@ -8,7 +8,8 @@ CREATURE-PLAYGROUND/
DumperCan/
PARENT.md
SONNET.md
GEMINI.md
/GEMINI.md
!Images/GEMINI.md
SPORE_SYSTEM_SPEC_v0.2.md
SEEDS.md
*-JL-notes.md
@@ -23,6 +24,15 @@ HomePage-JL-notes.md
*.PNG
*.gif
*.GIF
# Thumbnails are small (360px) and live in git
!Images/*/thumbnails/
!Images/*/thumbnails/*.jpg
!Images/*/thumbnails/*.JPG
!Images/*/thumbnails/*.jpeg
!Images/*/thumbnails/*.JPEG
!Images/*/thumbnails/*.png
!Images/*/thumbnails/*.PNG
*.mp3
*.mp4
*.webm
@@ -42,3 +52,4 @@ DumperCan/WAMEX/WAMEX
Thumbs.db
*.swp
*~
.venv/

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

104
Images/GEMINI-FIX.md Normal file
View File

@@ -0,0 +1,104 @@
# GEMINI FIX BRIEF — Images gallery fetch failure
## The problem
The gallery is fetching from FileBrowser on page load to build the thumbnail grid.
This blocks rendering and fails (likely CORS or network timing).
## The fix — two-stage asset loading
**Stage 1 — Grid (instant, no network):**
Thumbnail filenames are baked into the HTML as a static JS array.
Render the grid immediately from `thumbnails/{filename}` — zero fetch required.
**Stage 2 — Lightbox (lazy, on click):**
When a thumbnail is clicked, fetch the FileBrowser API for that collection in the background
to get the original filename (with correct extension) for the full-res URL.
If the fetch fails or is slow, fall back to displaying the thumbnail in the lightbox.
Cache the API result — don't re-fetch on subsequent clicks.
---
## Baked filename arrays — use these exactly
### WayBack — token `voxb2LeQ`
```js
const WAYBACK = ["3DCB5B82-94E6-4BA0-A382-3A98007038F2.jpg","BreakermanAvatar1.jpg","ChristmiesPortrait3_low.jpg","ChristmiesPortrait_low.jpg","_DSC3150.jpg","Enlight100.jpg","Enlight1-2.jpg","Enlight1-4 (copy 1).jpg","Enlight1-4.jpg","Enlight27.jpg","Enlight33.jpg","Enlight37.jpg","Enlight38.jpg","Enlight39.jpg","Enlight40.jpg","Enlight44.jpg","Enlight46.jpg","Enlight47.jpg","Enlight48.jpg","Enlight49.jpg","Enlight50.jpg","Enlight51.jpg","Enlight54.jpg","Enlight55.jpg","Enlight56.jpg","Enlight68.jpg","Enlight70.jpg","Enlight71.jpg","Enlight72.jpg","Enlight73.jpg","Enlight74.jpg","Enlight76.jpg","Enlight94.jpg","Enlight95.jpg","Enlight98.jpg","Enlight99.jpg","Enlight9.jpg","IMG_0375.jpg","IMG_0787.jpg","IMG_0791.jpg","IMG_0828.jpg","IMG_0831.jpg","IMG_0835.jpg","IMG_0941.jpg","IMG_0944.jpg","IMG_0948.jpg","IMG_0970.jpg","IMG_0971.jpg","IMG_0972.jpg","IMG_1207.jpg","IMG_1208.jpg","IMG_1209.jpg","IMG_1210.jpg","IMG_1211.jpg","IMG_1212.jpg","IMG_1214.jpg","IMG_1215.jpg","IMG_1216.jpg","IMG_2610.jpg","IMG_2611.jpg","IMG_2612.jpg","IMG_2613.jpg","IMG_2614.jpg","IMG_2615.jpg","IMG_2616.jpg","IMG_2669.jpg","IMG_2684.jpg","IMG_2685.jpg","IMG_2696.jpg","IMG_2697.jpg","IMG_3123.jpg","IMG_3124.jpg","IMG_3188.jpg","IMG_3190.jpg","IMG_3482.jpg","IMG_3483.jpg","IMG_3484.jpg","IMG_3485.jpg","IMG_3486.jpg","IMG_3509.jpg","IMG_3512.jpg","IMG_3515.jpg","IMG_3516.jpg","IMG_3517.jpg","IMG_3751.jpg","IMG_3752.jpg","IMG_3760.jpg","JncPortraits1.jpg","JncPortraits2.jpg","JncPortraits3.jpg","Jnc_Teaser2.jpg","JnC_Teaser3.jpg","JnC_Teaser4.jpg","JnC_Teaser.jpg","ORT_ad1.jpg","ORT_ad2.jpg","ORT_ad3.jpg","ORT_ad4.jpg","TJF Cover photo2.jpg","TJF Cover photo3.jpg","TJF Cover photo4.jpg","TJF Cover photo5.jpg","TJF Cover photo6.jpg"];
```
### YourNomadSoul — token `yNytp9Di`
```js
const NOMAD = ["03E15F7E-3C6F-4F97-B4C9-6795DA2AA5D9.jpg","10B9A361-651C-48B6-B546-A8B1FAFD1C63.jpg","13F18846-DE0A-4241-9871-918FEE42E99C.jpg","1E43042E-FED5-41C0-B6CC-1B2EBB2AC444.jpg","1F78EFFE-1047-4FD8-AF3E-02CF401E1301.jpg","20250424_153909.jpg","20250509_013815.jpg","2476C9EC-AF3D-4C6A-A4EC-C02DE23E19DC.jpg","255ADCA7-B3FC-45AC-B8A2-F467CE943B69.jpg","28C577F5-E72D-4A80-9713-F6B2D9B9481A.jpg","2E5C2060-D6FD-48B4-B73D-A23B54C8ACF6.jpg","302B44E4-0B31-4A0F-9706-9416779C69F6.jpg","37562198-5802-42D1-AD08-D5676245FF95.jpg","38301693-900F-4A86-B204-EC3ED225110C.jpg","420FDA25-6214-4994-8B3C-E5BC37250847.jpg","464B57C7-F7CA-4982-A1F7-6EFF374EEBF7.jpg","538DD231-EE16-451B-AFB3-118561D31BA4.jpg","556AD25E-D25F-4A61-8910-B295820E8824.jpg","5BFF1175-6213-4E53-B0EF-60C264044DC7.jpg","5D09E88F-DC1E-464E-AAE5-391B25A3844E.jpg","61ED267A-372A-4DF0-8AB7-AE7FF061D00B.jpg","65E63360-02D8-4D39-AF52-270B9EE20743.jpg","66E9E706-CABD-4845-B4A9-210240B14C60.jpg","6A71F1C3-5C6A-43FC-B098-C09C0429454D.jpg","6B143887-9178-467B-B712-0C75630AE6AE.jpg","72134D18-616F-4C60-83B8-2BD87E72AD19.jpg","7A938D4C-FA4F-4C4E-95F4-4A2F6EF65EC5.jpg","7DEF89AC-E0C1-42A4-9719-EA49D6CB654F.jpg","84A8BEBA-444A-4AAF-9783-432487B2EBC3.jpg","92A53036-1ECD-473C-8543-4C217B59977C.jpg","9D22BCCD-BCC1-4835-A19D-90666B31614B.jpg","A3F0ECCA-F462-415E-A5FC-5C266BB964EF.jpg","A943A54B-5434-4D75-9748-D7CF26BE8C7A.jpg","B7AFD385-7C23-43E9-BFAF-E3C7E0637992.jpg","BB8106F0-D6B2-4790-B5F4-2E3ABA132E5B.jpg","C0B2F65C-FE7B-4C87-A320-C3CE3B096DDA.jpg","C84F9036-CBFE-4A0C-AE36-7DDC10F38FBF.jpg","CE783D3C-EAE6-4307-BA68-69479458085C.jpg","CFDF72B8-893C-42BA-AFF4-0662DBAE75CD.jpg","D6121816-C247-444A-8FDB-BECA57195AC1.jpg","D6924AED-E593-459C-946D-EEDC9D9CF85C.jpg","DE5E965E-2C42-4245-8F97-3B1CDFD92612.jpg","E21A56E3-5221-447E-A255-20060248785E.jpg","E5C22C2D-036F-4CA6-9677-592E21F360EF.jpg","E75BF5E2-6389-47C7-8F92-5903C566B1CD.jpg","EA6FEF34-CE32-44F9-86E9-409DB1AEE150.jpg","Enlight1-15.jpg","Enlight1-16.jpg","Enlight1-1.jpg","Enlight1-2 (copy 1).jpg","Enlight14.jpg","Enlight1-5 (copy 1).jpg","Enlight15.jpg","Enlight16.jpg","Enlight1-7.jpg","Enlight17.jpg","Enlight1-8.jpg","Enlight18.jpg","Enlight1-9.jpg","Enlight1 (copy 1).jpg","Enlight1.jpg","Enlight25.jpg","Enlight28.jpg","Enlight30.jpg","Enlight31.jpg","Enlight32.jpg","Enlight34.jpg","Enlight35.jpg","Enlight41.jpg","Enlight42.jpg","Enlight43.jpg","Enlight53.jpg","Enlight57.jpg","Enlight5.jpg","Enlight65.jpg","Enlight66.jpg","Enlight67.jpg","Enlight69.jpg","Enlight6.jpg","Enlight75.jpg","Enlight77.jpg","Enlight79.jpg","Enlight7.jpg","Enlight80.jpg","Enlight81.jpg","Enlight82.jpg","Enlight84.jpg","Enlight85.jpg","Enlight87.jpg","Enlight88.jpg","Enlight89.jpg","Enlight8.jpg","Enlight93.jpg","F4B3B056-C476-412B-A360-7DC55190406B.jpg","IMG_0006.jpg","IMG_0081.jpg","IMG_0146.jpg","IMG_0232.jpg","IMG_0526.jpg","IMG_0844.jpg","IMG_0876.jpg","IMG_0878.jpg","IMG_0881.jpg","IMG_0883.jpg","IMG_0935.jpg","IMG_0938.jpg","IMG_0940.jpg","IMG_0958.jpg","IMG_0959.jpg","IMG_0960.jpg","IMG_0961.jpg","IMG_0962.jpg","IMG_0963.jpg","IMG_0983.jpg","IMG_0985.jpg","IMG_0986.jpg","IMG_0987.jpg","IMG_0988.jpg","IMG_0989.jpg","IMG_1002.jpg","IMG_1028.jpg","IMG_1029.jpg","IMG_1030.jpg","IMG_1035.jpg","IMG_1052.jpg","IMG_1053.jpg","IMG_1063.jpg","IMG_1093.jpg","IMG_1095.jpg","IMG_1131.jpg","IMG_1132.jpg","IMG_1134.jpg","IMG_1139.jpg","IMG_1142.jpg","IMG_1143.jpg","IMG_1144.jpg","IMG_1157.jpg","IMG_1158.jpg","IMG_1159.jpg","IMG_1161.jpg","IMG_1163.jpg","IMG_1192.jpg","IMG_1193.jpg","IMG_1194.jpg","IMG_1231.jpg","IMG_1232.jpg","IMG_1233.jpg","IMG_1256.jpg","IMG_1257.jpg","IMG_1258.jpg","IMG_1259.jpg","IMG_1260.jpg","IMG_1261.jpg","IMG_1262.jpg","IMG_1263.jpg","IMG_1308.jpg","IMG_1309.jpg","IMG_1310.jpg","IMG_1472.jpg","IMG_1601.jpg","IMG_2190.jpg","IMG_2816.jpg","IMG_3012.jpg","IMG_3017.jpg","IMG_3018.jpg","IMG_3019.jpg","IMG_3059.jpg","IMG_3060.jpg","IMG_3061.jpg","IMG_3077.jpg","IMG_3078.jpg","IMG_3079.jpg","IMG_3082.jpg","IMG_3109.jpg","IMG_3110.jpg","IMG_3111.jpg","IMG_3125.jpg","IMG_3126.jpg","IMG_3134.jpg","IMG_3135.jpg","IMG_3143.jpg","IMG_3144.jpg","IMG_3145.jpg","IMG_3162.jpg","IMG_3163.jpg","IMG_3164.jpg","IMG_3181.jpg","IMG_3182.jpg","IMG_3183.jpg","IMG_3189.jpg","IMG_3575.jpg","IMG_3576.jpg","IMG_3577.jpg","IMG_3578.jpg","IMG_4182.jpg","IMG_4185.jpg","IMG_4191.jpg","IMG_4193.jpg","IMG_4195.jpg","IMG_4273.jpg","IMG_4274.jpg","IMG_4275.jpg","IMG_4288.jpg","IMG_4289.jpg","IMG_4418.jpg","IMG_4430.jpg","IMG_4431.jpg","IMG_4432.jpg","IMG_4433.jpg","IMG_4434.jpg","IMG_6075.jpg","IMG_6117.jpg","IMG_6118.jpg","IMG_6119.jpg","IMG_6120.jpg","IMG_6121.jpg","IMG_7296.jpg","IMG_7297.jpg","IMG_7298.jpg","IMG_8180.jpg","IMG_8181.jpg","IMG_8184.jpg","IMG_8185.jpg"];
```
### MysterWizzard — token `swAa4bTp`
```js
const MYSTER = ["20240926_142229.jpg","20241127_195824.jpg","707ac20b-6197-4d14-8120-386662f8b757.jpg","71482354-65c6-4071-a5e5-656fd476635e.jpg","8DAD0415-7437-496B-8833-FEA53B54898C.jpg","a2e0e59a-7e73-46b8-a8b9-ca729908e599.jpg","b8d94cf9-98a1-44f3-a393-7eba7dc8c2cc.jpg","BLVD_ColorTest_Splash_5jpg.jpg","C572D811-090C-4080-BC9E-A0A4D6F2A513.jpg","Enlight96.jpg","Enlight97.jpg","FC17DC88-653C-4DE6-9714-FDEEC7B77559.jpg","IMG_0003.jpg","IMG_0004.jpg","IMG_0006.jpg","IMG_0007.jpg","IMG_0009.jpg","IMG_0010.jpg","IMG_0227.jpg","IMG_0233.jpg","IMG_2062.jpg","IMG_2094.jpg","IMG_2095.jpg","IMG_2096.jpg","IMG_2097.jpg","IMG_2098.jpg","IMG_2101.jpg","IMG_2172.jpg","IMG_2878.jpg","IMG_2883.jpg","IMG_2886.jpg","IMG_2888.jpg","IMG_2889.jpg","IMG_2903.jpg","IMG_2904.jpg","IMG_2905.jpg","IMG_2906.jpg","IMG_2907.jpg","IMG_2912.jpg","IMG_2913.jpg","IMG_2914.jpg","IMG_2919.jpg","IMG_2920.jpg","IMG_2921.jpg","IMG_2940.jpg","IMG_2941.jpg","IMG_2942.jpg","IMG_2949.jpg","IMG_2950.jpg","IMG_2951.jpg","IMG_2956.jpg","IMG_2957.jpg","IMG_2958.jpg","IMG_2973.jpg","IMG_2993.jpg","IMG_2994.jpg","IMG_2995.jpg","IMG_2996.jpg","IMG_2997.jpg","IMG_2998.jpg","IMG_2999.jpg","IMG_3001.jpg","IMG_3003.jpg","IMG_3004.jpg","IMG_3005.jpg","IMG_3011.jpg","IMG_3013.jpg","IMG_3027.jpg","IMG_3028.jpg","IMG_3029.jpg","IMG_3030.jpg","IMG_3041.jpg","IMG_3046.jpg","IMG_3047.jpg","IMG_3050.jpg","IMG_3051.jpg","IMG_3052.jpg","IMG_3069.jpg","IMG_3070.jpg","IMG_3558.jpg","IMG_3681.jpg","IMG_4298.jpg","IMG_4474.jpg","IMG_4919.jpg","IMG_5162.jpg","IMG_7493.jpg","IMG_7494.jpg","IMG_7495.jpg","IMG_7496.jpg","IMG_7500.jpg","IMG_9749.jpg","IMG_9753.jpg","IMG_9754.jpg","TShedza Skull Dressing Concept.jpg"];
```
### Exopraxist — token `97AGC2WQ`
```js
const EXOPRAXIST = ["jl_bg_intermediate3.jpg","jl_wallpaper_desktop_F.jpg"];
```
---
## How to use these arrays
Each thumbnail filename is already `.jpg`. Thumbnail src:
```js
`thumbnails/${filename}`
```
For the lightbox full-res URL, the thumbnail filenames match the FileBrowser originals
**except the extension may differ** (originals may be `.JPG`, `.JPEG`, `.PNG`).
Fetch the FileBrowser API lazily on first lightbox open to resolve the correct original filename:
```js
// Fetch once, cache result
let fbIndex = null;
async function getFBIndex(token) {
if (fbIndex) return fbIndex;
try {
const res = await fetch(`https://files.exopraxist.org/api/public/share/${token}`);
const data = await res.json();
// Build stem → original name map
fbIndex = {};
for (const item of data.items) {
const stem = item.name.replace(/\.[^.]+$/, '');
fbIndex[stem] = item.name;
}
} catch (e) {
fbIndex = {}; // fail gracefully
}
return fbIndex;
}
// On lightbox open:
async function openLightbox(thumbFilename, index) {
showLightbox(thumbFilename, index); // show thumbnail immediately
const stem = thumbFilename.replace('.jpg', '');
const idx = await getFBIndex(TOKEN);
const originalName = idx[stem];
if (originalName) {
const fullResUrl = `https://files.exopraxist.org/api/public/dl/${TOKEN}?files=/${originalName}`;
updateLightboxImage(fullResUrl); // swap in full-res when ready
updateDownloadLink(fullResUrl);
}
}
```
---
## Summary of changes needed
1. Remove the on-load FileBrowser fetch
2. Replace with baked filename arrays (above)
3. Render grid immediately from `thumbnails/{filename}`
4. Move FileBrowser fetch to lightbox open, lazy + cached
5. Lightbox shows thumbnail first, upgrades to full-res when fetch resolves
6. Download button uses full-res URL if available, thumbnail URL as fallback

192
Images/GEMINI.md Normal file
View File

@@ -0,0 +1,192 @@
# GEMINI.md — Images Section Build Brief
# Singular Particular Space — spaces.exopraxist.org
You are Gemini Flash, the front-end builder for Singular Particular Space.
You are building the Images section. Sonnet (parent) will review your output before anything goes live.
---
## Your task
Build 5 self-contained HTML files in the `Images/` folder:
| File | Purpose |
|---|---|
| `Images/index.html` | Hub — four collection cards, nav back to homepage |
| `Images/wayback.html` | WayBack gallery (20102014) |
| `Images/nomad-soul.html` | YourNomadSoul gallery (20152021) |
| `Images/myster-wizzard.html` | MysterWizzard gallery (20222025) |
| `Images/exopraxist.html` | Exopraxist gallery (2026present) |
All files: single self-contained HTML (inline CSS + JS). No npm, no React, no build tools.
Use exactly the output filenames above — do not invent variants.
---
## Asset architecture — two sources
**Thumbnails (grid display)** are committed to git and served from `spaces.exopraxist.org`:
```
Images/{collection}/thumbnails/{stem}.jpg ← 360px wide, local
```
**Full-resolution images** are on FileBrowser at `files.exopraxist.org` — used for lightbox and download only.
### FileBrowser API pattern
On page load, fetch the file list to know what exists and build lightbox data:
```
GET https://files.exopraxist.org/api/public/share/{token}
```
Returns JSON. The `items` array contains objects with: `name`, `size`, `path`, `type`.
Only use items where `type === "image"` and `isDir === false`.
Full-res URL per file (lightbox + download):
```
https://files.exopraxist.org/api/public/dl/{token}?files=/{name}
```
Thumbnail src per file (grid display — local file):
```
thumbnails/{stem}.jpg
```
Where `stem` = the filename without extension (e.g. `IMG_6121.JPG``thumbnails/IMG_6121.jpg`).
Strip extension with: `name.replace(/\.[^.]+$/, '.jpg')`
Show a loading state while fetching. If the API call fails, show a clear error message.
### Collection tokens
| Collection | Token | Years | Subtitle |
|---|---|---|---|
| WayBack | `voxb2LeQ` | 20102014 | From way back in the way back |
| YourNomadSoul | `yNytp9Di` | 20152021 | Scattered about the social internets |
| MysterWizzard | `swAa4bTp` | 20222025 | Time spent in the real world, learning about community |
| Exopraxist | `97AGC2WQ` | 2026present | Stepping up, stepping forth. Step by step we dance and we do |
---
## Gallery layout
- **Thumbnail grid**: 5 columns desktop / 3 columns mobile (CSS grid)
- Images fit column width — use `width: 100%; height: auto` (natural aspect ratios, no crop)
- Lazy-load images (`loading="lazy"`)
- On thumbnail click: open lightbox
---
## Lightbox
- Full-size image display (constrained to viewport)
- **Download button**: links to the `api/public/dl/` URL for that image
- **Previous / Next** navigation buttons
- **Close** button — also close on Escape key and click-outside
- Keyboard: `←` `→` for prev/next, `Escape` to close
- `max-height: 90vh; overflow-y: auto` on lightbox content — prevents mobile clip
- Use `DOMContentLoaded` to initialize lightbox logic — NOT `window.onload`
---
## Site palette — use these exactly
```css
--bg-void: #04060b;
--bg-deep: #050810;
--bg-warm: #0d1320;
--fire-amber: #e8943a;
--fire-coral: #d4654a;
--neon-green: #32dc8c;
--neon-teal: #2ac4b3;
--deep-red: #8b2020;
--blue-magenta: #6b3fa0;
--orchid: #c558d9;
--paradise: #ff7f3f;
--toucan: #ffcf40;
--fairy-pink: #f472b6;
--waterfall: #3fbfaf;
--phosphor: #00ff41;
--text-warm: #e8d5b8;
--text-muted: #6a7a8a;
```
Push these hard. Glows at 1520% opacity minimum — not 5%. Punchy and saturated, not subtle.
Each collection page should have a distinct dominant accent color drawn from this palette.
---
## Font system
**Display/heading fonts — pick one per page from this list only. Each page must use a different font.**
- Share Tech Mono
- Rambla
- Protest Revolution
- Rancho
- Ribeye Marrow
- Amarante
- Glass Antiqua
- Aladin
- Faculty Glyphic
- Estonia
- Babylonica
- Rubik Glitch
- Trade Winds
- Fredericka the Great
- Jacquard 12
- Sixtyfour Convergence
- Sixtyfour
- Workbench
- Bitcount
All fonts via Google Fonts CDN.
Body/UI fonts: your choice (Lora, Cormorant Garamond, Courier Prime are fine).
Data/label text: Share Tech Mono or a monospace of your choice.
Do NOT use: Bebas Neue, Barlow Condensed, Cinzel, Anton, Oswald, Josefin Sans, Raleway, Space Grotesk, Inter, Roboto, Arial, or any generic condensed sans for headings.
---
## Per-page aesthetic direction
Each page has a distinct accent color and heading font. Use these — do not substitute.
| Page | File | Accent color | Heading font |
|---|---|---|---|
| Hub | `index.html` | `--fire-amber` `#e8943a` | Ribeye Marrow |
| WayBack | `wayback.html` | `--fire-coral` `#d4654a` | Estonia |
| YourNomadSoul | `nomad-soul.html` | `--waterfall` `#3fbfaf` | Trade Winds |
| MysterWizzard | `myster-wizzard.html` | `--orchid` `#c558d9` | Aladin |
| Exopraxist | `exopraxist.html` | `--phosphor` `#00ff41` | Workbench |
Apply the accent as: page title glow, card borders, hover states, lightbox chrome.
Remaining palette colors available as secondary accents — use sparingly.
---
## Hard constraints
- No border-radius > 0px
- No box-shadow blur > 8px
- No glassmorphism, frosted glass, or blur effects
- No CRT/scanline overlays
- Transitions: 100ms ease. No bounce, no spring, no transform-on-hover
- DOMContentLoaded for all JS init — never window.onload
- All output: single self-contained HTML file (inline CSS + JS)
---
## Navigation
- Hub (`index.html`): four collection cards + back link to `../index.html` (homepage)
- Collection pages: back link to `Images/index.html`
- Sonnet will wire the homepage star node to `Images/index.html` — you do not need to touch `index.html` at the repo root
---
## Mistakes from the Videos build — do not repeat
- Do not use `window.onload` for lightbox or gate triggers — it waits for all images to load. Use `DOMContentLoaded`.
- Do not invent your own output filenames — use exactly what this brief specifies.
- Do not use fonts not on the list above.
- Muted/subtle colors are wrong. Push the palette.
- Lightbox content needs `max-height: 90vh; overflow-y: auto` or it clips on mobile.

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Some files were not shown because too many files have changed in this diff Show More