Whatever you are on today, the history comes across. We map the fields with you and reconcile the counts before anything goes live.
Where you are today
The most common starting point, and the easiest one. Export what you have, we handle the shape of it.
What comes across
Typical timeline
2 days, including the review
Column names never match. That part is our job, not yours.
Plan your migrationA migration section where your current system is picked from frosted glass cards floating on a photo panel, swapping the right side to a plain-language summary, a checked list of what carries across, the typical timeline, and a caveat.
Migration section where the system you are on today is picked from frosted glass cards floating on a photo panel, swapping the right side to a plain-language summary, a checked list of what carries across, the typical timeline, and the caveat that comes with it.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/saas105?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/saas105?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/saas105.tsx plus the badge23 and button21 components it uses for the eyebrow and the CTA.
The installed file exports saas105Demo alongside the block: the exact props behind the preview above. Spread it to get a working selector in one line.
import { Saas105, saas105Demo } from "@/components/beste/block/saas105";
export default function MigrationPage() {
return <Saas105 {...saas105Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Saas105 } from "@/components/beste/block/saas105";
export default function MigrationPage() {
return (
<Saas105
badge={{ label: "Migration" }}
heading="Bring the last ten years with you"
description="Whatever you are on today, the history comes across."
image={{ src: "/images/paperwork.jpg", alt: "Paperwork on a desk" }}
labels={{
sourcesLabel: "Where you are today",
carriesLabel: "What comes across",
timelineLabel: "Typical timeline",
}}
items={[
{
name: "Spreadsheets",
summary: "The most common starting point, and the easiest one.",
timeline: "2 days, including the review",
carries: ["Member details and contact history", "Outstanding balances"],
note: "Column names never match. That part is our job.",
},
{
name: "Another practice system",
summary: "If yours can export, it can move.",
timeline: "3 to 5 days, run alongside your live system",
carries: ["Member records with full history", "Invoice and payment ledger"],
},
]}
button={{ label: "Plan your migration", href: "/migration" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Monospace eyebrow above the hairline rule, rendered via Badge23 |
heading | string | – | Section heading in the left column |
description | string | – | Supporting paragraph, right-aligned from md up |
image | { src: string; alt: string } | – | Photo behind the source cards |
labels | Saas105Labels | {} | Kicker and column headings, see below |
items | Source[] | [] | Selectable source systems and what each one implies |
button | { label: string; href: string } | – | CTA under the timeline column |
className | string | – | Extra classes for the outer <section> |
type Source = {
name: string;
summary: string;
timeline: string;
carries?: string[];
note?: string;
};
type Saas105Labels = {
sourcesLabel?: string;
carriesLabel?: string;
timelineLabel?: string;
};backdrop-blur-md over a translucent fill, with the selected card simply carrying more of that fill. Nothing outlines, so the photo stays readable behind them.image is set. Without a photo the cards fall back to the flat muted fill the rest of the set uses, so the block never renders blur over a plain background.text-background tokens instead of the adaptive ones.carries and note are both optional per source, so a system with nothing to warn about simply ends at its timeline, and the CTA stays where it is.lg. Below that the photo becomes a band above the detail column, keeping the source cards first in reading order.