def g08_duotone(rng):
"""Quantised ground, then a dot several ramp steps away, sized by local gradient."""
steps = rng.randint(5, 7)
N = rng.choice([30, 40])
c = Canvas(N, _pal(rng), steps, "duotone", "dots")
f = Field(rng, "mesh", warp=rng.uniform(0.15, 0.35), steps=steps)
c.ground_from(f)
off = rng.choice([2, 3])
for j in range(N):
for i in range(N):
u, v = c.uv(i, j)
gx, gy = f.grad(u, v, 0.02)
r = min(0.5, math.hypot(gx, gy) * 9) * c.C
if r > 0.06 * c.C:
cx, cy = c.center(i, j)
c.dot(cx, cy, r, (f.idx(u, v) + off) % steps)
return c