Scaffolding merge for the reconcile; the final series to master is
authored fresh. Rank plumbing resolves to our axis-IR model, the node
macro and the LaneSource render walk stay ours, master's vector
restructure and gradient vocabulary are adopted, and the paint and
appearance adoption is deliberately deferred behind our fill and stroke
markers.
* Draw raster images with pad extension instead of repeat
* Add the GPU basic brush renderer
* Rework the brush tool around the GPU basic brush
* Remove the CPU brush implementation
* Decide branching mesh fill insideness by winding, normalizing drawn direction at the Path node
* Fix dead connector click targets by explicitly closing the kurbo ellipse port paths
* Fix hole subtraction when a hole vertex is snapped exactly onto its covering contour
* Classify embedded negative space by its single surrounding face so fully enclosed mesh cells still fill
* Port all remaining Subpath producers to BezPath and delete the legacy subpath module
* Reset contour state at each MoveTo so an open contour's segments don't leak into the next region
* Give the polygon and star constructors a true center and radius instead of compensated arguments
* Render a paint from its Graphic directly instead of a single-element List wrapper
* Fix a stale doc comment reference to the moved paint render implementation
* Add the rank-0 Item leaf variants to the Graphic enum, rendering leaves and list rows through shared per-row logic
* Traverse the rank-0 Graphic leaf variants in the vector node helpers and flattening
* Reach rank-0 vector graphics from the styling and gradient-fitting helpers
* Two code review fixes
* Fix comment
* Make the Artboard and Gradient newtype fields public to match the other list newtypes
* Rename the Graphic enum's self-named Graphic::Graphic variant to Graphic::GraphicList
* Rename the Graphic::Vector variant to Graphic::VectorList
* Rename the Graphic::RasterCPU variant to Graphic::RasterCPUList
* Rename the Graphic::RasterGPU variant to Graphic::RasterGPUList
* Rename the Graphic::Color variant to Graphic::ColorList
* Rename the Graphic::Gradient variant to Graphic::GradientList
* Rename the Graphic::Text variant to Graphic::TextList
* Restore the SVG group tag comment that the variant rename sweep clobbered
* Add the appearance model types and attribute constants
* Dual-write the appearance attribute alongside the fill/stroke pair in all paint-writing nodes
* Read paint from the appearance attribute in the renderer, analysis, metadata, and editor, cascading from ancestors
* Retire the fill/stroke attribute pair and the Vector stroke field in favor of the appearance attribute
* Replace the Stroke node's paint order input with the relative chain order of the Fill and Stroke nodes
* Code review fixes
* Re-save demo art
* Stamp coverages in place and fuse the renderer's per-item appearance reads into single walks
* Treat an empty appearance as the undeclared state so padded rows inherit instead of blocking the cascade
* Update demo art
* Treat padded appearance rows as undeclared in the boolean flatten's group recursion
* Honor clipping masks when rendering Vector[] lists, not just Graphic[] groups
* Keep per-layer click targets when a Vector[] round-trips through a Graphic[] wrapper
* Skip the rebuild and the merged-layers snapshot when flattening a lone anonymous graphic wrapper
* Fix a group's bounds excluding its raster children and stretching to the origin
* Fix SVG clipping masks landing in the wrong space when sibling layers differ in transform
* New nodes: 'Gradient Reverse', 'Gradient Shift', and 'Gradient Stretch' nodes for rearranging a ramp's stops
* Clip a lone out-of-range stop into the bake, and correct the docs that still promised edge-held stops
* Upgrade Vello to a git main revision that honors the brush's interpolation alpha space
* Interpolate Vello gradients with straight alpha, matching the SVG renderer
* Draw the gradient picker strip and fill swatches as SVG so transparency previews with straight alpha
* Keep gradient stop handles opaque so a transparent stop's RGB stays visible
* Paint a stopless gradient's picker strip and swatch black rather than transparent
* Delete dead code function
* Add a Gradient Interpolation axis with Stepped, Linear, and Smooth paths through the stops
* Keep the gradient interpolation attached when dragging stops in the picker
* Give the gradient popover's dropdowns the same tooltips as their row labels
* Order the gradient popover with Intrp. above Space
* Hold gradient stops in place when the cyclic flag is toggled
* Fix wrong Smooth gradient colors around stops sitting on the ramp boundaries
* Consolidate gradient settings plumbing and fix bugs
* Bundle whole-ramp gradient settings into GradientSettings across the editor plumbing
* Name the Smooth gradient interpolation's spline type in its tooltip
* Linearize the gamma hex stop colors recovered from imported Graphite SVGs
* Code review
* Aim the Smooth bake's seam subdivision at the copied boundary color
* Add GradientEvaluator to build gradient sampling state once per loop instead of per sample
* Correct the gradient evaluator's documented setup cost to O(n log n)
* Add a Cyclic gradient attribute that wraps the stop list through the 1|0 boundary back to the first stop
* Show the wrap segment's midpoint diamond in the color picker spectrum strip when cyclic
* Keep the wrap midpoint diamond tracking the pointer by a wrapped strip width when dragged past the ends
* Give the Gradient tool's viewport overlay the same cyclic wrap midpoint diamond and drag behavior
* Correct the docs claiming the final stop's midpoint is always ignored now that cyclic uses it
* Move the gradient cyclic toggle onto the Ends row as a Link icon checkbox
* Update labels
* Register GradientHueDirection with the Data panel so its attribute column renders
* Reword wrap segment to wrapped interval and stray segment usages to interval
* Clean up comments
* Fix the color picker write-back losing default position elision and the blend path guessing the cyclic flag
* Add an OkLab gradient interpolation space and make it the new default
* Fix the Properties panel fill row resetting the gradient interpolation space to the default
* Add OkLch, Lab, LCh, and HSL gradient interpolation spaces
* Add a hue direction attribute and picker choice for polar gradient interpolation spaces
* Add an HSV gradient interpolation space
* Rename the sRGB Linear and sRGB Gamma gradient spaces to RGB Linear and RGB Gamma
* Divide the gradient interpolation dropdown between absolute and relative color spaces
* Rename the OkLch gradient interpolation space to OkLCh for channel-notation capitalization
* Shorten the color picker popover's hue direction row label to Arc
* Call the Gradient Interpolation node's parameter Space and extend the picker tooltip title to match
* Rename the gradient interpolation attribute and type family to gradient space
* Rename the gradient tool's gradient space transform to gradient to viewport transform
* Add serde aliases and a node replacement covering the gradient space renames
* Give the gradient space choices artist-facing labels and reorder the dropdown sections
* Add a Gradient Hue Direction node and its attribute read node
* Say interpolate instead of blend for gradient stop color traversal in docs and tooltips
* Label the polar perceptual gradient spaces as Perceptual Hue and group the dropdown sections by geometry
* Add a migration alias covering the gradient space attribute reader rename
* Carry the gradient hue direction attribute through boolean operations
* Register GradientHueDirection wire types in the node registry
* Build dropdown menu entries from choice type metadata
* Add a gradient interpolation color space attribute, blending stops in linear light by default
* Add a Space interpolation dropdown to the color picker popover
* Stamp legacy gradient ramps with their implicit gamma interpolation during deserialization
* Resolve color-interpolation from SVG style blocks and fix cascade order among repeated declarations