diff --git a/dandiapi/api/slides/__init__.py b/dandiapi/api/slides/__init__.py
new file mode 100644
index 000000000..ff1a8321a
--- /dev/null
+++ b/dandiapi/api/slides/__init__.py
@@ -0,0 +1,5 @@
+from __future__ import annotations
+
+from dandiapi.api.slides.render import render_shareable_slide_svg
+
+__all__ = ['render_shareable_slide_svg']
diff --git a/dandiapi/api/slides/dandi_logo.svg b/dandiapi/api/slides/dandi_logo.svg
new file mode 100644
index 000000000..615edda2d
--- /dev/null
+++ b/dandiapi/api/slides/dandi_logo.svg
@@ -0,0 +1,78 @@
+
+
+
diff --git a/dandiapi/api/slides/render.py b/dandiapi/api/slides/render.py
new file mode 100644
index 000000000..c276fb963
--- /dev/null
+++ b/dandiapi/api/slides/render.py
@@ -0,0 +1,322 @@
+"""Render a CC-0 shareable slide for a published Dandiset Version as SVG.
+
+Produces a 1920x1080 SVG document summarizing a Version (title, DOI, contributors,
+key stats, citation, QR code) so researchers can drop it into talks. PNG
+rasterization is left to the caller (e.g. librsvg / rsvg-convert at the email
+or storage layer).
+
+Not yet wired into the publish flow; see issue #2797.
+"""
+
+from __future__ import annotations
+
+from io import BytesIO
+from pathlib import Path
+import re
+from typing import TYPE_CHECKING
+from xml.sax.saxutils import escape
+
+import qrcode
+from qrcode.image.svg import SvgPathImage
+
+if TYPE_CHECKING:
+ from dandiapi.api.models import Version
+
+# --- Layout ------------------------------------------------------------------
+W = 1920
+H = 1080
+
+# --- Brand palette (from web/src/assets/logo.svg + Vuetify theme) -----------
+NAVY = '#00436D'
+CORAL = '#D3868D'
+INK = '#1a1a1a'
+MUTED = '#5b6b7d'
+BG = '#ffffff'
+PANEL = '#f4f7fa'
+
+# --- Logo asset (verbatim copy of web/src/assets/logo.svg) ------------------
+_LOGO_PATH = Path(__file__).parent / 'dandi_logo.svg'
+
+# Map the source classes to direct fill attrs so
+# the logo renders correctly when embedded as an data URI (rsvg-convert
+# does not apply CSS rules across image boundaries).
+_LOGO_FILL_BY_CLASS = {
+ 'st0': '#D3868D',
+ 'st1': '#F0A5AC',
+ 'st2': '#A05A60',
+ 'st3': '#FFFFFF',
+ 'st4': '#00436D',
+}
+
+
+def _inline_logo_fills(svg_text: str) -> str:
+ out = svg_text
+ for cls, color in _LOGO_FILL_BY_CLASS.items():
+ out = re.sub(rf'class="{cls}"', f'fill="{color}"', out)
+ return re.sub(r'', '', out, flags=re.DOTALL)
+
+
+_LOGO_SVG_INLINED = _inline_logo_fills(_LOGO_PATH.read_text(encoding='utf-8'))
+
+# Extract the inner content of the logo