feat: add Prettier with go-template and toml plugins, format all files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+155
-119
@@ -1,33 +1,34 @@
|
||||
<!doctype html>
|
||||
<html lang="{{ .Site.LanguageCode }}" class="scroll-smooth">
|
||||
<head>
|
||||
{{- partial "head.html" . -}}
|
||||
</head>
|
||||
<body
|
||||
class="bg-void text-paper font-body min-h-screen flex flex-col antialiased"
|
||||
hx-boost="true"
|
||||
hx-select="#main-content"
|
||||
hx-target="#main-content"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="true"
|
||||
>
|
||||
<head>
|
||||
{{- partial "head.html" . -}}
|
||||
</head>
|
||||
<body
|
||||
class="bg-void text-paper font-body min-h-screen flex flex-col antialiased"
|
||||
hx-boost="true"
|
||||
hx-select="#main-content"
|
||||
hx-target="#main-content"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="true"
|
||||
>
|
||||
<!-- HTMX transition progress bar -->
|
||||
<div id="progress-bar" aria-hidden="true"></div>
|
||||
|
||||
<!-- HTMX transition progress bar -->
|
||||
<div id="progress-bar" aria-hidden="true"></div>
|
||||
{{- partial "nav.html" . -}}
|
||||
|
||||
{{- partial "nav.html" . -}}
|
||||
{{- block "page-background" . -}}{{- end -}}
|
||||
|
||||
{{- block "page-background" . -}}{{- end -}}
|
||||
|
||||
<main id="main-content" class="flex-1" hx-history-elt>
|
||||
{{- block "main" . }}{{- end }}
|
||||
</main>
|
||||
<main id="main-content" class="flex-1" hx-history-elt>
|
||||
{{- block "main" . }}{{- end }}
|
||||
</main>
|
||||
|
||||
{{- partial "footer.html" . -}}
|
||||
{{- partial "footer.html" . -}}
|
||||
|
||||
<!-- ── Global lightbox — lives outside #main-content so HTMX never touches it -->
|
||||
<div
|
||||
x-data="{
|
||||
|
||||
<!-- ── Global lightbox — lives outside #main-content so HTMX never touches it -->
|
||||
<div
|
||||
x-data="{
|
||||
open: false,
|
||||
idx: 0,
|
||||
fill: false,
|
||||
@@ -36,106 +37,141 @@
|
||||
prev() { this.idx = (this.idx - 1 + this.items.length) % this.items.length },
|
||||
next() { this.idx = (this.idx + 1) % this.items.length }
|
||||
}"
|
||||
@lightbox:open.window="items = $event.detail.items; idx = $event.detail.idx; open = true"
|
||||
@lightbox:close.window="close()"
|
||||
@keydown.escape.window="open && close()"
|
||||
@keydown.arrow-left.window="open && prev()"
|
||||
@keydown.arrow-right.window="open && next()"
|
||||
@keydown.f.window="open && (fill = !fill)"
|
||||
x-show="open"
|
||||
x-cloak
|
||||
x-transition:enter="transition duration-200 ease-out"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-150 ease-in"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
class="fixed inset-0 z-[200] flex items-center justify-center bg-void/95 backdrop-blur-sm"
|
||||
@click.self="close()"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Media lightbox"
|
||||
>
|
||||
<!-- Top chrome bar -->
|
||||
<div class="absolute top-0 inset-x-0 z-10 flex items-center justify-between px-2 h-14"
|
||||
style="background: linear-gradient(to bottom, rgba(5,5,16,0.85), transparent)">
|
||||
<div class="absolute top-0 inset-x-0 h-px gradient-line"></div>
|
||||
<div class="w-24"></div>
|
||||
<div class="label text-fog tabular-nums"
|
||||
x-text="items.length ? `${String(idx + 1).padStart(2,'0')} / ${String(items.length).padStart(2,'0')}` : ''"></div>
|
||||
<div class="flex items-center w-24 justify-end gap-1">
|
||||
<button @click="fill = !fill"
|
||||
class="w-10 h-10 flex items-center justify-center label transition-colors"
|
||||
:class="fill ? 'text-heat hover:text-chalk' : 'text-fog hover:text-heat'"
|
||||
:aria-label="fill ? 'Switch to fit mode' : 'Switch to fill mode'"
|
||||
x-text="fill ? 'FIT' : 'FILL'"></button>
|
||||
<button @click="close()"
|
||||
class="w-10 h-10 flex items-center justify-center label text-fog hover:text-chalk transition-colors"
|
||||
aria-label="Close">✕</button>
|
||||
@lightbox:open.window="items = $event.detail.items; idx = $event.detail.idx; open = true"
|
||||
@lightbox:close.window="close()"
|
||||
@keydown.escape.window="open && close()"
|
||||
@keydown.arrow-left.window="open && prev()"
|
||||
@keydown.arrow-right.window="open && next()"
|
||||
@keydown.f.window="open && (fill = !fill)"
|
||||
x-show="open"
|
||||
x-cloak
|
||||
x-transition:enter="transition duration-200 ease-out"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition duration-150 ease-in"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
class="fixed inset-0 z-[200] flex items-center justify-center bg-void/95 backdrop-blur-sm"
|
||||
@click.self="close()"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Media lightbox"
|
||||
>
|
||||
<!-- Top chrome bar -->
|
||||
<div
|
||||
class="absolute top-0 inset-x-0 z-10 flex items-center justify-between px-2 h-14"
|
||||
style="background: linear-gradient(to bottom, rgba(5,5,16,0.85), transparent)"
|
||||
>
|
||||
<div class="absolute top-0 inset-x-0 h-px gradient-line"></div>
|
||||
<div class="w-24"></div>
|
||||
<div
|
||||
class="label text-fog tabular-nums"
|
||||
x-text="items.length ? `${String(idx + 1).padStart(2,'0')} / ${String(items.length).padStart(2,'0')}` : ''"
|
||||
></div>
|
||||
<div class="flex items-center w-24 justify-end gap-1">
|
||||
<button
|
||||
@click="fill = !fill"
|
||||
class="w-10 h-10 flex items-center justify-center label transition-colors"
|
||||
:class="fill ? 'text-heat hover:text-chalk' : 'text-fog hover:text-heat'"
|
||||
:aria-label="fill ? 'Switch to fit mode' : 'Switch to fill mode'"
|
||||
x-text="fill ? 'FIT' : 'FILL'"
|
||||
></button>
|
||||
<button
|
||||
@click="close()"
|
||||
class="w-10 h-10 flex items-center justify-center label text-fog hover:text-chalk transition-colors"
|
||||
aria-label="Close"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Prev -->
|
||||
<button
|
||||
@click="prev()"
|
||||
x-show="items.length > 1"
|
||||
class="absolute left-2 top-1/2 -translate-y-1/2 z-10 w-10 h-10 md:w-12 md:h-12 flex items-center justify-center text-fog hover:text-heat transition-colors text-xl"
|
||||
aria-label="Previous"
|
||||
>
|
||||
{{- partial "icon.html" "arrow-left" -}}
|
||||
</button>
|
||||
<!-- Media -->
|
||||
<div
|
||||
class="absolute inset-0 flex items-center justify-center transition-[padding] duration-300"
|
||||
:class="fill ? 'p-0' : 'pt-14 pb-14 px-14 md:px-20'"
|
||||
>
|
||||
<video
|
||||
x-show="items[idx] && items[idx].video"
|
||||
:src="items[idx] && items[idx].video ? items[idx].video : ''"
|
||||
:poster="items[idx] ? items[idx].img : ''"
|
||||
x-effect="if (open && items[idx] && items[idx].video) { $el.load(); $el.play() }"
|
||||
:class="fill ? 'w-full h-full object-cover' : 'max-w-full max-h-full object-contain'"
|
||||
class="transition-all duration-300"
|
||||
controls
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
></video>
|
||||
<img
|
||||
x-show="items[idx] && !items[idx].video"
|
||||
:src="items[idx] && !items[idx].video ? items[idx].img : ''"
|
||||
alt=""
|
||||
:class="fill ? 'w-full h-full object-cover' : 'max-w-full max-h-full object-contain'"
|
||||
class="transition-all duration-300"
|
||||
/>
|
||||
</div>
|
||||
<!-- Next -->
|
||||
<button
|
||||
@click="next()"
|
||||
x-show="items.length > 1"
|
||||
class="absolute right-2 top-1/2 -translate-y-1/2 z-10 w-10 h-10 md:w-12 md:h-12 flex items-center justify-center text-fog hover:text-heat transition-colors text-xl"
|
||||
aria-label="Next"
|
||||
>
|
||||
{{- partial "icon.html" "arrow-right" -}}
|
||||
</button>
|
||||
<!-- Dots -->
|
||||
<div
|
||||
x-show="items.length > 1"
|
||||
class="absolute bottom-0 inset-x-0 z-10 flex items-center justify-center h-14 gap-2"
|
||||
style="background: linear-gradient(to top, rgba(5,5,16,0.85), transparent)"
|
||||
>
|
||||
<div class="absolute bottom-0 inset-x-0 h-px gradient-line"></div>
|
||||
<template x-for="(item, i) in items" :key="i">
|
||||
<button
|
||||
@click="idx = i"
|
||||
class="h-1.5 rounded-full transition-all duration-300"
|
||||
:class="i === idx ? 'w-5 bg-heat' : 'w-1.5 bg-fog hover:bg-chalk'"
|
||||
:aria-label="`Go to item ${i + 1}`"
|
||||
></button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Prev -->
|
||||
<button @click="prev()" x-show="items.length > 1"
|
||||
class="absolute left-2 top-1/2 -translate-y-1/2 z-10 w-10 h-10 md:w-12 md:h-12 flex items-center justify-center text-fog hover:text-heat transition-colors text-xl"
|
||||
aria-label="Previous">{{- partial "icon.html" "arrow-left" -}}</button>
|
||||
<!-- Media -->
|
||||
<div class="absolute inset-0 flex items-center justify-center transition-[padding] duration-300"
|
||||
:class="fill ? 'p-0' : 'pt-14 pb-14 px-14 md:px-20'">
|
||||
<video
|
||||
x-show="items[idx] && items[idx].video"
|
||||
:src="items[idx] && items[idx].video ? items[idx].video : ''"
|
||||
:poster="items[idx] ? items[idx].img : ''"
|
||||
x-effect="if (open && items[idx] && items[idx].video) { $el.load(); $el.play() }"
|
||||
:class="fill ? 'w-full h-full object-cover' : 'max-w-full max-h-full object-contain'"
|
||||
class="transition-all duration-300"
|
||||
controls loop muted playsinline></video>
|
||||
<img
|
||||
x-show="items[idx] && !items[idx].video"
|
||||
:src="items[idx] && !items[idx].video ? items[idx].img : ''"
|
||||
alt=""
|
||||
:class="fill ? 'w-full h-full object-cover' : 'max-w-full max-h-full object-contain'"
|
||||
class="transition-all duration-300">
|
||||
</div>
|
||||
<!-- Next -->
|
||||
<button @click="next()" x-show="items.length > 1"
|
||||
class="absolute right-2 top-1/2 -translate-y-1/2 z-10 w-10 h-10 md:w-12 md:h-12 flex items-center justify-center text-fog hover:text-heat transition-colors text-xl"
|
||||
aria-label="Next">{{- partial "icon.html" "arrow-right" -}}</button>
|
||||
<!-- Dots -->
|
||||
<div x-show="items.length > 1"
|
||||
class="absolute bottom-0 inset-x-0 z-10 flex items-center justify-center h-14 gap-2"
|
||||
style="background: linear-gradient(to top, rgba(5,5,16,0.85), transparent)">
|
||||
<div class="absolute bottom-0 inset-x-0 h-px gradient-line"></div>
|
||||
<template x-for="(item, i) in items" :key="i">
|
||||
<button @click="idx = i"
|
||||
class="h-1.5 rounded-full transition-all duration-300"
|
||||
:class="i === idx ? 'w-5 bg-heat' : 'w-1.5 bg-fog hover:bg-chalk'"
|
||||
:aria-label="`Go to item ${i + 1}`"></button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- HTMX (page transitions & progressive enhancement) -->
|
||||
<script src="https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js"></script>
|
||||
<!-- Alpine.js store initialisation (must run before alpine:init) -->
|
||||
<script>
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.store('nav', { path: window.location.pathname, open: false })
|
||||
})
|
||||
</script>
|
||||
<!-- Alpine.js (reactive UI — nav, interactions) -->
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.14.8/dist/cdn.min.js"></script>
|
||||
<!-- Site JS -->
|
||||
{{- $js := resources.Get "js/main.js" -}}
|
||||
{{- if eq hugo.Environment "production" -}}
|
||||
{{- $js = $js | minify | fingerprint "sha256" -}}
|
||||
{{- end -}}
|
||||
<script src="{{ $js.RelPermalink }}"{{ if eq hugo.Environment "production" }} integrity="{{ $js.Data.Integrity }}"{{ end }} defer></script>
|
||||
<!-- HTMX (page transitions & progressive enhancement) -->
|
||||
<script src="https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js"></script>
|
||||
<!-- Alpine.js store initialisation (must run before alpine:init) -->
|
||||
<script>
|
||||
document.addEventListener("alpine:init", () => {
|
||||
Alpine.store("nav", { path: window.location.pathname, open: false });
|
||||
});
|
||||
</script>
|
||||
<!-- Alpine.js (reactive UI — nav, interactions) -->
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.14.8/dist/cdn.min.js"></script>
|
||||
<!-- Site JS -->
|
||||
{{- $js := resources.Get "js/main.js" -}}
|
||||
{{- if eq hugo.Environment "production" -}}
|
||||
{{- $js = $js | minify | fingerprint "sha256" -}}
|
||||
{{- end -}}
|
||||
<script
|
||||
src="{{ $js.RelPermalink }}"
|
||||
{{ if eq hugo.Environment "production" }}integrity="{{ $js.Data.Integrity }}"{{ end }}
|
||||
defer
|
||||
></script>
|
||||
|
||||
{{- block "scripts" . }}{{- end }}
|
||||
{{- block "scripts" . }}{{- end }}
|
||||
|
||||
{{- if and (eq hugo.Environment "production") .Site.Params.umamiId -}}
|
||||
<!-- Umami analytics — cookie-free, self-hosted -->
|
||||
<script defer src="{{ .Site.Params.umamiSrc }}" data-website-id="{{ .Site.Params.umamiId }}"></script>
|
||||
{{- end -}}
|
||||
</body>
|
||||
{{- if and (eq hugo.Environment "production") .Site.Params.umamiId -}}
|
||||
<!-- Umami analytics — cookie-free, self-hosted -->
|
||||
<script defer src="{{ .Site.Params.umamiSrc }}" data-website-id="{{ .Site.Params.umamiId }}"></script>
|
||||
{{- end -}}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user