Content - 100 new plates under content/posts/02/ — one recurring red-haired model across 10 editorial registers (Haute Couture, Film Noir, Boudoir, Avant-Garde, Minimalism, Baroque, Street Style, Surrealism, Monochrome, Nocturne), generated with flux-1.1-pro, face-swapped to a consistent identity (FaceFusion), and upscaled (Upscayl + Remacri, 3328x4992). - content/issues/02/_index.md; issue 01 -> status archived; hugo.toml params (issueIds newest-first, issueNumber/Name/Season/Blurb). Structure - Plate bundles grouped by issue: content/posts/<issue>/<slug>/, with build.render:never stubs so /posts/<issue>/ isn't emitted. nginx 301s the legacy flat /posts/<slug>/ URLs to /posts/01/<slug>/. The /posts/ archive uses .RegularPagesRecursive. Image pipeline (scripts/, data/ gitignored) - generate-images.py — Replicate flux-1.1-pro, 960x1440, idempotent. - faceswap-images.py — FaceFusion batch-run, one consistent face. - upscale-images.py — Upscayl + remacri-4x, long edge clamped to 4992. - build-issue.py — prompts JSON -> content/posts/<issue>/*/index.md. Build - CSS now compiled by Hugo's css.TailwindCSS (partials/css.html + templates.Defer); dropped the standalone Tailwind CLI step, concurrently, and the gitignored static/css/main.css. Requires Hugo >= 0.161; Dockerfile collapsed to a single hugomods/hugo:debian-node build stage. pnpm-workspace.yaml: preferSymlinkedExecutables + allowBuilds. Front end - Pagination 8 per page. - Lightbox: brand mark and category link out; robust SPA back/forward (fetch before startViewTransition, single-flight guard, swallow the transition abort rejection, popstate re-renders / reopens the viewer). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DZPmxGywFnAhmYJB1eh9fm
50 lines
2.5 KiB
HTML
50 lines
2.5 KiB
HTML
{{ define "main" }}
|
|
{{- $issue := index (.Params.issues | default (slice "01")) 0 }}
|
|
{{- $issueURL := printf "/issues/%s/" $issue }}
|
|
{{- $img := .Resources.GetMatch "*.png" }}
|
|
{{- $cardSrc := "" }}
|
|
{{- if $img }}{{- $c := $img.Resize "900x1350 webp" }}{{- $cardSrc = $c.RelPermalink }}{{- end }}
|
|
|
|
<section id="hero" class="px-[var(--pad)] pt-[clamp(36px,5vw,64px)] pb-[clamp(28px,3.5vw,48px)] border-b border-[var(--rule)]">
|
|
<div class="font-sans font-medium text-[10px] leading-none tracking-[.22em] uppercase text-ink-soft mb-4">
|
|
№ {{ $issue }} · {{ index (.Params.categories | default (slice "Plate")) 0 }}
|
|
</div>
|
|
<h1 class="font-display font-normal text-[clamp(48px,7vw,96px)] leading-[0.94] m-0 mb-4"><em>{{ .Title }}</em></h1>
|
|
<p class="font-serif italic text-[clamp(13px,1vw,16px)] leading-[1.65] text-ink-2 max-w-[55ch] m-0 mb-5">
|
|
{{ .Params.description }}
|
|
</p>
|
|
<div class="flex items-center gap-5 flex-wrap">
|
|
<a href="{{ $issueURL }}"
|
|
class="font-sans font-medium text-[11px] leading-none tracking-[.16em] uppercase text-ink-soft
|
|
border-b border-[var(--rule)] pb-px transition-colors duration-200 hover:text-ink hover:border-ink">
|
|
← Return to issue
|
|
</a>
|
|
{{- if $cardSrc }}
|
|
<button id="viewFull" data-src="{{ $cardSrc }}"
|
|
class="inline-flex items-center gap-[7px]
|
|
font-sans font-medium text-[11px] leading-none tracking-[.16em] uppercase text-ink-soft
|
|
border-b border-[var(--rule)] pb-px transition-colors duration-200 hover:text-ink hover:border-ink">
|
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
|
|
</svg>
|
|
View full image
|
|
</button>
|
|
{{- end }}
|
|
</div>
|
|
</section>
|
|
|
|
<section id="grid" data-density="default"
|
|
class="grid [grid-template-columns:repeat(auto-fill,minmax(220px,1fr))] gap-[var(--gap)] px-[var(--pad)] py-[var(--gap)]">
|
|
{{- $termPage := $.Site.GetPage (printf "/issues/%s" $issue) }}
|
|
{{- $posts := cond (ne $termPage nil) $termPage.Pages .Site.RegularPages }}
|
|
{{- range $i, $p := $posts }}
|
|
{{- partial "card.html" (dict "Page" $p "Index" $i) }}
|
|
{{- end }}
|
|
</section>
|
|
|
|
{{/* Tell JS which slug to open in the lightbox (script for first load, data attr for SPA nav) */}}
|
|
<span data-open-slug="{{ .Params.slug }}" hidden></span>
|
|
<script>window.__ROUX_OPEN_SLUG = "{{ .Params.slug }}";</script>
|
|
{{ end }}
|