#!/usr/bin/env python3 """Generate Play Store feature graphics (1024x500) + store icon (512) for Tane. Brand green #2F7D34, white sprout from the adaptive foreground, 'Tane' wordmark in Noto Sans (the site's brand typeface), and the official value-proposition tagline. On-brand and replaceable with a designed asset later. Run from apps/app_seeds/: python3 tool/gen_feature_graphic.py """ import os from PIL import Image, ImageDraw, ImageFont REPO_APP = "/home/vjrj/proyectos/dev/tane/.claude/worktrees/interesting-cray-6261fd/apps/app_seeds" NOTO = "/usr/share/fonts/truetype/noto" F_BOLD = f"{NOTO}/NotoSans-Bold.ttf" F_MED = f"{NOTO}/NotoSans-Medium.ttf" F_REG = f"{NOTO}/NotoSans-Regular.ttf" FG = f"{REPO_APP}/assets/icon_foreground.png" ICON = f"{REPO_APP}/assets/icon.png" GREEN = (47, 125, 52) # #2F7D34 GREEN_DARK = (34, 82, 30) # #22521E WHITE = (255, 255, 255) FAINT = (208, 228, 210) W, H = 1024, 500 # value line = what the app is (explains it); attrs = the differentiators. COPY = { "en-US": ("Keep and share traditional seeds", "Offline · Encrypted · No account"), "es-ES": ("Guarda y comparte semillas tradicionales", "Sin conexión · Cifrado · Sin cuenta"), } def sprout(height): im = Image.open(FG).convert("RGBA") bb = im.getbbox() if bb: im = im.crop(bb) s = height / im.height return im.resize((max(1, int(im.width * s)), height), Image.LANCZOS) def bg(): top = Image.new("RGB", (W, H), GREEN) bot = Image.new("RGB", (W, H), GREEN_DARK) mask = Image.new("L", (W, H)) md = ImageDraw.Draw(mask) for y in range(H): md.line([(0, y), (W, y)], fill=int(60 * (y / H))) return Image.composite(bot, top, mask) def center_line(d, text, font, top, fill): b = d.textbbox((0, 0), text, font=font) w = b[2] - b[0] d.text(((W - w) / 2 - b[0], top - b[1]), text, font=font, fill=fill) return b[3] - b[1] def feature_graphic(locale, out): img = bg() d = ImageDraw.Draw(img) value, attrs = COPY[locale] # Row 1: sprout + 'Tane', centered as a group in the upper half. spr = sprout(150) wf = ImageFont.truetype(F_BOLD, 120) wb = d.textbbox((0, 0), "Tane", font=wf) ww, wh = wb[2] - wb[0], wb[3] - wb[1] gap = 26 gw = spr.width + gap + ww gx = (W - gw) // 2 row_top = 92 cy = row_top + spr.height / 2 img.paste(spr, (gx, row_top), spr) d.text((gx + spr.width + gap - wb[0], cy - wh / 2 - wb[1]), "Tane", font=wf, fill=WHITE) y = row_top + spr.height + 34 # Row 2: value proposition (explains the app). vf = ImageFont.truetype(F_MED, 42) y += center_line(d, value, vf, y, WHITE) + 18 # Row 3: differentiators, quieter. af = ImageFont.truetype(F_REG, 30) center_line(d, attrs, af, y, FAINT) img.save(out, "PNG") print("wrote", out, img.size) def store_icon(out): Image.open(ICON).convert("RGB").resize((512, 512), Image.LANCZOS).save(out, "PNG") print("wrote", out) for loc in ("en-US", "es-ES"): d = f"{REPO_APP}/fastlane/metadata/android/{loc}/images" os.makedirs(d, exist_ok=True) feature_graphic(loc, f"{d}/featureGraphic.png") store_icon(f"{d}/icon.png")