← back to Wallco Ai
reroll geometric-block-leaves via programmatic SVG tessellation (DTD-C): 19 tiles, 2-ink navy/cream, seamless-by-construction, vector master kept; gen-geom-svg-tessellate.js + svg_raster_snap.py
22eba6a89b803d57eeef4d6b4a99f563e9f837fe · 2026-05-27 16:44:19 -0700 · Steve Abrams
Files touched
M data/auto-decide-ledger.jsonlM data/rescreen-voids-ledger.jsonlA data/svgtess-manifest.jsonA scripts/gen-geom-svg-tessellate.jsA scripts/svg_raster_snap.py
Diff
commit 22eba6a89b803d57eeef4d6b4a99f563e9f837fe
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed May 27 16:44:19 2026 -0700
reroll geometric-block-leaves via programmatic SVG tessellation (DTD-C): 19 tiles, 2-ink navy/cream, seamless-by-construction, vector master kept; gen-geom-svg-tessellate.js + svg_raster_snap.py
---
data/auto-decide-ledger.jsonl | 269 +++++++++++++++++++++++++++++++++++++
data/rescreen-voids-ledger.jsonl | 126 +++++++++++++++++
data/svgtess-manifest.json | 7 +
scripts/gen-geom-svg-tessellate.js | 186 +++++++++++++++++++++++++
scripts/svg_raster_snap.py | 31 +++++
5 files changed, 619 insertions(+)
diff --git a/data/auto-decide-ledger.jsonl b/data/auto-decide-ledger.jsonl
index e154e54..051e348 100644
--- a/data/auto-decide-ledger.jsonl
+++ b/data/auto-decide-ledger.jsonl
@@ -3430,3 +3430,272 @@
{"t":"2026-05-27T23:33:29.944Z","id":47303,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating sloth motif."}
{"t":"2026-05-27T23:33:32.196Z","id":47304,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of sloths on branches."}
{"t":"2026-05-27T23:33:34.345Z","id":47305,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating sloth motif."}
+{"t":"2026-05-27T23:33:36.780Z","id":47311,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile with a repeating pattern of palm trees and monkeys."}
+{"t":"2026-05-27T23:33:39.028Z","id":47318,"verdict":"not","reason":"centered-hero (n=3)","see":"A centered sloth motif with partial motifs in the corners."}
+{"t":"2026-05-27T23:33:41.166Z","id":47322,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:33:43.350Z","id":47337,"verdict":"hot_candidate","n":5,"see":"The image shows a wallpaper repeat of parrots on branches."}
+{"t":"2026-05-27T23:33:45.562Z","id":47338,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:33:47.639Z","id":47360,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:33:49.870Z","id":47380,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:33:52.145Z","id":47403,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of red pandas and foliage."}
+{"t":"2026-05-27T23:33:54.346Z","id":47404,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper repeat of animal motifs."}
+{"t":"2026-05-27T23:33:56.600Z","id":47405,"verdict":"hot_candidate","n":6,"see":"The tile shows a repeating pattern of a lion-like creature."}
+{"t":"2026-05-27T23:33:58.844Z","id":47461,"verdict":"hot_candidate","n":8,"see":"This is a wallpaper tile with a repeating pattern of red pandas."}
+{"t":"2026-05-27T23:34:01.259Z","id":47537,"verdict":"hot_candidate","n":10,"see":"A wallpaper tile with a repeating pattern of monkeys on pedestals."}
+{"t":"2026-05-27T23:34:03.751Z","id":47538,"verdict":"hot_candidate","n":10,"see":"A repeating wallpaper pattern of monkeys on pedestals."}
+{"t":"2026-05-27T23:34:06.110Z","id":47539,"verdict":"hot_candidate","n":10,"see":"This is a wallpaper tile with a repeating pattern of monkeys on pedestals."}
+{"t":"2026-05-27T23:34:08.432Z","id":47599,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of gorillas, bottles, and glasses."}
+{"t":"2026-05-27T23:34:10.603Z","id":47600,"verdict":"hot_candidate","n":8,"see":"A repeating pattern of monkeys and barware."}
+{"t":"2026-05-27T23:34:12.918Z","id":47649,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:34:15.119Z","id":47650,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of giraffes."}
+{"t":"2026-05-27T23:34:17.317Z","id":47793,"verdict":"hot_candidate","n":4,"see":"I see a repeating pattern of a vase and two creatures."}
+{"t":"2026-05-27T23:34:19.598Z","id":47794,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of stylized lizards and vases."}
+{"t":"2026-05-27T23:34:21.868Z","id":47888,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:34:24.342Z","id":47889,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:34:26.405Z","id":47891,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:34:28.565Z","id":47902,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:34:30.678Z","id":47912,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of sloths and monkeys in trees."}
+{"t":"2026-05-27T23:34:32.804Z","id":47913,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of sloths and palm trees."}
+{"t":"2026-05-27T23:34:34.806Z","id":47914,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating sloth motif."}
+{"t":"2026-05-27T23:34:36.786Z","id":47923,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:34:39.011Z","id":47924,"verdict":"hot_candidate","n":6,"see":"A repeating wallpaper tile with giraffe motifs."}
+{"t":"2026-05-27T23:34:41.182Z","id":47933,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:34:43.450Z","id":47934,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:34:45.756Z","id":47947,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of lemurs and palm trees."}
+{"t":"2026-05-27T23:34:48.059Z","id":47948,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of lemurs and palm trees."}
+{"t":"2026-05-27T23:34:50.355Z","id":47949,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of lemurs and palm trees."}
+{"t":"2026-05-27T23:34:52.621Z","id":48014,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:34:54.666Z","id":48028,"verdict":"not","reason":"centered-hero (n=5)","see":"A centered frog motif with other frogs around it."}
+{"t":"2026-05-27T23:34:56.998Z","id":48030,"verdict":"hot_candidate","n":4,"see":"Four giraffe motifs are visible in a repeating pattern."}
+{"t":"2026-05-27T23:34:59.248Z","id":48035,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:35:01.470Z","id":48036,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:35:05.016Z","id":48039,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:35:07.365Z","id":48043,"verdict":"hot_candidate","n":15,"see":"A repeating pattern of animal and tree silhouettes."}
+{"t":"2026-05-27T23:35:09.731Z","id":48044,"verdict":"hot_candidate","n":20,"see":"A repeating pattern of animal silhouettes and palm trees."}
+{"t":"2026-05-27T23:35:11.870Z","id":48045,"verdict":"hot_candidate","n":15,"see":"A repeating pattern of animal and tree silhouettes."}
+{"t":"2026-05-27T23:35:14.245Z","id":48046,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:35:16.545Z","id":48051,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:35:18.769Z","id":48056,"verdict":"hot_candidate","n":4,"see":"A repeating wallpaper tile with a monkey and champagne bottle motif."}
+{"t":"2026-05-27T23:35:20.884Z","id":48103,"verdict":"hot_candidate","n":16,"see":"A repeating pattern of lemurs and raccoons."}
+{"t":"2026-05-27T23:35:23.498Z","id":48112,"verdict":"hot_candidate","n":25,"see":"This is a wallpaper repeat of racoon motifs."}
+{"t":"2026-05-27T23:35:25.663Z","id":48113,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of lemurs and raccoons."}
+{"t":"2026-05-27T23:35:27.876Z","id":48114,"verdict":"hot_candidate","n":15,"see":"A repeating pattern of lemurs and foliage."}
+{"t":"2026-05-27T23:35:29.856Z","id":48145,"verdict":"hot_candidate","n":4,"see":"The image shows a repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:35:32.047Z","id":48146,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating giraffe and tree motif."}
+{"t":"2026-05-27T23:35:34.240Z","id":48163,"verdict":"hot_candidate","n":20,"see":"A wallpaper tile with a repeating elephant motif."}
+{"t":"2026-05-27T23:35:36.495Z","id":48174,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:35:38.776Z","id":48175,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:35:43.937Z","id":48176,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating pattern of giraffes and other objects."}
+{"t":"2026-05-27T23:35:46.015Z","id":48177,"verdict":"hot_candidate","n":8,"see":"A repeating pattern of frogs."}
+{"t":"2026-05-27T23:35:48.363Z","id":48194,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of llama-like animals and trees."}
+{"t":"2026-05-27T23:35:50.518Z","id":48209,"verdict":"hot_candidate","n":4,"see":"I see a repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:35:52.763Z","id":48210,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:35:55.055Z","id":48219,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:35:57.108Z","id":48220,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of giraffes."}
+{"t":"2026-05-27T23:35:59.287Z","id":48240,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of monkeys and cocktails."}
+{"t":"2026-05-27T23:36:01.298Z","id":48241,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of sloths on branches with cocktails."}
+{"t":"2026-05-27T23:36:03.653Z","id":48246,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile featuring a repeating giraffe motif."}
+{"t":"2026-05-27T23:36:05.750Z","id":48256,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating monkey motif."}
+{"t":"2026-05-27T23:36:07.873Z","id":48257,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of monkeys and palm trees."}
+{"t":"2026-05-27T23:36:10.093Z","id":48258,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of giraffes and vases."}
+{"t":"2026-05-27T23:36:12.233Z","id":48260,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile with a repeating pattern of raccoons and trees."}
+{"t":"2026-05-27T23:36:14.439Z","id":48261,"verdict":"hot_candidate","n":7,"see":"This is a wallpaper tile with a repeating pattern of pandas and raccoons among trees."}
+{"t":"2026-05-27T23:36:16.540Z","id":48267,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating giraffe and vase motif."}
+{"t":"2026-05-27T23:36:18.648Z","id":48294,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating parrot motif."}
+{"t":"2026-05-27T23:36:20.896Z","id":48299,"verdict":"hot_candidate","n":4,"see":"The tile shows a repeating pattern of parrots on branches."}
+{"t":"2026-05-27T23:36:23.166Z","id":48300,"verdict":"hot_candidate","n":4,"see":"Four parrot motifs are visible in a repeating pattern."}
+{"t":"2026-05-27T23:36:25.183Z","id":48307,"verdict":"hot_candidate","n":7,"see":"The tile shows a repeating pattern of giraffes and palm trees."}
+{"t":"2026-05-27T23:36:27.417Z","id":48308,"verdict":"hot_candidate","n":7,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:36:29.907Z","id":48331,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of deer in a forest."}
+{"t":"2026-05-27T23:36:32.027Z","id":48332,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of deer and trees."}
+{"t":"2026-05-27T23:36:34.195Z","id":48400,"verdict":"not","reason":"centered-hero (n=1)","see":"A centered elephant motif with partial motifs around the edges."}
+{"t":"2026-05-27T23:36:36.415Z","id":48401,"verdict":"not","reason":"centered-hero (n=1)","see":"A centered elephant motif with partial motifs around the edges."}
+{"t":"2026-05-27T23:36:38.550Z","id":48444,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots on branches."}
+{"t":"2026-05-27T23:36:40.956Z","id":48445,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots on branches."}
+{"t":"2026-05-27T23:36:43.442Z","id":48449,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of animal silhouettes."}
+{"t":"2026-05-27T23:36:45.605Z","id":48450,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of animal silhouettes."}
+{"t":"2026-05-27T23:36:47.738Z","id":48455,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of elephants and trees."}
+{"t":"2026-05-27T23:36:49.972Z","id":48460,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile featuring a repeating pattern of elephants in a forest."}
+{"t":"2026-05-27T23:36:52.113Z","id":48462,"verdict":"hot_candidate","n":5,"see":"The tile shows a repeating pattern of elephants and trees."}
+{"t":"2026-05-27T23:36:54.226Z","id":48480,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating giraffe and tree motif."}
+{"t":"2026-05-27T23:36:56.498Z","id":48535,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of elephants."}
+{"t":"2026-05-27T23:36:58.657Z","id":48536,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of elephants."}
+{"t":"2026-05-27T23:37:01.146Z","id":48604,"verdict":"hot_candidate","n":4,"see":"A repeating wallpaper tile with a monkey motif."}
+{"t":"2026-05-27T23:37:05.732Z","id":48612,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:37:07.938Z","id":48623,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of parrots on branches."}
+{"t":"2026-05-27T23:37:10.037Z","id":48624,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots on branches."}
+{"t":"2026-05-27T23:37:12.069Z","id":48630,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating sloth motif."}
+{"t":"2026-05-27T23:37:14.225Z","id":48631,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of parrots and flowers."}
+{"t":"2026-05-27T23:37:30.615Z","id":48657,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:37:32.909Z","id":48658,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:37:35.291Z","id":48659,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:37:37.718Z","id":48669,"verdict":"hot_candidate","n":14,"see":"The image shows a wallpaper repeat of panda motifs."}
+{"t":"2026-05-27T23:37:40.030Z","id":48670,"verdict":"hot_candidate","n":14,"see":"The image shows a wallpaper tile with a repeating pattern of pandas and various objects."}
+{"t":"2026-05-27T23:37:42.263Z","id":48703,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of mythical creatures and trees."}
+{"t":"2026-05-27T23:37:44.380Z","id":48710,"verdict":"not","reason":"centered-hero (n=4)","see":"A centered elephant motif with wrap-around fragments."}
+{"t":"2026-05-27T23:37:46.459Z","id":48711,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots and trees."}
+{"t":"2026-05-27T23:37:48.665Z","id":48712,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper repeat of parrots and palm trees."}
+{"t":"2026-05-27T23:37:51.172Z","id":48714,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of lemurs and palm trees."}
+{"t":"2026-05-27T23:37:53.198Z","id":48722,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of parrots and trees."}
+{"t":"2026-05-27T23:37:55.489Z","id":48724,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:37:57.786Z","id":48731,"verdict":"hot_candidate","n":15,"see":"This is a wallpaper tile with a repeating pattern of mushrooms, trees, and animals."}
+{"t":"2026-05-27T23:37:59.993Z","id":48742,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of mushrooms, trees, and animals."}
+{"t":"2026-05-27T23:38:02.210Z","id":48743,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of lemurs and palm trees."}
+{"t":"2026-05-27T23:38:04.476Z","id":48744,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of lemurs in palm trees."}
+{"t":"2026-05-27T23:38:06.554Z","id":48755,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of parrots and branches."}
+{"t":"2026-05-27T23:38:08.590Z","id":48756,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots and branches."}
+{"t":"2026-05-27T23:38:11.195Z","id":48764,"verdict":"hot_candidate","n":9,"see":"A repeating pattern of mushrooms and plants."}
+{"t":"2026-05-27T23:38:13.354Z","id":48765,"verdict":"hot_candidate","n":9,"see":"A repeating pattern of mushrooms and plants."}
+{"t":"2026-05-27T23:38:15.649Z","id":48766,"verdict":"hot_candidate","n":8,"see":"A repeating pattern of mushrooms and plants."}
+{"t":"2026-05-27T23:38:17.809Z","id":48795,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:38:20.062Z","id":48802,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:38:22.240Z","id":48845,"verdict":"hot_candidate","n":10,"see":"A wallpaper tile with a repeating pattern of bears and plants."}
+{"t":"2026-05-27T23:38:24.420Z","id":48846,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of bear silhouettes with foliage."}
+{"t":"2026-05-27T23:38:26.341Z","id":48865,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating sloth motif."}
+{"t":"2026-05-27T23:38:28.457Z","id":48880,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of monkeys in trees."}
+{"t":"2026-05-27T23:38:30.647Z","id":48881,"verdict":"hot_candidate","n":4,"see":"I see a repeating pattern of monkeys in trees."}
+{"t":"2026-05-27T23:38:32.710Z","id":48882,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of monkeys in trees."}
+{"t":"2026-05-27T23:38:35.052Z","id":48896,"verdict":"hot_candidate","n":9,"see":"A repeating wallpaper pattern of monkeys, bottles, and glasses."}
+{"t":"2026-05-27T23:38:37.372Z","id":48897,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of monkeys, bottles, and glasses."}
+{"t":"2026-05-27T23:38:39.662Z","id":48898,"verdict":"hot_candidate","n":10,"see":"A repeating wallpaper pattern of monkeys, bottles, and glasses."}
+{"t":"2026-05-27T23:38:41.957Z","id":48899,"verdict":"hot_candidate","n":15,"see":"A repeating pattern of various animals."}
+{"t":"2026-05-27T23:38:44.400Z","id":48926,"verdict":"hot_candidate","n":20,"see":"This is a wallpaper repeat of giraffe motifs."}
+{"t":"2026-05-27T23:38:46.677Z","id":48943,"verdict":"hot_candidate","n":15,"see":"A repeating wallpaper tile with a giraffe motif."}
+{"t":"2026-05-27T23:38:48.832Z","id":48952,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of silhouetted palm trees and animals."}
+{"t":"2026-05-27T23:38:51.081Z","id":48953,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of silhouetted jungle trees and animals."}
+{"t":"2026-05-27T23:38:53.277Z","id":48965,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating floral motif."}
+{"t":"2026-05-27T23:38:55.493Z","id":48966,"verdict":"hot_candidate","n":4,"see":"There are multiple instances of a floral motif in a repeating pattern."}
+{"t":"2026-05-27T23:38:57.879Z","id":48982,"verdict":"hot_candidate","n":5,"see":"Repeating pattern of elephants and lamps."}
+{"t":"2026-05-27T23:39:00.082Z","id":48997,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper repeat of parrots and palm trees."}
+{"t":"2026-05-27T23:39:02.235Z","id":49065,"verdict":"hot_candidate","n":3,"see":"A wallpaper tile with a repeating pattern of sloths in trees."}
+{"t":"2026-05-27T23:39:04.304Z","id":49066,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating pattern of monkeys in trees."}
+{"t":"2026-05-27T23:39:06.654Z","id":49106,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of deer and trees."}
+{"t":"2026-05-27T23:39:08.760Z","id":49111,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:39:11.040Z","id":49163,"verdict":"hot_candidate","n":8,"see":"This is a wallpaper repeat of giraffes and trees."}
+{"t":"2026-05-27T23:39:13.223Z","id":49172,"verdict":"hot_candidate","n":7,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:39:15.534Z","id":49186,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating parrot motif."}
+{"t":"2026-05-27T23:39:17.584Z","id":49187,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of parrots."}
+{"t":"2026-05-27T23:39:19.673Z","id":49199,"verdict":"hot_candidate","n":8,"see":"A repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:39:21.986Z","id":49200,"verdict":"hot_candidate","n":8,"see":"A repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:39:24.235Z","id":49201,"verdict":"hot_candidate","n":10,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:39:26.374Z","id":49202,"verdict":"hot_candidate","n":8,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:39:28.676Z","id":49205,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of animal portraits."}
+{"t":"2026-05-27T23:39:31.077Z","id":49206,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of stylized animal faces."}
+{"t":"2026-05-27T23:39:33.139Z","id":49211,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of animal portraits."}
+{"t":"2026-05-27T23:39:35.281Z","id":49214,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots."}
+{"t":"2026-05-27T23:39:37.722Z","id":49224,"verdict":"hot_candidate","n":16,"see":"A wallpaper tile with a repeating pattern of pandas and raccoons."}
+{"t":"2026-05-27T23:39:40.049Z","id":49225,"verdict":"hot_candidate","n":15,"see":"A repeating pattern of pandas and raccoons with bamboo."}
+{"t":"2026-05-27T23:39:42.399Z","id":49226,"verdict":"hot_candidate","n":15,"see":"A wallpaper tile with a repeating pattern of pandas and other animals."}
+{"t":"2026-05-27T23:39:44.433Z","id":49250,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of horses and goats."}
+{"t":"2026-05-27T23:39:46.448Z","id":49255,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of horses and goats."}
+{"t":"2026-05-27T23:39:48.357Z","id":49256,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of horses and goats."}
+{"t":"2026-05-27T23:39:50.927Z","id":49257,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:39:53.151Z","id":49258,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:39:55.226Z","id":49263,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:39:57.513Z","id":49270,"verdict":"not","reason":"centered-hero (n=4)","see":"A centered lemur motif with wrap-around fragments in the corners."}
+{"t":"2026-05-27T23:39:59.577Z","id":49288,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of red pandas and flowers."}
+{"t":"2026-05-27T23:40:01.670Z","id":49290,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:40:03.802Z","id":49291,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:40:06.074Z","id":49292,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:40:08.187Z","id":49308,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:40:10.243Z","id":49309,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:40:12.487Z","id":49332,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of vase-like motifs within a floral frame."}
+{"t":"2026-05-27T23:40:14.676Z","id":49333,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of urns within a leafy frame."}
+{"t":"2026-05-27T23:40:16.829Z","id":49336,"verdict":"hot_candidate","n":10,"see":"This is a wallpaper tile with a repeating pattern of animal motifs."}
+{"t":"2026-05-27T23:40:19.046Z","id":49337,"verdict":"hot_candidate","n":10,"see":"This is a wallpaper tile with a repeating pattern of animal motifs."}
+{"t":"2026-05-27T23:40:21.360Z","id":49379,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of a person holding a champagne glass."}
+{"t":"2026-05-27T23:40:23.484Z","id":49383,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of parrots in trees."}
+{"t":"2026-05-27T23:40:25.468Z","id":49384,"verdict":"hot_candidate","n":7,"see":"This is a wallpaper tile with a repeating pattern of parrots in trees."}
+{"t":"2026-05-27T23:40:27.741Z","id":49385,"verdict":"hot_candidate","n":10,"see":"A wallpaper tile with repeating monkey and bottle motifs."}
+{"t":"2026-05-27T23:40:30.271Z","id":49428,"verdict":"hot_candidate","n":25,"see":"This is a wallpaper repeat of tanuki motifs on a dark red background."}
+{"t":"2026-05-27T23:40:32.412Z","id":49480,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of frog and candelabra motifs."}
+{"t":"2026-05-27T23:40:34.570Z","id":49481,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of frogs on candelabras."}
+{"t":"2026-05-27T23:40:36.885Z","id":49496,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile with a repeating sloth motif."}
+{"t":"2026-05-27T23:40:39.031Z","id":49497,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating monkey motif."}
+{"t":"2026-05-27T23:40:41.353Z","id":49498,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of monkeys in trees."}
+{"t":"2026-05-27T23:40:44.470Z","id":49499,"verdict":"not","reason":"centered-hero (n=2)","see":"A centered parrot motif with wrap-around fragments."}
+{"t":"2026-05-27T23:40:46.693Z","id":49542,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of vases and mushrooms with animals."}
+{"t":"2026-05-27T23:40:49.032Z","id":49554,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper repeat of giraffe motifs."}
+{"t":"2026-05-27T23:40:51.277Z","id":49555,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper repeat of vase and mushroom motifs."}
+{"t":"2026-05-27T23:40:53.681Z","id":49582,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:40:55.746Z","id":49587,"verdict":"hot_candidate","n":4,"see":"I see a repeating pattern of animals and trees."}
+{"t":"2026-05-27T23:40:57.934Z","id":49595,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of monkeys drinking from bottles."}
+{"t":"2026-05-27T23:41:00.297Z","id":49597,"verdict":"hot_candidate","n":4,"see":"I see a repeating pattern of animals and trees."}
+{"t":"2026-05-27T23:41:02.276Z","id":49598,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of animals and trees."}
+{"t":"2026-05-27T23:41:04.425Z","id":49612,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of giraffes."}
+{"t":"2026-05-27T23:41:06.472Z","id":49619,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of palm trees and monkeys."}
+{"t":"2026-05-27T23:41:09.013Z","id":49689,"verdict":"hot_candidate","n":25,"see":"A repeating pattern of giraffes."}
+{"t":"2026-05-27T23:41:11.361Z","id":49693,"verdict":"hot_candidate","n":25,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:41:13.482Z","id":49717,"verdict":"hot_candidate","n":8,"see":"A repeating pattern of horses and mushrooms."}
+{"t":"2026-05-27T23:41:15.675Z","id":49742,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:41:17.903Z","id":49751,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of giraffes and trees."}
+{"t":"2026-05-27T23:41:20.187Z","id":49752,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:41:22.267Z","id":49771,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe and tree motif."}
+{"t":"2026-05-27T23:41:24.471Z","id":49772,"verdict":"hot_candidate","n":5,"see":"A repeating wallpaper tile with a giraffe and tree motif."}
+{"t":"2026-05-27T23:41:26.618Z","id":49773,"verdict":"hot_candidate","n":6,"see":"A repeating wallpaper pattern with giraffes and trees."}
+{"t":"2026-05-27T23:41:28.791Z","id":49794,"verdict":"hot_candidate","n":9,"see":"A repeating pattern of deer and foliage."}
+{"t":"2026-05-27T23:41:30.735Z","id":49795,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of deer and foliage."}
+{"t":"2026-05-27T23:41:32.974Z","id":49796,"verdict":"hot_candidate","n":9,"see":"A wallpaper tile with a repeating pattern of deer and foliage."}
+{"t":"2026-05-27T23:41:35.002Z","id":49804,"verdict":"hot_candidate","n":9,"see":"A repeating pattern of chimpanzees."}
+{"t":"2026-05-27T23:41:37.052Z","id":49805,"verdict":"hot_candidate","n":9,"see":"A repeating pattern of chimpanzees."}
+{"t":"2026-05-27T23:41:39.171Z","id":49812,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating giraffe and tree motif."}
+{"t":"2026-05-27T23:41:41.326Z","id":49813,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:41:43.844Z","id":49817,"verdict":"hot_candidate","n":6,"see":"A repeating floral pattern with red and white flowers."}
+{"t":"2026-05-27T23:41:45.908Z","id":49849,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of lemurs and cocktails."}
+{"t":"2026-05-27T23:41:48.494Z","id":49913,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of pink flowers and green leaves."}
+{"t":"2026-05-27T23:41:50.567Z","id":49933,"verdict":"hot_candidate","n":6,"see":"The tile shows a repeating pattern of elephants."}
+{"t":"2026-05-27T23:41:52.729Z","id":49934,"verdict":"hot_candidate","n":6,"see":"This is a wallpaper tile with a repeating pattern of elephants."}
+{"t":"2026-05-27T23:41:54.875Z","id":49939,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating pattern of elephants."}
+{"t":"2026-05-27T23:41:57.042Z","id":49949,"verdict":"hot_candidate","n":8,"see":"This is a wallpaper tile with a repeating monkey motif."}
+{"t":"2026-05-27T23:41:59.349Z","id":49956,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:42:01.654Z","id":49957,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:42:04.067Z","id":49958,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of parrots and palm trees."}
+{"t":"2026-05-27T23:42:06.290Z","id":50017,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating lemur motif."}
+{"t":"2026-05-27T23:42:08.684Z","id":50027,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating elephant motif."}
+{"t":"2026-05-27T23:42:10.969Z","id":50028,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of elephants and trees."}
+{"t":"2026-05-27T23:42:13.223Z","id":50029,"verdict":"hot_candidate","n":6,"see":"I see a repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:42:15.465Z","id":50030,"verdict":"hot_candidate","n":6,"see":"I see a repeating pattern of monkeys and bottles."}
+{"t":"2026-05-27T23:42:17.998Z","id":50034,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating elephant motif."}
+{"t":"2026-05-27T23:42:20.206Z","id":50039,"verdict":"hot_candidate","n":12,"see":"A repeating pattern of chimpanzees."}
+{"t":"2026-05-27T23:42:22.629Z","id":50040,"verdict":"hot_candidate","n":10,"see":"A repeating pattern of chimpanzees."}
+{"t":"2026-05-27T23:42:24.723Z","id":50041,"verdict":"hot_candidate","n":15,"see":"A wallpaper tile with a repeating monkey motif."}
+{"t":"2026-05-27T23:42:28.436Z","id":50047,"verdict":"hot_candidate","n":5,"see":"A wallpaper tile with a repeating pattern of flowers and leaves."}
+{"t":"2026-05-27T23:42:31.063Z","id":50053,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of fox faces and roses."}
+{"t":"2026-05-27T23:42:33.898Z","id":50054,"verdict":"hot_candidate","n":40,"see":"A repeating pattern of bird motifs."}
+{"t":"2026-05-27T23:42:36.689Z","id":50056,"verdict":"not","reason":"centered-hero (n=4)","see":"A centered elephant motif with partial elephants around it."}
+{"t":"2026-05-27T23:42:39.572Z","id":50103,"verdict":"hot_candidate","n":5,"see":"This is a wallpaper tile with a repeating floral pattern."}
+{"t":"2026-05-27T23:42:42.325Z","id":50104,"verdict":"hot_candidate","n":5,"see":"I see a repeating floral pattern with yellow flowers and blue leaves."}
+{"t":"2026-05-27T23:42:45.031Z","id":50105,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile with a repeating floral pattern."}
+{"t":"2026-05-27T23:42:47.832Z","id":50106,"verdict":"hot_candidate","n":5,"see":"A repeating floral pattern with green flowers and purple leaves."}
+{"t":"2026-05-27T23:42:50.657Z","id":50123,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of purple flowers and green leaves."}
+{"t":"2026-05-27T23:42:53.695Z","id":50124,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating floral pattern."}
+{"t":"2026-05-27T23:42:56.229Z","id":50222,"verdict":"hot_candidate","n":3,"see":"A wallpaper tile with a repeating bird motif."}
+{"t":"2026-05-27T23:42:58.772Z","id":50223,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of owls and flowers."}
+{"t":"2026-05-27T23:43:01.961Z","id":50225,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of potted plants."}
+{"t":"2026-05-27T23:43:04.768Z","id":50226,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of parrots and flowers."}
+{"t":"2026-05-27T23:43:07.793Z","id":50227,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of parrots and roses."}
+{"t":"2026-05-27T23:43:10.494Z","id":50229,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating sloth motif."}
+{"t":"2026-05-27T23:43:13.413Z","id":50230,"verdict":"not","reason":"centered-hero (n=3)","see":"A centered sloth with two partial sloths."}
+{"t":"2026-05-27T23:43:16.273Z","id":50231,"verdict":"not","reason":"centered-hero (n=3)","see":"A sloth with a drink is centered in the tile."}
+{"t":"2026-05-27T23:43:19.209Z","id":50235,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of orchids and leaves."}
+{"t":"2026-05-27T23:43:21.863Z","id":50236,"verdict":"hot_candidate","n":6,"see":"A repeating floral pattern with white and red flowers on a green background."}
+{"t":"2026-05-27T23:43:24.527Z","id":50243,"verdict":"not","reason":"centered-hero (n=3)","see":"A sloth with a drink is centered with partial sloths at the edges."}
+{"t":"2026-05-27T23:43:27.111Z","id":50244,"verdict":"not","reason":"centered-hero (n=3)","see":"A sloth with a drink is centered in the tile."}
+{"t":"2026-05-27T23:43:29.809Z","id":50245,"verdict":"not","reason":"centered-hero (n=3)","see":"A centered sloth motif with partial sloths at the edges."}
+{"t":"2026-05-27T23:43:32.771Z","id":50246,"verdict":"hot_candidate","n":6,"see":"A wallpaper tile with a repeating floral pattern."}
+{"t":"2026-05-27T23:43:35.397Z","id":50247,"verdict":"hot_candidate","n":4,"see":"This is a wallpaper tile with a repeating pattern of capybaras."}
+{"t":"2026-05-27T23:43:38.004Z","id":50248,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of lemurs, orchids, and blue bottles."}
+{"t":"2026-05-27T23:43:40.598Z","id":50254,"verdict":"hot_candidate","n":6,"see":"A repeating pattern of wine glasses, roses, and leaves."}
+{"t":"2026-05-27T23:43:43.549Z","id":50263,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of flowers, leaves, and butterflies."}
+{"t":"2026-05-27T23:43:46.309Z","id":50264,"verdict":"hot_candidate","n":4,"see":"A wallpaper tile with a repeating pattern of parrots and orchids."}
+{"t":"2026-05-27T23:43:49.293Z","id":50267,"verdict":"hot_candidate","n":3,"see":"A repeating pattern of frogs and flowers."}
+{"t":"2026-05-27T23:43:52.003Z","id":50269,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of birds and flowers."}
+{"t":"2026-05-27T23:43:54.841Z","id":50275,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of giraffes and flowers."}
+{"t":"2026-05-27T23:43:57.455Z","id":50277,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of lemur faces and floral elements."}
+{"t":"2026-05-27T23:44:00.122Z","id":50284,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of elephants and hearts."}
+{"t":"2026-05-27T23:44:02.828Z","id":50291,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of raccoons on branches."}
+{"t":"2026-05-27T23:44:05.528Z","id":50292,"verdict":"hot_candidate","n":3,"see":"This is a wallpaper tile with a repeating giraffe motif."}
+{"t":"2026-05-27T23:44:08.334Z","id":50295,"verdict":"hot_candidate","n":14,"see":"A repeating pattern of stylized herons and leaves."}
+{"t":"2026-05-27T23:44:11.539Z","id":50296,"verdict":"hot_candidate","n":7,"see":"A repeating pattern of roses, wine glasses, and bottles."}
+{"t":"2026-05-27T23:44:14.413Z","id":50297,"verdict":"hot_candidate","n":5,"see":"A repeating pattern of monkeys and wine glasses."}
+{"t":"2026-05-27T23:44:17.087Z","id":50298,"verdict":"hot_candidate","n":4,"see":"A repeating pattern of parrots and beer glasses."}
diff --git a/data/rescreen-voids-ledger.jsonl b/data/rescreen-voids-ledger.jsonl
index e0e713e..296ed4c 100644
--- a/data/rescreen-voids-ledger.jsonl
+++ b/data/rescreen-voids-ledger.jsonl
@@ -609,3 +609,129 @@
{"t":"2026-05-27T23:33:30.161Z","id":20288,"verdict":"kept","n":4}
{"t":"2026-05-27T23:33:32.336Z","id":20289,"verdict":"kept","n":4}
{"t":"2026-05-27T23:33:34.556Z","id":20290,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:33:36.904Z","id":20323,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:33:39.232Z","id":20419,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:33:41.468Z","id":20423,"verdict":"kept","n":13}
+{"t":"2026-05-27T23:33:43.669Z","id":20424,"verdict":"kept","n":13}
+{"t":"2026-05-27T23:33:46.060Z","id":20425,"verdict":"kept","n":13}
+{"t":"2026-05-27T23:33:48.546Z","id":20428,"verdict":"kept","n":15}
+{"t":"2026-05-27T23:33:50.827Z","id":20429,"verdict":"kept","n":15}
+{"t":"2026-05-27T23:33:53.119Z","id":20430,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:33:55.543Z","id":20458,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:33:57.781Z","id":20460,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:33:59.981Z","id":20461,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:02.314Z","id":20462,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:04.518Z","id":20499,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:34:06.753Z","id":20500,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:09.077Z","id":20501,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:11.496Z","id":20502,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:34:13.867Z","id":20762,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:34:16.093Z","id":20763,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:18.464Z","id":20822,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:34:20.655Z","id":20823,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:34:22.907Z","id":20824,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:25.339Z","id":20882,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:34:27.572Z","id":20883,"verdict":"kept","n":8}
+{"t":"2026-05-27T23:34:29.756Z","id":20884,"verdict":"kept","n":9}
+{"t":"2026-05-27T23:34:31.979Z","id":20885,"verdict":"kept","n":9}
+{"t":"2026-05-27T23:34:34.550Z","id":20961,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:34:36.786Z","id":20962,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:38.990Z","id":20963,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:34:41.139Z","id":20964,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:34:43.457Z","id":21071,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:34:45.941Z","id":21072,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:34:48.407Z","id":21073,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:34:50.825Z","id":21074,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:34:53.226Z","id":21204,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:34:55.694Z","id":21206,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:34:58.002Z","id":21207,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:35:00.513Z","id":21209,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:35:02.784Z","id":21210,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:35:05.117Z","id":21211,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:35:07.443Z","id":21305,"verdict":"kept","n":8}
+{"t":"2026-05-27T23:35:09.748Z","id":21307,"verdict":"kept","n":10}
+{"t":"2026-05-27T23:35:12.132Z","id":21308,"verdict":"kept","n":10}
+{"t":"2026-05-27T23:35:14.297Z","id":21309,"verdict":"kept","n":8}
+{"t":"2026-05-27T23:35:16.587Z","id":21323,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:35:18.759Z","id":21324,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:35:20.909Z","id":21325,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:35:23.108Z","id":21359,"verdict":"kept","n":14}
+{"t":"2026-05-27T23:35:25.454Z","id":21361,"verdict":"kept","n":15}
+{"t":"2026-05-27T23:35:27.540Z","id":21370,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:35:29.785Z","id":21372,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:35:31.877Z","id":21373,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:35:34.207Z","id":21374,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:35:36.670Z","id":21383,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:35:38.862Z","id":21384,"verdict":"kept","n":2}
+{"t":"2026-05-27T23:35:41.070Z","id":21385,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:35:43.411Z","id":21406,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:35:45.713Z","id":21407,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:35:48.082Z","id":21408,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:35:50.455Z","id":21409,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:35:52.601Z","id":21433,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:35:54.761Z","id":21435,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:35:56.902Z","id":21436,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:35:59.240Z","id":21437,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:36:01.272Z","id":21525,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:03.446Z","id":21526,"verdict":"kept","n":3}
+{"t":"2026-05-27T23:36:05.501Z","id":21527,"verdict":"kept","n":3}
+{"t":"2026-05-27T23:36:07.950Z","id":21595,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:36:10.224Z","id":21596,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:36:12.587Z","id":21597,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:36:14.729Z","id":21673,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:36:16.894Z","id":21711,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:19.025Z","id":21724,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:36:21.107Z","id":21725,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:36:23.388Z","id":21726,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:36:25.671Z","id":21727,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:36:27.839Z","id":21778,"verdict":"kept","n":10}
+{"t":"2026-05-27T23:36:30.175Z","id":21779,"verdict":"kept","n":8}
+{"t":"2026-05-27T23:36:32.323Z","id":21780,"verdict":"kept","n":10}
+{"t":"2026-05-27T23:36:34.631Z","id":21781,"verdict":"kept","n":10}
+{"t":"2026-05-27T23:36:36.710Z","id":21842,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:38.993Z","id":21843,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:41.263Z","id":21844,"verdict":"kept","n":3}
+{"t":"2026-05-27T23:36:43.461Z","id":21845,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:45.605Z","id":21896,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:36:47.753Z","id":21897,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:36:49.907Z","id":21898,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:36:52.357Z","id":21959,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:36:54.475Z","id":21962,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:56.779Z","id":21963,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:36:58.987Z","id":21991,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:37:01.043Z","id":21992,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:37:03.249Z","id":22065,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:37:05.504Z","id":22108,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:37:07.979Z","id":22129,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:37:10.216Z","id":22130,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:37:12.540Z","id":22131,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:14.661Z","id":22132,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:16.840Z","id":22206,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:19.260Z","id":22207,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:21.869Z","id":22208,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:24.119Z","id":22209,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:26.254Z","id":22210,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:28.513Z","id":22212,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:37:30.691Z","id":22239,"verdict":"kept","n":3}
+{"t":"2026-05-27T23:37:32.811Z","id":22240,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:37:35.037Z","id":22241,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:37:37.152Z","id":22242,"verdict":"kept","n":5}
+{"t":"2026-05-27T23:37:39.580Z","id":22271,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:37:41.901Z","id":22272,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:37:44.477Z","id":22273,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:37:46.979Z","id":22274,"verdict":"kept","n":12}
+{"t":"2026-05-27T23:37:49.116Z","id":22276,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:37:51.554Z","id":22277,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:37:53.726Z","id":22278,"verdict":"kept","n":4}
+{"t":"2026-05-27T23:37:56.036Z","id":22411,"verdict":"kept","n":20}
+{"t":"2026-05-27T23:37:58.496Z","id":22412,"verdict":"kept","n":20}
+{"t":"2026-05-27T23:38:00.716Z","id":22413,"verdict":"kept","n":25}
+{"t":"2026-05-27T23:38:02.947Z","id":22420,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:38:05.187Z","id":22421,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:38:07.310Z","id":22422,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:38:09.504Z","id":22542,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:38:11.823Z","id":22543,"verdict":"kept","n":7}
+{"t":"2026-05-27T23:38:14.088Z","id":22544,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:38:16.376Z","id":22562,"verdict":"kept","n":6}
+{"t":"2026-05-27T23:38:18.838Z","id":22563,"verdict":"kept","n":8}
+{"t":"2026-05-27T23:38:21.304Z","id":22564,"verdict":"kept","n":6}
diff --git a/data/svgtess-manifest.json b/data/svgtess-manifest.json
new file mode 100644
index 0000000..96aa2e5
--- /dev/null
+++ b/data/svgtess-manifest.json
@@ -0,0 +1,7 @@
+[
+ {
+ "id": 53791,
+ "slug": "equilateral-style-triangle-field",
+ "navyPct": 50
+ }
+]
\ No newline at end of file
diff --git a/scripts/gen-geom-svg-tessellate.js b/scripts/gen-geom-svg-tessellate.js
new file mode 100644
index 0000000..42be74b
--- /dev/null
+++ b/scripts/gen-geom-svg-tessellate.js
@@ -0,0 +1,186 @@
+#!/usr/bin/env node
+/**
+ * Programmatic SVG tessellation generator for the "geometric-block-leaves" reroll.
+ * DTD verdict 2026-05-27 (C, 2/2): the prior Replicate-SDXL batch failed the gate
+ * 100% (broken seams ΔE 26-43, 9-color/not-solid). These are PURE geometric
+ * tessellations, so we generate them mathematically — guaranteed seamless (every
+ * motif sits on a lattice whose period divides the tile T, so left==right /
+ * top==bottom) and guaranteed 2 flat inks (navy on cream). Each tile is rendered
+ * by scripts/svg_raster_snap.py (cairosvg → 2-ink snap) and inserted UNPUBLISHED
+ * for Steve to curate at /admin/drunk-curator?category=geometric-block-leaves.
+ *
+ * The .svg master is kept next to the PNG → re-raster at 5400px for the 150-DPI
+ * archive any time, with vector-clean edges (no LANCZOS, no potrace needed).
+ *
+ * Usage: node scripts/gen-geom-svg-tessellate.js [--only name1,name2] [--size 1600]
+ */
+const fs = require('fs');
+const path = require('path');
+const { spawnSync } = require('child_process');
+
+const ROOT = path.join(__dirname, '..');
+const IMG_DIR = path.join(ROOT, 'data', 'generated');
+const VENV_PY = path.join(ROOT, 'scripts', 'vectorize', '.venv', 'bin', 'python3');
+const SNAP = path.join(ROOT, 'scripts', 'svg_raster_snap.py');
+const DB = process.env.WALLCO_DB || 'dw_unified';
+
+const T = 1200; // tile units — divisible by 2,3,4,5,6,8,10,12
+const NAVY = '#16203c'; // deep midnight navy ink
+const CREAM = '#f2e9d3'; // warm cream paper
+const SIZE = parseInt((process.argv.find(a => a.startsWith('--size='))||'').split('=')[1] || '1600', 10);
+const ONLY = (process.argv.find(a => a.startsWith('--only='))||'').split('=')[1];
+
+// ---- SVG primitives --------------------------------------------------------
+const poly = pts => `<polygon points="${pts.map(p => p.map(n => +n.toFixed(2)).join(',')).join(' ')}"/>`;
+const circ = (cx, cy, r) => `<circle cx="${cx.toFixed(2)}" cy="${cy.toFixed(2)}" r="${r.toFixed(2)}"/>`;
+const rect = (x, y, w, h) => `<rect x="${x.toFixed(2)}" y="${y.toFixed(2)}" width="${w.toFixed(2)}" height="${h.toFixed(2)}"/>`;
+const pathd = d => `<path d="${d}"/>`;
+// annulus / ring via evenodd: outer circle minus inner
+const ring = (cx, cy, ro, ri) =>
+ `<path d="M${(cx-ro).toFixed(2)},${cy} a${ro},${ro} 0 1,0 ${(2*ro).toFixed(2)},0 a${ro},${ro} 0 1,0 ${(-2*ro).toFixed(2)},0 Z `
+ + `M${(cx-ri).toFixed(2)},${cy} a${ri},${ri} 0 1,1 ${(2*ri).toFixed(2)},0 a${ri},${ri} 0 1,1 ${(-2*ri).toFixed(2)},0 Z"/>`;
+// square frame (ring) via evenodd: outer square minus inner square
+const frame = (x, y, s, t) =>
+ `<path d="M${x},${y} h${s} v${s} h${-s} Z M${x+t},${y+t} h${s-2*t} v${s-2*t} h${-(s-2*t)} Z"/>`;
+
+// iterate a lattice over [-1..N] on each axis so motifs that cross an edge are
+// also drawn wrapped; cairosvg clips to the viewBox → perfect seam.
+function lattice(nx, ny, fn) {
+ const cw = T / nx, ch = T / ny;
+ let s = '';
+ for (let i = -1; i <= nx; i++) for (let j = -1; j <= ny; j++) s += fn(i * cw, j * ch, cw, ch, i, j);
+ return s;
+}
+
+// ---- pattern drawers (return navy-shape SVG body) --------------------------
+const PATTERNS = {
+ 'perfect circles in a uniform dot-grid, equal spacing': () =>
+ lattice(6, 6, (x, y, cw, ch) => circ(x + cw/2, y + ch/2, cw * 0.34)),
+
+ 'concentric ring annuli on a flat grid': () =>
+ lattice(5, 5, (x, y, cw, ch) => ring(x + cw/2, y + ch/2, cw*0.42, cw*0.27) + circ(x + cw/2, y + ch/2, cw*0.12)),
+
+ 'narrow vertical rectangle columns, full-height stripes': () =>
+ lattice(8, 1, (x, _y, cw) => rect(x, -10, cw * 0.5, T + 20)),
+
+ 'vertical sheaf bundles of three parallel hairlines, regular column spacing': () =>
+ lattice(7, 1, (x, _y, cw) => rect(x + cw*0.28, -10, cw*0.04, T+20) + rect(x + cw*0.46, -10, cw*0.04, T+20) + rect(x + cw*0.64, -10, cw*0.04, T+20)),
+
+ 'cluster of three vertical bars, tessellated': () =>
+ lattice(5, 1, (x, _y, cw) => rect(x + cw*0.16, -10, cw*0.13, T+20) + rect(x + cw*0.42, -10, cw*0.13, T+20) + rect(x + cw*0.68, -10, cw*0.13, T+20)),
+
+ 'squares with a centered gap, uniform grid': () =>
+ lattice(6, 6, (x, y, cw, ch) => rect(x + cw*0.12, y + ch*0.12, cw*0.76, ch*0.76)),
+
+ 'concentric square frames nested, flat grid': () =>
+ lattice(5, 5, (x, y, cw) => frame(x+cw*0.08, y+cw*0.08, cw*0.84, cw*0.10) + frame(x+cw*0.28, y+cw*0.28, cw*0.44, cw*0.10)),
+
+ 'plus and cross shapes in a uniform grid, vertical axis': () =>
+ lattice(6, 6, (x, y, cw, ch) => rect(x + cw*0.38, y + ch*0.12, cw*0.24, ch*0.76) + rect(x + cw*0.12, y + ch*0.38, cw*0.76, ch*0.24)),
+
+ 'vertical diamond rhombi grid-locked, identical orientation': () =>
+ lattice(6, 6, (x, y, cw, ch) => poly([[x+cw/2, y+ch*0.06],[x+cw*0.94, y+ch/2],[x+cw/2, y+ch*0.94],[x+cw*0.06, y+ch/2]])),
+
+ 'vertical lozenge shapes stacked, edge-to-edge': () =>
+ lattice(8, 4, (x, y, cw, ch) => poly([[x+cw/2, y],[x+cw, y+ch/2],[x+cw/2, y+ch],[x, y+ch/2]])),
+
+ 'equilateral-style triangle field, every triangle pointing upward': () =>
+ lattice(8, 6, (x, y, cw, ch, i, j) => {
+ const off = (j % 2 ? cw/2 : 0);
+ return poly([[x+off, y+ch],[x+off+cw, y+ch],[x+off+cw/2, y]]);
+ }),
+
+ 'isoceles triangle wedges in vertical fan columns, single orientation': () =>
+ lattice(10, 6, (x, y, cw, ch) => poly([[x+cw*0.5, y],[x+cw*0.95, y+ch],[x+cw*0.05, y+ch]])),
+
+ 'stacked stepped-pyramid ziggurat blocks, all upright': () =>
+ lattice(5, 5, (x, y, cw, ch) => {
+ const steps = 4; let s = '';
+ for (let k = 0; k < steps; k++) {
+ const inset = cw * 0.12 * k, sh = ch / steps;
+ s += rect(x + cw*0.06 + inset, y + ch - (k+1)*sh, cw*0.88 - 2*inset, sh*0.86);
+ }
+ return s;
+ }),
+
+ 'regular octagons in a tessellated grid with square interstices': () =>
+ lattice(5, 5, (x, y, cw, ch) => {
+ const a = cw*0.29; // corner cut
+ return poly([[x+a,y],[x+cw-a,y],[x+cw,y+a],[x+cw,y+ch-a],[x+cw-a,y+ch],[x+a,y+ch],[x,y+ch-a],[x,y+a]]);
+ }),
+
+ 'squares with one corner cut into a triangular notch, identical orientation': () =>
+ lattice(6, 6, (x, y, cw, ch) =>
+ poly([[x+cw*0.10, y+ch*0.10],[x+cw*0.90, y+ch*0.10],[x+cw*0.90, y+ch*0.62],[x+cw*0.62, y+ch*0.90],[x+cw*0.10, y+ch*0.90]])),
+
+ 'quarter-circle fan tiles, curves opening upward, grid alignment': () =>
+ lattice(6, 6, (x, y, cw, ch) =>
+ pathd(`M${x},${y+ch} A${cw},${ch} 0 0 1 ${x+cw},${y+ch} Z`)),
+
+ 'half-moon crescent fish-scale field, horns-up, tight grid': () =>
+ lattice(8, 8, (x, y, cw, ch, i, j) => {
+ const off = (j % 2 ? cw/2 : 0);
+ // navy scallop = semicircle bump per cell, offset rows → classic fish-scale
+ return pathd(`M${x+off},${y+ch} A${cw/2},${ch} 0 0 1 ${x+off+cw},${y+ch} Z`);
+ }),
+
+ 'alternating trapezoid blocks, wide-base and narrow-base, grid-locked': () =>
+ lattice(6, 6, (x, y, cw, ch, i, j) =>
+ (j % 2 === 0)
+ ? poly([[x+cw*0.06, y+ch*0.85],[x+cw*0.94, y+ch*0.85],[x+cw*0.72, y+ch*0.15],[x+cw*0.28, y+ch*0.15]])
+ : poly([[x+cw*0.28, y+ch*0.85],[x+cw*0.72, y+ch*0.85],[x+cw*0.94, y+ch*0.15],[x+cw*0.06, y+ch*0.15]])),
+
+ 'uniform hexagonal honeycomb tiles, edge-to-edge tessellation': () =>
+ // brick-offset squished hexes — period (cw, 2*ch) both divide T → seamless
+ lattice(6, 6, (x, y, cw, ch, i, j) => {
+ const off = (j % 2 ? cw/2 : 0), X = x + off, q = ch*0.25;
+ return poly([[X+cw/2, y],[X+cw, y+q],[X+cw, y+ch-q],[X+cw/2, y+ch],[X, y+ch-q],[X, y+q]]);
+ }),
+};
+
+// ---- compose + render + persist -------------------------------------------
+function svgDoc(body) {
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${T} ${T}" width="${T}" height="${T}">`
+ + `<rect width="${T}" height="${T}" fill="${CREAM}"/>`
+ + `<g fill="${NAVY}" fill-rule="evenodd" shape-rendering="geometricPrecision">${body}</g></svg>`;
+}
+function psql(sql) {
+ const r = spawnSync('psql', ['-d', DB, '-tAc', sql], { encoding: 'utf8' });
+ if (r.status !== 0) throw new Error('psql: ' + (r.stderr || '').slice(0, 300));
+ return (r.stdout || '').trim();
+}
+
+const names = Object.keys(PATTERNS).filter(n => !ONLY || ONLY.split(',').some(o => n.includes(o)));
+console.log(`Generating ${names.length} SVG tessellations → geometric-block-leaves (unpublished)\n`);
+
+const made = [];
+names.forEach((shape, idx) => {
+ const body = PATTERNS[shape]();
+ const ts = Date.now();
+ const slug = shape.split(',')[0].replace(/[^a-z0-9]+/gi, '-').slice(0, 32).toLowerCase();
+ const base = `svgtess_${ts}_${idx}_${slug}`;
+ const svgPath = path.join(IMG_DIR, base + '.svg');
+ const pngPath = path.join(IMG_DIR, base + '.png');
+ fs.writeFileSync(svgPath, svgDoc(body));
+
+ const r = spawnSync(VENV_PY, [SNAP, svgPath, pngPath, String(SIZE), NAVY, CREAM], { encoding: 'utf8' });
+ if (r.status !== 0 || !fs.existsSync(pngPath)) {
+ console.log(` ✗ ${slug}: ${(r.stderr || r.stdout || 'raster failed').slice(0, 160)}`);
+ return;
+ }
+ const navyPct = parseFloat((r.stdout || '').trim().split(/\s+/).pop()) || 50;
+ const palette = JSON.stringify([{ hex: NAVY, pct: navyPct }, { hex: CREAM, pct: +(100 - navyPct).toFixed(1) }]).replace(/'/g, "''");
+ const prompt = `Geometric block leaf pattern - ${shape}. SVG tessellation, 2 solid screen-print inks (deep midnight navy on warm cream), seamless by construction.`.replace(/'/g, "''");
+ const sql = `INSERT INTO spoon_all_designs (kind, generator, prompt, seed, dominant_hex, palette, local_path, category, is_published)
+ VALUES ('seamless_tile','svg-tessellate','${prompt}', ${ts % 2147483647}, '${NAVY}', '${palette}'::jsonb,
+ '${pngPath.replace(/'/g, "''")}', 'geometric-block-leaves', FALSE) RETURNING id;`;
+ const id = parseInt(psql(sql), 10);
+ if (Number.isFinite(id)) {
+ psql(`UPDATE spoon_all_designs SET image_url='/designs/img/by-id/${id}' WHERE id=${id};`);
+ made.push({ id, slug, navyPct });
+ console.log(` ✓ #${id} ${slug} (navy ${navyPct}%)`);
+ }
+});
+
+console.log(`\nDone: ${made.length}/${names.length} tiles inserted (unpublished). ids: ${made.map(m => m.id).join(', ')}`);
+fs.writeFileSync(path.join(ROOT, 'data', 'svgtess-manifest.json'), JSON.stringify(made, null, 2));
diff --git a/scripts/svg_raster_snap.py b/scripts/svg_raster_snap.py
new file mode 100644
index 0000000..752eabc
--- /dev/null
+++ b/scripts/svg_raster_snap.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+"""Rasterize a tessellation SVG to PNG, then SNAP every pixel to the nearest of two
+inks (navy / cream). The SVG is exactly periodic, so the snapped PNG is:
+ - truly seamless (left edge == right edge, top == bottom → wrap ΔE = 0)
+ - exactly 2 flat colors (0% gradient ramp → passes the solid-screen-print gate)
+ - vector-clean (re-raster the .svg at 5400px any time for the 150-DPI archive)
+
+Usage: svg_raster_snap.py <in.svg> <out.png> <size> <#navyhex> <#creamhex>
+Prints: OK <out.png> <navy_pct>
+"""
+import sys, io
+import cairosvg, numpy as np
+from PIL import Image
+
+svg, png, size, navy_hex, cream_hex = sys.argv[1], sys.argv[2], int(sys.argv[3]), sys.argv[4], sys.argv[5]
+
+def hx(h):
+ h = h.lstrip('#')
+ return np.array([int(h[i:i+2], 16) for i in (0, 2, 4)], dtype=np.int32)
+
+navy, cream = hx(navy_hex), hx(cream_hex)
+buf = cairosvg.svg2png(url=svg, output_width=size, output_height=size, background_color='white')
+im = Image.open(io.BytesIO(buf)).convert('RGB')
+a = np.asarray(im, dtype=np.int32)
+dn = ((a - navy) ** 2).sum(2)
+dc = ((a - cream) ** 2).sum(2)
+mask = (dn <= dc)[..., None]
+out = np.where(mask, navy, cream).astype(np.uint8)
+Image.fromarray(out, 'RGB').save(png, optimize=True)
+navy_pct = round(float(mask.mean()) * 100, 1)
+print(f"OK {png} {navy_pct}")
← 45b818c room: user-adjustable wall-size slider (default 13.5ft) + fu
·
back to Wallco Ai
·
TODO: mark geometric-block-leaves reroll done (19 SVG tessel 7bc6023 →