mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 11:24:57 -05:00
docs: improve contrsat
This commit is contained in:
@@ -51,7 +51,7 @@ function useCopyButton(
|
||||
const cache = new Map<string, string>();
|
||||
|
||||
const tocAction =
|
||||
"inline-flex items-center gap-1.5 px-2 py-1 text-[11px] uppercase tracking-wider whitespace-nowrap transition-all duration-200 text-foreground/50 hover:text-foreground border border-transparent hover:border-foreground/10 hover:bg-foreground/5 cursor-pointer select-none [&_svg]:size-3";
|
||||
"inline-flex items-center gap-1.5 px-2 py-1 text-[11px] uppercase tracking-wider whitespace-nowrap transition-all duration-200 text-foreground/60 hover:text-foreground border border-transparent hover:border-foreground/10 hover:bg-foreground/5 cursor-pointer select-none [&_svg]:size-3";
|
||||
|
||||
export function LLMCopyButton() {
|
||||
const [isLoading, startTransition] = useTransition();
|
||||
@@ -211,11 +211,11 @@ export function ViewOptions(props: { markdownUrl: string; githubUrl: string }) {
|
||||
href={item.href}
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
className="flex items-center gap-2.5 px-2.5 py-2 text-[12px] text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors duration-150 [&_svg]:size-3.5 [&_svg]:shrink-0"
|
||||
className="flex items-center gap-2.5 px-2.5 py-2 text-[12px] text-foreground/60 hover:text-foreground hover:bg-foreground/5 transition-colors duration-150 [&_svg]:size-3.5 [&_svg]:shrink-0"
|
||||
>
|
||||
{item.icon}
|
||||
{item.title}
|
||||
<ExternalLink className="size-3 text-foreground/20 ms-auto" />
|
||||
<ExternalLink className="size-3 text-foreground/30 ms-auto" />
|
||||
</a>
|
||||
))}
|
||||
</PopoverContent>
|
||||
|
||||
@@ -759,17 +759,17 @@ html:not([data-anchor-scrolling]) {
|
||||
.docs-layout #nd-page article > div.\@container > a div svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
opacity: 0.3;
|
||||
opacity: 0.45;
|
||||
transition: opacity 200ms ease;
|
||||
}
|
||||
|
||||
.docs-layout #nd-page article > div.\@container > a:hover div svg {
|
||||
opacity: 0.7;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.docs-layout #nd-page article > div.\@container > a > p {
|
||||
font-size: 11px;
|
||||
opacity: 0.35;
|
||||
opacity: 0.5;
|
||||
font-family: var(--font-sans);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
@@ -239,17 +239,17 @@ function ComparisonCell({ value }: { value: string | boolean }) {
|
||||
if (value === true)
|
||||
return (
|
||||
<span className="inline-flex items-center justify-center w-5 h-5">
|
||||
<Check className="w-3.5 h-3.5 text-foreground/60" />
|
||||
<Check className="w-3.5 h-3.5 text-foreground/70" />
|
||||
</span>
|
||||
);
|
||||
if (value === false)
|
||||
return (
|
||||
<span className="inline-flex items-center justify-center w-5 h-5">
|
||||
<Minus className="w-3 h-3 text-foreground/50 " />
|
||||
<Minus className="w-3 h-3 text-foreground/40 " />
|
||||
</span>
|
||||
);
|
||||
return (
|
||||
<span className="text-[11px] text-foreground/70 dark:text-foreground/50 font-mono">
|
||||
<span className="text-[11px] text-foreground/80 dark:text-foreground/60 font-mono">
|
||||
{value}
|
||||
</span>
|
||||
);
|
||||
@@ -287,7 +287,7 @@ function PricingHero() {
|
||||
Infrastructure
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-[11px] text-foreground/60 dark:text-foreground/40 leading-relaxed max-w-[260px]">
|
||||
<p className="text-[11px] text-foreground/70 dark:text-foreground/50 leading-relaxed max-w-[260px]">
|
||||
Dashboard, security, audit logs, and more for your auth.
|
||||
</p>
|
||||
</div>
|
||||
@@ -301,15 +301,15 @@ function PricingHero() {
|
||||
tier.highlight ? "bg-foreground/[0.03]" : ""
|
||||
}`}
|
||||
>
|
||||
<p className="text-[8px] font-mono uppercase tracking-widest text-foreground/50 dark:text-foreground/30 mb-1">
|
||||
<p className="text-[8px] font-mono uppercase tracking-widest text-foreground/60 dark:text-foreground/40 mb-1">
|
||||
{tier.name}
|
||||
</p>
|
||||
<p className="text-sm font-light text-foreground/80 tabular-nums flex items-baseline justify-center gap-0.5">
|
||||
<span>{tier.price}</span>
|
||||
{tier.note && (
|
||||
<span className="text-[9px] text-foreground/40 dark:text-foreground/50 font-mono">
|
||||
{tier.note}
|
||||
</span>
|
||||
<span className="text-[9px] text-foreground/50 dark:text-foreground/55 font-mono">
|
||||
{tier.note}
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -330,10 +330,10 @@ function PricingHero() {
|
||||
}}
|
||||
className="flex items-baseline justify-between py-1.5 border-b border-dashed border-foreground/[0.06] last:border-0"
|
||||
>
|
||||
<span className="text-[11px] text-foreground/60 dark:text-foreground/40 uppercase tracking-wider">
|
||||
{item.label}
|
||||
</span>
|
||||
<span className="text-[11px] text-foreground/80 dark:text-foreground/70 font-mono">
|
||||
<span className="text-[11px] text-foreground/70 dark:text-foreground/50 uppercase tracking-wider">
|
||||
{item.label}
|
||||
</span>
|
||||
<span className="text-[11px] text-foreground/85 dark:text-foreground/75 font-mono">
|
||||
{item.value}
|
||||
</span>
|
||||
</motion.div>
|
||||
@@ -350,7 +350,7 @@ function PricingHero() {
|
||||
</Link>
|
||||
<Link
|
||||
href="/enterprise"
|
||||
className="inline-flex items-center gap-1.5 text-[12px] text-foreground/60 dark:text-foreground/40 hover:text-foreground/70 font-mono uppercase tracking-wider transition-colors"
|
||||
className="inline-flex items-center gap-1.5 text-[12px] text-foreground/70 dark:text-foreground/50 hover:text-foreground/80 font-mono uppercase tracking-wider transition-colors"
|
||||
>
|
||||
Contact Sales
|
||||
<svg
|
||||
@@ -403,13 +403,13 @@ function PricingCard({
|
||||
<div className="flex flex-col flex-1 p-5">
|
||||
{/* Tier name + badge */}
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<h3 className="text-[10px] font-mono uppercase tracking-widest text-foreground/60 dark:text-foreground/40">
|
||||
<h3 className="text-[10px] font-mono uppercase tracking-widest text-foreground/70 dark:text-foreground/50">
|
||||
{tier.name}
|
||||
</h3>
|
||||
{isHighlighted && (
|
||||
<span className="text-[8px] font-mono uppercase tracking-widest text-foreground/60 dark:text-foreground/40 border border-dashed border-foreground/10 px-1.5 py-0.5 leading-none">
|
||||
popular
|
||||
</span>
|
||||
<span className="text-[8px] font-mono uppercase tracking-widest text-foreground/70 dark:text-foreground/50 border border-dashed border-foreground/15 px-1.5 py-0.5 leading-none">
|
||||
popular
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -423,24 +423,24 @@ function PricingCard({
|
||||
{tier.price}
|
||||
</span>
|
||||
{tier.priceNote && (
|
||||
<span className="text-[10px] text-foreground/50 dark:text-foreground/30 font-mono">
|
||||
{tier.priceNote}
|
||||
</span>
|
||||
<span className="text-[10px] text-foreground/60 dark:text-foreground/40 font-mono">
|
||||
{tier.priceNote}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Features */}
|
||||
<div className="flex-1 mb-5">
|
||||
<p className="text-[9px] text-foreground/50 dark:text-foreground/30 uppercase tracking-widest font-mono mb-3">
|
||||
<p className="text-[9px] text-foreground/60 dark:text-foreground/40 uppercase tracking-widest font-mono mb-3">
|
||||
{tier.featuresPrefix}
|
||||
</p>
|
||||
<ul className="space-y-2">
|
||||
{tier.features.map((feature) => (
|
||||
<li
|
||||
key={feature}
|
||||
className="flex items-start gap-2 text-[11px] text-foreground/70 dark:text-foreground/50 group-hover:text-foreground/75 dark:group-hover:text-foreground/55 transition-colors duration-300"
|
||||
className="flex items-start gap-2 text-[11px] text-foreground/80 dark:text-foreground/60 group-hover:text-foreground/85 dark:group-hover:text-foreground/65 transition-colors duration-300"
|
||||
>
|
||||
<span className="text-foreground/40 dark:text-foreground/50 mt-px font-mono text-[9px] leading-none select-none shrink-0">
|
||||
<span className="text-foreground/50 dark:text-foreground/55 mt-px font-mono text-[9px] leading-none select-none shrink-0">
|
||||
+
|
||||
</span>
|
||||
<span>{feature}</span>
|
||||
@@ -456,7 +456,7 @@ function PricingCard({
|
||||
className={`w-full py-2.5 text-center transition-all duration-200 cursor-pointer ${
|
||||
isHighlighted
|
||||
? "bg-foreground text-background hover:opacity-90"
|
||||
: "border border-dashed border-foreground/[0.12] text-foreground/60 dark:text-foreground/40 hover:text-foreground/70 hover:border-foreground/25 hover:bg-foreground/[0.02]"
|
||||
: "border border-dashed border-foreground/[0.12] text-foreground/70 dark:text-foreground/50 hover:text-foreground/80 hover:border-foreground/25 hover:bg-foreground/[0.02]"
|
||||
}`}
|
||||
>
|
||||
<span className="font-mono text-[10px] uppercase tracking-widest">
|
||||
@@ -512,25 +512,25 @@ export function PricingPageClient() {
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3, delay: 0.05 }}
|
||||
>
|
||||
<p className="text-[10px] uppercase tracking-widest text-foreground/50 dark:text-foreground/30 font-mono mb-5">
|
||||
<span className="text-foreground/65 dark:text-foreground/50">
|
||||
# Framework
|
||||
</span>
|
||||
</p>
|
||||
<p className="text-[10px] uppercase tracking-widest text-foreground/55 dark:text-foreground/40 font-mono mb-5">
|
||||
<span className="text-foreground/75 dark:text-foreground/60">
|
||||
# Framework
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div className="relative border border-dashed border-foreground/[0.12] bg-foreground/[0.02] overflow-hidden">
|
||||
<div className="px-5 py-5">
|
||||
<div className="flex items-start justify-between gap-6">
|
||||
<div className="space-y-2.5 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="text-[10px] font-mono uppercase tracking-widest text-foreground/80">
|
||||
Community
|
||||
</h3>
|
||||
<span className="text-[8px] font-mono uppercase tracking-widest text-foreground/65 dark:text-foreground/50 border border-dashed border-foreground/10 px-1.5 py-0.5 leading-none">
|
||||
<h3 className="text-[10px] font-mono uppercase tracking-widest text-foreground/85">
|
||||
Community
|
||||
</h3>
|
||||
<span className="text-[8px] font-mono uppercase tracking-widest text-foreground/75 dark:text-foreground/60 border border-dashed border-foreground/15 px-1.5 py-0.5 leading-none">
|
||||
open source
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-[11px] text-foreground/70 dark:text-foreground/55 leading-relaxed max-w-md">
|
||||
<p className="text-[11px] text-foreground/80 dark:text-foreground/65 leading-relaxed max-w-md">
|
||||
Comprehensive authentication and authorization
|
||||
framework.
|
||||
</p>
|
||||
@@ -538,7 +538,7 @@ export function PricingPageClient() {
|
||||
<div className="text-right shrink-0 flex flex-col items-end gap-3">
|
||||
<Link
|
||||
href="/docs"
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 border border-foreground/[0.12] text-foreground/60 dark:text-foreground/40 hover:text-foreground/70 hover:border-foreground/25 hover:bg-foreground/[0.02] transition-all"
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 border border-foreground/[0.12] text-foreground/70 dark:text-foreground/50 hover:text-foreground/80 hover:border-foreground/25 hover:bg-foreground/[0.02] transition-all"
|
||||
>
|
||||
<span className="font-mono text-[10px] uppercase tracking-widest">
|
||||
Read Docs
|
||||
@@ -567,11 +567,11 @@ export function PricingPageClient() {
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.4, delay: 0.15 }}
|
||||
>
|
||||
<p className="text-[10px] uppercase tracking-widest text-foreground/50 dark:text-foreground/30 font-mono mb-5">
|
||||
<span className="text-foreground/65 dark:text-foreground/50">
|
||||
# Infrastructure
|
||||
</span>
|
||||
</p>
|
||||
<p className="text-[10px] uppercase tracking-widest text-foreground/55 dark:text-foreground/40 font-mono mb-5">
|
||||
<span className="text-foreground/75 dark:text-foreground/60">
|
||||
# Infrastructure
|
||||
</span>
|
||||
</p>
|
||||
|
||||
{/* Pricing Cards */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-0">
|
||||
@@ -587,15 +587,15 @@ export function PricingPageClient() {
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3, delay: 0.45 }}
|
||||
>
|
||||
<p className="text-[10px] uppercase tracking-widest text-foreground/50 dark:text-foreground/30 font-mono mb-5">
|
||||
# feature comparison
|
||||
</p>
|
||||
<p className="text-[10px] uppercase tracking-widest text-foreground/55 dark:text-foreground/40 font-mono mb-5">
|
||||
# feature comparison
|
||||
</p>
|
||||
|
||||
<div className="border border-dashed border-foreground/[0.08] overflow-x-auto">
|
||||
<table className="w-full min-w-[600px]">
|
||||
<thead>
|
||||
<tr className="border-b border-foreground/[0.08]">
|
||||
<th className="text-left text-[10px] uppercase tracking-widest text-foreground/50 dark:text-foreground/30 font-mono font-normal py-3 px-5 w-[28%]">
|
||||
<th className="text-left text-[10px] uppercase tracking-widest text-foreground/60 dark:text-foreground/40 font-mono font-normal py-3 px-5 w-[28%]">
|
||||
Feature
|
||||
</th>
|
||||
{tierLabels.map((name) => (
|
||||
@@ -603,8 +603,8 @@ export function PricingPageClient() {
|
||||
key={name}
|
||||
className={`text-center text-[10px] uppercase tracking-widest font-mono font-normal py-3 px-3 w-[18%] ${
|
||||
name === "Pro"
|
||||
? "text-foreground/70 bg-foreground/[0.025]"
|
||||
: "text-foreground/50 dark:text-foreground/30"
|
||||
? "text-foreground/80 bg-foreground/[0.025]"
|
||||
: "text-foreground/60 dark:text-foreground/40"
|
||||
}`}
|
||||
>
|
||||
{name}
|
||||
@@ -620,7 +620,7 @@ export function PricingPageClient() {
|
||||
i % 2 === 0 ? "bg-foreground/[0.008]" : ""
|
||||
}`}
|
||||
>
|
||||
<td className="text-[11px] text-foreground/70 dark:text-foreground/50 py-2.5 px-5">
|
||||
<td className="text-[11px] text-foreground/80 dark:text-foreground/60 py-2.5 px-5">
|
||||
{row.label}
|
||||
</td>
|
||||
{tierKeys.map((tier) => (
|
||||
|
||||
@@ -27,7 +27,7 @@ export const CustomItem: FC<{ item: PageTreeItem }> = ({ item }) => {
|
||||
${
|
||||
active
|
||||
? "text-foreground bg-foreground/[0.06] border-l-2 border-foreground font-medium"
|
||||
: "text-muted-foreground hover:text-foreground hover:bg-foreground/[0.04] border-l-2 border-transparent"
|
||||
: "text-muted-foreground/80 hover:text-foreground hover:bg-foreground/[0.04] border-l-2 border-transparent"
|
||||
}
|
||||
`}
|
||||
>
|
||||
@@ -54,7 +54,7 @@ export const CustomFolder: FC<{
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className="flex items-center justify-between px-3 py-1.5 text-sm font-mono font-medium text-muted-foreground hover:text-foreground transition-colors cursor-pointer"
|
||||
className="flex items-center justify-between px-3 py-1.5 text-sm font-mono font-medium text-muted-foreground/80 hover:text-foreground transition-colors cursor-pointer"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
{item.icon && <span className="shrink-0 size-4">{item.icon}</span>}
|
||||
@@ -98,7 +98,7 @@ export const CustomSeparator: FC<{ item: PageTreeSeparator }> = ({ item }) => {
|
||||
return (
|
||||
<div className="mt-5 mb-1.5 px-3">
|
||||
{item.name ? (
|
||||
<span className="text-xs font-mono uppercase tracking-wider text-muted-foreground">
|
||||
<span className="text-xs font-mono uppercase tracking-wider text-muted-foreground/80">
|
||||
{item.name}
|
||||
</span>
|
||||
) : (
|
||||
@@ -117,7 +117,7 @@ export const SearchButton: FC = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(true)}
|
||||
className="flex items-center gap-2 w-full px-3 py-2 mb-2 text-sm font-mono text-muted-foreground border border-border hover:text-foreground hover:bg-foreground/[0.04] transition-colors cursor-pointer"
|
||||
className="flex items-center gap-2 w-full px-3 py-2 mb-2 text-sm font-mono text-muted-foreground/80 border border-border hover:text-foreground hover:bg-foreground/[0.04] transition-colors cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -135,7 +135,7 @@ export const SearchButton: FC = () => {
|
||||
<path d="m21 21-4.3-4.3" />
|
||||
</svg>
|
||||
<span className="flex-1 text-left">Search...</span>
|
||||
<kbd className="hidden sm:inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] font-mono bg-foreground/[0.06] border border-border text-muted-foreground">
|
||||
<kbd className="hidden sm:inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] font-mono bg-foreground/[0.06] border border-border text-muted-foreground/70">
|
||||
<span className="text-xs">⌘</span>K
|
||||
</kbd>
|
||||
</button>
|
||||
|
||||
@@ -75,13 +75,13 @@ export function DocsSidebar() {
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center gap-2 px-4 lg:px-7 py-2.5 border-b border-foreground/5 text-[12px] uppercase tracking-wider text-foreground/45 hover:text-foreground/75 transition-colors"
|
||||
className="flex w-full items-center gap-2 px-4 lg:px-7 py-2.5 border-b border-foreground/5 text-[12px] uppercase tracking-wider text-foreground/55 hover:text-foreground/80 transition-colors"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<Search className="size-3.5 shrink-0" />
|
||||
<span className="truncate">Search</span>
|
||||
<span
|
||||
className="ml-auto flex items-center gap-1 shrink-0 text-foreground/50 hover:text-foreground/55 transition-colors"
|
||||
className="ml-auto flex items-center gap-1 shrink-0 text-foreground/55 hover:text-foreground/70 transition-colors"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openAI();
|
||||
@@ -114,7 +114,7 @@ export function DocsSidebar() {
|
||||
"font-medium text-sm tracking-wider",
|
||||
currentOpen === index
|
||||
? "text-foreground bg-foreground/3"
|
||||
: "text-foreground/65 hover:text-foreground hover:bg-foreground/3",
|
||||
: "text-foreground/70 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() => {
|
||||
setCurrentOpen((prev) => (prev === index ? -1 : index));
|
||||
@@ -196,16 +196,16 @@ function BranchSwitcher() {
|
||||
className="flex w-full items-center gap-2 px-4 lg:px-7 py-3 hover:bg-foreground/[0.02] transition-colors"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
>
|
||||
<GitBranch className="size-3.5 text-foreground/55 shrink-0" />
|
||||
<GitBranch className="size-3.5 text-foreground/60 shrink-0" />
|
||||
<div className="grow text-left min-w-0">
|
||||
<p className="text-[12px] uppercase tracking-wider text-foreground/55 block">
|
||||
<p className="text-[12px] uppercase tracking-wider text-foreground/60 block">
|
||||
{branch}{" "}
|
||||
<span className="text-[9px] text-foreground/30 ">
|
||||
<span className="text-[9px] text-foreground/40 ">
|
||||
{branch === "main" ? "" : "pre-release"}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center shrink-0 text-foreground/35">
|
||||
<div className="flex flex-col items-center shrink-0 text-foreground/45">
|
||||
<ChevronDownIcon className="size-3 rotate-180 -mb-[3px]" />
|
||||
<ChevronDownIcon className="size-3 -mt-[3px]" />
|
||||
</div>
|
||||
@@ -226,12 +226,12 @@ function BranchSwitcher() {
|
||||
"flex w-full items-center gap-2 px-3 py-2 text-[12px] transition-colors",
|
||||
branch === "main"
|
||||
? "text-foreground bg-foreground/5"
|
||||
: "text-foreground/55 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() => switchBranch("main")}
|
||||
>
|
||||
<span className="grow text-left">main</span>
|
||||
<span className="text-[10px] text-foreground/35 uppercase tracking-wider">
|
||||
: "text-foreground/60 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() => switchBranch("main")}
|
||||
>
|
||||
<span className="grow text-left">main</span>
|
||||
<span className="text-[10px] text-foreground/45 uppercase tracking-wider">
|
||||
Stable
|
||||
</span>
|
||||
</button>
|
||||
@@ -241,13 +241,13 @@ function BranchSwitcher() {
|
||||
"flex w-full items-center gap-2 px-3 py-2 text-[12px] transition-colors",
|
||||
branch === "canary"
|
||||
? "text-foreground bg-foreground/5"
|
||||
: "text-foreground/55 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() => switchBranch("canary")}
|
||||
: "text-foreground/60 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() => switchBranch("canary")}
|
||||
>
|
||||
<span className="grow text-left">canary</span>
|
||||
<Badge
|
||||
className="pointer-events-none no-underline! border-dashed decoration-transparent! rounded-none px-1.5 py-0 text-[9px] uppercase tracking-wider text-foreground/50 border-foreground/20"
|
||||
className="pointer-events-none no-underline! border-dashed decoration-transparent! rounded-none px-1.5 py-0 text-[9px] uppercase tracking-wider text-foreground/55 border-foreground/25"
|
||||
variant="outline"
|
||||
>
|
||||
Pre-release
|
||||
@@ -288,7 +288,7 @@ function SidebarSection({
|
||||
key={`sep-${item.title}-${i}`}
|
||||
className="flex flex-row items-center gap-2 mx-4 lg:mx-7 my-2"
|
||||
>
|
||||
<p className="text-[10px] text-foreground/35 uppercase tracking-wider">
|
||||
<p className="text-[10px] text-foreground/45 uppercase tracking-wider">
|
||||
{item.title}
|
||||
</p>
|
||||
<div className="grow h-px bg-border" />
|
||||
@@ -301,7 +301,7 @@ function SidebarSection({
|
||||
key={`group-${item.title}-${i}`}
|
||||
className="flex flex-row items-center gap-2 mx-4 my-1 lg:mx-7"
|
||||
>
|
||||
<p className="text-[10px] text-foreground/35 uppercase tracking-wider">
|
||||
<p className="text-[10px] text-foreground/45 uppercase tracking-wider">
|
||||
{item.title}
|
||||
</p>
|
||||
<div className="grow h-px bg-border" />
|
||||
@@ -409,7 +409,7 @@ function SubpageLink({
|
||||
"relative flex items-center pr-4 lg:pr-7 py-1 text-[13px] transition-all duration-150",
|
||||
active
|
||||
? "text-foreground bg-foreground/6"
|
||||
: "text-foreground/45 hover:text-foreground/75 hover:bg-foreground/3",
|
||||
: "text-foreground/55 hover:text-foreground/80 hover:bg-foreground/3",
|
||||
)}
|
||||
>
|
||||
<span className="truncate">{children}</span>
|
||||
@@ -441,14 +441,14 @@ function SidebarLink({
|
||||
${
|
||||
active
|
||||
? "text-foreground bg-foreground/6"
|
||||
: "text-foreground/55 hover:text-foreground/85 hover:bg-foreground/3"
|
||||
: "text-foreground/65 hover:text-foreground/90 hover:bg-foreground/3"
|
||||
}
|
||||
`}
|
||||
>
|
||||
{icon && (
|
||||
<span
|
||||
className={`transition-colors duration-150 ${
|
||||
active ? "text-foreground" : "text-foreground/55"
|
||||
active ? "text-foreground" : "text-foreground/65"
|
||||
}`}
|
||||
>
|
||||
{icon}
|
||||
@@ -467,7 +467,7 @@ function NewBadge({ isSelected }: { isSelected?: boolean }) {
|
||||
"pointer-events-none no-underline! border-dashed decoration-transparent! rounded-none px-1.5 py-0 text-[9px] uppercase tracking-wider",
|
||||
isSelected
|
||||
? "border-solid! bg-foreground/10 text-foreground"
|
||||
: "text-foreground/50 border-foreground/20",
|
||||
: "text-foreground/55 border-foreground/25",
|
||||
)}
|
||||
variant="outline"
|
||||
>
|
||||
|
||||
@@ -77,7 +77,7 @@ export function APIMethod({
|
||||
<span className="rounded bg-primary/10 px-2 py-0.5 text-xs font-semibold uppercase text-primary">
|
||||
{method}
|
||||
</span>
|
||||
<span className="text-muted-foreground">{path}</span>
|
||||
<span className="text-muted-foreground/80">{path}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="prose-sm">{children}</div>
|
||||
@@ -187,7 +187,7 @@ function TypeIcon({ type }: { type: string }) {
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className={cn(className, "text-foreground/30")}
|
||||
className={cn(className, "text-foreground/40")}
|
||||
>
|
||||
<path d="M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5a2 2 0 0 0 2 2h1" />
|
||||
<path d="M16 3h1a2 2 0 0 1 2 2v5a2 2 0 0 0 2 2 2 2 0 0 0-2 2v5a2 2 0 0 1-2 2h-1" />
|
||||
@@ -263,7 +263,7 @@ function SchemaCodeBlock({
|
||||
<div className="relative">
|
||||
<button
|
||||
type="button"
|
||||
className="absolute top-2 right-2 font-mono text-[10px] text-foreground/30 hover:text-foreground/60 transition-colors"
|
||||
className="absolute top-2 right-2 font-mono text-[10px] text-foreground/40 hover:text-foreground/65 transition-colors"
|
||||
onClick={() => {
|
||||
void navigator.clipboard.writeText(code);
|
||||
setCopied(true);
|
||||
@@ -272,7 +272,7 @@ function SchemaCodeBlock({
|
||||
>
|
||||
{copied ? "copied" : "copy"}
|
||||
</button>
|
||||
<pre className="overflow-x-auto p-4 font-mono text-[12px] leading-relaxed text-foreground/70 whitespace-pre">
|
||||
<pre className="overflow-x-auto p-4 font-mono text-[12px] leading-relaxed text-foreground/80 whitespace-pre">
|
||||
{code}
|
||||
</pre>
|
||||
</div>
|
||||
@@ -319,24 +319,24 @@ export function DatabaseTable({
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="text-foreground/40"
|
||||
>
|
||||
<ellipse cx="12" cy="5" rx="9" ry="3" />
|
||||
className="text-foreground/50"
|
||||
>
|
||||
<ellipse cx="12" cy="5" rx="9" ry="3" />
|
||||
<path d="M3 5v14a9 3 0 0 0 18 0V5" />
|
||||
<path d="M3 12a9 3 0 0 0 18 0" />
|
||||
</svg>
|
||||
{name ? (
|
||||
<span className="font-mono text-[13px] text-foreground/70">
|
||||
<span className="text-foreground/30">table </span>
|
||||
<span className="font-mono text-[13px] text-foreground/80">
|
||||
<span className="text-foreground/40">table </span>
|
||||
{name}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-[11px] text-foreground/30 font-mono uppercase tracking-widest">
|
||||
<span className="text-[11px] text-foreground/40 font-mono uppercase tracking-widest">
|
||||
Table
|
||||
</span>
|
||||
)}
|
||||
{name && (
|
||||
<span className="text-[10px] text-foreground/20 font-mono">
|
||||
<span className="text-[10px] text-foreground/35 font-mono">
|
||||
({fields.length})
|
||||
</span>
|
||||
)}
|
||||
@@ -357,8 +357,8 @@ export function DatabaseTable({
|
||||
className={cn(
|
||||
"px-2 py-0.5 font-mono text-[10px] tracking-wide transition-colors cursor-pointer",
|
||||
view === opt.key
|
||||
? "text-foreground/70 bg-foreground/[0.05]"
|
||||
: "text-foreground/50 hover:text-foreground/50",
|
||||
? "text-foreground/80 bg-foreground/[0.05]"
|
||||
: "text-foreground/55 hover:text-foreground/65",
|
||||
)}
|
||||
>
|
||||
{opt.label}
|
||||
@@ -378,8 +378,8 @@ export function DatabaseTable({
|
||||
className={cn(
|
||||
"px-1.5 py-0.5 font-mono text-[9px] tracking-wide transition-colors cursor-pointer",
|
||||
sqlDialect === d.key
|
||||
? "text-foreground/60 bg-foreground/[0.05]"
|
||||
: "text-foreground/20 hover:text-foreground/40",
|
||||
? "text-foreground/70 bg-foreground/[0.05]"
|
||||
: "text-foreground/35 hover:text-foreground/50",
|
||||
)}
|
||||
>
|
||||
{d.label}
|
||||
@@ -397,8 +397,8 @@ export function DatabaseTable({
|
||||
className={cn(
|
||||
"px-1.5 py-0.5 font-mono text-[9px] tracking-wide transition-colors cursor-pointer",
|
||||
drizzleProvider === d.key
|
||||
? "text-foreground/60 bg-foreground/[0.05]"
|
||||
: "text-foreground/20 hover:text-foreground/40",
|
||||
? "text-foreground/70 bg-foreground/[0.05]"
|
||||
: "text-foreground/35 hover:text-foreground/50",
|
||||
)}
|
||||
>
|
||||
{d.label}
|
||||
@@ -411,16 +411,16 @@ export function DatabaseTable({
|
||||
<>
|
||||
{/* Column headers */}
|
||||
<div className="grid grid-cols-[minmax(120px,1.2fr)_minmax(100px,0.8fr)_minmax(40px,0.4fr)_minmax(150px,2fr)] border-b border-foreground/[0.06] bg-foreground/[0.02]">
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/50">
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/60">
|
||||
Field
|
||||
</div>
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/50">
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/60">
|
||||
Type
|
||||
</div>
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/50">
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/60">
|
||||
Key
|
||||
</div>
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/50">
|
||||
<div className="px-4 py-1.5 text-[10px] font-mono uppercase tracking-widest text-foreground/60">
|
||||
Description
|
||||
</div>
|
||||
</div>
|
||||
@@ -436,7 +436,7 @@ export function DatabaseTable({
|
||||
</div>
|
||||
<div className="px-4 py-2 flex items-center gap-1.5">
|
||||
<TypeIcon type={field.type} />
|
||||
<span className="font-mono text-[11px] text-foreground/40">
|
||||
<span className="font-mono text-[11px] text-foreground/55">
|
||||
{field.type}
|
||||
</span>
|
||||
</div>
|
||||
@@ -454,17 +454,17 @@ export function DatabaseTable({
|
||||
</span>
|
||||
)}
|
||||
{field.isOptional && (
|
||||
<span className="font-mono text-[10px] text-foreground/20">
|
||||
<span className="font-mono text-[10px] text-foreground/35">
|
||||
?
|
||||
</span>
|
||||
)}
|
||||
{!field.isPrimaryKey &&
|
||||
!field.isForeignKey &&
|
||||
!field.isOptional && (
|
||||
<span className="text-foreground/10">—</span>
|
||||
<span className="text-foreground/20">—</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="px-4 py-2 text-[11px] text-foreground/40 leading-relaxed">
|
||||
<div className="px-4 py-2 text-[11px] text-foreground/55 leading-relaxed">
|
||||
{field.description}
|
||||
</div>
|
||||
</div>
|
||||
@@ -516,7 +516,7 @@ export function Endpoint({
|
||||
)}
|
||||
>
|
||||
<Method method={method || "GET"} />
|
||||
<span className="font-mono text-sm text-muted-foreground">{path}</span>
|
||||
<span className="font-mono text-sm text-muted-foreground/80">{path}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -590,7 +590,7 @@ export function DividerText({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="flex items-center justify-center w-full">
|
||||
<div className="w-full border-b border-muted"></div>
|
||||
<div className="flex items-center justify-center w-full text-muted-foreground">
|
||||
<div className="flex items-center justify-center w-full text-muted-foreground/80">
|
||||
{children}
|
||||
</div>
|
||||
<div className="w-full border-b border-muted"></div>
|
||||
@@ -602,7 +602,7 @@ export function DividerText({ children }: { children: ReactNode }) {
|
||||
|
||||
export function GenerateAppleJwt() {
|
||||
return (
|
||||
<div className="my-4 rounded-lg border bg-card p-4 text-sm text-muted-foreground">
|
||||
<div className="my-4 rounded-lg border bg-card p-4 text-sm text-muted-foreground/80">
|
||||
See the Apple documentation for generating a client secret JWT.
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -146,7 +146,7 @@ export function StepperTOC({ items, children }: StepperTOCProps) {
|
||||
? "bg-foreground border-foreground scale-125"
|
||||
: isVisible
|
||||
? "bg-foreground/50 border-foreground/50"
|
||||
: "bg-transparent border-foreground/20 group-hover:border-foreground/40"
|
||||
: "bg-transparent border-foreground/30 group-hover:border-foreground/50"
|
||||
}
|
||||
`}
|
||||
/>
|
||||
@@ -157,8 +157,8 @@ export function StepperTOC({ items, children }: StepperTOCProps) {
|
||||
isActive
|
||||
? "text-foreground"
|
||||
: isVisible
|
||||
? "text-foreground/50"
|
||||
: "text-foreground/30 group-hover:text-foreground/60"
|
||||
? "text-foreground/60"
|
||||
: "text-foreground/40 group-hover:text-foreground/65"
|
||||
}
|
||||
`}
|
||||
>
|
||||
@@ -167,7 +167,7 @@ export function StepperTOC({ items, children }: StepperTOCProps) {
|
||||
</a>
|
||||
|
||||
{i < headings.length - 1 && (
|
||||
<span className="mx-2 text-foreground/20 text-[11px] select-none">
|
||||
<span className="mx-2 text-foreground/30 text-[11px] select-none">
|
||||
/
|
||||
</span>
|
||||
)}
|
||||
@@ -181,7 +181,7 @@ export function StepperTOC({ items, children }: StepperTOCProps) {
|
||||
{children && (
|
||||
<div className="flex items-center gap-3 shrink-0 ml-auto pl-2">
|
||||
{headings.length > 0 && (
|
||||
<span className="text-foreground/10 text-[11px] select-none">
|
||||
<span className="text-foreground/20 text-[11px] select-none">
|
||||
|
|
||||
</span>
|
||||
)}
|
||||
@@ -229,8 +229,8 @@ export function StepperTOC({ items, children }: StepperTOCProps) {
|
||||
<span
|
||||
className={`text-[10px] uppercase tracking-wider whitespace-nowrap transition-colors duration-200 ${
|
||||
isSubActive
|
||||
? "text-foreground"
|
||||
: "text-foreground/30 group-hover:text-foreground/60"
|
||||
? "text-foreground"
|
||||
: "text-foreground/40 group-hover:text-foreground/65"
|
||||
}`}
|
||||
>
|
||||
{sub.title}
|
||||
|
||||
@@ -17,7 +17,7 @@ export function FloatingToolbar() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(true)}
|
||||
className="group flex items-center justify-center size-9 text-foreground/30 hover:text-foreground/60 transition-colors"
|
||||
className="group flex items-center justify-center size-9 text-foreground/40 hover:text-foreground/70 transition-colors"
|
||||
>
|
||||
<kbd className="flex items-center gap-0.5 text-[10px] font-mono">
|
||||
<span className="text-[11px]">⌘</span>K
|
||||
@@ -25,7 +25,7 @@ export function FloatingToolbar() {
|
||||
<span className="sr-only">Command menu</span>
|
||||
</button>
|
||||
<span className="w-px h-3 bg-foreground/[0.08]" />
|
||||
<div className="flex items-center justify-center size-9 [&_button]:text-foreground/30 [&_button:hover]:text-foreground/60">
|
||||
<div className="flex items-center justify-center size-9 [&_button]:text-foreground/40 [&_button:hover]:text-foreground/70">
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// spell-checker:disable
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useLayoutEffect, useRef } from "react";
|
||||
|
||||
const VERTEX_SHADER = `
|
||||
attribute vec2 a_position;
|
||||
@@ -139,7 +139,7 @@ export function HalftoneBackground() {
|
||||
const smoothMouseRef = useRef({ x: -1, y: -1 });
|
||||
const clickRef = useRef({ strength: 0, x: 0, y: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
const canvas = canvasRef.current;
|
||||
const wrapper = wrapperRef.current;
|
||||
if (!canvas || !wrapper) return;
|
||||
@@ -225,12 +225,10 @@ export function HalftoneBackground() {
|
||||
const draw = () => {
|
||||
const elapsed = (performance.now() - startTime) / 1000;
|
||||
|
||||
// Smooth mouse interpolation for fluid feel
|
||||
const lerp = 0.08;
|
||||
const target = mouseRef.current;
|
||||
const smooth = smoothMouseRef.current;
|
||||
if (target.x < 0) {
|
||||
// Mouse left - smoothly fade out
|
||||
smooth.x += (target.x - smooth.x) * 0.02;
|
||||
smooth.y += (target.y - smooth.y) * 0.02;
|
||||
} else {
|
||||
@@ -238,7 +236,6 @@ export function HalftoneBackground() {
|
||||
smooth.y += (target.y - smooth.y) * lerp;
|
||||
}
|
||||
|
||||
// Decay click strength
|
||||
clickRef.current.strength *= 0.96;
|
||||
|
||||
gl.uniform1f(uTime, elapsed);
|
||||
@@ -247,9 +244,18 @@ export function HalftoneBackground() {
|
||||
gl.uniform1f(uClick, clickRef.current.strength);
|
||||
gl.uniform2f(uClickPos, clickRef.current.x, clickRef.current.y);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
|
||||
frameRef.current = requestAnimationFrame(draw);
|
||||
};
|
||||
|
||||
// Draw the first frame synchronously so the canvas has content before paint
|
||||
gl.uniform1f(uTime, 0);
|
||||
gl.uniform2f(uResolution, canvas.width, canvas.height);
|
||||
gl.uniform2f(uMouse, -1, -1);
|
||||
gl.uniform1f(uClick, 0);
|
||||
gl.uniform2f(uClickPos, 0, 0);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
|
||||
frameRef.current = requestAnimationFrame(draw);
|
||||
|
||||
return () => {
|
||||
@@ -268,10 +274,13 @@ export function HalftoneBackground() {
|
||||
return (
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
className="absolute inset-0 overflow-hidden bg-white dark:bg-black"
|
||||
className="absolute inset-0 overflow-hidden bg-background"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<canvas ref={canvasRef} className="w-full h-full invert dark:invert-0" />
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="w-full h-full invert dark:invert-0"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1530,11 +1530,11 @@ export function HeroReadMe({
|
||||
transition={{ duration: 0.4, delay: 0.3 }}
|
||||
className="overflow-y-auto overflow-x-hidden no-scrollbar pt-[30px] pb-0"
|
||||
>
|
||||
<h1 className="flex items-center gap-2 text-sm sm:text-[15px] font-mono text-neutral-800 dark:text-neutral-200 pb-2 sm:pb-3 mb-4 sm:mb-5 border-b border-foreground/10">
|
||||
<h1 className="flex items-center gap-2 text-sm sm:text-[15px] font-mono text-neutral-900 dark:text-neutral-100 pb-2 sm:pb-3 mb-4 sm:mb-5 border-b border-foreground/15">
|
||||
README
|
||||
</h1>
|
||||
|
||||
<p className="text-sm sm:text-[14px] text-neutral-700 dark:text-neutral-300 leading-[1.8] sm:leading-[1.9] mb-5 sm:mb-6">
|
||||
<p className="text-sm sm:text-[14px] text-neutral-600 dark:text-neutral-300 leading-[1.8] sm:leading-[1.9] mb-5 sm:mb-6">
|
||||
Better Auth is an authentication and authorization framework. It provides a comprehensive set of features out of the box and includes a Plugin ecosystem that simplifies adding advanced functionalities and infrastructure to help own your auth at scale.
|
||||
</p>
|
||||
|
||||
@@ -1542,7 +1542,7 @@ export function HeroReadMe({
|
||||
|
||||
<div className="flex items-center gap-3 my-4">
|
||||
<div className="flex-1 border-t border-foreground/6"></div>
|
||||
<span className="text-[10px] text-foreground/60 dark:text-foreground/40 font-mono tracking-wider uppercase shrink-0">
|
||||
<span className="text-[10px] text-foreground/70 dark:text-foreground/50 font-mono tracking-wider uppercase shrink-0">
|
||||
Trusted By
|
||||
</span>
|
||||
</div>
|
||||
@@ -1550,13 +1550,13 @@ export function HeroReadMe({
|
||||
<TrustedBy />
|
||||
|
||||
<div className="flex items-center gap-3 my-4">
|
||||
<span className="text-[10px] text-foreground/60 dark:text-foreground/40 font-mono tracking-wider uppercase shrink-0">
|
||||
<span className="text-[10px] text-foreground/70 dark:text-foreground/50 font-mono tracking-wider uppercase shrink-0">
|
||||
Features
|
||||
</span>
|
||||
<div className="flex-1 border-t border-foreground/6"></div>
|
||||
<div className="flex-1 border-t border-foreground/10"></div>
|
||||
</div>
|
||||
|
||||
<div className="relative grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 mb-2 border border-foreground/10 overflow-hidden">
|
||||
<div className="relative grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 mb-2 border border-foreground/15 overflow-hidden">
|
||||
{[
|
||||
{
|
||||
label: "Framework Agnostic",
|
||||
@@ -1643,7 +1643,7 @@ export function HeroReadMe({
|
||||
}
|
||||
}}
|
||||
className={cn(
|
||||
"group/card relative p-4 lg:p-5 border-foreground/[0.1] min-h-[180px] transition-all duration-200 hover:bg-foreground/[0.02] hover:shadow-[inset_0_1px_0_0_rgba(128,128,128,0.1)] hover:z-10",
|
||||
"group/card relative p-4 lg:p-5 border-foreground/[0.15] min-h-[180px] transition-all duration-200 hover:bg-foreground/[0.02] hover:shadow-[inset_0_1px_0_0_rgba(128,128,128,0.1)] hover:z-10",
|
||||
// Bottom border: all except last; 3-col last row starts at 6
|
||||
i < 8 && "border-b",
|
||||
i >= 6 && "md:border-b-0",
|
||||
@@ -1673,16 +1673,16 @@ export function HeroReadMe({
|
||||
<polyline points="7 7 17 7 17 17" />
|
||||
</svg>
|
||||
</span>
|
||||
<div className="text-[11px] font-mono text-neutral-500 mb-2 uppercase tracking-wider transition-colors duration-200 group-hover/card:text-neutral-400 dark:group-hover/card:text-neutral-400">
|
||||
<span className="text-foreground/35 dark:text-foreground/20 mr-1.5 transition-colors duration-200 group-hover/card:text-foreground/50 dark:group-hover/card:text-foreground/30">
|
||||
<div className="text-[11px] font-mono text-neutral-500 dark:text-neutral-400 mb-2 uppercase tracking-wider transition-colors duration-200 group-hover/card:text-neutral-400 dark:group-hover/card:text-neutral-300">
|
||||
<span className="text-foreground/45 dark:text-foreground/30 mr-1.5 transition-colors duration-200 group-hover/card:text-foreground/60 dark:group-hover/card:text-foreground/40">
|
||||
{String(i + 1).padStart(2, "0")}
|
||||
</span>
|
||||
{feature.label}
|
||||
</div>
|
||||
<div className="text-[13px] font-semibold text-neutral-800 dark:text-neutral-200 leading-snug mb-1.5 transition-colors duration-200 group-hover/card:text-neutral-900 dark:group-hover/card:text-neutral-100">
|
||||
<div className="text-[13px] font-semibold text-neutral-900 dark:text-neutral-100 leading-snug mb-1.5 transition-colors duration-200 group-hover/card:text-neutral-950 dark:group-hover/card:text-white">
|
||||
{feature.headline}
|
||||
</div>
|
||||
<div className="text-[11px] text-neutral-500 leading-relaxed transition-colors duration-200 group-hover/card:text-neutral-400 dark:group-hover/card:text-neutral-400">
|
||||
<div className="text-[11px] text-neutral-500 dark:text-neutral-400 leading-relaxed transition-colors duration-200 group-hover/card:text-neutral-400 dark:group-hover/card:text-neutral-300">
|
||||
{feature.desc}
|
||||
</div>
|
||||
{"logos" in feature && feature.logos && (
|
||||
|
||||
@@ -39,7 +39,7 @@ const resourceFiles: NavFileItem[] = [
|
||||
function DropdownItem({ item }: { item: NavFileItem }) {
|
||||
return (
|
||||
<div className="group/item flex items-center gap-1.5 px-3 py-1.5 hover:bg-foreground/[0.06] transition-colors duration-150 cursor-pointer">
|
||||
<span className="font-mono text-[10px] uppercase tracking-wider text-foreground/65 dark:text-foreground/50 group-hover/item:text-foreground transition-colors duration-150 whitespace-nowrap">
|
||||
<span className="font-mono text-[10px] uppercase tracking-wider text-foreground/75 dark:text-foreground/60 group-hover/item:text-foreground transition-colors duration-150 whitespace-nowrap">
|
||||
{item.name}
|
||||
</span>
|
||||
</div>
|
||||
@@ -197,7 +197,7 @@ export function StaggeredNavFiles() {
|
||||
}
|
||||
}
|
||||
}}
|
||||
className="flex items-center justify-center px-4 py-3 text-foreground/65 dark:text-foreground/50 hover:text-foreground/80 transition-colors"
|
||||
className="flex items-center justify-center px-4 py-3 text-foreground/75 dark:text-foreground/60 hover:text-foreground/85 transition-colors"
|
||||
>
|
||||
{mobileMenuOpen ? (
|
||||
<svg
|
||||
@@ -266,10 +266,10 @@ export function StaggeredNavFiles() {
|
||||
className={`font-mono text-xs uppercase tracking-wider transition-colors duration-150 whitespace-nowrap ${
|
||||
active
|
||||
? "text-foreground"
|
||||
: "text-foreground/60 dark:text-foreground/40 group-hover/tab:text-foreground/70"
|
||||
}`}
|
||||
>
|
||||
{item.name}
|
||||
: "text-foreground/65 dark:text-foreground/50 group-hover/tab:text-foreground/75"
|
||||
}`}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
</Link>
|
||||
</motion.div>
|
||||
@@ -300,13 +300,13 @@ export function StaggeredNavFiles() {
|
||||
? "text-foreground"
|
||||
: resourcesOpen
|
||||
? "text-foreground/80"
|
||||
: "text-foreground/60 dark:text-foreground/40 group-hover/tab:text-foreground/70"
|
||||
}`}
|
||||
>
|
||||
resources
|
||||
: "text-foreground/65 dark:text-foreground/50 group-hover/tab:text-foreground/75"
|
||||
}`}
|
||||
>
|
||||
resources
|
||||
</span>
|
||||
<svg
|
||||
className={`h-2 w-2 text-foreground/50 dark:text-foreground/30 transition-transform duration-200 ${
|
||||
className={`h-2 w-2 text-foreground/55 dark:text-foreground/40 transition-transform duration-200 ${
|
||||
resourcesOpen ? "rotate-180" : ""
|
||||
}`}
|
||||
viewBox="0 0 10 6"
|
||||
@@ -352,8 +352,8 @@ export function StaggeredNavFiles() {
|
||||
href="https://github.com/better-auth/better-auth"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="p-1.5 text-foreground/50 dark:text-foreground/30 hover:text-foreground/70 transition-colors"
|
||||
aria-label="GitHub"
|
||||
className="p-1.5 text-foreground/55 dark:text-foreground/40 hover:text-foreground/75 transition-colors"
|
||||
aria-label="GitHub"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -371,8 +371,8 @@ export function StaggeredNavFiles() {
|
||||
href="https://discord.gg/better-auth"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="p-1.5 text-foreground/50 dark:text-foreground/30 hover:text-foreground/70 transition-colors"
|
||||
aria-label="Discord"
|
||||
className="p-1.5 text-foreground/55 dark:text-foreground/40 hover:text-foreground/75 transition-colors"
|
||||
aria-label="Discord"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -390,8 +390,8 @@ export function StaggeredNavFiles() {
|
||||
href="https://reddit.com/r/better_auth"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="p-1.5 text-foreground/50 dark:text-foreground/30 hover:text-foreground/70 transition-colors"
|
||||
aria-label="Reddit"
|
||||
className="p-1.5 text-foreground/55 dark:text-foreground/40 hover:text-foreground/75 transition-colors"
|
||||
aria-label="Reddit"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -411,8 +411,8 @@ export function StaggeredNavFiles() {
|
||||
href="https://x.com/better_auth"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="p-1.5 text-foreground/50 dark:text-foreground/30 hover:text-foreground/70 transition-colors"
|
||||
aria-label="X"
|
||||
className="p-1.5 text-foreground/55 dark:text-foreground/40 hover:text-foreground/75 transition-colors"
|
||||
aria-label="X"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -430,8 +430,8 @@ export function StaggeredNavFiles() {
|
||||
href="https://www.npmjs.com/package/better-auth"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="p-1.5 text-foreground/50 dark:text-foreground/30 hover:text-foreground/70 transition-colors"
|
||||
aria-label="npm"
|
||||
className="p-1.5 text-foreground/55 dark:text-foreground/40 hover:text-foreground/75 transition-colors"
|
||||
aria-label="npm"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -499,7 +499,7 @@ export function StaggeredNavFiles() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setMobileView("nav")}
|
||||
className="flex items-center gap-2 px-5 py-2.5 text-foreground/55 dark:text-foreground/35 hover:text-foreground/60 transition-colors border-b border-foreground/[0.06]"
|
||||
className="flex items-center gap-2 px-5 py-2.5 text-foreground/65 dark:text-foreground/45 hover:text-foreground/70 transition-colors border-b border-foreground/[0.06]"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -531,10 +531,10 @@ export function StaggeredNavFiles() {
|
||||
"font-medium text-sm tracking-wider",
|
||||
mobileDocSection === index
|
||||
? "text-foreground bg-foreground/3"
|
||||
: "text-foreground/65 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() =>
|
||||
setMobileDocSection((prev) =>
|
||||
: "text-foreground/70 hover:text-foreground hover:bg-foreground/3",
|
||||
)}
|
||||
onClick={() =>
|
||||
setMobileDocSection((prev) =>
|
||||
prev === index ? -1 : index,
|
||||
)
|
||||
}
|
||||
@@ -568,10 +568,10 @@ export function StaggeredNavFiles() {
|
||||
"relative flex items-center gap-2.5 px-5 py-1.5 text-[14px] transition-all duration-150",
|
||||
pathname === section.href
|
||||
? "text-foreground bg-foreground/6"
|
||||
: "text-foreground/70 dark:text-foreground/55 hover:text-foreground/85 hover:bg-foreground/3",
|
||||
)}
|
||||
>
|
||||
<span className="truncate">Overview</span>
|
||||
: "text-foreground/75 dark:text-foreground/60 hover:text-foreground/90 hover:bg-foreground/3",
|
||||
)}
|
||||
>
|
||||
<span className="truncate">Overview</span>
|
||||
</Link>
|
||||
)}
|
||||
{section.list.map((item, i) => {
|
||||
@@ -581,7 +581,7 @@ export function StaggeredNavFiles() {
|
||||
key={`sep-${item.title}-${i}`}
|
||||
className="flex flex-row items-center gap-2 mx-5 my-2"
|
||||
>
|
||||
<p className="text-[10px] text-foreground/55 dark:text-foreground/35 uppercase tracking-wider">
|
||||
<p className="text-[10px] text-foreground/65 dark:text-foreground/45 uppercase tracking-wider">
|
||||
{item.title}
|
||||
</p>
|
||||
<div className="grow h-px bg-border" />
|
||||
@@ -603,15 +603,15 @@ export function StaggeredNavFiles() {
|
||||
"relative flex items-center gap-2.5 px-5 py-1.5 text-[14px] transition-all duration-150",
|
||||
active
|
||||
? "text-foreground bg-foreground/6"
|
||||
: "text-foreground/70 dark:text-foreground/55 hover:text-foreground/85 hover:bg-foreground/3",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"min-w-5 [&>svg]:size-[14px] transition-colors duration-150",
|
||||
active
|
||||
? "text-foreground"
|
||||
: "text-foreground/70 dark:text-foreground/55",
|
||||
: "text-foreground/75 dark:text-foreground/60 hover:text-foreground/90 hover:bg-foreground/3",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"min-w-5 [&>svg]:size-[14px] transition-colors duration-150",
|
||||
active
|
||||
? "text-foreground"
|
||||
: "text-foreground/75 dark:text-foreground/60",
|
||||
)}
|
||||
>
|
||||
<item.icon className="text-foreground/75" />
|
||||
@@ -625,7 +625,7 @@ export function StaggeredNavFiles() {
|
||||
"pointer-events-none border-dashed rounded-none px-1.5 py-0 text-[9px] uppercase tracking-wider",
|
||||
active
|
||||
? "border-solid bg-foreground/10 text-foreground"
|
||||
: "text-foreground/65 dark:text-foreground/50 border-foreground/20",
|
||||
: "text-foreground/70 dark:text-foreground/55 border-foreground/25",
|
||||
)}
|
||||
variant="outline"
|
||||
>
|
||||
@@ -651,7 +651,7 @@ export function StaggeredNavFiles() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setMobileView("docs")}
|
||||
className="flex items-center gap-2 px-5 py-2.5 text-foreground/55 dark:text-foreground/35 hover:text-foreground/60 transition-colors border-b border-foreground/[0.06]"
|
||||
className="flex items-center gap-2 px-5 py-2.5 text-foreground/65 dark:text-foreground/45 hover:text-foreground/70 transition-colors border-b border-foreground/[0.06]"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -695,14 +695,14 @@ export function StaggeredNavFiles() {
|
||||
isActive(item.path || item.href) ||
|
||||
(item.href === "/docs" && isDocs)
|
||||
? "text-foreground"
|
||||
: "text-foreground/65 dark:text-foreground/50"
|
||||
}`}
|
||||
: "text-foreground/75 dark:text-foreground/60"
|
||||
}`}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
{item.external && (
|
||||
<svg
|
||||
className="h-2.5 w-2.5 text-foreground/35 dark:text-foreground/20 ml-auto"
|
||||
className="h-2.5 w-2.5 text-foreground/45 dark:text-foreground/30 ml-auto"
|
||||
viewBox="0 0 10 10"
|
||||
fill="none"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user