All Taste components
Call to action
Call to action — app store download
An invitation to get the mobile app, with store buttons and a scan code beside a phone showing the booking screen.
App Store + Google Play buttons · scan code · phone mock · stacks on mobile
Slotwise for iPhone and Android
Your whole diary, in your pocket
See today’s bookings, move appointments with a drag and get a nudge when someone cancels, wherever you are.
Or scan with your phone’s camera to download the app.
import { Calendar } from "lucide-react";
// Use the official store badges from Apple and Google if you have them;
// these buttons follow their wording. Store buttons use the neutral ramp
// from the Taste preset so they stay dark in both modes.
const stores = [
{ label: "Download on the", name: "App Store", href: "https://apps.apple.com/app/your-app-id" },
{ label: "Get it on", name: "Google Play", href: "https://play.google.com/store/apps/details?id=your.app.id" },
];
const slots = [
{ time: "09:00" }, { time: "10:30", taken: true }, { time: "11:15", selected: true },
{ time: "13:00" }, { time: "14:30", taken: true }, { time: "16:00" },
];
export function CtaAppDownload() {
return (
<section aria-labelledby="cta-app-title" className="bg-bg px-5 py-16 font-sans sm:px-10 sm:py-20">
<div className="mx-auto grid max-w-6xl gap-9 overflow-hidden rounded-xl border border-border bg-surface px-7 pt-9 lg:grid-cols-[1.25fr_1fr] lg:gap-12 lg:px-14 lg:pt-14">
<div className="grid content-center justify-items-start gap-5 pb-2 lg:pb-14">
<p className="text-[13px] font-medium text-primary">Slotwise for iPhone and Android</p>
<h2 id="cta-app-title" className="text-3xl font-semibold tracking-tight text-fg sm:text-4xl">Your whole diary, in your pocket</h2>
<p className="max-w-xl text-base text-fg-muted sm:text-lg">See today’s bookings, move appointments with a drag and get a nudge when someone cancels, wherever you are.</p>
<div className="flex flex-wrap gap-2.5">
{stores.map((s) => (
<a key={s.name} href={s.href} aria-label={s.label + " " + s.name}
className="inline-flex h-[50px] items-center gap-2.5 rounded-lg border border-neutral-800 bg-neutral-950 pl-3.5 pr-[18px] text-neutral-50 transition hover:bg-neutral-800">
<span className="text-left leading-tight">
<span className="block text-[10.5px] text-neutral-300">{s.label}</span>
<span className="block text-[15px] font-semibold">{s.name}</span>
</span>
</a>
))}
</div>
<div className="flex items-center gap-3.5 border-t border-border pt-[18px] text-[13px] text-fg-muted">
<img src="/app-qr.svg" alt="" className="size-[66px] rounded-sm border border-border bg-bg p-1" />
<span>Or scan with your phone’s camera to download the app.</span>
</div>
</div>
<div aria-hidden className="grid w-[250px] max-w-full content-start gap-3 justify-self-center self-end rounded-t-[38px] border-[8px] border-b-0 border-neutral-900 bg-bg px-3.5 pb-6 pt-[18px] text-xs text-fg shadow-2xl">
<div className="flex items-center justify-between"><b className="text-[15px]">November</b><Calendar className="size-4" /></div>
<div className="grid grid-cols-2 gap-1.5">
{slots.map((s) => (
<span key={s.time} className={
s.selected ? "rounded border border-primary bg-primary-soft py-2 text-center font-medium tabular-nums text-primary-soft-fg"
: s.taken ? "rounded border border-border py-2 text-center tabular-nums text-fg-subtle line-through"
: "rounded border border-border py-2 text-center font-medium tabular-nums"
}>{s.time}</span>
))}
</div>
<span className="grid h-[34px] place-items-center rounded bg-primary font-semibold text-primary-fg">Book 11:15</span>
</div>
</div>
</section>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.