diff --git a/README.md b/README.md
index 433ab6e0..0623367f 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
-
+
## Key Features
diff --git a/apps/landing/public/og-image.png b/apps/landing/public/og-image.png
index 31243cbc..5a1223d9 100644
Binary files a/apps/landing/public/og-image.png and b/apps/landing/public/og-image.png differ
diff --git a/apps/web/public/og-image.png b/apps/web/public/og-image.png
index 29872b2e..5a1223d9 100644
Binary files a/apps/web/public/og-image.png and b/apps/web/public/og-image.png differ
diff --git a/branding/README.md b/branding/README.md
index b3f60748..f7c2a635 100644
--- a/branding/README.md
+++ b/branding/README.md
@@ -2,6 +2,8 @@
Press kit for use in blog posts, articles, reviews, and other publications about SnapOtter. Free to use when referencing SnapOtter.
+SnapOtter is an open-source, self-hosted file processing suite with 157 tools across image, video, audio, PDF, and file workflows.
+
## Files
| File | Size | Use |
@@ -17,23 +19,26 @@ Press kit for use in blog posts, articles, reviews, and other publications about
| `social-preview.png` | 1280x640 | OpenGraph / social media preview |
| `wordmark.svg` | Scalable | "SnapOtter" text mark (dark text) |
| `wordmark-white.svg` | Scalable | "SnapOtter" text mark (white text, for dark backgrounds) |
-| `banner.svg` | Scalable | Logo + tagline banner on dark background |
-| `dashboard.png` | Screenshot | Full dashboard screenshot for README / marketing |
-| `dashboard_no_detail.png` | Screenshot | Dashboard screenshot without detail panel |
+| `banner.svg` | Scalable | Wordmark + tagline banner on dark background |
+| `dashboard.gif` | Animated | Scrolling tour of all 157 tools across the five modalities (README hero) |
## Brand Colors
| Name | Hex | Usage |
|------|-----|-------|
-| Primary Blue | `#3b82f6` | "Otter" in wordmark, buttons, accents |
-| Dark | `#0f172a` | "Snap" in wordmark, dark mode background |
-| Slate | `#94a3b8` | Subtitle/muted text |
-| White | `#ffffff` | Light mode background |
+| Otter Orange | `#E07832` | "Otter" in wordmark, buttons, links, CTAs |
+| Orange Light | `#F09550` | Hover states |
+| Orange Dark | `#C06520` | Text emphasis on light backgrounds |
+| Dark Chocolate | `#1A1210` | Dark sections, banner background |
+| Foreground | `#1A1814` | "Snap" in wordmark, primary text |
+| Cream | `#FAFAF7` | Page / light background |
+| Muted | `#6B6560` | Secondary / subtitle text |
## Typography
-- **Headings / brand name**: Nunito (weight 800)
-- **Body text**: Inter
+- **Headings / brand name**: Bricolage Grotesque (weight 800)
+- **Body text**: Instrument Sans
+- **Code / monospace**: JetBrains Mono
## Usage Guidelines
diff --git a/branding/banner.svg b/branding/banner.svg
index d3953a6c..0bb1a2f7 100644
--- a/branding/banner.svg
+++ b/branding/banner.svg
@@ -1,9 +1,9 @@
diff --git a/branding/dashboard.gif b/branding/dashboard.gif
new file mode 100644
index 00000000..0167a9c0
Binary files /dev/null and b/branding/dashboard.gif differ
diff --git a/branding/dashboard.png b/branding/dashboard.png
deleted file mode 100644
index b6377b0d..00000000
Binary files a/branding/dashboard.png and /dev/null differ
diff --git a/branding/dashboard_no_detail.png b/branding/dashboard_no_detail.png
deleted file mode 100644
index 9e11229d..00000000
Binary files a/branding/dashboard_no_detail.png and /dev/null differ
diff --git a/branding/social-preview.png b/branding/social-preview.png
index 31243cbc..5a1223d9 100644
Binary files a/branding/social-preview.png and b/branding/social-preview.png differ
diff --git a/branding/wordmark-white.svg b/branding/wordmark-white.svg
index fd394eee..8ff4018f 100644
--- a/branding/wordmark-white.svg
+++ b/branding/wordmark-white.svg
@@ -1,5 +1,5 @@
diff --git a/branding/wordmark.svg b/branding/wordmark.svg
index 82bed2c7..2794c107 100644
--- a/branding/wordmark.svg
+++ b/branding/wordmark.svg
@@ -1,5 +1,5 @@
diff --git a/scripts/branding/generate-social-preview.mjs b/scripts/branding/generate-social-preview.mjs
new file mode 100644
index 00000000..ea3416f8
--- /dev/null
+++ b/scripts/branding/generate-social-preview.mjs
@@ -0,0 +1,150 @@
+// Generates branding/social-preview.png (1280x640) -- the SnapOtter social/OG card.
+// Echoes the landing hero: trust badges, the "Every file tool you need / Nothing
+// leaves your network" headline, the supporting subhead, and the five modality
+// cards. Rendered from HTML with the real brand fonts via headless Chromium.
+// Run: node scripts/branding/generate-social-preview.mjs
+//
+// The same output is the canonical OG image; sync it to apps/landing/public/og-image.png
+// and apps/web/public/og-image.png (see scripts/branding/sync-og.sh).
+
+import { rmSync, writeFileSync } from "node:fs";
+import { dirname, resolve } from "node:path";
+import { fileURLToPath } from "node:url";
+import { chromium } from "@playwright/test";
+
+const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
+const out = resolve(repoRoot, "branding/social-preview.png");
+// Temp HTML lives in branding/ so the page origin is file:// and can load the
+// sibling logo and the ../apps fonts as file:// subresources.
+const htmlPath = resolve(repoRoot, "branding/.og.html");
+
+// Enterprise trust badges (subset of Hero.astro's list).
+const BADGES = ["On-premise", "GDPR & HIPAA", "Air-gap", "SAML SSO", "Open source"];
+
+// lucide icon inner-SVG (stroke), matching the icons used in CategoryCards.astro.
+const ICON = {
+ image:
+ '',
+ video:
+ '',
+ music: '',
+ fileText:
+ '',
+ database:
+ '',
+};
+
+// Mirrors CategoryCards.astro (label/blurb/color/icon). Counts are toolSection()
+// section counts (image 64, video 29, audio 17, pdf 25, files 22 = 157); refresh
+// with: tsx -e "import('@snapotter/shared')..." over toolSection (see git history).
+const CARDS = [
+ {
+ label: "Image Tools",
+ count: 64,
+ blurb: "Resize, convert, and enhance",
+ color: "#E07832",
+ icon: ICON.image,
+ },
+ {
+ label: "Video Tools",
+ count: 29,
+ blurb: "Trim, convert, and caption",
+ color: "#BE4A3C",
+ icon: ICON.video,
+ },
+ {
+ label: "Audio Tools",
+ count: 17,
+ blurb: "Convert, trim, and transcribe",
+ color: "#2C7A75",
+ icon: ICON.music,
+ },
+ {
+ label: "PDF & Documents",
+ count: 25,
+ blurb: "Merge, split, and convert",
+ color: "#44568C",
+ icon: ICON.fileText,
+ },
+ {
+ label: "File Tools",
+ count: 22,
+ blurb: "Convert and transform",
+ color: "#5C8642",
+ icon: ICON.database,
+ },
+];
+const total = CARDS.reduce((s, c) => s + c.count, 0);
+
+const badgesHtml = BADGES.map(
+ (b) =>
+ `${b}`,
+).join("");
+
+const cardsHtml = CARDS.map(
+ (c) => `
+
+
+ ${c.count} tools
+
+
${c.label}
+
${c.blurb}
+
`,
+).join("");
+
+const html = `
+
SnapOtter${total} tools
+
${badgesHtml}
+
Every file tool you need.Nothing leaves your network.
+
The file-processing suite for teams that keep sensitive data in-house.
+
${cardsHtml}
+
`;
+
+writeFileSync(htmlPath, html);
+try {
+ const browser = await chromium.launch();
+ const ctx = await browser.newContext({ viewport: { width: 1280, height: 640 } });
+ const page = await ctx.newPage();
+ await page.goto("file://" + htmlPath, { waitUntil: "load" });
+ await page.evaluate(async () => {
+ await document.fonts.ready;
+ });
+ await page.waitForTimeout(150);
+ await page.screenshot({ path: out });
+ await browser.close();
+ console.log("wrote " + out);
+} finally {
+ rmSync(htmlPath, { force: true });
+}
diff --git a/scripts/branding/sync-og.sh b/scripts/branding/sync-og.sh
new file mode 100755
index 00000000..33b07ec8
--- /dev/null
+++ b/scripts/branding/sync-og.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# Propagate the canonical social card to the app OG-image locations.
+# Run after regenerating branding/social-preview.png.
+set -euo pipefail
+root="$(cd "$(dirname "$0")/../.." && pwd)"
+src="$root/branding/social-preview.png"
+cp "$src" "$root/apps/landing/public/og-image.png"
+cp "$src" "$root/apps/web/public/og-image.png"
+echo "synced social-preview.png -> apps/landing/public/og-image.png, apps/web/public/og-image.png"