3) Replace src/store/favorites.ts (Cloud + Local fallback)
import { useEffect, useMemo, useState } from "react";
import {
  ensureFirebase,
  isFirebaseConfigured,
  doc,
  onSnapshot,
  setDoc,
  updateDoc,
  arrayUnion,
  arrayRemove,
} from "../lib/firebase";

// -------- Local fallback --------
const LS_KEY = "ibrandbiz_icon_favorites";
function lsLoad(): string[] {
  try {
    const raw = localStorage.getItem(LS_KEY);
    const arr = raw ? JSON.parse(raw) : [];
    return Array.isArray(arr) ? arr : [];
  } catch {
    return [];
  }
}
function lsSave(ids: string[]) {
  try {
    localStorage.setItem(LS_KEY, JSON.stringify(ids));
  } catch {}
}

// -------- Hook API (cloud-first, local fallback) --------
export function useFavorites() {
  const [favorites, setFavorites] = useState<string[]>(lsLoad());
  const [ready, setReady] = useState<boolean>(!isFirebaseConfigured()); // if no Firebase, we're already "ready"
  const [cloud, setCloud] = useState<{ uid: string } | null>(null);

  useEffect(() => {
    const fb = ensureFirebase();
    if (!fb) {
      // no firebase config -> local only
      setReady(true);
      return;
    }

    (async () => {
      const { db, authReady } = fb;
      const user = await authReady;
      if (!user) {
        setReady(true);
        return;
      }
      setCloud({ uid: user.uid });

      const ref = doc(db, "users", user.uid, "favorites", "icons");
      // ensure doc exists
      await setDoc(ref, { ids: lsLoad() }, { merge: true });

      // subscribe
      const unsub = onSnapshot(ref, (snap) => {
        const data = snap.data() as any;
        const ids: string[] = Array.isArray(data?.ids) ? data.ids : [];
        setFavorites(ids);
        lsSave(ids); // keep local cache in sync
        setReady(true);
      });

      return () => unsub();
    })();
  }, []);

  const api = useMemo(() => {
    async function toggleFavorite(id: string) {
      // cloud path
      if (cloud && isFirebaseConfigured()) {
        const fb = ensureFirebase();
        if (fb) {
          const ref = doc(fb.db, "users", cloud.uid, "favorites", "icons");
          const has = favorites.includes(id);
          await updateDoc(ref, { ids: has ? arrayRemove(id) : arrayUnion(id) });
          return;
        }
      }
      // local fallback
      const cur = lsLoad();
      const next = cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id];
      lsSave(next);
      // optimistic UI update
      setFavorites(next);
    }

    function isFavorite(id: string) {
      return favorites.includes(id);
    }

    return { favorites, ready, toggleFavorite, isFavorite, cloudEnabled: !!cloud };
  }, [favorites, ready, cloud]);

  return api;
}

4) Minimal tweaks to src/pages/business-assets/stock/Icons.tsx

Replace the old imports of loadFavorites/saveFavorites/toggleFavorite/isFavorite with the new hook:
import { useFavorites } from "../../../store/favorites";

Remove the old useEffect(() => setFavorites(loadFavorites()), []) and state wiring.

Use the hook’s values.

Diff-style guidance
- import { loadFavorites, saveFavorites, toggleFavorite, isFavorite } from "../../../store/favorites";
+ import { useFavorites } from "../../../store/favorites";

  export default function IconsPage() {
-   const [favorites, setFavorites] = useState<string[]>([]);
+   const { favorites, ready, toggleFavorite, isFavorite } = useFavorites();

-   useEffect(() => {
-     setFavorites(loadFavorites());
-   }, []);
+   // no need to manually load; the hook handles local or cloud

  // ...
-  function handleToggleFavorite(id: string) {
-    const updated = toggleFavorite(id);
-    setFavorites(updated);
-  }
+  async function handleToggleFavorite(id: string) {
+    await toggleFavorite(id); // hook updates state (cloud or local)
+  }

  // ...
-  const fav = isFavorite(favorites, icon.id);
+  const fav = isFavorite(icon.id);


Everything else (copy/download sanitized SVGs, color changes, etc.) stays exactly the same.

5) Firestore security rules (recommended)

In your Firebase console → Firestore Rules, allow each user to read/write only their own favorites:

// firestore.rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{uid}/favorites/icons {
      allow read, write: if request.auth != null && request.auth.uid == uid;
    }
  }
}


We’re using anonymous auth, so request.auth.uid will still be present and unique per browser/device. You can later upgrade to full accounts without changing this code.

What you get now

Realtime Cloud Favorites at users/{uid}/favorites/icons (array of icon IDs).

Anonymous Auth (no signup flow) — it “just works.”

Local fallback: if Firebase config is missing or offline, it keeps using localStorage.

Zero change to your Icons UX except favorites now follow the user across devices once they share the same signed-in session.