diff --git a/app/globals.css b/app/globals.css index 192394a..b75fbc3 100644 --- a/app/globals.css +++ b/app/globals.css @@ -51,6 +51,10 @@ --color-tier-copper: var(--tier-copper); --color-border: var(--border); --color-input: var(--input); + --color-control: var(--control); + --color-control-hover: var(--control-hover); + --color-control-border: var(--control-border); + --color-control-border-hover: var(--control-border-hover); --color-ring: var(--ring); --color-chart-1: var(--chart-1); --color-chart-2: var(--chart-2); @@ -104,6 +108,10 @@ --tier-copper: oklch(0.65 0.12 55); --border: oklch(0.96 0.01 88 / 12%); --input: oklch(0.96 0.01 88 / 16%); + --control: oklch(0.26 0.02 274); + --control-hover: oklch(0.32 0.025 274); + --control-border: oklch(0.52 0.02 274); + --control-border-hover: oklch(0.64 0.02 274); --ring: oklch(0.79 0.14 78); --chart-1: oklch(0.76 0.16 76); --chart-2: oklch(0.7 0.14 255); @@ -156,11 +164,78 @@ text-rendering: optimizeLegibility; } + button:not(:disabled):not([aria-disabled="true"]):not([data-disabled]), + [role="button"]:not(:disabled):not([aria-disabled="true"]):not([data-disabled]) { + cursor: pointer; + } + + button:disabled, + [role="button"][aria-disabled="true"], + button[data-disabled] { + cursor: not-allowed; + } + ::selection { background: color-mix(in oklch, var(--primary) 30%, transparent); } } +/* Keep header actions understated while page controls use visible surfaces. */ +[data-slot="header-shell"] [data-variant="ghost"] { + border-color: transparent; + background: transparent; + color: inherit; +} + +[data-slot="header-shell"] [data-variant="ghost"]:hover { + background: color-mix(in oklch, var(--muted) 50%, transparent); + color: var(--foreground); +} + +[data-slot="header-shell"] [data-variant="ghost"][aria-expanded="true"] { + background: var(--muted); + color: var(--foreground); +} + +[data-slot="header-shell"] [data-variant="outline"] { + border-color: var(--input); + background: color-mix(in oklch, var(--input) 30%, transparent); + color: inherit; +} + +[data-slot="header-shell"] [data-variant="outline"]:hover { + background: color-mix(in oklch, var(--input) 50%, transparent); + color: var(--foreground); +} + +[data-slot="header-shell"] [data-variant="outline"][aria-expanded="true"] { + background: var(--muted); + color: var(--foreground); +} + +[data-slot="header-shell"] [data-variant="secondary"] { + border-color: transparent; + background: var(--secondary); + color: var(--secondary-foreground); +} + +[data-slot="header-shell"] [data-variant="secondary"]:hover { + background: color-mix(in oklch, var(--secondary), var(--foreground) 5%); +} + +[data-slot="header-shell"] [data-variant="link"] { + text-decoration-line: none; +} + +[data-slot="header-shell"] [data-variant="link"]:hover { + text-decoration-line: underline; + text-decoration-thickness: auto; +} + +[data-slot="header-shell"] [data-variant]:focus-visible { + border-color: var(--ring); +} + .extra-sheet-grid { --background-color: var(--background); --text-color: var(--foreground); @@ -284,6 +359,7 @@ @media (pointer: coarse) { [data-slot="button"], [data-slot="toggle-group-item"], + [data-slot="tabs-trigger"], [data-slot="select-trigger"], [data-slot="input"], [data-slot="input-group"] { diff --git a/components/header-shell.tsx b/components/header-shell.tsx index 73d35ec..f1529cc 100644 --- a/components/header-shell.tsx +++ b/components/header-shell.tsx @@ -11,7 +11,7 @@ export function HeaderShell({ homeHref, homeLabel, children }: { children: ReactNode; }) { return ( -
+
( {index > 0 ?
- {guide.name} + + {guide.name} + {guide.overview} @@ -305,7 +309,7 @@ function GuideToggleFilter({
{options.map((option) => ( - + {optionIcon?.(option)}{showLabels ? optionLabels[option] ?? option : optionText?.(option)} ))} diff --git a/components/ui/button.tsx b/components/ui/button.tsx index b033601..33c7ee1 100644 --- a/components/ui/button.tsx +++ b/components/ui/button.tsx @@ -4,20 +4,20 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" const buttonVariants = cva( - "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "group/button inline-flex shrink-0 items-center justify-center rounded-lg border bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { variants: { variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/80", + default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", outline: - "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50", + "border-control-border bg-control text-foreground hover:border-control-border-hover hover:bg-control-hover aria-expanded:border-primary aria-expanded:bg-primary/15 aria-expanded:text-primary aria-[current=page]:border-primary aria-[current=page]:bg-primary/15 aria-[current=page]:text-primary", secondary: - "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", + "border-control-border bg-control text-secondary-foreground hover:border-control-border-hover hover:bg-control-hover aria-expanded:border-primary aria-expanded:bg-primary/15 aria-expanded:text-primary", ghost: - "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50", + "border-control-border bg-control text-foreground hover:border-control-border-hover hover:bg-control-hover aria-expanded:border-primary aria-expanded:bg-primary/15 aria-expanded:text-primary aria-[current=page]:border-primary aria-[current=page]:bg-primary/15 aria-[current=page]:text-primary", destructive: - "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40", - link: "text-primary underline-offset-4 hover:underline", + "border-destructive bg-destructive/20 text-destructive hover:bg-destructive/30 focus-visible:border-destructive focus-visible:ring-destructive/40", + link: "border-transparent text-primary underline underline-offset-4 hover:decoration-2", }, size: { default: @@ -49,6 +49,7 @@ function Button({ return ( diff --git a/components/ui/select.tsx b/components/ui/select.tsx index e8021f5..9394a0c 100644 --- a/components/ui/select.tsx +++ b/components/ui/select.tsx @@ -41,7 +41,7 @@ function SelectTrigger({ data-slot="select-trigger" data-size={size} className={cn( - "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-control-border bg-control text-foreground hover:border-control-border-hover hover:bg-control-hover aria-expanded:border-primary aria-expanded:bg-primary/15 py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className )} {...props} diff --git a/components/ui/tabs.tsx b/components/ui/tabs.tsx index 8ee8054..1fe34c1 100644 --- a/components/ui/tabs.tsx +++ b/components/ui/tabs.tsx @@ -24,11 +24,11 @@ function Tabs({ } const tabsListVariants = cva( - "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none", + "group/tabs-list inline-flex w-fit items-center justify-center gap-1 rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:min-h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none", { variants: { variant: { - default: "bg-muted", + default: "border border-border bg-card", line: "gap-1 bg-transparent", }, }, @@ -58,10 +58,9 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {