Refactor: replace all BEM CSS with Tailwind utility classes

Remove all BEM component classes (hero__*, card__*, issue-card__*, foot__*,
masthead__*, searchpop__*, lb__*) from CSS and templates. Replace with
Tailwind v4 utility classes inline in HTML. Create card.html partial to
avoid repeating verbose utility strings across grid templates. Rename
lightbox CSS to flat lb-* and search popup to sp-*.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 18:06:55 +02:00
parent e3e9cf6742
commit 54a87dc4ed
15 changed files with 590 additions and 604 deletions
+8 -35
View File
@@ -1,45 +1,18 @@
{{ define "main" }}
{{- $issueNum := .Params.issueNumber | default (printf "№ %s" .Title) }}
<section class="hero" id="hero">
<div class="hero__eyebrow">
<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">
{{ $issueNum }} · {{ .Params.season }}
· <a href="/issues/" style="border-bottom:1px solid currentColor;margin-left:6px">All issues</a>
· <a href="/issues/" class="border-b border-current ml-1">All issues</a>
</div>
<h1 class="hero__title"><em>{{ .Title }}</em></h1>
<p class="hero__lede">{{ .Params.description }}</p>
<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">{{ .Params.description }}</p>
</section>
<section class="grid" id="grid" data-density="default">
<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)]">
{{- range $i, $p := .Pages }}
{{- $img := $p.Resources.GetMatch "*.png" }}
<a class="card"
href="{{ $p.RelPermalink }}"
style="--d:{{ mul (math.Min $i 18) 24 }}ms"
data-id="{{ $p.Params.plate }}"
data-slug="{{ $p.Params.slug }}">
<div class="card__frame">
{{- if $img }}
{{- $w := $img.Resize "600x900 webp" }}
<picture>
<source srcset="{{ $w.RelPermalink }}" type="image/webp" />
<img class="card__img"
loading="{{ if lt $i 8 }}eager{{ else }}lazy{{ end }}"
src="{{ $w.RelPermalink }}"
alt="{{ $p.Title }}" />
</picture>
{{- end }}
<span class="card__num">PLATE №{{ $p.Params.plate }}</span>
<span class="card__cat">{{ index ($p.Params.categories | default (slice "")) 0 }}</span>
<span class="card__issue">№ {{ index ($p.Params.issues | default (slice "01")) 0 }}</span>
</div>
<div class="card__meta">
<h2 class="card__title">{{ $p.Title }}</h2>
<div class="card__sub">
<span>{{ index ($p.Params.categories | default (slice "")) 0 }}</span>
</div>
<p class="card__desc">{{ $p.Params.description }}</p>
</div>
</a>
{{- partial "card.html" (dict "Page" $p "Index" $i) }}
{{- end }}
</section>
{{ end }}
+33 -25
View File
@@ -1,32 +1,40 @@
{{ define "main" }}
{{- $issues := .Site.Data.issues }}
<section class="hero" id="hero">
<div class="hero__eyebrow">Archive · Every issue</div>
<h1 class="hero__title">The <em>issues</em></h1>
<p class="hero__lede">Roux publishes one hundred photographs at a time, once a season. Each issue is a complete thing.</p>
<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">Archive · Every issue</div>
<h1 class="font-display font-normal text-[clamp(48px,7vw,96px)] leading-[0.94] m-0 mb-4">The <em>issues</em></h1>
<p class="font-serif italic text-[clamp(13px,1vw,16px)] leading-[1.65] text-ink-2 max-w-[55ch] m-0">
Roux publishes one hundred photographs at a time, once a season. Each issue is a complete thing.
</p>
</section>
<div class="issues-grid">
<div class="grid [grid-template-columns:repeat(auto-fill,minmax(280px,1fr))] gap-[var(--gap)] px-[var(--pad)] py-[var(--gap)]">
{{- range $i, $iss := $issues }}
{{- $delay := mul $i 80 }}
{{- $delay := mul $i 80 }}
{{- $isCurrent := eq $iss.status "current" }}
{{- $isForth := eq $iss.status "forthcoming" }}
{{- $issueURL := printf "/issues/%s/" $iss.id }}
{{- if $isForth }}
<div class="issue-card issue-card--forthcoming" style="--d:{{ $delay }}ms">
<div data-issue-card style="--d:{{ $delay }}ms"
class="flex flex-col opacity-60">
{{- else }}
<a href="{{ $issueURL }}" class="issue-card" style="--d:{{ $delay }}ms">
<a href="{{ $issueURL }}" data-issue-card style="--d:{{ $delay }}ms"
class="group flex flex-col">
{{- end }}
<div class="issue-card__cover">
{{/* Cover image */}}
<div class="relative aspect-[2/3] overflow-hidden bg-paper-2 rounded-[1px] mb-5
after:content-[''] after:absolute after:inset-0
after:shadow-[inset_0_0_0_1px_rgba(22,17,13,.04)] after:pointer-events-none">
{{- if $isForth }}
<div class="issue-card__forth">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3
font-sans font-medium text-[10px] leading-none tracking-[.18em] uppercase text-ink-soft">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Forthcoming
</div>
{{- else }}
{{- $termPage := $.Site.GetPage (printf "/issues/%s" $iss.id) }}
{{- $termPage := $.Site.GetPage (printf "/issues/%s" $iss.id) }}
{{- $firstPost := cond (ne $termPage nil) (index $termPage.Pages 0) nil }}
{{- if $firstPost }}
{{- $img := $firstPost.Resources.GetMatch "*.png" }}
@@ -34,25 +42,25 @@
{{- $cover := $img.Resize "480x720 webp" }}
<picture>
<source srcset="{{ $cover.RelPermalink }}" type="image/webp" />
<img src="{{ $cover.RelPermalink }}" alt="Issue {{ $iss.number }} cover" loading="lazy" />
<img src="{{ $cover.RelPermalink }}" alt="Issue {{ $iss.number }} cover" loading="lazy"
class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.02]" />
</picture>
{{- end }}
{{- end }}
{{- end }}
</div>
<div class="issue-card__meta">
<div class="issue-card__num">{{ $iss.number }}</div>
<h2 class="issue-card__title">{{ $iss.title }}</h2>
<p class="issue-card__blurb">{{ $iss.blurb }}</p>
<div class="issue-card__foot">
<span>{{ $iss.season }}</span>
{{- if $isCurrent }}
<span class="issue-card__cta">Read the issue →</span>
{{- else if $isForth }}
<span class="issue-card__cta issue-card__cta--muted">Subscribe →</span>
{{- end }}
</div>
{{/* Metadata */}}
<div class="font-sans font-medium text-[10px] leading-none tracking-[.22em] uppercase text-roux mb-2">{{ $iss.number }}</div>
<h2 class="font-display font-normal text-[clamp(22px,2vw,30px)] leading-[1.05] m-0 mb-2">{{ $iss.title }}</h2>
<p class="font-serif italic text-[13px] leading-[1.5] text-ink-soft mb-4 flex-1">{{ $iss.blurb }}</p>
<div class="flex items-center justify-between font-sans text-[11px] leading-none tracking-[.1em] text-ink-soft mt-auto pt-4 border-t border-[var(--rule-2)]">
<span>{{ $iss.season }}</span>
{{- if $isCurrent }}
<span class="text-ink">Read the issue →</span>
{{- else if $isForth }}
<span class="opacity-50">Subscribe →</span>
{{- end }}
</div>
{{- if $isForth }}</div>{{- else }}</a>{{- end }}