SPB Git

Repository Public

FilmCard.tsx 1.8 KB 33 lines tsx

1import Link from "next/link";2import type { Film } from "@/lib/films";3import { fmtDuration, href, type Locale } from "@/lib/i18n";45/** Poster card. The image is decorative: the link text carries the title. */6export function FilmCard({ film, locale, note, priority = false }: { film: Film; locale: Locale; note?: string; priority?: boolean }) {7  return (8    <article className="group relative">9      <Link href={href(locale, `/film/${film.slug}`)} className="block">10        <div className="poster relative aspect-[9/16]">11          <img src={film.thumb} alt="" width={360} height={640} loading={priority ? "eager" : "lazy"} decoding="async"12            className="h-full w-full object-cover transition-transform duration-700 ease-[var(--ease-film)] group-hover:scale-[1.04]" />13          <div className="absolute inset-0 bg-gradient-to-t from-black/85 via-black/10 to-transparent" />14          <span className="absolute right-2 top-2 rounded bg-black/60 px-1.5 py-0.5 text-[0.68rem] tabular-nums text-white/90">{fmtDuration(film.duration)}</span>15          <div className="absolute inset-x-0 bottom-0 p-3">16            {film.series && <p className="mb-1 text-[0.62rem] uppercase tracking-[0.18em]" style={{ color: film.series.accent }}>{film.series.title}</p>}17            <h3 className="display text-xl leading-tight text-white">{film.title}</h3>18          </div>19        </div>20      </Link>21      {note && <p className="mt-2 text-xs text-[var(--color-faint)]">{note}</p>}22    </article>23  );24}2526export function FilmGrid({ films, locale, notes }: { films: Film[]; locale: Locale; notes?: Record<string, string> }) {27  return (28    <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 sm:gap-4 lg:grid-cols-4 xl:grid-cols-5">29      {films.map((f, i) => <FilmCard key={f.id} film={f} locale={locale} note={notes?.[f.id]} priority={i < 4} />)}30    </div>31  );32}33
Files main
Menu

Theme