Files
pivoine.art/layouts/tracks/single.html

160 lines
5.6 KiB
HTML
Executable File

{{ define "main" }}
{{- $audio := "" -}}
{{- with .Resources.GetMatch "track.*" -}}
{{- $audio = .RelPermalink -}}
{{- end -}}
<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"
x-data="{
hovering: false,
get isActive() {
return this.hovering || ($store.audio.isPlaying && $store.audio.currentTrack?.url === '{{ $audio }}');
}
}"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
{{- if $audio }}
@click="
if ($store.audio.currentTrack?.url === '{{ $audio }}') {
window.__pivoine?.audioManager?.toggle();
} else {
$store.audio.currentTrack = {
title: '{{ $.Title }}',
url: '{{ $audio }}',
image: '{{ with $.Resources.GetMatch "cover.*" }}{{ (.Resize "200x webp q85").RelPermalink }}{{ end }}'
};
window.__pivoine?.audioManager?.play('{{ $audio }}');
$store.audio.isPlaying = true;
}
"
{{- end }}
>
<img
src="{{ $img.RelPermalink }}"
alt="{{ $.Title }}"
class="w-full h-full object-cover transition-all duration-500"
:class="isActive ? 'grayscale-0' : 'grayscale'"
loading="eager"
>
{{/* Video preview on hover or playing */}}
{{- with $.Resources.GetMatch "preview.*" }}
<video
x-ref="video"
src="{{ .RelPermalink }}"
class="absolute inset-0 w-full h-full object-cover transition-opacity duration-300"
:class="isActive ? 'opacity-100' : 'opacity-0'"
muted
loop
playsinline
x-effect="if (isActive) { $el.play().catch(() => {}) } else { $el.pause(); $el.currentTime = 0; }"
></video>
{{- end }}
</figure>
{{- end }}
{{/* Play Widget - 2 columns */}}
{{- if $audio }}
<div
x-data
@click="
if ($store.audio.currentTrack?.url === '{{ $audio }}') {
window.__pivoine?.audioManager?.toggle();
} else {
$store.audio.currentTrack = {
title: '{{ .Title }}',
url: '{{ $audio }}',
image: '{{ with .Resources.GetMatch "cover.*" }}{{ (.Resize "200x webp q85").RelPermalink }}{{ end }}'
};
window.__pivoine?.audioManager?.play('{{ $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 }}