Center lockup-plus-card and card-stack create-flow steps in the nav–footer band so they are not stuck under the header when the content is shorter than the viewport.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilallo
2026-08-19 21:10:58 -06:00
co-authored by Cursor
parent 3c7fca83b2
commit d6d6a5e055
8 changed files with 54 additions and 9 deletions
+4 -3
View File
@@ -70,6 +70,7 @@ import {
CREATE_FLOW_FOOTER_BUTTON_CLASS, CREATE_FLOW_FOOTER_BUTTON_CLASS,
CREATE_FLOW_FOOTER_BUTTON_ON_DARK_CLASS, CREATE_FLOW_FOOTER_BUTTON_ON_DARK_CLASS,
} from "./utils/createFlowFooterClassNames"; } from "./utils/createFlowFooterClassNames";
import { CREATE_FLOW_MD_CENTERED_MAIN_CLASS } from "./components/createFlowLayoutTokens";
import { import {
CUSTOM_RULE_CONFIRM_FOOTER_STEP_BY_STEP, CUSTOM_RULE_CONFIRM_FOOTER_STEP_BY_STEP,
methodCardFacetSectionForConfirmStep, methodCardFacetSectionForConfirmStep,
@@ -467,13 +468,13 @@ function CreateFlowLayoutContent({
); );
const stepIdx = currentStep != null ? getStepIndex(currentStep) : -1; const stepIdx = currentStep != null ? getStepIndex(currentStep) : -1;
/** At `md+`, main cross-axis: center by default; exceptions stay top-aligned (see product spec). */ /** Lockup+card / card-stack: `items-start` + shell `my-auto` so overflow scrolls from the top. */
const mainContentClass = isCompletedStep const mainContentClass = isCompletedStep
? "items-stretch overflow-y-auto md:overflow-hidden" ? "items-stretch overflow-y-auto md:overflow-hidden"
: isSelectSplitScrollStep : isSelectSplitScrollStep
? "items-start justify-start overflow-y-auto max-lg:overflow-y-auto lg:min-h-0 lg:items-stretch lg:overflow-hidden" ? "items-start justify-start overflow-y-auto max-lg:overflow-y-auto lg:min-h-0 lg:items-stretch lg:overflow-hidden"
: isFinalReviewLike || isCardLayoutStep || isTemplateReviewRoute : isTemplateReviewRoute || isFinalReviewLike || isCardLayoutStep
? "items-start justify-center overflow-y-auto" ? CREATE_FLOW_MD_CENTERED_MAIN_CLASS
: "items-start justify-center overflow-y-auto md:items-center"; : "items-start justify-center overflow-y-auto md:items-center";
const isTextStep = createFlowStepUsesCenteredTextLayout(currentStep); const isTextStep = createFlowStepUsesCenteredTextLayout(currentStep);
@@ -4,6 +4,7 @@ import type { ReactNode } from "react";
import { CreateFlowHeaderLockup } from "./CreateFlowHeaderLockup"; import { CreateFlowHeaderLockup } from "./CreateFlowHeaderLockup";
import { CreateFlowStepShell } from "./CreateFlowStepShell"; import { CreateFlowStepShell } from "./CreateFlowStepShell";
import { import {
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
CREATE_FLOW_MD_UP_GRID_CELL_CLASS, CREATE_FLOW_MD_UP_GRID_CELL_CLASS,
CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS, CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS,
} from "./createFlowLayoutTokens"; } from "./createFlowLayoutTokens";
@@ -18,14 +19,18 @@ type CreateFlowLockupCardStepShellProps = {
children: ReactNode; children: ReactNode;
}; };
/** Final-review layout: `wideGrid`, two columns from `md:`, column widths from `createFlowLayoutTokens`. */ /** Lockup + card: `wideGrid`, two columns from `md:`, centered in the navfooter band from `md`. */
export function CreateFlowLockupCardStepShell({ export function CreateFlowLockupCardStepShell({
lockupTitle, lockupTitle,
lockupDescription, lockupDescription,
children, children,
}: CreateFlowLockupCardStepShellProps) { }: CreateFlowLockupCardStepShellProps) {
return ( return (
<CreateFlowStepShell variant="wideGrid" contentTopBelowMd="space-800"> <CreateFlowStepShell
variant="wideGrid"
contentTopBelowMd="space-800"
className={CREATE_FLOW_MD_CENTERED_SHELL_CLASS}
>
<div <div
className={`mx-auto flex w-full min-w-0 flex-col gap-4 md:grid md:w-full md:grid-cols-2 md:justify-items-center md:gap-[var(--measures-spacing-1200,48px)] ${CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS}`} className={`mx-auto flex w-full min-w-0 flex-col gap-4 md:grid md:w-full md:grid-cols-2 md:justify-items-center md:gap-[var(--measures-spacing-1200,48px)] ${CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS}`}
> >
@@ -9,6 +9,19 @@ export const CREATE_FLOW_MD_UP_GRID_CELL_CLASS =
/** Two 640px columns + `--measures-spacing-1200` (48px) gutter. */ /** Two 640px columns + `--measures-spacing-1200` (48px) gutter. */
export const CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS = "md:max-w-[1328px]"; export const CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS = "md:max-w-[1328px]";
/**
* Lockup+card and card-stack `<main>`: keep `items-start` so a tall card can
* scroll from the top. Pair with {@link CREATE_FLOW_MD_CENTERED_SHELL_CLASS}.
*/
export const CREATE_FLOW_MD_CENTERED_MAIN_CLASS =
"items-start justify-center overflow-y-auto";
/**
* Center the step in the navfooter band from `md` when it fits (`my-auto`),
* and drop the mobile top inset so that centering is not biased downward.
*/
export const CREATE_FLOW_MD_CENTERED_SHELL_CLASS = "md:my-auto md:pt-0";
/** /**
* Card-stack steps only (Figma compact card stack): wider than header lockup so the card grid / * Card-stack steps only (Figma compact card stack): wider than header lockup so the card grid /
* pyramid fits (max 860px). Header lockup stays {@link CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}. * pyramid fits (max 860px). Header lockup stays {@link CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}.
@@ -15,14 +15,17 @@ import {
CreateFlowLockupCardStepShell, CreateFlowLockupCardStepShell,
} from "../../components/CreateFlowLockupCardStepShell"; } from "../../components/CreateFlowLockupCardStepShell";
import { CreateFlowStepShell } from "../../components/CreateFlowStepShell"; import { CreateFlowStepShell } from "../../components/CreateFlowStepShell";
import { CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS } from "../../components/createFlowLayoutTokens"; import {
CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS,
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
} from "../../components/createFlowLayoutTokens";
import { useCreateFlowMdUp } from "../../hooks/useCreateFlowMdUp"; import { useCreateFlowMdUp } from "../../hooks/useCreateFlowMdUp";
interface PageProps { interface PageProps {
params: Promise<{ slug: string }>; params: Promise<{ slug: string }>;
} }
/** Template review route — same shell/grid as final-review; Figma `22142-898702`. */ /** Template review — lockup + card, vertically centered (Figma `22142-898702`). */
export default function ReviewTemplatePage({ params }: PageProps) { export default function ReviewTemplatePage({ params }: PageProps) {
const { slug: rawSlug } = use(params); const { slug: rawSlug } = use(params);
const slug = decodeURIComponent(rawSlug); const slug = decodeURIComponent(rawSlug);
@@ -72,7 +75,11 @@ export default function ReviewTemplatePage({ params }: PageProps) {
if (loading) { if (loading) {
return ( return (
<CreateFlowStepShell variant="wideGrid" contentTopBelowMd="space-800"> <CreateFlowStepShell
variant="wideGrid"
contentTopBelowMd="space-800"
className={CREATE_FLOW_MD_CENTERED_SHELL_CLASS}
>
<div <div
className={`flex shrink-0 items-center justify-start pb-16 ${CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}`} className={`flex shrink-0 items-center justify-start pb-16 ${CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}`}
> >
@@ -101,7 +108,11 @@ export default function ReviewTemplatePage({ params }: PageProps) {
/> />
</div> </div>
</div> </div>
<CreateFlowStepShell variant="wideGrid" contentTopBelowMd="space-800"> <CreateFlowStepShell
variant="wideGrid"
contentTopBelowMd="space-800"
className={CREATE_FLOW_MD_CENTERED_SHELL_CLASS}
>
<div <div
className={`min-h-[40vh] shrink-0 ${CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}`} className={`min-h-[40vh] shrink-0 ${CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}`}
aria-hidden aria-hidden
@@ -28,6 +28,7 @@ import InlineTextButton from "../../../../components/buttons/InlineTextButton";
import { CreateFlowStepShell } from "../../components/CreateFlowStepShell"; import { CreateFlowStepShell } from "../../components/CreateFlowStepShell";
import { import {
CREATE_FLOW_CARD_STACK_AREA_MAX_CLASS, CREATE_FLOW_CARD_STACK_AREA_MAX_CLASS,
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS, CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS,
} from "../../components/createFlowLayoutTokens"; } from "../../components/createFlowLayoutTokens";
import { CommunicationMethodEditFields } from "../../components/methodEditFields"; import { CommunicationMethodEditFields } from "../../components/methodEditFields";
@@ -727,6 +728,7 @@ export function CommunicationMethodsScreen() {
<CreateFlowStepShell <CreateFlowStepShell
variant="wideGridLoosePadding" variant="wideGridLoosePadding"
contentTopBelowMd="space-800" contentTopBelowMd="space-800"
className={CREATE_FLOW_MD_CENTERED_SHELL_CLASS}
> >
<div className="flex w-full min-w-0 flex-col items-center gap-6"> <div className="flex w-full min-w-0 flex-col items-center gap-6">
<div className={CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}> <div className={CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}>
@@ -25,6 +25,7 @@ import InlineTextButton from "../../../../components/buttons/InlineTextButton";
import { CreateFlowStepShell } from "../../components/CreateFlowStepShell"; import { CreateFlowStepShell } from "../../components/CreateFlowStepShell";
import { import {
CREATE_FLOW_CARD_STACK_AREA_MAX_CLASS, CREATE_FLOW_CARD_STACK_AREA_MAX_CLASS,
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS, CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS,
} from "../../components/createFlowLayoutTokens"; } from "../../components/createFlowLayoutTokens";
import { ConflictManagementEditFields } from "../../components/methodEditFields"; import { ConflictManagementEditFields } from "../../components/methodEditFields";
@@ -726,6 +727,7 @@ export function ConflictManagementScreen() {
<CreateFlowStepShell <CreateFlowStepShell
variant="wideGridLoosePadding" variant="wideGridLoosePadding"
contentTopBelowMd="space-800" contentTopBelowMd="space-800"
className={CREATE_FLOW_MD_CENTERED_SHELL_CLASS}
> >
<div className="flex w-full min-w-0 flex-col items-center gap-6"> <div className="flex w-full min-w-0 flex-col items-center gap-6">
<div className={CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}> <div className={CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}>
@@ -26,6 +26,7 @@ import InlineTextButton from "../../../../components/buttons/InlineTextButton";
import { CreateFlowStepShell } from "../../components/CreateFlowStepShell"; import { CreateFlowStepShell } from "../../components/CreateFlowStepShell";
import { import {
CREATE_FLOW_CARD_STACK_AREA_MAX_CLASS, CREATE_FLOW_CARD_STACK_AREA_MAX_CLASS,
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS, CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS,
} from "../../components/createFlowLayoutTokens"; } from "../../components/createFlowLayoutTokens";
import { MembershipMethodEditFields } from "../../components/methodEditFields"; import { MembershipMethodEditFields } from "../../components/methodEditFields";
@@ -719,6 +720,7 @@ export function MembershipMethodsScreen() {
<CreateFlowStepShell <CreateFlowStepShell
variant="wideGridLoosePadding" variant="wideGridLoosePadding"
contentTopBelowMd="space-800" contentTopBelowMd="space-800"
className={CREATE_FLOW_MD_CENTERED_SHELL_CLASS}
> >
<div className="flex w-full min-w-0 flex-col items-center gap-6"> <div className="flex w-full min-w-0 flex-col items-center gap-6">
<div className={CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}> <div className={CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS}>
@@ -3,6 +3,8 @@ import {
CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS, CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS,
CREATE_FLOW_MD_UP_GRID_CELL_CLASS, CREATE_FLOW_MD_UP_GRID_CELL_CLASS,
CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS, CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS,
CREATE_FLOW_MD_CENTERED_MAIN_CLASS,
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
} from "../../app/(app)/create/components/createFlowLayoutTokens"; } from "../../app/(app)/create/components/createFlowLayoutTokens";
describe("createFlowLayoutTokens", () => { describe("createFlowLayoutTokens", () => {
@@ -15,4 +17,11 @@ describe("createFlowLayoutTokens", () => {
); );
expect(CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS).toBe("md:max-w-[1328px]"); expect(CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS).toBe("md:max-w-[1328px]");
}); });
it("centers lockup+card and card-stack steps in the navfooter band from md", () => {
expect(CREATE_FLOW_MD_CENTERED_MAIN_CLASS).toBe(
"items-start justify-center overflow-y-auto",
);
expect(CREATE_FLOW_MD_CENTERED_SHELL_CLASS).toBe("md:my-auto md:pt-0");
});
}); });