Files
pivoine.art/layouts/tracks/single.html
2025-11-29 17:51:00 +01:00

139 lines
4.8 KiB
HTML
Executable File

{{ define "main" }}
<article class="py-16">
<div class="container-wide">
{{/* Content area with offset */}}
<div class="md:mx-72">
{{/* Header */}}
<header class="mb-8">
{{/* Meta */}}
<div class="flex items-center gap-4 text-sm text-text-muted mb-3">
<time datetime="{{ .Date.Format "2006-01-02" }}">
{{ .Date.Format "January 2, 2006" }}
</time>
{{- with .Params.genre }}
<span class="px-2 py-1 bg-surface-2 rounded">{{ . }}</span>
{{- end }}
</div>
<h1 class="text-3xl md:text-4xl font-medium tracking-tight mb-2">
{{ .Title }}
</h1>
{{- with .Description }}
<p class="text-text-secondary">{{ . }}</p>
{{- end }}
</header>
{{/* Cover Image + Play Widget - 2 Column Layout */}}
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
{{/* Cover Image - 1 column */}}
{{- with .Resources.GetMatch "cover.*" }}
{{- $img := .Resize "400x webp q90" }}
<figure
class="overflow-hidden rounded-lg group cursor-pointer relative aspect-square border border-border"
{{- if $.Params.audio }}
x-data
@click="
$store.audio.currentTrack = {
title: '{{ $.Title }}',
url: '{{ $.Params.audio }}',
image: '{{ with $.Resources.GetMatch "cover.*" }}{{ (.Resize "200x webp q85").RelPermalink }}{{ end }}'
};
window.__pivoine?.audioManager?.play('{{ $.Params.audio }}');
$store.audio.isPlaying = true;
"
{{- end }}
>
<img
src="{{ $img.RelPermalink }}"
alt="{{ $.Title }}"
class="w-full h-full object-cover grayscale group-hover:grayscale-0 transition-all duration-500"
loading="eager"
>
{{/* Video preview on hover */}}
{{- with $.Resources.GetMatch "preview.*" }}
<video
src="{{ .RelPermalink }}"
class="absolute inset-0 w-full h-full object-cover opacity-0 group-hover:opacity-100 transition-opacity duration-300"
muted
loop
playsinline
onmouseenter="this.play()"
onmouseleave="this.pause(); this.currentTime=0;"
></video>
{{- end }}
</figure>
{{- end }}
{{/* Play Widget - 2 columns */}}
{{- if .Params.audio }}
<div
x-data
@click="
$store.audio.currentTrack = {
title: '{{ .Title }}',
url: '{{ .Params.audio }}',
image: '{{ with .Resources.GetMatch "cover.*" }}{{ (.Resize "200x webp q85").RelPermalink }}{{ end }}'
};
window.__pivoine?.audioManager?.play('{{ .Params.audio }}');
$store.audio.isPlaying = true;
"
class="md:col-span-2 flex items-center gap-4 cursor-pointer group"
>
<button
class="w-14 h-14 flex-shrink-0 flex items-center justify-center rounded-full bg-accent text-surface-0 group-hover:scale-110 transition-transform"
aria-label="Play {{ .Title }}"
>
<svg class="w-6 h-6 ml-0.5" fill="currentColor" viewBox="0 0 24 24">
<path d="M8 5v14l11-7z"/>
</svg>
</button>
<div>
<p class="font-medium group-hover:text-accent transition-colors">Play Track</p>
{{- with .Params.duration }}
<p class="text-sm text-text-muted tabular-nums">{{ . }}</p>
{{- end }}
</div>
</div>
{{- end }}
</div>
{{/* Content */}}
{{- if .Content }}
<div class="prose prose-invert prose-lg max-w-none">
{{ .Content }}
</div>
{{- end }}
{{/* Tags */}}
{{- with .GetTerms "tags" }}
<footer class="mt-12 pt-8 border-t border-border">
<div class="flex flex-wrap gap-2">
{{- range . }}
<a
href="{{ .Permalink }}"
class="px-3 py-1 text-sm bg-surface-2 hover:bg-surface-3 transition-colors rounded"
>
{{ .LinkTitle }}
</a>
{{- end }}
</div>
</footer>
{{- end }}
{{/* Related Tracks */}}
{{- $related := .Site.RegularPages.Related . | first 3 }}
{{- if $related }}
<aside class="mt-16 pt-12 border-t border-border">
<h2 class="text-xl font-medium mb-8">Related Tracks</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
{{- range $related }}
{{ partial "track-card.html" . }}
{{- end }}
</div>
</aside>
{{- end }}
</div>
</div>
</article>
{{ end }}