# moneycanbuy.fun announcement posters

Four opaque PNG images, each exactly **1600 × 900**, RGB, no alpha channel. Intended for X and Telegram. The `-clean` images are the identical underlying artwork before text and text plates are composited. No generative model was used; model name/version: **not applicable**.

moneycanbuy.fun may use, change and publish these files without attribution.

## File record

| File | Tool and model/version | Exact drawing/compositing method | Reference files used |
| --- | --- | --- | --- |
| uk-toad.png | Python; CairoSVG 2.9.1; Pillow 13.0.0; no model | UK vector drawing below; composite uk-title at 1420 px wide and site at 340 px wide with the exact code and coordinates below | brand/mark.png; brand/colors.md; posters/README.md; posters/text/uk-title.png; posters/text/site.png |
| langs-toad.png | Python; CairoSVG 2.9.1; Pillow 13.0.0; no model | Traveler vector drawing below; composite langs-title at 1200 px wide, ten labels at 34 px high, site at 340 px wide | brand/mark.png; brand/colors.md; posters/README.md; posters/text/langs-title.png; posters/text/site.png; posters/text/lang-en.png, lang-zh.png, lang-es.png, lang-fr.png, lang-tr.png, lang-hi.png, lang-uk.png, lang-ru.png, lang-ja.png, lang-ko.png |
| uk-toad-clean.png | Python; CairoSVG 2.9.1; Pillow 13.0.0; no model | UK artwork before the overlay loop; no lettering or text plates; the original dollar pendant remains | brand/mark.png; brand/colors.md; posters/README.md |
| langs-toad-clean.png | Python; CairoSVG 2.9.1; Pillow 13.0.0; no model | Traveler artwork before the overlay loop; no lettering or text plates; original dollar pendants remain | brand/mark.png; brand/colors.md; posters/README.md |
| README.md | Python string assembly; no model | This production record, placement table, review and verbatim drawing source | Only the references listed above and the produced images |

## Drawing method

Draw explicit SVG paths, ellipses and rounded rectangles with dark #09210B strokes and flat colors. Render at 3200 × 1800 with CairoSVG, reduce uniformly to 1600 × 900 with Pillow LANCZOS, and save RGB PNG. Supersampling supplies edge antialiasing; no gradients, blur filters, photography or 3D rendering are used.

The provided raster toad is embedded directly: its face is neither reinterpreted nor generated. The traveler and all ten small toads reuse the original bust, including eyelids, eye cream, smirk, spots, black tank, chain and dollar tag. Legs, forearms, hands, travel hat and suitcase are drawn with matching flat fills and outlines. The Cossack uses a masked copy of the same head and an isolated original pendant, over a drawn embroidered shirt, sash and trousers; dark drooping mustache and a long crown lock curled behind the side of the head are added. The only skin greens used for new shapes are #82B63E, #599A35 and #44842A. Original source antialiasing and new antialiasing naturally have intermediate edge pixels.

UK background: flat blue #0057B7 sky, gold/yellow sun, Lavra ensemble and tall bell tower at left, St Andrew's Church and hill at right, Dnipro across the middle, sunflowers in front. Landmarks are simplified cartoon illustrations, not measured architectural elevations. The figure is a three-quarter Cossack, with no weapon or flag.

Languages background: #0D120E with a #182019 polygonal world map. Ten circular badges have outer diameter 188 px and inner diameter 172 px. Their centers are at y=252,374,496,618,740. Left x alternates 160,365,160,365,160; right x alternates 1440,1235,1440,1235,1440. Left order en/zh/es/fr/tr; right hi/uk/ru/ja/ko. Foods are respectively fish and chips in a cone; hugged panda; paella pan; croissant and baguette; doner wrap; chai and samosa; red borscht with sour cream; a freestanding wedge of Kyiv cake with meringue/cream tiers and cream flowers; sushi plate; barbecue grill with meat. The cake is Kyiv cake from Kyiv, Ukraine. The suitcase stickers are simple colored shapes, without text or flags.

## Exact overlay placements

Coordinates are top-left pixels on the final 1600 × 900 canvas. Dimensions are the complete supplied transparent overlay canvas, uniformly resized; the target axis is set exactly and the other dimension is rounded to the nearest pixel, without stretching. Every label is 34 px high. Titles and labels have black plates at 184/255 = 72.1569% opacity. Title plates extend 7 px on every side; label pills extend 6 px. Website lines have no plates. Each site canvas ends exactly 40 px from the bottom; the UK site canvas ends exactly 40 px from the right. No letter is cropped, rotated, recolored, warped, regenerated or retyped.

