Give the archive its signature back

- the plate carries project colour on the lead image, in the cards and in
  every row, not only when an entry lacks an image
- entries no longer fade in one after another, the page is readable at once
- detail pages lead on: previous, next and more from the project
- the month band shows from the first month, the nav item hides without one
- side cards and row teasers get room instead of ellipsis
- admin opens on drafts, scheduled and published plus what was edited last,
  and its tables use the full width
This commit is contained in:
Matthias G
2026-08-01 13:04:08 +02:00
parent a123e0bca2
commit c95db3a044
17 changed files with 264 additions and 84 deletions
+19 -14
View File
@@ -3,7 +3,7 @@ import { useTranslations } from 'next-intl'
import { Badge } from '~/components/ui/Badge'
import { Cover, type CoverMedia } from '~/components/ui/Cover'
import { EntryDate } from '~/components/ui/EntryDate'
import { Plate, entryMark, projectStyle } from '~/components/ui/Plate'
import { Plate, projectStyle } from '~/components/ui/Plate'
import { SectionLabel } from '~/components/ui/SectionLabel'
import { postPath } from '~/lib/routes'
import type { PostListItem } from '~/data/repositories/posts'
@@ -11,12 +11,14 @@ import type { PostListItem } from '~/data/repositories/posts'
export type SideEntriesProps = {
items: PostListItem[]
covers?: Map<string, CoverMedia>
label?: string
layout?: 'column' | 'grid'
className?: string
}
const coverSizes = '(min-width: 64rem) 6rem, 20vw'
const coverSizes = '(min-width: 64rem) 22rem, 40vw'
export function SideEntries({ items, covers, className }: SideEntriesProps) {
export function SideEntries({ items, covers, label, layout = 'column', className }: SideEntriesProps) {
const t = useTranslations('entry')
if (items.length === 0) {
@@ -25,8 +27,8 @@ export function SideEntries({ items, covers, className }: SideEntriesProps) {
return (
<aside className={`flex flex-col gap-3 ${className ?? ''}`}>
<SectionLabel as="h3">{t('next')}</SectionLabel>
<ul className="m-0 flex list-none flex-col gap-3 p-0">
<SectionLabel as="h3">{label ?? t('next')}</SectionLabel>
<ul className={`m-0 grid list-none gap-3 p-0 ${layout === 'grid' ? 'md:grid-cols-3' : 'md:grid-cols-2 lg:grid-cols-1'}`}>
{items.map(item => {
const source = { code: item.projectCode, slug: item.projectSlug }
@@ -35,12 +37,12 @@ export function SideEntries({ items, covers, className }: SideEntriesProps) {
<Link
href={postPath(item.projectSlug, item.slug)}
style={projectStyle(item.projectColor)}
className="group flex animate-rise gap-3 border border-rule bg-surface p-2.5 no-underline transition-colors duration-120 hover:border-ink-3 motion-reduce:animate-none motion-reduce:transition-none"
className="group flex flex-col gap-2 border border-rule bg-surface p-3 no-underline transition-colors duration-120 hover:border-ink-3 motion-reduce:transition-none"
>
<Cover
media={covers?.get(item.id)}
sizes={coverSizes}
className="aspect-video w-24 shrink-0"
className="aspect-shot w-full"
fallback={
<Plate
project={source}
@@ -51,18 +53,21 @@ export function SideEntries({ items, covers, className }: SideEntriesProps) {
/>
}
/>
<span className="flex min-w-0 flex-1 flex-col gap-1">
<span className="flex flex-wrap items-center gap-x-2 gap-y-1 font-mono text-micro text-ink-3">
<span className="font-semibold uppercase tracking-mark text-ink-2 tabular-nums">
{entryMark(source, item.number)}
</span>
<span className="flex min-w-0 flex-col gap-1.5">
<span className="flex flex-wrap items-center gap-x-3 gap-y-1">
<Plate
project={source}
color={item.projectColor}
number={item.number}
size="row"
/>
<Badge type={item.type} />
</span>
<span className="font-display text-small font-semibold leading-snug text-balance text-ink">
<span className="font-display text-base font-semibold leading-snug text-balance text-ink">
{item.title}
</span>
{item.teaser ? (
<span className="line-clamp-2 text-micro leading-snug text-ink-2">{item.teaser}</span>
<span className="line-clamp-2 text-small leading-snug text-ink-2">{item.teaser}</span>
) : null}
{item.publishAt ? (
<EntryDate date={item.publishAt} className="font-mono text-micro text-ink-3" />