diff --git a/assets/branding/README.md b/assets/branding/README.md
new file mode 100644
index 0000000..b1906f5
--- /dev/null
+++ b/assets/branding/README.md
@@ -0,0 +1,51 @@
+# KB-RPCS3 visual identity
+
+Original artwork for KB-RPCS3. None of it is derived from Sony or PlayStation
+branding, and none of it is upstream RPCS3 artwork.
+
+The mark is an original stylised numeral **3**: two right-facing bowls joined by a
+short middle stroke, drawn from primitives in `kb-rpcs3-mark.svg` and
+`port/make-kb-icon.py` (the console title icon).
+
+## Files
+
+| File | Use | Size |
+|---|---|---|
+| `kb-rpcs3-mark.svg` / `.png` | the numeral-3 mark on its own, transparent | 1024×1024 |
+| `kb-rpcs3-app-icon.svg` / `.png` | square app/tile icon with wordmark and version | 1024×1024 |
+| `kb-rpcs3-banner.svg` / `.png` | wide README banner | 1600×500 |
+| `kb-rpcs3-social-preview.svg` / `.png` | GitHub social-preview image (2:1) | 1280×640 |
+| `kb-rpcs3-release.svg` / `.png` | release artwork | 1280×640 |
+
+The `.svg` files are the editable source of truth. Regenerate every PNG with:
+
+```sh
+python3 -m venv .venv
+.venv/bin/pip install cairosvg Pillow
+.venv/bin/python assets/branding/render.py
+```
+
+## Palette
+
+| Role | Hex |
+|---|---|
+| Ink (background gradient) | `#0B111C` → `#18284C` |
+| Cyan (mark, accents) | `#00D6E8` / `#00A8CF` |
+| Border cyan | `#00BED6` |
+| Foreground | `#E8F6FF` |
+| Muted text | `#96CDDC` / `#9DBECE` / `#6E93A3` |
+
+## Type
+
+Bold sans for the wordmark and headings, regular sans for support text. The SVGs
+name `Arial, Helvetica, sans-serif` so they render consistently anywhere a
+Helvetica-metric font is available.
+
+## Usage
+
+- Keep the mark cyan-on-dark or cyan-on-transparent; do not place it on a light
+ background without a dark plate.
+- Do not add a Sony, PlayStation or RPCS3 logo to the artwork, and do not imply
+ endorsement by either.
+- Keep the wordmark "KB-RPCS3" as one word with hyphens; the product name is never
+ spelled "KB RPCS3" or "KBRPCS3".
diff --git a/assets/branding/kb-rpcs3-app-icon.png b/assets/branding/kb-rpcs3-app-icon.png
new file mode 100644
index 0000000..0beb905
Binary files /dev/null and b/assets/branding/kb-rpcs3-app-icon.png differ
diff --git a/assets/branding/kb-rpcs3-app-icon.svg b/assets/branding/kb-rpcs3-app-icon.svg
new file mode 100644
index 0000000..da0fdec
--- /dev/null
+++ b/assets/branding/kb-rpcs3-app-icon.svg
@@ -0,0 +1,25 @@
+
diff --git a/assets/branding/kb-rpcs3-banner.png b/assets/branding/kb-rpcs3-banner.png
new file mode 100644
index 0000000..a2a4f43
Binary files /dev/null and b/assets/branding/kb-rpcs3-banner.png differ
diff --git a/assets/branding/kb-rpcs3-banner.svg b/assets/branding/kb-rpcs3-banner.svg
new file mode 100644
index 0000000..a6bc8e5
--- /dev/null
+++ b/assets/branding/kb-rpcs3-banner.svg
@@ -0,0 +1,50 @@
+
diff --git a/assets/branding/kb-rpcs3-mark.png b/assets/branding/kb-rpcs3-mark.png
new file mode 100644
index 0000000..08a400f
Binary files /dev/null and b/assets/branding/kb-rpcs3-mark.png differ
diff --git a/assets/branding/kb-rpcs3-mark.svg b/assets/branding/kb-rpcs3-mark.svg
new file mode 100644
index 0000000..1278843
--- /dev/null
+++ b/assets/branding/kb-rpcs3-mark.svg
@@ -0,0 +1,15 @@
+
diff --git a/assets/branding/kb-rpcs3-release.png b/assets/branding/kb-rpcs3-release.png
new file mode 100644
index 0000000..f891021
Binary files /dev/null and b/assets/branding/kb-rpcs3-release.png differ
diff --git a/assets/branding/kb-rpcs3-release.svg b/assets/branding/kb-rpcs3-release.svg
new file mode 100644
index 0000000..4ffed41
--- /dev/null
+++ b/assets/branding/kb-rpcs3-release.svg
@@ -0,0 +1,49 @@
+
diff --git a/assets/branding/kb-rpcs3-social-preview.png b/assets/branding/kb-rpcs3-social-preview.png
new file mode 100644
index 0000000..99b8770
Binary files /dev/null and b/assets/branding/kb-rpcs3-social-preview.png differ
diff --git a/assets/branding/kb-rpcs3-social-preview.svg b/assets/branding/kb-rpcs3-social-preview.svg
new file mode 100644
index 0000000..e31c1f2
--- /dev/null
+++ b/assets/branding/kb-rpcs3-social-preview.svg
@@ -0,0 +1,48 @@
+
diff --git a/assets/branding/render.py b/assets/branding/render.py
new file mode 100644
index 0000000..3949530
--- /dev/null
+++ b/assets/branding/render.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""Render the KB-RPCS3 branding SVGs to PNG.
+
+The SVG files in this folder are the editable source of truth. This script only
+rasterises them, so a change to a source file plus a re-run reproduces every PNG
+deterministically.
+
+ python3 -m venv .venv && .venv/bin/pip install cairosvg Pillow
+ .venv/bin/python assets/branding/render.py
+
+Requires cairosvg (and, for PNG optimisation, Pillow).
+"""
+from __future__ import annotations
+
+import sys
+from pathlib import Path
+
+try:
+ import cairosvg
+except ImportError: # pragma: no cover
+ sys.exit("cairosvg is required: pip install cairosvg")
+
+HERE = Path(__file__).resolve().parent
+
+# source SVG -> (output PNG, width, height)
+TARGETS = {
+ "kb-rpcs3-mark.svg": ("kb-rpcs3-mark.png", 1024, 1024),
+ "kb-rpcs3-app-icon.svg": ("kb-rpcs3-app-icon.png", 1024, 1024),
+ "kb-rpcs3-banner.svg": ("kb-rpcs3-banner.png", 1600, 500),
+ "kb-rpcs3-social-preview.svg": ("kb-rpcs3-social-preview.png", 1280, 640),
+ "kb-rpcs3-release.svg": ("kb-rpcs3-release.png", 1280, 640),
+}
+
+
+def optimise(path: Path) -> None:
+ """Re-save as an optimised, flattened PNG (branding art has no transparency)."""
+ try:
+ from PIL import Image
+ except ImportError:
+ return
+ with Image.open(path) as im:
+ im.convert("RGB").save(path, format="PNG", optimize=True)
+
+
+def main() -> int:
+ for svg_name, (png_name, width, height) in TARGETS.items():
+ src = HERE / svg_name
+ if not src.exists():
+ sys.exit(f"missing source: {src}")
+ dst = HERE / png_name
+ cairosvg.svg2png(
+ url=str(src), write_to=str(dst), output_width=width, output_height=height
+ )
+ optimise(dst)
+ print(f"{svg_name} -> {png_name} ({width}x{height}, {dst.stat().st_size:,} bytes)")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())