File
Blob: src/client/components/editorial-message.tsx
| 1 | import { ArrowLeft } from "lucide-react"; |
| 2 | import type { ReactNode } from "react"; |
| 3 | import { Link } from "react-router"; |
| 4 | |
| 5 | interface EditorialMessageProps { |
| 6 | eyebrow: string; |
| 7 | title: string; |
| 8 | body: ReactNode; |
| 9 | hint?: ReactNode; |
| 10 | ctaTo?: string; |
| 11 | ctaLabel?: string; |
| 12 | } |
| 13 | |
| 14 | export const EditorialMessage = ({ |
| 15 | eyebrow, |
| 16 | title, |
| 17 | body, |
| 18 | hint, |
| 19 | ctaTo = "/sign-in", |
| 20 | ctaLabel = "Back to sign in", |
| 21 | }: EditorialMessageProps) => ( |
| 22 | <div className="mx-auto max-w-2xl py-12 sm:py-20"> |
| 23 | <p className="mb-6 text-[11px] font-medium uppercase tracking-[0.18em] text-zinc-500">{eyebrow}</p> |
| 24 | |
| 25 | <h1 className="mb-8 font-display text-[clamp(2rem,5.5vw,3.25rem)] font-semibold leading-[1.05] tracking-tight text-zinc-100"> |
| 26 | {title} |
| 27 | </h1> |
| 28 | |
| 29 | <p className="mb-6 max-w-[60ch] text-base leading-[1.7] text-zinc-300">{body}</p> |
| 30 | |
| 31 | {hint ? <p className="mb-10 max-w-[60ch] text-sm leading-[1.7] text-zinc-400">{hint}</p> : null} |
| 32 | |
| 33 | <div className="mb-16"> |
| 34 | <Link |
| 35 | to={ctaTo} |
| 36 | className="group inline-flex h-11 items-center gap-2 rounded-xl border border-zinc-700/60 bg-zinc-800/60 px-5 text-sm font-medium text-zinc-200 transition-colors hover:border-zinc-700 hover:bg-zinc-700/60 hover:text-zinc-100" |
| 37 | > |
| 38 | <ArrowLeft |
| 39 | className="h-4 w-4 transition-transform duration-200 group-hover:-translate-x-0.5" |
| 40 | aria-hidden="true" |
| 41 | /> |
| 42 | {ctaLabel} |
| 43 | </Link> |
| 44 | </div> |
| 45 | </div> |
| 46 | ); |