diff --git a/frontend/src/components/AddToPlaylist.tsx b/frontend/src/components/AddToPlaylist.tsx
index 9b360c48..f1139049 100644
--- a/frontend/src/components/AddToPlaylist.tsx
+++ b/frontend/src/components/AddToPlaylist.tsx
@@ -2,7 +2,8 @@ import { useLayoutEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { qk } from "../lib/queryKeys";
-import { Check, ListPlus, Plus, Youtube } from "lucide-react";
+import { ListPlus, Plus, Youtube } from "lucide-react";
+import { MenuCheck } from "./ui/MenuCheck";
import { api, type Playlist } from "../lib/api";
import { notifyActionError } from "../lib/actionErrors";
import { useScrollFade } from "../lib/useScrollFade";
@@ -177,13 +178,7 @@ function MembershipPanel({
label={playlistName(pl, t)}
className="w-full flex items-center gap-2 text-sm px-1.5 py-1.5 rounded-lg text-fg outline-hidden transition"
>
-
- {pl.has_video && }
-
+
{playlistName(pl, t)}
{(pl.source === "youtube" || pl.yt_playlist_id) && (
diff --git a/frontend/src/components/ChannelTags.tsx b/frontend/src/components/ChannelTags.tsx
index 75a57f78..5ef4023d 100644
--- a/frontend/src/components/ChannelTags.tsx
+++ b/frontend/src/components/ChannelTags.tsx
@@ -1,5 +1,6 @@
import { useRef, useState } from "react";
-import { Check, Plus, Sparkles } from "lucide-react";
+import { Plus, Sparkles } from "lucide-react";
+import { MenuCheck } from "./ui/MenuCheck";
import { useTranslation } from "react-i18next";
import { type Tag } from "../lib/api";
import { PopoverSurface, PopoverItem } from "./ui/AnchoredPopover";
@@ -232,13 +233,7 @@ function TagEditorMenu({
on ? "text-fg" : "text-muted"
}`}
>
-
- {on && }
-
+
{tg.name}
);
diff --git a/frontend/src/components/DateFilterSelect.tsx b/frontend/src/components/DateFilterSelect.tsx
index 5f082f55..145a2d2f 100644
--- a/frontend/src/components/DateFilterSelect.tsx
+++ b/frontend/src/components/DateFilterSelect.tsx
@@ -1,6 +1,7 @@
import { useLayoutEffect, useState } from "react";
import { useTranslation } from "react-i18next";
-import { CalendarDays, Check } from "lucide-react";
+import { CalendarDays } from "lucide-react";
+import { MenuCheck } from "./ui/MenuCheck";
import { PopoverItem, PopoverSurface } from "./ui/AnchoredPopover";
import { useAnchoredPopover } from "./ui/anchoredPopoverHooks";
import { type FeedFilters } from "../lib/api";
@@ -132,7 +133,7 @@ export default function DateFilterSelect({
on ? "text-fg" : "text-muted"
}`}
>
-
+
{o.label}
);
diff --git a/frontend/src/components/LanguageSwitcher.tsx b/frontend/src/components/LanguageSwitcher.tsx
index e20db88b..a811d9c6 100644
--- a/frontend/src/components/LanguageSwitcher.tsx
+++ b/frontend/src/components/LanguageSwitcher.tsx
@@ -1,5 +1,6 @@
import { useState } from "react";
-import { Check, Globe } from "lucide-react";
+import { Globe } from "lucide-react";
+import { MenuCheck } from "./ui/MenuCheck";
import { LANGUAGES, type LangCode } from "../i18n";
import { PopoverItem, PopoverSurface } from "./ui/AnchoredPopover";
import { useAnchoredPopover } from "./ui/anchoredPopoverHooks";
@@ -83,10 +84,10 @@ export default function LanguageSwitcher({
setOpen(false);
}}
label={l.label}
- className="w-full flex items-center justify-between gap-2 text-sm px-2 py-2 rounded-lg text-muted outline-hidden transition hover:text-fg"
+ className="w-full flex items-center gap-2 text-sm px-2 py-2 rounded-lg text-muted outline-hidden transition hover:text-fg"
>
+
{l.label}
- {l.code === value && }
))}
diff --git a/frontend/src/components/PlexCollectionEditor.tsx b/frontend/src/components/PlexCollectionEditor.tsx
index 6ff9633c..05011583 100644
--- a/frontend/src/components/PlexCollectionEditor.tsx
+++ b/frontend/src/components/PlexCollectionEditor.tsx
@@ -2,7 +2,8 @@ import { useMemo, useState } from "react";
import { qk } from "../lib/queryKeys";
import { useTranslation } from "react-i18next";
import { useQuery, useQueryClient } from "@tanstack/react-query";
-import { Check, Plus } from "lucide-react";
+import { Plus } from "lucide-react";
+import { MenuCheck } from "./ui/MenuCheck";
import { api } from "../lib/api";
import { notifyActionError } from "../lib/actionErrors";
import { useScrollFade } from "../lib/useScrollFade";
@@ -202,13 +203,7 @@ export default function PlexCollectionEditor({
inIt ? "text-accent" : ""
}`}
>
-
- {inIt && }
-
+
{c.title}
{t("plex.collEditor.count", { count: c.child_count ?? 0 })}
diff --git a/frontend/src/components/PlexPlaylistAdd.tsx b/frontend/src/components/PlexPlaylistAdd.tsx
index afae8dd8..2961c013 100644
--- a/frontend/src/components/PlexPlaylistAdd.tsx
+++ b/frontend/src/components/PlexPlaylistAdd.tsx
@@ -2,7 +2,8 @@ import { useState } from "react";
import { qk } from "../lib/queryKeys";
import { useTranslation } from "react-i18next";
import { useQuery, useQueryClient } from "@tanstack/react-query";
-import { Check, Minus, Plus } from "lucide-react";
+import { Plus } from "lucide-react";
+import { MenuCheck } from "./ui/MenuCheck";
import { api, type PlexPlaylist } from "../lib/api";
import { notifyActionError } from "../lib/actionErrors";
import { useScrollFade } from "../lib/useScrollFade";
@@ -158,17 +159,7 @@ export default function PlexPlaylistAdd({
all ? "text-accent" : ""
}`}
>
-
- {all ? (
-
- ) : partial ? (
-
- ) : null}
-
+
{p.title}
{isGroup ? (
diff --git a/frontend/src/components/ui/MenuCheck.tsx b/frontend/src/components/ui/MenuCheck.tsx
new file mode 100644
index 00000000..9bd3f03e
--- /dev/null
+++ b/frontend/src/components/ui/MenuCheck.tsx
@@ -0,0 +1,29 @@
+import { Check, Minus } from "lucide-react";
+
+// The ONE drawn check of a checkable row that cannot hold the browser's own checkbox (A6) — a menu
+// row, or a whole-row button whose `role` says checkbox: an `` inside a `