Initial commit: site code, layouts, content (images added separately)

Fixes duplicate placeholder cover image on the 3 newest blog posts,
broken aspect-ratio classes on the albums listing page, and a
non-responsive fixed sidebar on the chat page.
This commit is contained in:
Dr. Jones
2026-07-08 06:18:17 +00:00
commit d9961a76ad
80 changed files with 9438 additions and 0 deletions

35
layouts/albums/list.html Normal file
View File

@@ -0,0 +1,35 @@
{{ define "main" }}
<div class="bg-gray-900 py-16 px-4 sm:px-6 lg:px-8">
<div class="max-w-7xl mx-auto text-center">
<h1 class="text-4xl font-extrabold text-gray-100 tracking-tight sm:text-5xl">Photo Albums</h1>
<p class="mt-4 max-w-2xl text-xl text-gray-300 mx-auto">
Visual documentation of successful grows and sterile setups.
</p>
</div>
<div class="mt-12 max-w-7xl mx-auto grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{{ range .Pages }}
<a href="{{ .RelPermalink }}" class="group relative block rounded-xl overflow-hidden shadow-lg hover:shadow-2xl transition-all transform hover:-translate-y-1">
<div class="aspect-[4/3] bg-gray-800">
<!-- Cover Image (First image from params or fallback) -->
{{ $cover := "/images/IMG_0599.jpeg" }}
{{ if .Params.cover }}
{{ $cover = .Params.cover }}
{{ else if .Params.images }}
{{ range first 1 .Params.images }}
{{ $cover = .url }}
{{ end }}
{{ end }}
<img src="{{ $cover }}" alt="{{ .Title }}" class="object-cover w-full h-full group-hover:scale-105 transition-transform duration-500">
</div>
<div class="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent flex items-end p-6">
<div>
<h3 class="text-xl font-bold text-white">{{ .Title }}</h3>
<p class="text-gray-200 text-sm mt-1">{{ .Params.description }}</p>
</div>
</div>
</a>
{{ end }}
</div>
</div>
{{ end }}

View File

@@ -0,0 +1,98 @@
{{ define "main" }}
<div class="bg-gray-900 min-h-screen py-16 px-4 sm:px-6 lg:px-8"
x-data="{
lightboxOpen: false,
activeImage: '',
activeCaption: '',
images: [
{{ range .Params.images }}
{ url: '{{ .url }}', caption: '{{ .caption }}' },
{{ end }}
],
currentIndex: 0,
openLightbox(index) {
this.currentIndex = index;
this.activeImage = this.images[index].url;
this.activeCaption = this.images[index].caption;
this.lightboxOpen = true;
},
next() {
this.currentIndex = (this.currentIndex + 1) % this.images.length;
this.activeImage = this.images[this.currentIndex].url;
this.activeCaption = this.images[this.currentIndex].caption;
},
prev() {
this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length;
this.activeImage = this.images[this.currentIndex].url;
this.activeCaption = this.images[this.currentIndex].caption;
}
}"
@keydown.escape.window="lightboxOpen = false"
@keydown.arrow-right.window="next()"
@keydown.arrow-left.window="prev()">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-12">
<a href="/albums/" class="text-primary hover:text-emerald-700 font-medium mb-4 inline-block">&larr; Back to Albums</a>
<h1 class="text-4xl font-extrabold text-gray-100">{{ .Title }}</h1>
<p class="mt-4 text-gray-300">{{ .Description }}</p>
</div>
<!-- Masonry Grid -->
<div class="columns-1 md:columns-2 lg:columns-3 gap-8 space-y-8">
<template x-for="(img, index) in images" :key="index">
<div class="break-inside-avoid rounded-xl overflow-hidden shadow-md hover:shadow-xl transition-all cursor-pointer bg-gray-800"
@click="openLightbox(index)">
<template x-if="img.url.toLowerCase().endsWith('.mov') || img.url.toLowerCase().endsWith('.mp4')">
<video class="w-full h-auto object-cover" controls preload="metadata">
<source :src="img.url">
Your browser does not support the video tag.
</video>
</template>
<template x-if="!(img.url.toLowerCase().endsWith('.mov') || img.url.toLowerCase().endsWith('.mp4'))">
<img :src="img.url" :alt="img.caption" class="w-full h-auto">
</template>
<div class="p-4" x-show="img.caption">
<p class="text-sm text-gray-600" x-text="img.caption"></p>
</div>
</div>
</template>
</div>
</div>
<!-- Lightbox Modal -->
<div x-show="lightboxOpen"
style="display: none;"
class="fixed inset-0 z-[100] flex items-center justify-center bg-black/90 backdrop-blur-sm"
x-transition.opacity>
<!-- Close Button -->
<button @click="lightboxOpen = false" class="absolute top-4 right-4 text-white text-4xl font-light hover:text-gray-300 focus:outline-none">&times;</button>
<!-- Nav Buttons -->
<button @click="prev()" class="absolute left-4 text-white text-4xl font-light hover:text-gray-300 focus:outline-none p-4">&lsaquo;</button>
<button @click="next()" class="absolute right-4 text-white text-4xl font-light hover:text-gray-300 focus:outline-none p-4">&rsaquo;</button>
<!-- Image/Video Display -->
<div class="max-w-5xl max-h-screen p-4 flex flex-col items-center justify-center w-full">
<template x-if="activeImage.toLowerCase().endsWith('.mov') || activeImage.toLowerCase().endsWith('.mp4')">
<video controls autoplay class="max-h-[85vh] max-w-full rounded-lg shadow-2xl">
<source :src="activeImage">
Your browser does not support the video tag.
</video>
</template>
<template x-if="!(activeImage.toLowerCase().endsWith('.mov') || activeImage.toLowerCase().endsWith('.mp4'))">
<img :src="activeImage" class="max-h-[85vh] max-w-full rounded-lg shadow-2xl object-contain">
</template>
<p x-text="activeCaption" class="text-white mt-4 text-lg font-medium tracking-wide"></p>
<p class="text-gray-400 text-sm mt-1" x-text="(currentIndex + 1) + ' / ' + images.length"></p>
</div>
</div>
</div>
{{ end }}