Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/mail/app/(routes)/settings/connections/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export default function ConnectionsPage() {
<Trash className="h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent showOverlay>
<DialogContent>
<DialogHeader>
<DialogTitle>
{m['pages.settings.connections.disconnectTitle']()}
Expand Down
2 changes: 1 addition & 1 deletion apps/mail/app/(routes)/settings/danger-zone/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function DeleteAccountDialog() {
<DialogTrigger asChild>
<Button variant="destructive">{m['pages.settings.dangerZone.deleteAccount']()}</Button>
</DialogTrigger>
<DialogContent showOverlay>
<DialogContent>
<DialogHeader>
<DialogTitle>{m['pages.settings.dangerZone.title']()}</DialogTitle>
<DialogDescription>{m['pages.settings.dangerZone.description']()}</DialogDescription>
Expand Down
22 changes: 17 additions & 5 deletions apps/mail/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
--subtleBlack: #1F1F1F;
--skyBlue: #0066FF;
--shinyGray: #A1A1A1;
--sidebar: hsl(0 0% 98%);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Unify the sidebar token — single source of truth.

You introduced --sidebar but the theme still maps to --sidebar-background. Wire it up or delete the new var to avoid dead config.

Apply this diff to use the new token across the theme:

@@
-  --sidebar: hsl(0 0% 98%);
+  --sidebar: hsl(0 0% 98%);
@@
-  --sidebar: hsl(240 5.9% 10%);
+  --sidebar: hsl(240 5.9% 10%);
@@
-  --color-sidebar: var(--sidebar-background);
+  --color-sidebar: var(--sidebar);

If other files still consume --sidebar-background, keep both and plan a follow-up sweep.

Also applies to: 118-118, 166-174

🤖 Prompt for AI Agents
In apps/mail/app/globals.css around lines 80 (and also check 118 and 166-174),
you added a new CSS variable --sidebar but the rest of the theme still uses
--sidebar-background, creating a dead/duplicate token; either wire the theme to
use --sidebar everywhere or remove --sidebar. Fix by updating all occurrences of
--sidebar-background in this file (and any other project files) to reference
--sidebar (or add --sidebar-background as an alias that references --sidebar) so
there is a single source of truth, and if you choose to keep both add a TODO to
sweep other files later.

}

.dark {
Expand Down Expand Up @@ -114,6 +115,7 @@
--sidebar-border: hsl(240 3.7% 15.9%);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
--panel: hsl(240 3.7% 10.2%);
--sidebar: hsl(240 5.9% 10%);
}

@theme inline {
Expand All @@ -137,14 +139,14 @@
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);

/* Chart colors */
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);

/* Static colors */
--color-darkBackground: var(--darkBackground);
--color-lightBackground: var(--lightBackground);
Expand All @@ -160,7 +162,7 @@
--color-subtleBlack: var(--subtleBlack);
--color-skyBlue: var(--skyBlue);
--color-shinyGray: var(--shinyGray);

/* sidebar colors */
--color-sidebar: var(--sidebar-background);
--color-sidebar-foreground: var(--sidebar-foreground);
Expand All @@ -170,7 +172,7 @@
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);

/* Border radius */
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
Expand Down Expand Up @@ -234,7 +236,6 @@
--animate-blink: blink 0.8s ease-in-out infinite;
}


