Files
singular-particular-space/Images/nomad-soul.html
JL Kruger 696bc9c2a7 Fix FileBrowser download URL pattern in image galleries
/api/public/dl/{token}?files=/{name} returns empty ZIP.
Correct pattern is /api/public/dl/{token}/{name} (path-style).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:22:45 +02:00

369 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YourNomadSoul (20152021) | Singular Particular Space</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredericka+the+Great&family=Lora:ital,wght@0,400..700;1,400..700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
<style>
:root {
--bg-void: #04060b;
--bg-deep: #050810;
--bg-warm: #0d1320;
--waterfall: #3fbfaf;
--text-warm: #e8d5b8;
--text-muted: #6a7a8a;
--accent: var(--waterfall);
--accent-glow: rgba(63, 191, 175, 0.3);
--transition: 100ms ease;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
border-radius: 0 !important;
}
body {
background-color: var(--bg-void);
color: var(--text-warm);
font-family: 'Lora', serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
}
header {
padding: 2rem;
border-bottom: 2px solid var(--accent);
display: flex;
justify-content: space-between;
align-items: center;
background: var(--bg-deep);
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 4px 15px var(--accent-glow);
}
.header-title-wrap {
text-align: left;
}
h1 {
font-family: 'Fredericka the Great', system-ui;
font-size: 3.5rem;
color: var(--accent);
line-height: 1.1;
text-shadow: 0 0 10px var(--accent-glow);
}
.subtitle {
font-family: 'Share Tech Mono', monospace;
font-size: 0.9rem;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.15em;
}
.nav-back {
font-family: 'Share Tech Mono', monospace;
color: var(--text-muted);
text-decoration: none;
text-transform: uppercase;
border: 1px solid var(--text-muted);
padding: 0.5rem 1.5rem;
transition: var(--transition);
}
.nav-back:hover {
color: var(--accent);
border-color: var(--accent);
background: var(--accent-glow);
box-shadow: 0 0 10px var(--accent-glow);
}
main {
flex: 1;
padding: 2rem;
}
#gallery {
column-count: 5;
column-gap: 1.5rem;
width: 100%;
}
@media (max-width: 1200px) {
#gallery { column-count: 4; }
}
@media (max-width: 900px) {
#gallery { column-count: 3; }
}
@media (max-width: 600px) {
#gallery { column-count: 2; }
h1 { font-size: 2.2rem; }
}
.thumb-link {
display: inline-block;
width: 100%;
margin-bottom: 1.5rem;
break-inside: avoid;
border: 1px solid var(--bg-warm);
overflow: hidden;
transition: var(--transition);
background: var(--bg-deep);
cursor: pointer;
position: relative;
}
.thumb-link:hover {
border-color: var(--accent);
box-shadow: 0 0 15px var(--accent-glow);
z-index: 10;
}
.thumb-link img {
width: 100%;
height: auto;
display: block;
transition: var(--transition);
filter: grayscale(0.2) contrast(1.05);
}
.thumb-link:hover img {
filter: grayscale(0) contrast(1);
}
/* Lightbox */
#lightbox {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(4, 6, 11, 0.98);
display: none;
justify-content: center;
align-items: center;
z-index: 1000;
padding: 2rem;
}
.lightbox-content {
position: relative;
max-width: 100%;
max-height: 90vh;
display: flex;
flex-direction: column;
align-items: center;
overflow-y: auto;
}
#lightbox-img {
max-width: 100%;
max-height: 80vh;
object-fit: contain;
border: 2px solid var(--accent);
box-shadow: 0 0 30px var(--accent-glow);
}
.lightbox-controls {
margin-top: 1.5rem;
display: flex;
gap: 1.5rem;
align-items: center;
width: 100%;
justify-content: center;
}
.lightbox-btn {
background: var(--bg-deep);
border: 1px solid var(--text-muted);
color: var(--text-warm);
padding: 0.75rem 1.5rem;
cursor: pointer;
font-family: 'Share Tech Mono', monospace;
transition: var(--transition);
text-transform: uppercase;
}
.lightbox-btn:hover {
border-color: var(--accent);
color: var(--accent);
background: var(--accent-glow);
box-shadow: 0 0 10px var(--accent-glow);
}
.close-btn {
position: absolute;
top: -4rem;
right: 0;
}
#lightbox-filename {
font-family: 'Share Tech Mono', monospace;
font-size: 0.9rem;
color: var(--text-muted);
margin-top: 0.75rem;
letter-spacing: 0.05em;
}
.loading-indicator {
font-family: 'Share Tech Mono', monospace;
color: var(--accent);
font-size: 0.8rem;
margin-top: 0.5rem;
display: none;
}
</style>
</head>
<body>
<header>
<div class="header-title-wrap">
<span class="subtitle">20152021 Collection</span>
<h1>YourNomadSoul</h1>
</div>
<a href="images.html" class="nav-back">← Back to Hub</a>
</header>
<main>
<div id="gallery"></div>
</main>
<div id="lightbox">
<div class="lightbox-content">
<button class="lightbox-btn close-btn" id="close-btn">CLOSE [ESC]</button>
<img id="lightbox-img" src="" alt="">
<div id="lightbox-filename"></div>
<div id="loading-indicator" class="loading-indicator">UPGRADING TO FULL RESOLUTION...</div>
<div class="lightbox-controls">
<button class="lightbox-btn" id="prev-btn">PREV</button>
<a href="#" id="dl-btn" class="lightbox-btn" target="_blank">DOWNLOAD</a>
<button class="lightbox-btn" id="next-btn">NEXT</button>
</div>
</div>
</div>
<script>
const COLLECTION_TOKEN = 'yNytp9Di';
const THUMBNAILS = ["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"];
let fbIndex = null;
let currentIndex = -1;
const galleryEl = document.getElementById('gallery');
const lightboxEl = document.getElementById('lightbox');
const lightboxImg = document.getElementById('lightbox-img');
const lightboxFilename = document.getElementById('lightbox-filename');
const dlBtn = document.getElementById('dl-btn');
const loadingIndicator = document.getElementById('loading-indicator');
function renderGallery() {
THUMBNAILS.forEach((filename, index) => {
const thumbSrc = `YourNomadSoul/thumbnails/${filename}`;
const link = document.createElement('div');
link.className = 'thumb-link';
link.innerHTML = `<img src="${thumbSrc}" alt="${filename}" loading="lazy">`;
link.onclick = () => openLightbox(index);
galleryEl.appendChild(link);
});
}
async function getFBIndex() {
if (fbIndex) return fbIndex;
try {
const res = await fetch(`https://files.exopraxist.org/api/public/share/${COLLECTION_TOKEN}`);
const data = await res.json();
fbIndex = {};
for (const item of data.items) {
const stem = item.name.replace(/\.[^.]+$/, '');
fbIndex[stem] = item.name;
}
} catch (e) {
console.error('FileBrowser fetch failed:', e);
fbIndex = {};
}
return fbIndex;
}
async function openLightbox(index) {
currentIndex = index;
const thumbFilename = THUMBNAILS[currentIndex];
const thumbUrl = `YourNomadSoul/thumbnails/${thumbFilename}`;
lightboxImg.src = thumbUrl;
lightboxFilename.textContent = thumbFilename;
dlBtn.href = thumbUrl;
loadingIndicator.style.display = 'block';
lightboxEl.style.display = 'flex';
document.body.style.overflow = 'hidden';
const stem = thumbFilename.replace('.jpg', '');
const idx = await getFBIndex();
const originalName = idx[stem];
if (originalName) {
const fullResUrl = `https://files.exopraxist.org/api/public/dl/${COLLECTION_TOKEN}/${encodeURIComponent(originalName)}`;
if (currentIndex === index) {
const img = new Image();
img.onload = () => {
if (currentIndex === index) {
lightboxImg.src = fullResUrl;
dlBtn.href = fullResUrl;
loadingIndicator.style.display = 'none';
}
};
img.src = fullResUrl;
}
} else {
loadingIndicator.style.display = 'none';
}
}
function closeLightbox() {
lightboxEl.style.display = 'none';
lightboxImg.src = '';
document.body.style.overflow = 'auto';
}
function nextImage() {
currentIndex = (currentIndex + 1) % THUMBNAILS.length;
openLightbox(currentIndex);
}
function prevImage() {
currentIndex = (currentIndex - 1 + THUMBNAILS.length) % THUMBNAILS.length;
openLightbox(currentIndex);
}
document.getElementById('close-btn').onclick = closeLightbox;
document.getElementById('next-btn').onclick = nextImage;
document.getElementById('prev-btn').onclick = prevImage;
lightboxEl.onclick = (e) => {
if (e.target === lightboxEl) closeLightbox();
};
window.addEventListener('keydown', (e) => {
if (lightboxEl.style.display === 'flex') {
if (e.key === 'Escape') closeLightbox();
if (e.key === 'ArrowRight') nextImage();
if (e.key === 'ArrowLeft') prevImage();
}
});
document.addEventListener('DOMContentLoaded', renderGallery);
</script>
</body>
</html>