feat: initial commit — storefront, convex backend, and shared packages
Completes the first milestone of The Pet Loft ecommerce platform: - apps/storefront: full customer-facing Next.js app with HeroUI (cart, checkout, orders, wishlist, product detail, shop, search, auth) - convex/: serverless backend with schema, queries, mutations, actions, HTTP routes, Stripe/Shippo integrations, and co-located tests - packages/types, packages/utils, packages/convex: shared workspace packages Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
const CTA_IMAGES = {
|
||||
main: "/images/cta/cta-01.webp",
|
||||
kitty: "/images/cta/cta-02.webp",
|
||||
doggy: "/images/cta/cta-03.webp",
|
||||
} as const;
|
||||
|
||||
export function CtaSection() {
|
||||
return (
|
||||
<section
|
||||
aria-label="Promotional offers and shop by pet"
|
||||
className="w-full max-w-full min-w-0 overflow-x-hidden"
|
||||
>
|
||||
<div className="mx-auto max-w-7xl min-w-0">
|
||||
<div className="grid min-w-0 grid-cols-2 gap-4 overflow-x-hidden lg:grid-cols-3 lg:grid-rows-2 lg:gap-5">
|
||||
{/* Main CTA — Up to 45% OFF */}
|
||||
<section
|
||||
aria-labelledby="cta-main"
|
||||
className="relative col-span-2 flex min-h-[280px] flex-col justify-between overflow-hidden rounded-[var(--radius)] p-6 md:p-8 lg:row-span-2"
|
||||
>
|
||||
<div className="absolute inset-0 z-0">
|
||||
<Image
|
||||
src={CTA_IMAGES.main}
|
||||
alt=""
|
||||
fill
|
||||
className="object-cover brightness-[0.92] contrast-[1.05] saturate-[0.88]"
|
||||
sizes="(max-width: 1024px) 100vw, 66vw"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="absolute inset-0 z-[1] bg-gradient-to-r from-[var(--brand-mist)]/95 via-[var(--brand-mist)]/40 to-transparent"
|
||||
aria-hidden
|
||||
/>
|
||||
<div className="relative z-10 flex min-h-0 flex-1 flex-col justify-center pr-4 md:max-w-[58%] md:pr-8">
|
||||
<p className="font-sans text-base font-normal text-[var(--foreground)] md:text-lg">
|
||||
Up to
|
||||
</p>
|
||||
<h2
|
||||
id="cta-main"
|
||||
className="mt-1 font-[family-name:var(--font-fraunces)] text-4xl font-bold leading-tight tracking-tight text-[var(--foreground)] drop-shadow-sm md:text-5xl lg:text-6xl lg:leading-tight"
|
||||
>
|
||||
<span className="relative inline-block border-b-4 border-[var(--warm)] pb-1">
|
||||
45% OFF
|
||||
</span>
|
||||
</h2>
|
||||
<p className="mt-3 font-sans text-base text-[var(--foreground)] md:text-lg">
|
||||
Thousands of pet favourites
|
||||
</p>
|
||||
<Link
|
||||
href="/shop"
|
||||
className="mt-6 inline-flex w-fit items-center gap-1 rounded-full bg-[var(--warm)] px-6 py-3 font-sans text-sm font-medium text-[var(--neutral-900)] shadow-sm transition-[transform,box-shadow] duration-[var(--transition-base)] hover:scale-[1.02] hover:shadow-md focus:outline-none focus:ring-2 focus:ring-[var(--brand)] focus:ring-offset-2"
|
||||
>
|
||||
Shop Now
|
||||
<span aria-hidden>→</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="relative z-10 mt-4 flex items-center gap-1 font-sans text-[var(--muted)]" aria-hidden>
|
||||
<span>—</span>
|
||||
<span>—</span>
|
||||
<span>—</span>
|
||||
<span className="opacity-60">…</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kitty CTA */}
|
||||
<section
|
||||
aria-labelledby="cta-kitty"
|
||||
className="relative h-[130px] overflow-hidden rounded-[var(--radius)] p-3 md:h-[160px] md:p-6 lg:h-auto"
|
||||
>
|
||||
<div className="absolute inset-0 z-0 bg-[var(--brand-dark)]/70" aria-hidden />
|
||||
<div className="relative z-10">
|
||||
<h2
|
||||
id="cta-kitty"
|
||||
className="font-[family-name:var(--font-fraunces)] text-lg font-bold text-white md:text-3xl"
|
||||
>
|
||||
<span className="font-sans text-xs font-normal md:text-lg">Lookin for </span>
|
||||
<span>Kitty</span>
|
||||
<br />
|
||||
<span className="font-sans text-xs font-normal md:text-lg"> Stuff???</span>
|
||||
</h2>
|
||||
<Link
|
||||
href="/shop/cats"
|
||||
className="mt-2 inline-flex items-center gap-1 rounded-full border-2 border-white bg-transparent px-3 py-1.5 font-sans text-xs font-medium text-white transition-[transform,opacity] duration-[var(--transition-base)] hover:scale-[1.02] hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-[var(--brand-dark)] md:mt-4 md:px-5 md:py-2.5 md:text-sm"
|
||||
>
|
||||
Shop here
|
||||
<span aria-hidden>→</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="absolute inset-0">
|
||||
<Image
|
||||
src={CTA_IMAGES.doggy}
|
||||
alt=""
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 768px) 50vw, 33vw"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Doggy CTA */}
|
||||
<section
|
||||
aria-labelledby="cta-doggy"
|
||||
className="relative h-[130px] overflow-hidden rounded-[var(--radius)] p-3 md:h-[160px] md:p-6 lg:h-auto"
|
||||
>
|
||||
<div className="absolute inset-0 z-0 bg-[var(--brand-dark)]/70" aria-hidden />
|
||||
<div className="relative z-10">
|
||||
<h2
|
||||
id="cta-doggy"
|
||||
className="font-[family-name:var(--font-fraunces)] text-lg font-bold text-white md:text-3xl"
|
||||
>
|
||||
<span className="font-sans text-xs font-normal md:text-lg">Lookin for </span>
|
||||
<span>Doggy</span>
|
||||
<br />
|
||||
<span className="font-sans text-xs font-normal md:text-lg"> Stuff???</span>
|
||||
</h2>
|
||||
<Link
|
||||
href="/shop/dogs"
|
||||
className="mt-2 inline-flex items-center gap-1 rounded-full border-2 border-white bg-transparent px-3 py-1.5 font-sans text-xs font-medium text-white transition-[transform,opacity] duration-[var(--transition-base)] hover:scale-[1.02] hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-[var(--brand-dark)] md:mt-4 md:px-5 md:py-2.5 md:text-sm"
|
||||
>
|
||||
Shop here
|
||||
<span aria-hidden>→</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="absolute inset-0">
|
||||
<Image
|
||||
src={CTA_IMAGES.kitty}
|
||||
alt=""
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 768px) 50vw, 33vw"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user