Keep process-card numerals upright and match Display type and section gaps.
Rotate only the numbered shapes, use 24/32 and 32/1.1 card copy, and tighten the header-to-CTA stack. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -31,11 +31,11 @@ const Step = memo<StepProps>(({ number, text, size: sizeProp }) => {
|
|||||||
small:
|
small:
|
||||||
"font-bricolage-grotesque font-medium text-[24px] leading-[32px] text-[var(--color-gray-900)]",
|
"font-bricolage-grotesque font-medium text-[24px] leading-[32px] text-[var(--color-gray-900)]",
|
||||||
medium:
|
medium:
|
||||||
"font-bricolage-grotesque font-medium text-[24px] leading-[24px] text-[var(--color-gray-900)]",
|
"font-bricolage-grotesque font-medium text-[24px] leading-[32px] text-[var(--color-gray-900)]",
|
||||||
large:
|
large:
|
||||||
"font-bricolage-grotesque font-medium text-[24px] leading-[24px] text-[var(--color-gray-900)]",
|
"font-bricolage-grotesque font-medium text-[24px] leading-[32px] text-[var(--color-gray-900)]",
|
||||||
xlarge:
|
xlarge:
|
||||||
"font-bricolage-grotesque font-medium text-[32px] leading-[32px] text-[var(--color-gray-900)]",
|
"font-bricolage-grotesque font-medium text-[32px] leading-[1.1] text-[var(--color-gray-900)] [font-variation-settings:'opsz'_14,'wdth'_100]",
|
||||||
};
|
};
|
||||||
|
|
||||||
const sectionNumberWrapperClasses = {
|
const sectionNumberWrapperClasses = {
|
||||||
@@ -92,7 +92,7 @@ const Step = memo<StepProps>(({ number, text, size: sizeProp }) => {
|
|||||||
|
|
||||||
{/* Card Content - Responsive positioning */}
|
{/* Card Content - Responsive positioning */}
|
||||||
<div className="sm:flex-1 lg:absolute lg:bottom-8 lg:left-8 lg:right-16">
|
<div className="sm:flex-1 lg:absolute lg:bottom-8 lg:left-8 lg:right-16">
|
||||||
<p className="font-bricolage-grotesque font-medium text-[24px] leading-[32px] sm:leading-[24px] sm:text-[24px] lg:text-[24px] lg:leading-[24px] xl:text-[32px] xl:leading-[32px] text-[var(--color-gray-900)]">
|
<p className="font-bricolage-grotesque font-medium text-[24px] leading-[32px] xl:text-[32px] xl:leading-[1.1] xl:[font-variation-settings:'opsz'_14,'wdth'_100] text-[var(--color-gray-900)]">
|
||||||
{text}
|
{text}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function CardStepsView({
|
|||||||
/>
|
/>
|
||||||
<section className="bg-transparent py-[var(--spacing-scale-032)] px-[var(--spacing-scale-020)] sm:py-[var(--spacing-scale-048)] sm:px-[var(--spacing-scale-032)] lg:py-[var(--spacing-scale-064)] lg:px-[var(--spacing-scale-064)] xl:py-[var(--spacing-scale-076)] xl:px-[var(--spacing-scale-064)]">
|
<section className="bg-transparent py-[var(--spacing-scale-032)] px-[var(--spacing-scale-020)] sm:py-[var(--spacing-scale-048)] sm:px-[var(--spacing-scale-032)] lg:py-[var(--spacing-scale-064)] lg:px-[var(--spacing-scale-064)] xl:py-[var(--spacing-scale-076)] xl:px-[var(--spacing-scale-064)]">
|
||||||
<div className="max-w-[var(--spacing-measures-max-width-lg)] mx-auto">
|
<div className="max-w-[var(--spacing-measures-max-width-lg)] mx-auto">
|
||||||
<div className="grid grid-cols-1 gap-y-[var(--spacing-scale-032)] sm:gap-y-[var(--spacing-scale-048)] lg:gap-y-[var(--spacing-scale-056)]">
|
<div className="grid grid-cols-1 gap-y-[var(--spacing-scale-024)] sm:gap-y-[var(--spacing-scale-032)] lg:gap-y-[var(--spacing-scale-056)]">
|
||||||
<div>
|
<div>
|
||||||
<SectionHeader
|
<SectionHeader
|
||||||
variant="multi-line"
|
variant="multi-line"
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ const SectionNumber = memo<SectionNumberProps>(({ number }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative size-[40px] overflow-visible -rotate-[15deg]">
|
<div className="relative size-[40px] overflow-visible">
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element -- dynamic src from getImageSrc */}
|
{/* eslint-disable-next-line @next/next/no-img-element -- dynamic src from getImageSrc */}
|
||||||
<img
|
<img
|
||||||
src={getImageSrc(number)}
|
src={getImageSrc(number)}
|
||||||
alt={`Section ${number}`}
|
alt={`Section ${number}`}
|
||||||
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 size-[47.37px] max-w-none"
|
className="absolute left-1/2 top-1/2 size-[47.37px] max-w-none -translate-x-1/2 -translate-y-1/2 rotate-15"
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-0 flex items-center justify-center">
|
<div className="absolute inset-0 flex items-center justify-center">
|
||||||
<span className="text-[var(--font-size-body-small)] font-[var(--font-weight-bold)] text-[var(--color-content-inverse-primary)]">
|
<span className="text-large-label text-[var(--color-content-invert-primary)]">
|
||||||
{number}
|
{number}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import "@testing-library/jest-dom/vitest";
|
||||||
|
import SectionNumber from "../../app/components/sections/SectionNumber";
|
||||||
|
|
||||||
|
describe("SectionNumber", () => {
|
||||||
|
it("rotates the shape and keeps the numeral upright", () => {
|
||||||
|
render(<SectionNumber number={1} />);
|
||||||
|
|
||||||
|
const numeral = screen.getByText("1");
|
||||||
|
expect(numeral).toHaveClass("text-large-label");
|
||||||
|
expect(numeral.className).not.toMatch(/rotate/);
|
||||||
|
|
||||||
|
const shape = screen.getByAltText("Section 1");
|
||||||
|
expect(shape).toHaveClass("rotate-15");
|
||||||
|
expect(shape.parentElement).not.toHaveClass("rotate-15");
|
||||||
|
expect(shape.parentElement?.className).not.toMatch(/-rotate-/);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -137,12 +137,9 @@ describe("Step Component", () => {
|
|||||||
const textElement = screen.getByText("Test Card Text");
|
const textElement = screen.getByText("Test Card Text");
|
||||||
expect(textElement).toHaveClass(
|
expect(textElement).toHaveClass(
|
||||||
"text-[24px]",
|
"text-[24px]",
|
||||||
"sm:text-[24px]",
|
"leading-[32px]",
|
||||||
"sm:leading-[24px]",
|
|
||||||
"lg:text-[24px]",
|
|
||||||
"lg:leading-[24px]",
|
|
||||||
"xl:text-[32px]",
|
"xl:text-[32px]",
|
||||||
"xl:leading-[32px]",
|
"xl:leading-[1.1]",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -234,7 +231,7 @@ describe("Step Component", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const textElement = screen.getByText("Test Card Text");
|
const textElement = screen.getByText("Test Card Text");
|
||||||
expect(textElement).toHaveClass("text-[24px]", "leading-[24px]");
|
expect(textElement).toHaveClass("text-[24px]", "leading-[32px]");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("applies Large size variant correctly", () => {
|
it("applies Large size variant correctly", () => {
|
||||||
@@ -254,7 +251,7 @@ describe("Step Component", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const textElement = screen.getByText("Test Card Text");
|
const textElement = screen.getByText("Test Card Text");
|
||||||
expect(textElement).toHaveClass("text-[24px]", "leading-[24px]");
|
expect(textElement).toHaveClass("text-[24px]", "leading-[32px]");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("applies XLarge size variant correctly", () => {
|
it("applies XLarge size variant correctly", () => {
|
||||||
@@ -274,6 +271,6 @@ describe("Step Component", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const textElement = screen.getByText("Test Card Text");
|
const textElement = screen.getByText("Test Card Text");
|
||||||
expect(textElement).toHaveClass("text-[32px]", "leading-[32px]");
|
expect(textElement).toHaveClass("text-[32px]", "leading-[1.1]");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user