Revert to static JS site (Svelte built, but no CSR); Optimize images
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/build unknown status
ci/woodpecker/push/deploy unknown status

This commit is contained in:
2026-02-16 00:54:08 -03:00
parent 6734dfa51e
commit af70682fa8
117 changed files with 686 additions and 109 deletions

View File

@@ -1,77 +1,20 @@
<script lang="ts">
import type { MediaItem } from '$lib/media';
interface Props {
item: MediaItem | null;
onClose: () => void;
}
let { item, onClose }: Props = $props();
let ref = $state<HTMLDialogElement | null>(null);
$effect(() => {
if (ref && item) {
document.body.style.overflow = 'hidden';
ref.showModal();
} else {
document.body.style.overflow = 'auto';
ref?.close();
}
});
/**
* Structure-only lightbox shell. Content is injected by static/assets/js/script.js
* (no client-side Svelte; csr = false). Keeps HTML/CSS in one place.
*/
</script>
<dialog
class="lightbox"
aria-hidden="true"
onclose={onClose}
closedby="any"
aria-describedby="lb-caption"
bind:this={ref}
>
{#if item}
<header>
<button
class="lb-close"
aria-label="Close"
onclick={() => ref?.close()}
onkeydown={(e) => {
if (e.key === 'Enter') ref?.close();
}}>&times;</button
>
</header>
<div class="lb-content">
{#if item?.type === 'video'}
<video
src={`/assets/media/videos/${item?.name}.mp4`}
controls
autoplay
>
<track
kind="captions"
src={`/assets/media/videos/${item?.name}-captions.vtt`}
default
/>
</video>
{:else}
<picture>
{#each [{ bp: 'desktop', minWidth: 1024 }, { bp: 'tablet', minWidth: 768 }, { bp: 'mobile', minWidth: 0 }] as breakpoint}
<source
media="(min-width:{breakpoint.minWidth}px)"
srcset={item?.type === 'image'
? `/assets/media/${breakpoint.bp}/${item?.name}@1x.webp 1x, /assets/media/${breakpoint.bp}/${item?.name}.webp 2x`
: `/assets/media/${breakpoint.bp}/${item?.name}_still@1x.webp 1x, /assets/media/${breakpoint.bp}/${item?.name}_still.webp 2x`}
/>
{/each}
<img
src="/assets/media/thumbnail/{item?.name}.webp"
alt={item?.alt.replace(/['']/g, '')}
/>
</picture>
{/if}
</div>
<p id="lb-caption" class="lb-caption">{item?.caption}</p>
{/if}
<dialog class="lightbox" aria-hidden="true" aria-describedby="lb-caption" closedby="any">
<header>
<button type="button" class="lb-close" aria-label="Close"
>&times;</button
>
</header>
<div class="lb-content">
<!-- script.js injects image or video here -->
</div>
<p id="lb-caption" class="lb-caption"></p>
</dialog>
<style>
@@ -98,8 +41,9 @@
opacity: 1;
}
& img,
& video {
/* Injected by script.js */
:global(img),
:global(video) {
max-width: 90vw;
max-height: 80vh;
border-radius: 8px;
@@ -117,6 +61,7 @@
border: none;
font-size: 2rem;
color: var(--fg);
cursor: pointer;
}
.lb-content {
@@ -125,7 +70,8 @@
justify-content: center;
align-items: center;
& img {
/* Injected by script.js */
:global(img) {
max-width: 90vw;
max-height: 80vh;
}