Foundation for the adaline-based landing rebuild: - globals.css: warm-cream light theme + Material-3 dark theme mapped onto the existing CSS-var names; CSS-keyframe entrance + IntersectionObserver reveal motion (to replace framer-motion incrementally) - layout.tsx: self-host Instrument Sans/Serif, Newsreader and JetBrains Mono via next/font/google; drop the external Google Fonts <link> - _headers: tighten CSP style/font-src to 'self' now that fonts are local - components/ui: Container, Reveal, Eyebrow, Badge, Button, SectionHeading - lib/landing-content.ts: feature-section copy for the six product screens - public/images: six product screenshots optimized to WebP - add reicon-react/reicon-brands (bundled, CSP-safe SVG icons) Business logic (D1 download counter, platform metadata, theme, SEO) unchanged.
48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
import type { ReactNode } from "react";
|
|
|
|
type ButtonVariant = "primary" | "ghost";
|
|
type ButtonSize = "md" | "sm";
|
|
|
|
const base =
|
|
"eyebrow inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[20px] text-sm transition-colors";
|
|
|
|
const sizeClasses: Record<ButtonSize, string> = {
|
|
md: "h-11 px-6",
|
|
sm: "h-9 px-4",
|
|
};
|
|
|
|
const variantClasses: Record<ButtonVariant, string> = {
|
|
primary: "bg-[var(--cta)] text-[var(--text-on-cta)] hover:bg-[var(--cta-hover)]",
|
|
ghost: "border border-[var(--border-strong)] text-[var(--text-secondary)] hover:border-[var(--muted)]",
|
|
};
|
|
|
|
/** Link-styled call to action. Every landing CTA is an anchor. */
|
|
export function Button({
|
|
children,
|
|
href,
|
|
variant = "primary",
|
|
size = "md",
|
|
external = false,
|
|
className = "",
|
|
"aria-label": ariaLabel,
|
|
}: {
|
|
children: ReactNode;
|
|
href: string;
|
|
variant?: ButtonVariant;
|
|
size?: ButtonSize;
|
|
external?: boolean;
|
|
className?: string;
|
|
"aria-label"?: string;
|
|
}) {
|
|
return (
|
|
<a
|
|
href={href}
|
|
aria-label={ariaLabel}
|
|
{...(external ? { target: "_blank", rel: "noopener noreferrer" } : {})}
|
|
className={`${base} ${sizeClasses[size]} ${variantClasses[variant]} ${className}`}
|
|
>
|
|
{children}
|
|
</a>
|
|
);
|
|
}
|