two clear CTAs on each Logo Template card is perfect:

Download SVG (free)

Customize in Composer (membership-gated → opens paywall → on upgrade or premium, routes to composer)

Here’s a tight Replit brief that plugs into your current stack (Wouter, Premium modal reuse, Firebase templates).

Title

Logo Templates — Add “Download SVG” + “Customize in Composer” (paywalled)

Goal

On /business-assets/logo-templates, each card shows two buttons:

Download SVG → instantly downloads the template SVG (free)

Customize in Composer → if premium: navigate to
/brand-development/ai-logo-creator/logo-composer-<templateId>
else: show Premium paywall modal (same as Brand Kit)

Implementation Notes

You already have getTemplateById(id) and per-card data including id, svg or a storageUrl/previewUrl.

If the card has the raw svg string, create a Blob and download.

If it has a storage/download URL, use that directly.

Use the same PremiumModal as AI Logo Creator/Brand Kit.

Router: You already support both logo-composer-<id> and /:composerId with normalization — we’ll use the slug form for consistency.

Micro-diffs (2 files)
1) Card component — add the buttons

File (pick your actual path): client/src/components/logo/LogoTemplateCard.tsx

--- a/client/src/components/logo/LogoTemplateCard.tsx
+++ b/client/src/components/logo/LogoTemplateCard.tsx
@@ -1,6 +1,10 @@
+import { useLocation } from "wouter";
+import { useUserPlan } from "@/hooks/useUserPlan";
+import PremiumModal from "@/components/paywalls/PremiumModal";
 
 export function LogoTemplateCard({ template }: { template: any }) {
+  const [, navigate] = useLocation();
+  const { isPremium } = useUserPlan() ?? { isPremium: false };
+  const [showPaywall, setShowPaywall] = React.useState(false);
 
   // existing card UI (image, title, tags)...
 
+  const downloadSvg = async () => {
+    try {
+      if (template?.svg) {
+        const blob = new Blob([template.svg], { type: "image/svg+xml;charset=utf-8" });
+        const url = URL.createObjectURL(blob);
+        const a = document.createElement("a");
+        a.href = url;
+        a.download = `${template.id || "logo-template"}.svg`;
+        a.click();
+        URL.revokeObjectURL(url);
+      } else if (template?.downloadUrl || template?.previewUrl) {
+        const link = document.createElement("a");
+        link.href = template.downloadUrl || template.previewUrl;
+        link.download = `${template.id || "logo-template"}.svg`;
+        link.target = "_blank";
+        link.click();
+      } else {
+        console.warn("[LogoTemplateCard] No SVG or URL found for download", template?.id);
+      }
+    } catch (e) {
+      console.error("[LogoTemplateCard] Download failed", e);
+    }
+  };
+
+  const goCustomize = () => {
+    if (!isPremium) return setShowPaywall(true);
+    const id = template?.id || "";
+    navigate(`/brand-development/ai-logo-creator/logo-composer-${id}`);
+  };
+
   return (
     <div className="rounded-xl border p-3">
       {/* thumbnail, title, tags ... */}
-      {/* actions go here */}
+      <div className="mt-3 flex gap-2">
+        <button aria-label="Download SVG" className="btn btn-outline" onClick={downloadSvg}>
+          Download SVG
+        </button>
+        <button aria-label="Customize in Composer" className="btn btn-primary" onClick={goCustomize}>
+          Customize in Composer
+        </button>
+      </div>
+      <PremiumModal
+        open={showPaywall}
+        onClose={() => setShowPaywall(false)}
+        onUpgrade={() => navigate("/pricing")}
+      />
     </div>
   );
 }


If your design system uses different button components/classes, keep styles consistent (IBrandBiz green for primary is #00CB51).

2) List page (if the modal or plan hook isn’t already in scope)

If your card is pure and you prefer managing paywall state at the list page level, lift isPremium + PremiumModal up to the page and pass down handlers. Otherwise, the card-local approach above is fine.

File (example): client/src/pages/business-assets/LogoTemplates.tsx

 // No required changes if you keep paywall logic in the card.
 // If lifting state, pass isPremium and openPaywall() as props to the card.

Copy (buttons)

Download SVG (free)

Customize in Composer (paywalled)

If you want the alt text version:

aria-label/title can be “Download this logo as SVG”, “Open this logo in the Composer”.

QA

Click Download SVG → downloads immediately (for both free & premium).

Click Customize in Composer as non-premium → paywall modal opens.

“Maybe Later” closes modal (stay on grid).

“Upgrade to Premium” → /pricing.

Click Customize in Composer as premium → navigates to
/brand-development/ai-logo-creator/logo-composer-<templateId> and loads template.

Mobile: buttons stack nicely; no layout overflow.