Center leftover Learn cards on a short last row and keep thumbnail copy in the top half so it does not cover the artwork.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -31,11 +31,13 @@ export default function LearnPage() {
|
||||
|
||||
{/*
|
||||
* Single responsive render: ContentThumbnailTemplate variant="responsive"
|
||||
* uses <picture> to swap horizontal/vertical art at smd (530px). The
|
||||
* container switches from a vertical flex stack (<smd) to a grid (≥smd),
|
||||
* matching the prior twin-region layout without doubling the DOM.
|
||||
* uses <picture> to swap horizontal/vertical art at smd (530px). Wrap and
|
||||
* center leftover cards so a short last row is not left-aligned.
|
||||
*/}
|
||||
<div className="flex flex-col space-y-[var(--spacing-scale-002)] sm:space-y-[var(--spacing-scale-008)] sm:px-[var(--spacing-scale-020)] sm:pt-[var(--spacing-scale-024)] sm:pb-[var(--spacing-scale-024)] smd:grid smd:grid-cols-2 smd:gap-[var(--spacing-scale-008)] smd:space-y-0 smd:px-[var(--spacing-scale-020)] smd:pt-[var(--spacing-scale-024)] smd:pb-[var(--spacing-scale-024)] md:gap-[var(--spacing-scale-016)] md:px-[var(--spacing-scale-032)] xmd:grid-cols-3 xmd:gap-[var(--spacing-scale-012)] lg:grid-cols-3 lg:gap-[var(--spacing-scale-016)] lg:px-[var(--spacing-scale-064)] lg:pt-[var(--spacing-scale-032)] lg:pb-[var(--spacing-scale-064)] lg2:grid-cols-4 lg2:gap-x-[var(--spacing-scale-016)] lg2:gap-y-[var(--spacing-scale-024)] xl:grid-cols-5 xl:gap-x-[var(--spacing-scale-016)] xl:gap-y-[var(--spacing-scale-016)] [&>*]:min-w-0">
|
||||
<div
|
||||
data-testid="learn-article-grid"
|
||||
className="flex flex-col space-y-[var(--spacing-scale-002)] sm:space-y-[var(--spacing-scale-008)] sm:px-[var(--spacing-scale-020)] sm:pt-[var(--spacing-scale-024)] sm:pb-[var(--spacing-scale-024)] smd:flex-row smd:flex-wrap smd:justify-center smd:gap-[var(--spacing-scale-008)] smd:space-y-0 smd:px-[var(--spacing-scale-020)] smd:pt-[var(--spacing-scale-024)] smd:pb-[var(--spacing-scale-024)] md:gap-[var(--spacing-scale-016)] md:px-[var(--spacing-scale-032)] xmd:gap-[var(--spacing-scale-012)] lg:gap-[var(--spacing-scale-016)] lg:px-[var(--spacing-scale-064)] lg:pt-[var(--spacing-scale-032)] lg:pb-[var(--spacing-scale-064)] lg2:gap-x-[var(--spacing-scale-016)] lg2:gap-y-[var(--spacing-scale-024)] xl:gap-x-[var(--spacing-scale-016)] xl:gap-y-[var(--spacing-scale-016)] [&>*]:min-w-0 [&>*]:w-full smd:[&>*]:w-[calc((100%-var(--spacing-scale-008))/2)] md:[&>*]:w-[calc((100%-var(--spacing-scale-016))/2)] xmd:[&>*]:w-[calc((100%-2*var(--spacing-scale-012))/3)] lg:[&>*]:w-[calc((100%-2*var(--spacing-scale-016))/3)] lg2:[&>*]:w-[calc((100%-3*var(--spacing-scale-016))/4)] xl:[&>*]:w-[calc((100%-4*var(--spacing-scale-016))/5)]"
|
||||
>
|
||||
{allPosts.map((post) => (
|
||||
<ContentThumbnailTemplate
|
||||
key={post.slug}
|
||||
|
||||
@@ -36,7 +36,7 @@ function ContentThumbnailTemplateView({
|
||||
/>
|
||||
</picture>
|
||||
</div>
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] smd:left-[6.923%] smd:top-[4.615%] smd:w-[76.923%]">
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] max-h-[48%] overflow-hidden smd:left-[6.923%] smd:top-[4.615%] smd:w-[76.923%]">
|
||||
<ContentContainer post={post} size="xs" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -82,7 +82,7 @@ function ContentThumbnailTemplateView({
|
||||
className="pointer-events-none size-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute left-[6.923%] top-[4.615%] z-20 w-[76.923%]">
|
||||
<div className="absolute left-[6.923%] top-[4.615%] z-20 w-[76.923%] max-h-[48%] overflow-hidden">
|
||||
<ContentContainer post={post} size="xs" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,7 +124,7 @@ function ContentThumbnailTemplateView({
|
||||
className="pointer-events-none size-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%]">
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] max-h-[48%] overflow-hidden">
|
||||
<ContentContainer post={post} size="xs" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -83,12 +83,12 @@ describe("LearnPage", () => {
|
||||
});
|
||||
|
||||
it("renders one card per post (single responsive grid, no duplication)", () => {
|
||||
const { container } = render(<LearnPage />);
|
||||
render(<LearnPage />);
|
||||
|
||||
const grid = container.querySelector(".smd\\:grid");
|
||||
expect(grid).toBeTruthy();
|
||||
const grid = screen.getByTestId("learn-article-grid");
|
||||
expect(grid).toHaveClass("smd:justify-center", "smd:flex-wrap");
|
||||
|
||||
const links = within(grid as HTMLElement).getAllByRole("link");
|
||||
const links = within(grid).getAllByRole("link");
|
||||
expect(links).toHaveLength(mockPosts.length);
|
||||
|
||||
expect(links[0]).toHaveAttribute(
|
||||
|
||||
@@ -35,6 +35,8 @@ describe("ContentThumbnailTemplate", () => {
|
||||
const container = screen.getByRole("link");
|
||||
const thumbnailDiv = container.querySelector("div.relative");
|
||||
expect(thumbnailDiv).toHaveClass("aspect-[260/390]", "w-full");
|
||||
const copy = thumbnailDiv?.querySelector(".z-20");
|
||||
expect(copy).toHaveClass("max-h-[48%]", "overflow-hidden");
|
||||
});
|
||||
|
||||
it("should display post title and description", () => {
|
||||
@@ -61,6 +63,8 @@ describe("ContentThumbnailTemplate", () => {
|
||||
const container = screen.getByRole("link");
|
||||
const thumbnailDiv = container.querySelector("div.relative");
|
||||
expect(thumbnailDiv).toHaveClass("aspect-[320/225.5]", "w-full");
|
||||
const copy = thumbnailDiv?.querySelector(".z-20");
|
||||
expect(copy).toHaveClass("max-h-[48%]", "overflow-hidden");
|
||||
});
|
||||
|
||||
it("should render fixed vertical dimensions when sizing is fixed", () => {
|
||||
|
||||
Reference in New Issue
Block a user