diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml
index 8b2c0a49..8a9b7ad8 100644
--- a/.github/workflows/acceptance.yml
+++ b/.github/workflows/acceptance.yml
@@ -74,6 +74,10 @@ jobs:
run: |
raco pkg install --auto --no-docs "https://github.com/turinglambdaai/keel.git#${KEEL_PIN}"
raco pkg install --auto --no-docs "https://github.com/turinglambdaai/rivet.git#${RIVET_PIN}"
+ - name: Render DMG artwork from SVG
+ run: |
+ brew install librsvg
+ bash scripts/render-dmg-background.sh
- name: Run executable acceptance contract
shell: bash
run: |
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 3fba709d..3743d25b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -45,6 +45,12 @@ jobs:
raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#${{ env.RIVET_PIN }}'
- name: Version preflight (VERSION == rivet.rktd == updater == tag)
run: bash scripts/check-release-version.sh "${{ github.ref_name }}"
+ # The Finder DMG uses the PNG, not the editable SVG. Regenerate it so
+ # artwork changes always land in the release (Rivet uses a 660x400 view).
+ - name: Render DMG artwork from SVG
+ run: |
+ brew install librsvg
+ bash scripts/render-dmg-background.sh
# DMG (human installer) + portable zip + SBOM + notices, launch
# smoke included. The macOS update feed entry is the portable zip,
# assembled by scripts/make-update-manifest.sh in the publish job.
diff --git a/assets/dmg-background.svg b/assets/dmg-background.svg
index d7cded46..371f6af8 100644
--- a/assets/dmg-background.svg
+++ b/assets/dmg-background.svg
@@ -7,22 +7,29 @@
-
-
-
-
- taskly
+ Taskly
A focused, keyboard-friendly task manager
-
-
-
+
+ DRAG TO INSTALL
+
+
+
+
- Drag taskly into Applications to install
+ Drag Taskly into Applications
diff --git a/scripts/render-dmg-background.sh b/scripts/render-dmg-background.sh
new file mode 100755
index 00000000..11c35b26
--- /dev/null
+++ b/scripts/render-dmg-background.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# The SVG is the editable source; Rivet stages the PNG named in rivet.rktd.
+# Run before packaging on macOS so the release never ships stale artwork.
+set -euo pipefail
+root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+svg="$root/assets/dmg-background.svg"
+png="$root/assets/dmg-background.png"
+if ! command -v rsvg-convert >/dev/null 2>&1; then
+ echo "rsvg-convert is required (macOS: brew install librsvg)" >&2
+ exit 1
+fi
+rsvg-convert --format png --output "$png" "$svg"
+# Fail before Rivet if the generated image no longer matches its fixed Finder
+# window geometry (660x400 at 2x): a valid PNG may still crop/misalign icons.
+python3 - "$png" <<'PY'
+import struct
+import sys
+with open(sys.argv[1], "rb") as stream:
+ header = stream.read(24)
+if header[:8] != b"\x89PNG\r\n\x1a\n" or header[12:16] != b"IHDR":
+ raise SystemExit("DMG artwork is not a valid PNG")
+size = struct.unpack(">II", header[16:24])
+if size != (1320, 800):
+ raise SystemExit(f"DMG artwork must be 1320x800, got {size}")
+print(f"Rendered DMG artwork: {size[0]}x{size[1]}")
+PY
diff --git a/shared/spec/DESIGN-TOKENS.md b/shared/spec/DESIGN-TOKENS.md
index 853904b0..1270ee11 100644
--- a/shared/spec/DESIGN-TOKENS.md
+++ b/shared/spec/DESIGN-TOKENS.md
@@ -109,3 +109,20 @@ accent-filled white-text rounded button. No chrome field borders anywhere.
White rounded square (macOS-squircle radius ≈ 22.5%) with a quiet checklist
mark: one system-blue rounded bar over two neutral (`#CECED3`) bars, staggered
widths. Monochrome, no gradients — must read on light and dark docks alike.
+
+## macOS DMG artwork contract
+
+- The editable source is `assets/dmg-background.svg`; the shipping installer
+ embeds `assets/dmg-background.png`, regenerated before macOS release and
+ packaged acceptance by `scripts/render-dmg-background.sh` (`librsvg`).
+- Finder's branded installer is 660×400 points at 2× scale, requiring a
+ 1320×800 background. The Taskly and Applications icon slots are controlled
+ by pinned Rivet (positions 130,160 and 450,160 at 80pt icons). Keep the
+ straight drag arrow centered in the clear space between those slots and
+ do not draw art over the icon/label areas. The small `DRAG TO INSTALL`
+ cue and high-contrast bottom instruction sit entirely in the background's
+ clear middle and lower text zones, never underneath Finder's icon labels.
+- Final visual acceptance must inspect the mounted DMG in Finder (not only the
+ raw SVG/PNG): app icon, Applications target, arrowhead and labels must stay
+ aligned at native scale. The 1320x800 renderer check is necessary but cannot
+ prove Finder's overlay composition is correct.