fix: Harmonize rings and hover states

This commit is contained in:
Dries Augustyns
2026-04-24 16:01:18 +02:00
parent 6f31fa2503
commit f40cc86cec
34 changed files with 177 additions and 219 deletions
+1 -1
View File
@@ -353,7 +353,7 @@ export const ActivityItem = memo(function ActivityItem({activity, isUpcoming = f
<div className={`flex items-start gap-4 ${isUpcoming ? 'opacity-80' : ''}`}>
{/* Icon */}
<div
className={`h-10 w-10 rounded-lg ${config.bgColor} flex items-center justify-center flex-shrink-0 ${isUpcoming ? 'ring-2 ring-offset-2 ring-neutral-300' : ''}`}
className={`h-10 w-10 rounded-lg ${config.bgColor} flex items-center justify-center flex-shrink-0 ${isUpcoming ? 'border-2 border-dashed border-neutral-300' : ''}`}
>
<Icon className={`h-5 w-5 ${config.color}`} />
</div>
+1 -1
View File
@@ -62,7 +62,7 @@ export function ContactPicker({
type="button"
role="combobox"
aria-expanded={open}
className="flex h-10 w-full items-center justify-between rounded-md border border-neutral-200 bg-white px-3 py-2 text-sm text-neutral-500 hover:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:ring-offset-0 transition-colors"
className="flex h-10 w-full items-center justify-between rounded-md border border-neutral-200 bg-white px-3 py-2 text-sm text-neutral-500 hover:border-neutral-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 transition-colors"
>
<span>{placeholder}</span>
<ChevronsUpDown className="h-4 w-4 opacity-40 shrink-0" />
+9 -9
View File
@@ -169,7 +169,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
<div className="relative" ref={projectMenuRef}>
<button
onClick={handleToggleProjectMenu}
className="w-full flex items-center justify-between px-3 py-2 text-sm rounded-lg hover:bg-neutral-50 transition-colors"
className="w-full flex items-center justify-between px-3 py-2 text-sm rounded-lg hover:bg-neutral-50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<div className="flex items-center gap-2 flex-1 min-w-0">
<div className="h-8 w-8 rounded-lg bg-neutral-900 text-white flex items-center justify-center text-xs font-medium flex-shrink-0">
@@ -194,7 +194,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
setActiveProject(project);
setShowProjectMenu(false);
}}
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors whitespace-nowrap"
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors whitespace-nowrap focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<div className="h-6 w-6 rounded-md bg-neutral-900 text-white flex items-center justify-center text-xs font-medium flex-shrink-0">
{project.name.charAt(0).toUpperCase()}
@@ -209,7 +209,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
<Link
href="/projects/create"
onClick={() => setShowProjectMenu(false)}
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors text-neutral-700 whitespace-nowrap"
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors text-neutral-700 whitespace-nowrap focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<Plus className="h-4 w-4" />
<span>Create project</span>
@@ -238,7 +238,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
key={item.name}
href={item.href}
onClick={() => setShowMobileMenu(false)}
className={`flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors ${
className={`flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${
isActive ? 'bg-neutral-100 text-neutral-900' : 'text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900'
}`}
>
@@ -258,7 +258,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
href={WIKI_URI}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900"
className="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<BookOpen className="h-5 w-5" />
Documentation
@@ -267,7 +267,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
<Link
href="/settings"
onClick={() => setShowMobileMenu(false)}
className={`flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors ${
className={`flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${
router.pathname.startsWith('/settings')
? 'bg-neutral-100 text-neutral-900'
: 'text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900'
@@ -280,7 +280,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
<div className="relative" ref={userMenuRef}>
<button
onClick={handleToggleUserMenu}
className="w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900 transition-colors"
className="w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<div className="h-5 w-5 rounded-full bg-neutral-900 text-white flex items-center justify-center text-[10px] font-semibold flex-shrink-0">
{user?.email?.charAt(0).toUpperCase() ?? '?'}
@@ -299,7 +299,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
</div>
<button
onClick={handleLogoutClick}
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors text-red-600"
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors text-red-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<LogOut className="h-4 w-4" />
<span>Log out</span>
@@ -340,7 +340,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
<div className="lg:hidden h-16 bg-white border-b border-neutral-200 flex items-center px-4">
<button
onClick={() => setShowMobileMenu(true)}
className="p-2 rounded-lg hover:bg-neutral-100 transition-colors"
className="p-2 rounded-lg hover:bg-neutral-100 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
aria-label="Open menu"
>
<Menu className="h-6 w-6 text-neutral-900" />
@@ -894,8 +894,8 @@ export function EmailEditor({value, onChange, placeholder, subject, from, replyT
border: 1px solid #e5e7eb;
border-radius: 8px;
box-shadow:
0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
0 4px 6px -1px rgba(0, 0, 0, 0.07),
0 2px 4px -1px rgba(0, 0, 0, 0.04);
padding: 4px;
max-height: 320px;
overflow-y: auto;
@@ -427,7 +427,7 @@ export function Toolbar({editor, onInsertVariable, onInsertImage, canUploadImage
</Button>
{showColorPicker && (
<div
className="absolute top-10 left-0 bg-white border border-neutral-200 rounded-lg shadow-lg p-3 z-50 max-h-96 overflow-y-auto"
className="absolute top-10 left-0 bg-white border border-neutral-200 rounded-lg shadow-md p-3 z-50 max-h-96 overflow-y-auto"
style={{width: '280px'}}
>
{/* Custom color input */}
@@ -483,7 +483,7 @@ export function Toolbar({editor, onInsertVariable, onInsertImage, canUploadImage
>
{selectedColor === color && (
<div className="absolute inset-0 flex items-center justify-center">
<div className="w-2 h-2 rounded-full bg-white shadow-lg" />
<div className="w-2 h-2 rounded-full bg-white shadow-sm" />
</div>
)}
</button>
@@ -511,7 +511,7 @@ export function Toolbar({editor, onInsertVariable, onInsertImage, canUploadImage
<Link className="h-4 w-4" />
</Button>
{showLinkInput && (
<div className="absolute top-10 right-0 bg-white border border-neutral-200 rounded-lg shadow-lg p-2 z-50 min-w-max">
<div className="absolute top-10 right-0 bg-white border border-neutral-200 rounded-lg shadow-md p-2 z-50 min-w-max">
<div className="flex gap-2 mb-2">
<input
type="url"
+12 -14
View File
@@ -36,22 +36,22 @@ function HelpResources() {
<div className="mt-4 pt-4 border-t border-neutral-200">
<p className="text-xs font-medium text-neutral-500 mb-3">Need help?</p>
<div className="flex flex-col sm:flex-row gap-2">
<Link href={WIKI_URI} target="_blank" className="flex-1">
<Button variant="outline" size="sm" className="w-full">
<Button asChild variant="outline" size="sm" className="flex-1">
<Link href={WIKI_URI} target="_blank">
<BookOpen className="h-3.5 w-3.5" />
Documentation
</Button>
</Link>
<Link href={`${LANDING_URI}/discord`} target="_blank" className="flex-1">
<Button variant="outline" size="sm" className="w-full">
</Link>
</Button>
<Button asChild variant="outline" size="sm" className="flex-1">
<Link href={`${LANDING_URI}/discord`} target="_blank">
<MessageCircle className="h-3.5 w-3.5" />
Join Discord
</Button>
</Link>
</Link>
</Button>
<motion.button
onClick={copyEmail}
whileTap={{scale: 0.97}}
className="flex-1 relative flex items-center justify-center gap-1.5 h-9 rounded-md border border-neutral-200 bg-white px-3 text-sm font-medium text-neutral-700 overflow-hidden transition-colors hover:bg-neutral-50 hover:text-neutral-900 hover:border-neutral-300"
className="flex-1 relative flex items-center justify-center gap-1.5 h-9 rounded-md border border-neutral-200 bg-white px-3 text-xs font-medium text-neutral-700 overflow-hidden transition-colors hover:bg-neutral-50 hover:text-neutral-900 hover:border-neutral-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<AnimatePresence mode="wait" initial={false}>
{copied ? (
@@ -274,11 +274,9 @@ export function QuickStart({setupState, isLoading}: QuickStartProps) {
</div>
<p className="text-xs text-neutral-600 leading-relaxed">{step.description}</p>
</div>
<Link href={step.link} className="flex-shrink-0">
<Button size="sm" variant={step.isCompleted ? 'outline' : 'default'}>
{step.linkText}
</Button>
</Link>
<Button asChild size="sm" variant={step.isCompleted ? 'outline' : 'default'} className="flex-shrink-0">
<Link href={step.link}>{step.linkText}</Link>
</Button>
</div>
);
})}
@@ -33,11 +33,9 @@ export function SecurityWarningBanner({status}: SecurityWarningBannerProps) {
: 'Your bounce or complaint rates are approaching limits. Review your contact lists and remove invalid addresses to maintain good standing.'}
</p>
</div>
<Link href="/settings?tab=security">
<Button size="sm" variant="outline" className="w-full sm:w-auto flex-shrink-0">
View Details
</Button>
</Link>
<Button asChild size="sm" variant="outline" className="w-full sm:w-auto flex-shrink-0">
<Link href="/settings?tab=security">View Details</Link>
</Button>
</AlertDescription>
</Alert>
);
@@ -196,7 +196,7 @@ export function OnboardingBanner() {
const Icon = step.icon;
const isCurrent = step.id === currentStepId;
const base =
'group relative inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-xs font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900 focus-visible:ring-offset-2';
'group relative inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-xs font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2';
const variant = step.done
? 'border-green-200 bg-green-50 text-green-900 hover:border-green-300'
: isCurrent