| Poster | Overlay in posters/text/ | x | y | width | height | Plate padding |
| --- | --- | ---: | ---: | ---: | ---: | ---: |
| uk | uk-title.png | 90 | 47 | 1420 | 127 | 7 |
| uk | site.png | 1220 | 813 | 340 | 47 | 0 |
| langs | langs-title.png | 200 | 47 | 1200 | 124 | 7 |
| langs | lang-en.png | 112 | 332 | 97 | 34 | 6 |
| langs | lang-zh.png | 335 | 454 | 60 | 34 | 6 |
| langs | lang-es.png | 107 | 576 | 107 | 34 | 6 |
| langs | lang-fr.png | 303 | 698 | 125 | 34 | 6 |
| langs | lang-tr.png | 111 | 820 | 98 | 34 | 6 |
| langs | lang-hi.png | 1411 | 332 | 59 | 34 | 6 |
| langs | lang-uk.png | 1155 | 454 | 161 | 34 | 6 |
| langs | lang-ru.png | 1381 | 576 | 118 | 34 | 6 |
| langs | lang-ja.png | 1192 | 698 | 86 | 34 | 6 |
| langs | lang-ko.png | 1400 | 820 | 81 | 34 | 6 |
| langs | site.png | 630 | 813 | 340 | 47 | 0 |

## Rejected and regenerated renders

All iterations were deterministic local renders, not model generations. Intermediate images were overwritten at the same four output paths; no rejected image is delivered.

- Draft 1, all four PNG paths: rejected because the Cossack head mask admitted a fragment of the source chain, the hair crossed the right lid, the chest stitchwork was obscured, and several miniature food items covered the dollar tags. Regenerated with a tighter head mask, hair curving outside the face, visible twin embroidery bands and revised badge layering. Sunflowers were moved away from the website line.
- Draft 2, all four PNG paths: rejected because the isolated pendant still included surrounding source pixels, the miniature hands appeared disconnected, and the panda was too small. Regenerated with an explicit pendant mask, connected forearms, a larger panda at the side and a hugging hand.
- Draft 3, all four PNG paths: replaced during a palette cleanup: dark hair and panda blacks unified to #07130B, church green to #599A35, grounding to #182019, badge border to #222B24 and grill metal to #9EA69F. Final outputs are this cleaned revision.

## Rejection-list review

1. PASS — All lettering comes exclusively from supplied PNG overlays, with uniform LANCZOS scaling. An independent recomposition from each clean PNG and the overlay coordinates matched the corresponding finished PNG pixel for pixel. No letters were synthesized.
2. PASS — Artwork and clean versions contain no text, numbers, logos or watermarks; only original dollar tags remain. Finished images add only the authorized overlays.
3. PASS — No flags or state/Soviet imagery anywhere. The ru badge contains Kyiv cake, with cream flowers and visible layered filling; no buildings or prohibited Russian symbols. Panda appears only as the expressly requested zh symbol.
4. PASS — Every toad reuses the same original face, skin and eye shape. Traveler and badge toads wear the original black tank; no nationalized anatomy or ethnic costume is applied to them.
5. PASS — No other-company brands or logos; suitcase decorations are shapes only.
6. PASS — Original face/bust is reused; original cream half-closed eyes, smirk, spots and gold chain/tag remain. New character skin uses the prescribed greens and dark outlines; all art uses flat fills with discrete shadows, no gradients or photographic/3D styling.
7. PASS — Cossack has drooping mustache, long crown lock curled at the side, embroidered white shirt, red sash, chain/tag and Kyiv landmarks above Dnipro. Traveler has hat and suitcase. Ten badges, ten toads, correct food/symbols and labels, correct staggered menu order; no buildings in badges.
8. PASS — No weapons, smoking or blood. Red in the UK image is sash/stitchwork; red in food badges is food.
9. PASS — All four files decoded as PNG, RGB, 1600 × 900, no alpha. Full overlay and plate bounding boxes are at least 40 px from every edge. Badge diameter 188 px exceeds 150 px. Titles are 1420/1200 px wide, site overlays 340 px wide, labels 34 px high. Full-size art and 400 px wide previews were inspected; large headlines and supplied labels remain readable, while food and embroidery details are necessarily small at preview scale.
10. PASS — This README is delivered with one row per file, tools/versions, exact method/source, overlay positions, reference list, discarded render history and usage permission.

## Validation and limitations