/* Add scrollbar styling */
@utility style-scrollbar {
@apply scrollbar scrollbar-w-0 scrollbar-thumb-accent/40 scrollbar-track-transparent hover:scrollbar-thumb-accent scrollbar-thumb-rounded-full;
Expand Down Expand Up @@ -473,3 +474,14 @@
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
/*
---break---
*/
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
Comment on lines +480 to +487
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Kill the duplication: two base layers fight; last one wins.

You now have two @layer base blocks for * and body. This creates conflicting cascade. Pick one baseline and delete the other. If the intent is the simplified body, remove the earlier block.

Apply this diff to consolidate:

@@
-@layer base {
-  * {
-    @apply border-border;
-  }
-  body {
-    @apply bg-background text-foreground font-sans overscroll-none style-scrollbar;
-  }
-}

Optionally, if you still want the scrollbar styling and font family, fold them into the final block instead:

 @layer base {
   * {
-    @apply border-border outline-ring/50;
+    @apply border-border outline-ring/50;
   }
   body {
-    @apply bg-background text-foreground;
+    @apply bg-background text-foreground font-sans style-scrollbar;
+    /* If you intended to drop overscroll-none, omit it; else add it back explicitly */
+    /* @apply overscroll-none; */
   }
 }

Also sanity-check outline-ring/50 on * — global outline color is fine, but unnecessary work. Consider scoping to focusable elements if perf or specificity becomes noisy.


🏁 Script executed:

#!/bin/bash
echo "Occurrences of '@layer base' in apps/mail/app/globals.css:"
rg -n '@layer base' apps/mail/app/globals.css
echo ""
echo "Snippets around each occurrence:"
for L in $(rg -n '@layer base' apps/mail/app/globals.css | cut -d: -f1); do
  echo "=== Snippet around line $L ==="
  sed -n "$((L-5)),$((L+10))p" apps/mail/app/globals.css
  echo ""
done

Length of output: 1199


Consolidate duplicate @layer base blocks (lines 278 & 480). Only the last block wins, so remove the one at 278 or merge its unique body styles (font-sans overscroll-none style-scrollbar) into the block at 480. Consider scoping outline-ring/50 to focusable elements for better performance.

🤖 Prompt for AI Agents
In apps/mail/app/globals.css around lines 480 (and duplicate at 278), there are
two @layer base blocks where only the last one wins; remove the earlier block at
line 278 or merge its unique declarations (font-sans, overscroll-none,
style-scrollbar) into the block at 480 so all base styles are consolidated; also
scope the universal outline-rule (outline-ring/50) to focusable elements (e.g.,
links, buttons, inputs, textareas, selects, and elements using tabindex) instead
of applying to * to reduce styling cost and avoid unintended outlines.

2 changes: 1 addition & 1 deletion apps/mail/components/connection/add.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const AddConnectionDialog = ({
</Button>
)}
</DialogTrigger>
<DialogContent showOverlay={true}>
<DialogContent>
<DialogHeader>
<DialogTitle>{m['pages.settings.connections.connectEmail']()}</DialogTitle>
<DialogDescription>
Expand Down
20 changes: 10 additions & 10 deletions apps/mail/components/context/command-palette-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { format, subDays } from 'date-fns';
import { VisuallyHidden } from 'radix-ui';
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
import { m } from '@/paraglide/messages';
import { Pencil2 } from '../icons/icons';
import { Button } from '../ui/button';
Expand All @@ -65,7 +65,7 @@ type CommandPaletteContext = {
clearAllFilters: () => void;
};

interface CommandItem {
interface CommandItemType {
title: string;
icon?: ComponentType<{ size?: number; strokeWidth?: number; className?: string }>;
url?: string;
Expand Down Expand Up @@ -644,13 +644,13 @@ export function CommandPalette({ children }: { children: React.ReactNode }) {
const allCommands = useMemo(() => {
type CommandGroup = {
group: string;
items: CommandItem[];
items: CommandItemType[];
};

const searchCommands: CommandItem[] = [];
const mailCommands: CommandItem[] = [];
const settingsCommands: CommandItem[] = [];
const otherCommands: Record<string, CommandItem[]> = {};
const searchCommands: CommandItemType[] = [];
const mailCommands: CommandItemType[] = [];
const settingsCommands: CommandItemType[] = [];
const otherCommands: Record<string, CommandItemType[]> = {};

mailCommands.push({
title: 'Compose Email',
Expand Down Expand Up @@ -713,7 +713,7 @@ export function CommandPalette({ children }: { children: React.ReactNode }) {
section?.sections.forEach((group) => {
group.items.forEach((navItem) => {
if (navItem.disabled) return;
const item: CommandItem = {
const item: CommandItemType = {
title: navItem.title,
icon: navItem.icon,
url: navItem.url,
Expand Down Expand Up @@ -1885,10 +1885,10 @@ export function CommandPalette({ children }: { children: React.ReactNode }) {
setOpen(isOpen ? 'true' : null);
}}
>
<VisuallyHidden.VisuallyHidden>
<VisuallyHidden>
<DialogTitle>{m['common.commandPalette.title']()}</DialogTitle>
<DialogDescription>{m['common.commandPalette.description']()}</DialogDescription>
</VisuallyHidden.VisuallyHidden>
</VisuallyHidden>
{renderView()}
</CommandDialog>
{children}
Expand Down
2 changes: 1 addition & 1 deletion apps/mail/components/context/label-sidebar-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function LabelSidebarContextMenu({ children, labelId, hide }: LabelSideba
</ContextMenu>

<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<DialogContent showOverlay={true}>
<DialogContent>
<DialogHeader>
<DialogTitle>{m['common.labels.deleteLabelConfirm']()}</DialogTitle>
<DialogDescription>
Expand Down
4 changes: 2 additions & 2 deletions apps/mail/components/create/email-composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ export function EmailComposer({
</div>

<Dialog open={showLeaveConfirmation} onOpenChange={setShowLeaveConfirmation}>
<DialogContent showOverlay className="z-99999 sm:max-w-[425px]">
<DialogContent className="z-99999 sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Discard message?</DialogTitle>
<DialogDescription>
Expand All @@ -1025,7 +1025,7 @@ export function EmailComposer({
</Dialog>

<Dialog open={showAttachmentWarning} onOpenChange={setShowAttachmentWarning}>
<DialogContent showOverlay className="z-99999 sm:max-w-[425px]">
<DialogContent className="z-99999 sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Attachment Warning</DialogTitle>
<DialogDescription>
Expand Down
2 changes: 1 addition & 1 deletion apps/mail/components/create/template-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ const TemplateButtonComponent: React.FC<TemplateButtonProps> = ({
</DropdownMenu>

<Dialog open={saveDialogOpen} onOpenChange={setSaveDialogOpen}>
<DialogContent showOverlay>
<DialogContent>
<DialogHeader>
<DialogTitle>Save as Template</DialogTitle>
</DialogHeader>
Expand Down
2 changes: 1 addition & 1 deletion apps/mail/components/labels/label-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export function LabelDialog({
return (
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
{trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
<DialogContent showOverlay={true}>
<DialogContent>
<DialogHeader>
<DialogTitle>
{editingLabel ? m['common.labels.editLabel']() : m['common.mail.createNewLabel']()}
Expand Down
2 changes: 1 addition & 1 deletion apps/mail/components/magicui/file-tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { ScrollArea } from '@/components/ui/scroll-area';
import { Button } from '@/components/ui/button';
import { FileIcon } from 'lucide-react';
import { Accordion } from 'radix-ui';
import * as Accordion from '@radix-ui/react-accordion';
import { cn } from '@/lib/utils';

type TreeViewElement = {
Expand Down
4 changes: 2 additions & 2 deletions apps/mail/components/mail/mail-display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ const MoreAboutPerson = ({

return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent showOverlay>
<DialogContent>
<DialogHeader>
<DialogTitle>More about {cleanNameDisplay(person.name)}</DialogTitle>
</DialogHeader>
Expand Down Expand Up @@ -634,7 +634,7 @@ const MoreAboutQuery = ({

return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent showOverlay>
<DialogContent>
<DialogHeader>
<DialogTitle>Search Results</DialogTitle>
</DialogHeader>
Expand Down
5 changes: 1 addition & 4 deletions apps/mail/components/onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ export function OnboardingDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogTitle></DialogTitle>
<DialogContent
showOverlay
className="bg-panelLight mx-auto w-full max-w-[90%] rounded-xl border p-0 sm:max-w-[690px] dark:bg-[#111111]"
>
<DialogContent className="bg-panelLight mx-auto w-full max-w-[90%] rounded-xl border p-0 sm:max-w-[690px] dark:bg-[#111111]">
<div className="flex flex-col gap-4 p-4">
Comment on lines +75 to 76
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Place DialogTitle inside DialogContent (or add a header) for proper a11y semantics.

Right now DialogTitle sits outside Content. Move it inside so aria attributes resolve correctly.

-    <Dialog open={open} onOpenChange={onOpenChange}>
-      <DialogTitle></DialogTitle>
-      <DialogContent className="bg-panelLight mx-auto w-full max-w-[90%] rounded-xl border p-0 sm:max-w-[690px] dark:bg-[#111111]">
+    <Dialog open={open} onOpenChange={onOpenChange}>
+      <DialogContent className="bg-panelLight mx-auto w-full max-w-[90%] rounded-xl border p-0 sm:max-w-[690px] dark:bg-[#111111]">
+        {/* Optional header for a11y */}
+        {/* <DialogHeader><DialogTitle>Welcome to Zero Email</DialogTitle></DialogHeader> */}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<DialogContent className="bg-panelLight mx-auto w-full max-w-[90%] rounded-xl border p-0 sm:max-w-[690px] dark:bg-[#111111]">
<div className="flex flex-col gap-4 p-4">
<Dialog open={open} onOpenChange={onOpenChange}>
{/* Removed the standalone <DialogTitle> so that it lives inside the content for proper aria semantics */}
<DialogContent className="bg-panelLight mx-auto w-full max-w-[90%] rounded-xl border p-0 sm:max-w-[690px] dark:bg-[#111111]">
{/* Optional header for a11y */}
{/* <DialogHeader>
<DialogTitle>Welcome to Zero Email</DialogTitle>
</DialogHeader> */}
<div className="flex flex-col gap-4 p-4">
{/* …the rest of your onboarding UI… */}
</div>
</DialogContent>
</Dialog>
🤖 Prompt for AI Agents
In apps/mail/components/onboarding.tsx around lines 75-76, DialogTitle is
currently placed outside of DialogContent which breaks accessibility semantics;
move the existing DialogTitle element so it is nested directly inside the
DialogContent (or add a header wrapper inside DialogContent and place
DialogTitle there) ensuring the title is rendered before the main content and
that aria-labelledby/aria-describedby references resolve correctly; update any
classNames/layout as needed so visual layout is unchanged after moving the
title.

{steps[currentStep] && steps[currentStep].video && (
<div className="relative flex items-center justify-center">
Expand Down
2 changes: 1 addition & 1 deletion apps/mail/components/responsive-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
DialogTitle,
} from '@/components/ui/dialog';
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';
import { VisuallyHidden } from 'radix-ui';
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
import { type ReactElement } from 'react';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Type import nit — import ReactNode directly.

Cleaner and consistent with TS strict prefs.

-import { type ReactElement } from 'react';
+import type { ReactElement, ReactNode } from 'react';

 ...

 type ResponsiveModalProps = {
-  children: React.ReactNode;
+  children: ReactNode;
   open: boolean;
   onOpenChange: (open: boolean) => void;
 };

Also applies to: 13-17

🤖 Prompt for AI Agents
In apps/mail/components/responsive-modal.tsx around line 10 (and similarly lines
13–17), the import uses "type ReactElement"; change the import to pull ReactNode
instead (e.g. import { type ReactNode } from 'react') and update any related
prop/type annotations that currently reference ReactElement to use ReactNode for
consistency with TS strict preferences.

// import { useMedia } from 'react-use';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

isDesktop hardcoded to true — mobile Drawer path is dead. Intended?

If not deliberate, re-enable a media query so this actually responds. Speed is key; correctness too.

-// import { useMedia } from 'react-use';
+import { useMedia } from 'react-use';

 ...

-  const isDesktop = true;
+  const isDesktop = useMedia('(min-width: 768px)', true);

Verify no hydration warnings and that Drawer renders below 768px.

Also applies to: 24-27

🤖 Prompt for AI Agents
In apps/mail/components/responsive-modal.tsx around line 11 (and also affecting
lines 24–27) you hardcoded isDesktop = true which disables the mobile Drawer —
re-enable a media query (e.g., import useMedia from 'react-use' and call
useMedia('(min-width: 768px)')) to derive isDesktop; to avoid hydration
warnings, compute isDesktop only on the client (use a mounted flag with
useEffect or useMedia's initialValue tied to typeof window check) or render a
placeholder until mounted so server vs client markup matches; finally ensure the
Drawer branch is returned when isDesktop is false (width < 768px) so the Drawer
renders on mobile.


Expand Down
2 changes: 1 addition & 1 deletion apps/mail/components/setup-phone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const SetupInboxDialog = () => {
<OldPhone className="fill-iconLight dark:fill-iconDark h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent showOverlay>
<DialogContent>
<DialogTitle>Set up your Inbox assistant</DialogTitle>
<DialogDescription>
<span className={showOtpInput ? 'hidden' : 'block'}>
Expand Down
8 changes: 5 additions & 3 deletions apps/mail/components/ui/accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Accordion as AccordionPrimitive } from 'radix-ui';
'use client';

import * as AccordionPrimitive from '@radix-ui/react-accordion';
import { ChevronDown } from 'lucide-react';
import * as React from 'react';

Expand All @@ -22,7 +24,7 @@ const AccordionTrigger = React.forwardRef<
<AccordionPrimitive.Trigger
ref={ref}
className={cn(
'flex flex-1 items-center justify-between py-4 font-medium hover:underline [&[data-state=open]>svg]:rotate-180',
'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
className,
)}
{...props}
Expand All @@ -40,7 +42,7 @@ const AccordionContent = React.forwardRef<
>(({ className, children, ...props }, ref) => (
<AccordionPrimitive.Content
ref={ref}
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm transition-all"
{...props}
>
<div className={cn('pb-4 pt-0', className)}>{children}</div>
Expand Down
3 changes: 2 additions & 1 deletion apps/mail/components/ui/alert.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
import * as React from 'react';

import { cn } from '@/lib/utils';

const alertVariants = cva(
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
{
Expand Down
14 changes: 10 additions & 4 deletions apps/mail/components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Avatar as AvatarPrimitive } from 'radix-ui';
import { cn } from '@/lib/utils';
'use client';

import * as AvatarPrimitive from '@radix-ui/react-avatar';
import * as React from 'react';

import { cn } from '@/lib/utils';

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-md', className)}
className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
{...props}
/>
));
Expand All @@ -32,7 +35,10 @@ const AvatarFallback = React.forwardRef<
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn('bg-muted flex h-full w-full items-center justify-center rounded-md', className)}
className={cn(
'bg-muted flex h-full w-full items-center justify-center rounded-full',
className,
)}
{...props}
/>
));
Expand Down
9 changes: 2 additions & 7 deletions apps/mail/components/ui/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ import * as React from 'react';
import { cn } from '@/lib/utils';

const badgeVariants = cva(
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
{
Comment on lines +7 to 8
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

🛠️ Refactor suggestion

Replace focus:outline-none → focus-visible:outline-hidden and wrap to ≤100 chars.
Tracks our Tailwind rename policy and line-length rule.

-  'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
+  'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold',
+  'transition-colors focus-visible:outline-hidden focus-visible:ring-2',
+  'focus-visible:ring-ring focus-visible:ring-offset-2',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
{
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold',
'transition-colors focus-visible:outline-hidden focus-visible:ring-2',
'focus-visible:ring-ring focus-visible:ring-offset-2',
{
🤖 Prompt for AI Agents
In apps/mail/components/ui/badge.tsx around lines 7 to 8, replace the Tailwind
class token "focus:outline-none" with "focus-visible:outline-hidden" to follow
the Tailwind rename policy, and reflow the class string so no line exceeds 100
characters (wrap the array elements or object entries appropriately while
preserving existing spacing and commas).

variants: {
variant: {
default: 'border-transparent bg-primary text-primary-foreground ',
default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
secondary:
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
destructive:
'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
outline: 'text-foreground',
important: 'border-0 text-amber-700 dark:text-amber-500 ',
promotions: 'border-0 text-red-700 dark:text-red-500 ',
personal: 'border-0 text-green-700 dark:text-green-500 ',
updates: 'border-0 text-purple-700 dark:text-purple-500 ',
forums: 'border-transparent text-blue-500 dark:text-blue-400',
},
},
defaultVariants: {
Expand Down
Loading
Loading