Comet Badge
A four-color badge traced straight off its green screen. One --remove-background flag, no masking.
Examples / proof sheets
Drag each control to compare the original PNG with the Kurviq output. The checkerboard makes transparent regions visible; captions report the actual file sizes shown.
A four-color badge traced straight off its green screen. One --remove-background flag, no masking.
A die-cut mascot lifted from a magenta chroma card: bold outlines, small details, and the white keyline survive.
A softly modeled 3D object: gradient-aware tracing keeps volume and highlights while the green screen disappears.
Fine cyan construction lines test precision, symmetry, and crisp technical geometry.
A compact multicolor icon balances rounded geometry with restrained inner shading.
Organic pen strokes and coral wash accents showcase expressive line-art tracing.
Fine facial details, soft shadows, and rounded color transitions.
Thin strokes and enclosed shapes after background removal.
Layered objects, attached shadows, and gentle gradients.
Narrow bars and soft-alpha edges on a compact source.
Near-white structure protected from an almost-white background.
Small calendar details, smooth curves, and multiple materials.
A dark neon diagram: --upscale 2 keeps the dashed radar rings and tick marks that a plain trace loses, then --consolidate 48 holds the file to 156 KB.
A full page mockup in 16 KB. --consolidate collapses the anti-aliased ramps, --snap recovers five circles and the button rectangles.
Soft gradients preserved with --gradient_step 8, then consolidated and snapped: 30 rectangles and 4 circles become real primitives.
Flat editorial artwork in 5 KB. Twenty-three colors carry the whole illustration once near-identical fills are merged.
A shaded board panel: gradient flags keep the shading smooth while consolidation keeps the palette to 24 colors.
A large tonal illustration reduced to 64 perceptual colors. 68 KB with the tonal transitions intact.
A small shaded marker: 21 snapped rectangles and a 24-color palette.
A wide two-panel illustration traced with --snap only, keeping the full tonal range at 79 KB.
The combination nothing else does: a generated raster draft, traced by Kurviq, then
enhanced with authored SVG on top of the trace. Tracing with
--structure groups leaves stable palette classes behind, and those classes are
the handles the animation and interaction attach to.
// 1. trace the draft, asking for addressable output
const traced = convert(raster, { consolidate: true, structure: 'groups' });
// 2. the trace's own palette classes are the handles
const plan = A.animationPlan({ duration: 1400, stagger: 70 });
for (const c of paletteClasses(traced)) {
plan.animate({ selector: '.' + c, property: 'opacity', from: 0, to: 1 });
}Checked against the target it ships to before it went on this page. That is the point of the toolbelt: an SVG that quietly does nothing, a hover state in an image or a selector the renderer ignores, fails the check instead of the user.
The two things a tracer cannot give you. Every piece below is generated by
kurviq/author, and each was checked against the target it ships to before it
went on this page.
stroke-dashoffset on a traced fill is a
provable no-op, which is why the tracer's own --animate draw refuses to
pretend otherwise.
const A = require('kurviq/author-animate');
const { strokedPath } = require('kurviq/author-stroke');
// A real draw-on. Only possible because the strokes are AUTHORED —
// animating stroke-dashoffset on a traced fill is a provable no-op.
const plan = A.animationPlan({ duration: 1800, stagger: 130 });
plan.animate({ selector: '.draw-0', property: 'stroke-dashoffset', from: L, to: 0 });:target, so the panels work anywhere the SVG is inlined, including
with the browser back button.
Verified before publishing: the draw-on is valid as an <img> because
declarative animation runs there; both interactive pieces are rejected for
browser-img and are inlined instead. All three keep a correct static frame, and
the animation ships a reduced-motion fallback that settles on the final state.
Kurviq also builds SVG. Everything below was generated by
kurviq/author and verified through @tecsteps/kurviq-toolbelt — rendered,
diffed, and validated against a measured target-support matrix. No hand-written SVG.
const { createScene, shapes } = require('kurviq/author');
const { linearGradient } = require('kurviq/author-paint');
const { strokedPath, arrowhead, withMarkers } = require('kurviq/author-stroke');
const { clipPath } = require('kurviq/author-mask');
// ...then verify it, rather than hoping:
const { evaluate, validateTarget } = require('@tecsteps/kurviq-toolbelt');
validateTarget(svg, 'browser-img').ok; // false when it needs pointer events<img> receives no pointer events and
the states would never fire. Kurviq refuses to declare it valid for that embedding.
Verified before publishing: the legend is rejected for browser-img and static
rasterisers, the loader is rejected for static rasterisers only, and the other two are valid
everywhere. Full walkthrough in the authoring guide.
These are ordinary traces. --animate reveal adds a CSS-only entrance
that staggers each colour group, with no JavaScript and no runtime library. The final
frame is byte-identical to the unanimated trace, so any renderer that ignores CSS shows
the correct static image, and prefers-reduced-motion switches the motion off.
npx kurviq --input icon.png --output icon.svg \
--consolidate 8 --structure groups --animate revealKurviq refuses above 120 animated elements — the blueprint example
resolves to 187 groups and is rejected rather than emitting a stylesheet larger than the
geometry. Run --consolidate first, or pass --animate-force.
Flat outline art can become smaller as SVG. Detailed 3D icons can grow because gradients and soft edges need many colored paths. Choose settings at the display size and fidelity your product actually needs.
Kurviq is deterministic for identical input bytes, options, version, and platform. Record all four when a generated asset is part of a reviewed build.
Find the matching recipe →