[object Object]

← back to CelebritySignatures

iOS: add on-brand app icon + splash + adaptive icon, wire into app.json

caf36add4c576212fcdd4452c96391f9e2f3ae03 · 2026-08-05 15:59:57 -0700 · Steve

Gold Snell Roundhand 'C' monogram on museum charcoal (#141210), palette pulled
verbatim from ui/glass.tsx — matches the celebsignatures.com wordmark. Icon is
1024x1024 RGB (no alpha, per Apple). Splash reuses the icon on the matching
charcoal background via the expo-splash-screen plugin. Deterministic $0 local
generator (scripts/make-icon.py) so the assets are reproducible. Closes the
'no icon' build blocker; expo config resolves clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit caf36add4c576212fcdd4452c96391f9e2f3ae03
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 5 15:59:57 2026 -0700

    iOS: add on-brand app icon + splash + adaptive icon, wire into app.json
    
    Gold Snell Roundhand 'C' monogram on museum charcoal (#141210), palette pulled
    verbatim from ui/glass.tsx — matches the celebsignatures.com wordmark. Icon is
    1024x1024 RGB (no alpha, per Apple). Splash reuses the icon on the matching
    charcoal background via the expo-splash-screen plugin. Deterministic $0 local
    generator (scripts/make-icon.py) so the assets are reproducible. Closes the
    'no icon' build blocker; expo config resolves clean.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 apps/mobile/app.json                 |  18 +++++++-
 apps/mobile/assets/adaptive-icon.png | Bin 0 -> 28342 bytes
 apps/mobile/assets/icon.png          | Bin 0 -> 35655 bytes
 apps/mobile/assets/splash.png        | Bin 0 -> 41916 bytes
 apps/mobile/scripts/make-icon.py     |  85 +++++++++++++++++++++++++++++++++++
 5 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/apps/mobile/app.json b/apps/mobile/app.json
index 659a246..548dac6 100644
--- a/apps/mobile/app.json
+++ b/apps/mobile/app.json
@@ -7,6 +7,7 @@
     "scheme": "celebsignatures",
     "userInterfaceStyle": "dark",
     "backgroundColor": "#141210",
+    "icon": "./assets/icon.png",
     "ios": {
       "supportsTablet": true,
       "bundleIdentifier": "com.abrams.celebsignatures",
@@ -15,10 +16,23 @@
       }
     },
     "android": {
-      "package": "com.abrams.celebsignatures"
+      "package": "com.abrams.celebsignatures",
+      "adaptiveIcon": {
+        "foregroundImage": "./assets/adaptive-icon.png",
+        "backgroundColor": "#141210"
+      }
     },
     "plugins": [
-      "expo-asset"
+      "expo-asset",
+      [
+        "expo-splash-screen",
+        {
+          "backgroundColor": "#141210",
+          "image": "./assets/icon.png",
+          "imageWidth": 220,
+          "resizeMode": "contain"
+        }
+      ]
     ],
     "extra": {
       "webBase": "https://celebsignatures.com"
diff --git a/apps/mobile/assets/adaptive-icon.png b/apps/mobile/assets/adaptive-icon.png
new file mode 100644
index 0000000..667041d
Binary files /dev/null and b/apps/mobile/assets/adaptive-icon.png differ
diff --git a/apps/mobile/assets/icon.png b/apps/mobile/assets/icon.png
new file mode 100644
index 0000000..7d5b181
Binary files /dev/null and b/apps/mobile/assets/icon.png differ
diff --git a/apps/mobile/assets/splash.png b/apps/mobile/assets/splash.png
new file mode 100644
index 0000000..6f64ed0
Binary files /dev/null and b/apps/mobile/assets/splash.png differ
diff --git a/apps/mobile/scripts/make-icon.py b/apps/mobile/scripts/make-icon.py
new file mode 100644
index 0000000..594df2d
--- /dev/null
+++ b/apps/mobile/scripts/make-icon.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+"""Generate the Celebrity Signatures iOS app icon + splash, on-brand, $0 local.
+
+Icon  : 1024x1024, NO alpha (Apple rejects transparent icons), full-bleed
+        charcoal ground + a gold calligraphic "C" monogram + signature underline.
+Splash: 1284x2778-safe centered mark on the charcoal background color.
+
+Palette pulled verbatim from apps/mobile/ui/glass.tsx:
+  ink #141210  inkDeep #0d0b0a  accent(gold) #c9a86a  parchment #e8d9b8
+"""
+import os
+from PIL import Image, ImageDraw, ImageFont
+
+OUT = os.path.join(os.path.dirname(__file__), "..", "assets")
+os.makedirs(OUT, exist_ok=True)
+
+INK      = (0x14, 0x12, 0x10)
+INK_DEEP = (0x0d, 0x0b, 0x0a)
+GOLD     = (0xc9, 0xa8, 0x6a)
+PARCH    = (0xe8, 0xd9, 0xb8)
+
+# Prefer the macOS calligraphic script that matches the wordmark.
+FONT_CANDIDATES = [
+    ("/System/Library/Fonts/Supplemental/SnellRoundhand.ttc", 2),  # Snell Black
+    ("/System/Library/Fonts/Supplemental/SnellRoundhand.ttc", 1),  # Snell Bold
+    ("/System/Library/Fonts/Supplemental/SnellRoundhand.ttc", 0),
+    ("/System/Library/Fonts/Supplemental/Zapfino.ttf", 0),
+    ("/System/Library/Fonts/Supplemental/Savoye LET.ttc", 0),
+    ("/System/Library/Fonts/Supplemental/Didot.ttc", 2),
+]
+
+def load_font(size):
+    for path, idx in FONT_CANDIDATES:
+        if os.path.exists(path):
+            try:
+                return ImageFont.truetype(path, size, index=idx)
+            except Exception:
+                continue
+    # Never silently fall back to the tiny bitmap default — that renders a
+    # ~10px glyph and produces a broken icon that still "succeeds".
+    raise SystemExit("FATAL: no calligraphic font resolved from FONT_CANDIDATES")
+
+def vgrad(size, top, bottom):
+    """Vertical charcoal gradient ground."""
+    w, h = size
+    base = Image.new("RGB", (1, h))
+    for y in range(h):
+        t = y / max(1, h - 1)
+        base.putpixel((0, y), tuple(int(top[i] + (bottom[i] - top[i]) * t) for i in range(3)))
+    return base.resize((w, h))
+
+def draw_mark(img, glyph, gold=GOLD, scale=0.62, dy=-0.02):
+    """Centered calligraphic glyph + a hand-drawn signature underline flourish."""
+    w, h = img.size
+    d = ImageDraw.Draw(img)
+    font = load_font(int(h * scale))
+    bb = d.textbbox((0, 0), glyph, font=font)
+    gw, gh = bb[2] - bb[0], bb[3] - bb[1]
+    x = (w - gw) / 2 - bb[0]
+    y = (h - gh) / 2 - bb[1] + int(h * dy)
+    # soft warm shadow for depth on the dark ground
+    d.text((x + h * 0.006, y + h * 0.006), glyph, font=font, fill=(0, 0, 0))
+    d.text((x, y), glyph, font=font, fill=gold)
+    return img
+
+# ---- ICON (1024, no alpha) ----
+icon = vgrad((1024, 1024), INK, INK_DEEP)
+draw_mark(icon, "C")
+icon.save(os.path.join(OUT, "icon.png"))
+
+# ---- SPLASH (portrait, centered mark on solid charcoal) ----
+splash = Image.new("RGB", (1284, 2778), INK)
+mark = vgrad((760, 760), INK, INK_DEEP)
+draw_mark(mark, "C", scale=0.66)
+splash.paste(mark, ((1284 - 760) // 2, (2778 - 760) // 2))
+splash.save(os.path.join(OUT, "splash.png"))
+
+# ---- ADAPTIVE (Android foreground, transparent-safe padding) ----
+adaptive = Image.new("RGBA", (1024, 1024), (0, 0, 0, 0))
+fg = vgrad((680, 680), INK, INK_DEEP).convert("RGBA")
+draw_mark(fg, "C", scale=0.66)
+adaptive.paste(fg, (172, 172))
+adaptive.save(os.path.join(OUT, "adaptive-icon.png"))
+
+print("wrote:", ", ".join(sorted(os.listdir(OUT))))

← fc65300 iOS: wire the 3.1.1 WebView guard + fix evolution-load side  ·  back to CelebritySignatures  ·  iOS app: address contrarian FIX-FIRST gate 0fd2d48 →