Local assertions checked PNG format, RGB mode, dimensions, text/plate bounding boxes, ordered labels, fixed label height, and exact pixel equality of overlay recomposition. All passed. Each clean image was visually inspected, as were the finished posters and 400 × 225 previews. No unmet visual requirement identified in this review. This records the maker's review; it is not an independent visual certification. Stylized landmarks, food and travel map are illustrations, not geographic/culinary reference drawings.

## Verbatim drawing and overlay code

This is the exact final production source, included to record the drawing method and complete overlay implementation. It uses Pillow and CairoSVG as authoring tools; the delivered PNGs have no runtime dependencies. Scratch paths in this source are authoring/validation intermediates and are not deliverables.

```python
import sys,io,base64,math,json
sys.path.insert(0,'test/scratch/deps')
from PIL import Image,ImageDraw
import cairosvg
from pathlib import Path
O='#09210B'; G='#82B63E'; S='#599A35'; SP='#44842A'; GOLD='#F5C451'; C='#FFF0CF'
mark=Image.open('brand/mark.png').convert('RGBA')
def data(im):
 b=io.BytesIO(); im.save(b,format='PNG'); return 'data:image/png;base64,'+base64.b64encode(b.getvalue()).decode()
MARK=data(mark)
# Keep the exact head, including its original outline; mask follows the lower jaw.
masksvg='''<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024"><path fill="white" d="M180 140 H850 V440 C842 529 792 574 670 607 C550 638 447 633 345 602 C231 571 188 529 180 470 Z"/></svg>'''
mask=Image.open(io.BytesIO(cairosvg.svg2png(bytestring=masksvg.encode()))).convert('RGBA').getchannel('A')
head=mark.copy(); import PIL.ImageChops
head.putalpha(PIL.ImageChops.multiply(mark.getchannel('A'),mask)); HEAD=data(head)
tag=mark.crop((451,658,568,831))
tm=Image.new('L',tag.size); ImageDraw.Draw(tm).polygon([(54,2),(74,10),(108,47),(113,150),(103,168),(24,171),(9,158),(6,52),(38,11)],fill=255)
tag.putalpha(PIL.ImageChops.multiply(tag.getchannel('A'),tm));TAG=data(tag)
class Art:
 def __init__(self,bg): self.s=[f'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1600" height="900" viewBox="0 0 1600 900"><rect width="1600" height="900" fill="{bg}"/>']
 def raw(self,s):self.s.append(s)
 def path(self,d,f,sw=6,stroke=O):self.raw(f'<path d="{d}" fill="{f}" stroke="{stroke}" stroke-width="{sw}" stroke-linejoin="round" stroke-linecap="round"/>')
 def ellipse(self,x,y,rx,ry,f,sw=6,stroke=O): self.raw(f'<ellipse cx="{x}" cy="{y}" rx="{rx}" ry="{ry}" fill="{f}" stroke="{stroke}" stroke-width="{sw}"/>')
 def rect(self,x,y,w,h,f,r=0,sw=6,stroke=O):self.raw(f'<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="{r}" fill="{f}" stroke="{stroke}" stroke-width="{sw}"/>')
 def image(self,url,x,y,w,h):self.raw(f'<image x="{x}" y="{y}" width="{w}" height="{h}" xlink:href="{url}"/>')
 def group(self,x,y,s=1):self.raw(f'<g transform="translate({x} {y}) scale({s})">')
 def end(self):self.raw('</g>')
 def save(self,p):
  svg=''.join(self.s)+'</svg>'; im=Image.open(io.BytesIO(cairosvg.svg2png(bytestring=svg.encode(),output_width=3200,output_height=1800))).convert('RGB').resize((1600,900),Image.Resampling.LANCZOS);im.save(p); return im

def dome(a,x,y,scale=1):
 a.group(x,y,scale)
 a.rect(-30,0,60,68,'#FFF0CF',2,4)
 a.path('M-38 0 Q-52 -27 -22 -47 Q0 -60 0 -79 Q0 -60 22 -47 Q52 -27 38 0 Z',GOLD,4)
 a.path('M0 -81 V-99 M-8 -92 H8','none',3)
 for dx in [-17,0,17]: a.rect(dx-4,19,8,27,'#0057B7',4,2)
 a.path('M-31 57 H31','none',3)
 a.end()
def flower(a,x,y,s=1):
 a.group(x,y,s);a.path('M0 0 Q8 46 -5 92','none',7)
 a.path('M0 58 Q-40 23 -43 49 Q-29 71 0 69 M0 48 Q28 14 39 36 Q29 59 0 61',S,3)
 for i in range(10):
  t=2*math.pi*i/10;px=math.cos(t)*22;py=math.sin(t)*22
  a.raw(f'<ellipse cx="{px}" cy="{py}" rx="10" ry="19" transform="rotate({i*36+90} {px} {py})" fill="#FFD700" stroke="{O}" stroke-width="3"/>')
 a.ellipse(0,0,15,15,'#6F421F',3)
 for dx,dy in [(-5,-5),(5,4),(-5,6),(5,-6)]:a.ellipse(dx,dy,1.5,1.5,GOLD,0)
 a.end()
def cross(a,x,y,s=1,col='#B72C33'):
 a.path(f'M{x-3*s} {y-3*s} L{x+3*s} {y+3*s} M{x-3*s} {y+3*s} L{x+3*s} {y-3*s}','none',2*s,col)

def uk():
 a=Art('#0057B7')
 # Broad flat sun and clouds; title sits on clear blue.
 a.ellipse(1350,292,158,158,'#FFD700',0)
 for x,y,s in [(100,245,1),(360,220,.7),(1020,245,.7)]:
  a.group(x,y,s);a.path('M-130 16 Q-147 -20 -105 -26 Q-90 -78 -46 -59 Q-14 -99 17 -51 Q66 -70 77 -27 Q120 -26 118 16 Z','#FFF0CF',4);a.end()
 # River and wooded banks.
 a.path('M0 547 Q228 493 430 543 Q620 589 790 533 Q1030 480 1600 545 V900 H0 Z','#357FB9',6)
 a.path('M0 515 Q189 441 414 482 Q524 495 620 474 L635 567 Q365 544 0 604 Z',S,6)
 a.path('M951 515 Q1131 415 1280 429 Q1455 425 1600 477 V614 Q1350 565 1030 599 Z',S,6)
 # Lavra ensemble at left, unmistakable tall bell tower and gold domes.
 a.rect(37,434,475,116,'#E8D9AC',4,5)
 for xx in range(57,489,34):a.rect(xx,470,15,45,'#0057B7',7,3)
 for xx,yy,ss in [(75,421,.73),(155,396,.95),(248,418,.70),(428,413,.88)]:dome(a,xx,yy,ss)
 a.rect(286,294,76,230,'#FFF0CF',2,5)
 a.rect(277,352,94,15,GOLD,1,4);a.rect(280,416,88,13,GOLD,1,4)
 a.rect(293,250,62,47,'#FFF0CF',2,4)
 dome(a,324,250,.80)
 for yy in [308,371,445]:
  for xx in [299,327]:a.rect(xx,yy,20,32,'#0057B7',10,3)
 a.path('M273 528 H375 L383 551 H264 Z','#FFF0CF',4)
 # St Andrew's Church: turquoise baroque body, central dome, four corner spires.
 a.path('M1114 505 L1166 412 H1390 L1440 506 Z','#FFF0CF',5)
 a.rect(1172,380,212,125,'#FFF0CF',2,5)
 a.rect(1200,348,156,153,S,3,5)
 a.path('M1186 381 L1278 321 L1370 381 Z','#FFF0CF',5)
 for xx in [1212,1242,1293,1323]:a.rect(xx,392,12,97,'#FFF0CF',2,2)
 a.rect(1260,435,36,65,'#0057B7',18,4)
 for xx,yy,ss in [(1185,359,.50),(1370,359,.50),(1210,325,.43),(1345,325,.43),(1278,295,.95)]:dome(a,xx,yy,ss)
 a.path('M1148 509 H1408 M1135 520 H1422 M1121 532 H1437','none',6,'#FFF0CF')
 # River ripples and foreground.
 for x,y,w in [(50,652,235),(1050,649,280),(1230,702,230),(85,735,350),(1110,768,360)]:a.path(f'M{x} {y} h{w}','none',5,'#82B6CF')
 a.path('M0 835 Q300 775 586 835 Q855 785 1060 830 Q1380 801 1600 852 V900 H0 Z',SP,6)
 # Three-quarter Cossack body with white embroidered shirt and red sash.
 a.ellipse(800,846,270,26,'#182019',0)
 a.path('M650 689 L627 838 Q680 864 735 835 L793 749 L834 843 Q900 862 964 832 L944 689 Z','#6C3540',9)
 a.path('M654 745 Q682 780 687 844 M928 748 Q901 790 904 847','none',6,'#492C32')
 # Arms and torso.
 a.path('M660 490 Q584 497 531 578 L492 687 Q507 728 554 715 L640 634 Z','#FFF0CF',9)
 a.path('M927 492 Q1009 503 1051 580 L1095 680 Q1081 727 1037 709 L948 628 Z','#FFF0CF',9)
 a.path('M663 483 Q793 457 926 484 L963 715 Q810 758 623 714 Z','#FFF0CF',10)
 a.path('M650 629 L633 711 Q801 746 956 712 L942 661 Q801 692 650 666 Z','#DDD1AC',0)
 a.path('M640 702 Q800 733 956 701 L957 741 Q795 775 632 739 Z','#BA2D35',8)
 a.path('M932 729 L984 761 L973 833 L945 813 L928 840 L919 752 Z','#BA2D35',7)
 a.path('M953 760 L956 807','none',4,'#E2604C')
 # Cuffs and dense cross stitch bands.
 a.path('M509 646 L567 667 L550 711 L493 689 Z','#FFF0CF',5)
 a.path('M1024 666 L1076 643 L1094 683 L1042 709 Z','#FFF0CF',5)
 for yy in range(516,684,14):
  for xx in [775,791,807,823]:cross(a,xx,yy,1.5, '#B72C33' if (yy//14)%2 else O)
 for j in range(5):
  for k in range(3):
   cross(a,516+j*9+k*3,662+k*11,1.1,'#B72C33' if k!=1 else O)
   cross(a,1041+j*9-k*3,680-k*11,1.1,'#B72C33' if k!=1 else O)
 for xx in range(670,932,14):cross(a,xx,508+abs(xx-800)*.12,1.4)
 # Hands with no weapons.
 a.path('M492 685 Q466 670 456 690 Q439 714 465 726 Q480 749 509 731 L538 718 Z',G,7)
 a.path('M1090 680 Q1119 660 1130 680 Q1155 700 1135 720 Q1113 742 1085 725 L1058 711 Z',G,7)
 # Visible chest embroidery bands, beside the chain and pendant.
 for xx in [707,724,877,894]:
  for yy in range(553,695,13):cross(a,xx,yy,1.25,'#B72C33' if yy%3 else O)
 # Exact source head, at 0.77 scale. Top of head at y240.
 a.image(HEAD,405,106,790,790)
 # Long oseledets, curled behind the ear, drawn from crown to back-right.
 a.path('M783 273 Q791 209 843 222 Q915 235 1008 324 Q1065 360 1042 399 Q1029 419 1009 408 Q1025 426 1044 421 Q1083 404 1064 363 Q1043 320 946 258 Q871 203 827 224 Q809 233 800 280 Z','#07130B',7)
 # Chain links over the shirt, then exact source pendant.
 a.path('M627 531 Q800 684 978 531','none',22,O)
 a.path('M627 531 Q800 684 978 531','none',13,GOLD)
 for i in range(13):
  t=i/12;x=632+340*t;y=537+100*math.sin(math.pi*t)
  a.raw(f'<rect x="{x-14}" y="{y-5}" width="28" height="10" rx="5" transform="rotate({42-84*t} {x} {y})" fill="{GOLD}" stroke="{O}" stroke-width="3"/>')
 a.image(TAG,760,620,86,127)
 # Drooping dark Cossack moustache preserves visible flat mouth above.
 a.path('M794 463 Q762 451 741 473 Q715 502 721 543 Q690 531 699 502 Q701 472 730 453 Q762 434 794 451 Q820 434 851 453 Q882 472 884 502 Q891 533 864 546 Q867 506 841 476 Q817 456 794 463 Z','#07130B',6)
 for x,y,s in [(89,821,1.05),(159,858,.75),(1402,758,.95),(1531,751,1.1),(55,893,.6)]:flower(a,x,y,s)
 return a.save('artifacts/uk-toad-clean.png')

# Compact foods drawn in a 120 x 85 foreground coordinate space.
def food(a,code):
 if code=='en':
  a.path('M17 28 L100 28 L65 89 Z','#E8D9AC',3)
  for x,y,r in [(28,5,-12),(40,1,5),(54,7,-3),(67,3,12),(79,8,15)]:
   a.raw(f'<rect x="{x}" y="{y}" width="8" height="43" rx="2" transform="rotate({r} {x} {y})" fill="#F5C451" stroke="{O}" stroke-width="2"/>')
  a.path('M30 33 Q46 10 89 31 L100 43 L88 51 Q47 62 30 33 Z','#BD8136',3)
  a.path('M42 34 Q64 27 83 38','none',2,GOLD)
 elif code=='zh':
  for x in [33,88]:a.ellipse(x,8,15,16,'#07130B',2)
  a.ellipse(60,52,41,37,'#FFF0CF',3)
  a.ellipse(60,25,39,29,'#FFF0CF',3)
  for x in [43,76]:
   a.ellipse(x,25,12,15,'#07130B',1);a.ellipse(x+2,23,3,4,'#FFF0CF',0)
  a.ellipse(60,37,6,4,'#07130B',0)
  a.path('M60 40 Q55 48 50 43 M60 40 Q65 48 70 43','none',2)
  a.ellipse(30,64,13,23,'#07130B',2);a.ellipse(91,64,13,23,'#07130B',2)
 elif code=='es':
  a.path('M8 55 L-3 49 M111 55 L123 49','none',6)
  a.ellipse(60,55,53,27,'#303831',3);a.ellipse(60,46,51,24,'#E0A839',3)
  for x,y in [(24,44),(48,33),(73,49),(96,42),(46,57)]:
   a.path(f'M{x-6} {y+4} q-9 -12 4 -13 q14 0 10 12','none',5,'#D06643')
  for x,y in [(38,42),(63,58),(86,33),(24,56)]:a.ellipse(x,y,3,3,SP,0)
  a.path('M58 36 L67 26 L76 35 Z','#FFF0CF',2)
 elif code=='fr':
  a.path('M63 68 Q46 51 55 33 L85 -9 Q100 -19 110 -7 Q115 3 107 16 L81 70 Z','#D89A45',3)
  for x,y in [(74,29),(84,15),(63,44)]:a.path(f'M{x} {y} l15 4','none',3,'#FFF0CF')
  a.path('M4 57 Q2 30 29 24 Q55 22 66 48 L61 64 L46 51 L30 48 L17 65 Z','#E8AC4E',3)
  a.path('M21 30 L28 48 M37 28 L40 48 M50 34 L49 52','none',3,'#A57034')
 elif code=='tr':
  a.path('M30 24 L95 24 L78 87 L47 87 Z','#FFF0CF',3)
  a.ellipse(63,25,34,16,'#D79C56',3)
  a.path('M34 25 l12 -9 l10 9 l13 -12 l15 12 l10 -4','none',9,SP)
  a.path('M39 30 l12 -5 l13 9 l14 -9 l10 5','none',8,'#944E33')
  a.path('M43 47 L86 39 M47 59 L81 51','none',3,'#D2B98C')
 elif code=='hi':
  a.path('M15 32 H67 L61 73 Q41 85 21 72 Z','#D8A45D',3)
  a.ellipse(41,32,26,8,'#93552D',3)
  a.path('M67 41 Q94 35 84 58 Q77 66 64 61','none',6,'#D8A45D')
  a.path('M77 81 L100 31 L122 80 Z','#E3B45F',3)
  a.path('M100 34 L102 72 L119 80','none',2,'#A57538')
 elif code=='uk':
  a.ellipse(59,74,54,10,'#FFF0CF',3)
  a.path('M11 35 H109 Q104 80 60 81 Q19 80 11 35 Z','#4DA1AD',3)
  a.ellipse(60,35,49,17,'#A82A37',3)
  a.path('M44 31 Q52 17 63 26 Q82 20 83 33 Q64 47 44 31 Z','#FFF0CF',2)
  for x,y in [(29,34),(47,41),(87,34)]:a.path(f'M{x} {y} l7 -4','none',3,SP)
 elif code=='ru':
  # A freestanding wedge of Kyiv cake: meringue tiers, cream rosettes.
  a.ellipse(60,78,59,10,'#FFF0CF',2)
  a.path('M14 41 L85 14 L110 42 V73 L14 73 Z','#C08A58',3)
  a.path('M16 49 H108 V56 H16 Z','#FFF0CF',1)
  a.path('M16 63 H108 V69 H16 Z','#FFF0CF',1)
  a.path('M14 41 L85 14 L110 42 Z','#D9B777',3)
  for x,y,col in [(78,24,'#E6A5A1'),(93,35,'#FFF0CF'),(55,33,'#F5C451')]:
   for k in range(5):a.ellipse(x+5*math.cos(k*1.256),y+4*math.sin(k*1.256),5,4,col,1)
   a.ellipse(x,y,3,3,'#FFF0CF',1)
  a.path('M37 37 Q36 24 49 29 Q49 37 37 37',S,1)
  for x,y in [(26,44),(44,58),(71,61),(93,47)]:a.ellipse(x,y,2,2,'#8A5936',0)
 elif code=='ja':
  a.ellipse(60,68,57,20,'#FFF0CF',3)
  for x,y in [(30,49),(58,58),(86,46)]:
   a.rect(x-12,y-4,25,22,'#FFF0CF',5,2)
   a.path(f'M{x-15} {y-3} q14 -14 30 0 l-2 10 h-25 Z','#DE856D',2)
   a.path(f'M{x-5} {y-7} l-1 12 M{x+5} {y-7} l-1 12','none',2,'#FFF0CF')
  a.path('M100 63 l8 -13 l8 13 Z',S,2)
 elif code=='ko':
  a.path('M20 55 L10 86 M100 55 L110 86','none',6)
  a.ellipse(60,50,54,29,'#303831',3)
  a.ellipse(60,42,51,24,'#9EA69F',3)
  for x in range(22,110,12):a.path(f'M{x} 27 V58','none',2)
  for y in [31,40,49,58]:a.path(f'M15 {y} H105','none',2)
  for x,y in [(32,34),(60,45),(87,32)]:
   a.path(f'M{x-12} {y-4} q8 -8 24 0 l-2 13 q-14 7 -23 -1 Z','#A85B43',2)
   a.path(f'M{x-7} {y-3} l-1 12 M{x+2} {y-3} l-1 13','none',2,'#5A3327')

LABELS=[]
def langs():
 a=Art('#0D120E')
 # Stylized world map, a single faint flat tone.
 continents=[ 'M120 271 L179 211 L272 198 L328 232 L395 216 L448 263 L421 304 L364 318 L341 365 L279 354 L242 399 L212 351 L157 340 Z', 'M363 411 L430 436 L452 504 L426 568 L412 638 L373 693 L349 656 L361 590 L325 517 L327 457 Z','M635 250 L680 215 L746 235 L777 282 L745 320 L687 316 L670 356 L629 326 Z','M681 349 L762 340 L826 406 L807 465 L765 490 L744 558 L703 545 L661 479 L646 403 Z','M776 247 L853 204 L953 225 L1024 194 L1121 231 L1203 211 L1390 277 L1438 321 L1370 347 L1318 325 L1278 380 L1214 360 L1180 425 L1114 440 L1086 387 L1039 368 L1001 322 L945 344 L904 313 L850 339 L801 305 Z','M1234 551 L1294 529 L1363 550 L1410 593 L1374 630 L1291 622 L1248 643 L1216 600 Z','M1107 442 L1140 454 L1167 502 L1138 517 L1107 488 Z']
 for d in continents:a.path(d,'#182019',0)
 # Ground spotlight, flat rather than a gradient.
 a.ellipse(805,805,300,39,'#182019',0)
 # Big suitcase with wheels, handle and decorative shape-only stickers.
 a.rect(995,540,71,89,'#0D120E',12,7,stroke=GOLD)
 a.rect(941,601,191,201,'#BF863D',20,8)
 a.rect(951,611,171,179,'#E1AC56',15,4)
 a.rect(968,609,16,180,'#794F2D',5,3);a.rect(1092,609,15,180,'#794F2D',5,3)
 a.ellipse(975,809,11,13,'#07130B',4);a.ellipse(1104,809,11,13,'#07130B',4)
 a.ellipse(1024,652,24,24,'#0057B7',3)
 a.path('M1010 663 L1024 634 L1038 663 Z','#FFD700',3)
 a.path('M1000 715 L1035 695 L1059 723 L1023 746 Z','#BA664A',3)
 a.ellipse(1077,753,21,21,'#FFF0CF',3)
 a.path('M1066 756 Q1077 737 1089 756 Q1078 770 1066 756 Z',S,2)
 a.rect(1064,675,29,26,'#785B94',6,3)
 a.path('M1070 685 l9 -6 l8 7 l-9 7 Z','#E1AC56',2)
 # Traveler body extends below original bust.
 a.path('M652 655 L641 785 Q681 810 739 789 L788 711 L825 788 Q881 807 935 782 L923 653 Z','#07130B',9)
 a.path('M650 778 Q681 762 727 786 L741 816 Q691 833 628 813 Z',G,7)
 a.path('M840 786 Q887 761 931 783 L957 813 Q894 837 831 815 Z',G,7)
 # Source bust: exact head, black tank, chain, tag, spots.
 a.image(MARK,482,166,628,628)
 # Hat fits atop original crown, keeping eyelids fully visible.
 a.path('M651 303 L676 217 Q724 193 768 217 Q803 224 848 206 Q890 216 905 296 Z','#C8A064',8)
 a.path('M663 268 Q787 288 897 262 L905 295 Q779 329 651 302 Z','#795D38',6)
 a.path('M608 292 Q748 321 936 281 Q964 280 959 300 Q801 357 615 322 Q585 309 608 292 Z','#DAB67B',7)
 a.path('M700 231 L688 266 M865 229 L879 263','none',4,'#795D38')
 # The suitcase handle is held by the same green hand.
 a.path('M1010 560 Q997 546 985 559 Q970 571 981 585 L1001 594 Q1024 593 1030 574 Z',G,6)
 a.path('M991 563 L1004 576 M1000 557 L1014 570','none',3)
 # Ten staggered badges; all share the exact reference bust.
 codes=['en','zh','es','fr','tr','hi','uk','ru','ja','ko']
 for idx,code in enumerate(codes):
  j=idx%5;left=idx<5;x=160 if j%2==0 else 365
  if not left:x=1440 if j%2==0 else 1235
  y=252+j*122
  a.ellipse(x,y,94,94,'#222B24',4,stroke='#222B24')
  a.ellipse(x,y,86,86,'#182019',3,stroke=GOLD)
  # Connected forearms extend the source bust naturally toward the held item.
  a.path(f'M{x-55} {y+7} Q{x-62} {y+37} {x-43} {y+51} L{x-27} {y+53} L{x-25} {y+40} L{x-40} {y+30} L{x-39} {y+9} Z',G,3)
  a.path(f'M{x+55} {y+7} Q{x+62} {y+37} {x+43} {y+51} L{x+27} {y+53} L{x+25} {y+40} L{x+40} {y+30} L{x+39} {y+9} Z',G,3)
  a.image(MARK,x-79,y-99,158,158)
  # Two small hands visibly hold each food/symbol.
  a.ellipse(x-34,y+48,11,8,G,3);a.ellipse(x+34,y+48,11,8,G,3)
  if code=='zh':
   a.group(x,y+6,.70);food(a,code);a.end()
   a.path(f'M{x+63} {y+35} Q{x+78} {y+49} {x+62} {y+62} L{x+48} {y+62} Q{x+37} {y+54} {x+47} {y+48} L{x+59} {y+48} Z',G,3)
  else:
   a.group(x-31.2,y+29,.52);food(a,code);a.end()
  LABELS.append((code,x,y+80))
 return a.save('artifacts/langs-toad-clean.png')

uk();langs()
# All text comes from supplied PNGs. Only uniform LANCZOS resizing is used.
placements={}
def overlay(im,path,x,y,w=None,h=None,plate=False,pad=8):
 src=Image.open(path).convert('RGBA')
 if w is not None:h=round(src.height*w/src.width)
 else:w=round(src.width*h/src.height)
 src=src.resize((w,h),Image.Resampling.LANCZOS)
 if plate:
  layer=Image.new('RGBA',im.size);d=ImageDraw.Draw(layer);d.rounded_rectangle((x-pad,y-pad,x+w+pad,y+h+pad),radius=14,fill=(0,0,0,184));im.alpha_composite(layer)
 im.alpha_composite(src,(x,y))
 return {'file':path,'x':x,'y':y,'width':w,'height':h,'plate':plate,'platePadding':pad if plate else 0,'plateOpacity':184/255 if plate else 0}
for kind in ['uk','langs']:
 im=Image.open(f'artifacts/{kind}-toad-clean.png').convert('RGBA');p=[]
 w=1420 if kind=='uk' else 1200;x=(1600-w)//2
 p.append(overlay(im,f'posters/text/{kind}-title.png',x,47,w=w,plate=True,pad=7))
 if kind=='langs':
  for code,cx,y in LABELS:
   src=Image.open(f'posters/text/lang-{code}.png');ww=round(src.width*34/src.height)
   p.append(overlay(im,f'posters/text/lang-{code}.png',cx-ww//2,y,h=34,plate=True,pad=6))
 w=340;src=Image.open('posters/text/site.png');h=round(src.height*w/src.width)
 x=1220 if kind=='uk' else 630;y=900-40-h
 p.append(overlay(im,'posters/text/site.png',x,y,w=w))
 im.convert('RGB').save(f'artifacts/{kind}-toad.png');placements[kind]=p
Path('test/scratch/placements.json').write_text(json.dumps(placements,indent=2))
print(json.dumps(placements,indent=2))

```
