@@ -53,7 +69,7 @@ export function HomeFeedList({
variant="body-medium-lighter"
className="py-[var(--app-spacing-xl)] text-center text-[var(--content-disabled)]"
>
- {activeFilter
+ {effectiveFilter
? "No items match the selected filter."
: "No items to show."}
diff --git a/apps/web/src/domains/home/home-page.tsx b/apps/web/src/domains/home/home-page.tsx
index 532edffb282..ad09693d705 100644
--- a/apps/web/src/domains/home/home-page.tsx
+++ b/apps/web/src/domains/home/home-page.tsx
@@ -150,7 +150,7 @@ export function HomePage({
return (
{isUnread && (
-
+
)}
diff --git a/apps/web/src/domains/home/home-suggestion-pill-bar.tsx b/apps/web/src/domains/home/home-suggestion-pill-bar.tsx
index 290a4707e21..519a14ce773 100644
--- a/apps/web/src/domains/home/home-suggestion-pill-bar.tsx
+++ b/apps/web/src/domains/home/home-suggestion-pill-bar.tsx
@@ -80,7 +80,7 @@ export function HomeSuggestionPillBar({
style={{ width: 26, height: 26 }}
aria-hidden="true"
>
-
+
{suggestion.label}
diff --git a/packages/design-library/src/components/resizable-panel.tsx b/packages/design-library/src/components/resizable-panel.tsx
index dd115af9ca1..9c233d27cd8 100644
--- a/packages/design-library/src/components/resizable-panel.tsx
+++ b/packages/design-library/src/components/resizable-panel.tsx
@@ -1,6 +1,7 @@
import {
useCallback,
useEffect,
+ useLayoutEffect,
useRef,
useState,
type ComponentProps,
@@ -9,6 +10,27 @@ import {
import { cn } from "../utils/cn.js";
+/**
+ * Read a persisted pixel width from localStorage, validating both shape
+ * and finiteness. Returns `null` for unset/malformed entries or when
+ * storage access throws (strict-privacy contexts, quota errors, SSR).
+ */
+function readStoredWidth(
+ storageKey: string | undefined,
+ minLeftWidth: number,
+): number | null {
+ if (!storageKey || typeof window === "undefined") return null;
+ try {
+ const stored = localStorage.getItem(storageKey);
+ if (stored == null) return null;
+ const parsed = Number(stored);
+ if (!Number.isFinite(parsed)) return null;
+ return Math.max(minLeftWidth, parsed);
+ } catch {
+ return null;
+ }
+}
+
export interface ResizablePanelProps extends Omit, "children"> {
/** Content for the left pane. */
left: ReactNode;
@@ -16,6 +38,8 @@ export interface ResizablePanelProps extends Omit, "childr
right: ReactNode;
/** Initial width of the left pane in px (default 400). */
defaultLeftWidth?: number;
+ /** Initial width of the left pane as a percentage of the container (0–100). Resolved via useLayoutEffect on mount. */
+ defaultLeftPercent?: number;
/** Minimum left pane width in px (default 300). */
minLeftWidth?: number;
/** Minimum right pane width in px (default 300). */
@@ -36,6 +60,7 @@ export function ResizablePanel({
left,
right,
defaultLeftWidth = 400,
+ defaultLeftPercent,
minLeftWidth = 300,
minRightWidth = 300,
onWidthChange,
@@ -45,20 +70,9 @@ export function ResizablePanel({
}: ResizablePanelProps) {
const containerRef = useRef(null);
- const [leftWidth, setLeftWidth] = useState(() => {
- if (storageKey) {
- try {
- const stored = localStorage.getItem(storageKey);
- if (stored != null) {
- const parsed = Number(stored);
- if (Number.isFinite(parsed)) return Math.max(minLeftWidth, parsed);
- }
- } catch {
- // localStorage access can throw under strict-privacy contexts.
- }
- }
- return defaultLeftWidth;
- });
+ const [leftWidth, setLeftWidth] = useState(
+ () => readStoredWidth(storageKey, minLeftWidth) ?? defaultLeftWidth,
+ );
const dragRef = useRef<{ startX: number; startWidth: number } | null>(null);
const [isDragging, setIsDragging] = useState(false);
@@ -125,6 +139,19 @@ export function ResizablePanel({
return () => window.removeEventListener("resize", onResize);
}, [clamp]);
+ // Resolve percentage-based default on mount (before paint) when no valid
+ // persisted preference exists. Runs in useLayoutEffect so the resolved
+ // width is committed before the browser paints, preventing a single-frame
+ // flash of the `defaultLeftWidth` pixel fallback.
+ useLayoutEffect(() => {
+ if (defaultLeftPercent == null) return;
+ if (readStoredWidth(storageKey, minLeftWidth) !== null) return;
+ const container = containerRef.current;
+ if (!container) return;
+ const target = (container.offsetWidth * defaultLeftPercent) / 100;
+ setLeftWidth(clamp(target));
+ }, [defaultLeftPercent, storageKey, minLeftWidth, clamp]);
+
return (