* Make the dropdown widget's file drop a callback and keep stray file drops from navigating the browser away
* Look up the dropped file's widget before reading the file
* New node: 'Color Lookup' for applying .cube, .3dl, .look, .csp, and .icc LUT files
* Add LUT ingest to the UI
* Add caching to the parsed LUT
* More code review fixes
* Add a dropdown for resource selection and adopt it in the Image node
* Route every image upload through a new ResourceUpload handler with desktop support and migrate wired 'Image' node inputs
* Show each resource's user count in the resource picker dropdown
* Send a picked resource file to the document that requested it, list every non-font resource in the picker, and link sibling message docs
* Add a 'Use Tint' toggle to the 'Black & White' node and give its tint the Luminosity blend's clipping
* Fix the Black & White migration for a wired tint and gray out the tint when unused
* Add colorize and six hue ranges to the 'Hue/Saturation' node
* Hide the 'Hue/Saturation' range rows while colorize is on, note the +100 saturation rule, and tidy two lints and a tooltip
* Add per-channel records and a gamma midtones value to the 'Levels' node, with a channel selector in its Properties panel
* Migrate the old 'Levels' midtones through its output range and bound a lone midtone marker by the track edges
* Add a selection mode to the spectrum widget so only the gradient editor keeps a highlighted stop
* Record the drag mode for every drag and require selection for reordering so a non-selecting widget cannot drag the wrong stop
* Add a range slider mode to the spectrum widget and slider rows to node properties
* Reset the weighted strength slider to the node's default of zero and skip markers off the track when picking up the nearest one
* Remove the 'Threshold' node's luminance calculation dropdown so it always compares the Rec. 601 luma
* Find the HSL lightness extremes before encoding and drop a stale luminance TODO
* Let the Freehand tool continue a selected open path from its endpoint and show endpoint overlays in the Freehand and Spline tools
* Share the closest-point search with the open path endpoint lookup, tally endpoint connections in a single pass, and rename the endpoint overlay function
* Skip hidden layers and use the feeds-aware transform in path point searches, path overlays, and Freehand point placement
* Map the Spline tool's merge goal with the feeds-aware transform so it matches the endpoint candidates
* Highlight the hovered open path endpoint in the Freehand and Spline tools
* Give each Pen tool segment its own history step and keep drawing across undo/redo
* Test that undo during a Pen tool handle transform cancels it and rewinds
* Pin cargo-binstall and cargo-about and cross-reference all tool version pins
* Pin the cargo-binstall GitHub Action to its release tag
* Use a version floor for cargo-about and drop the Nix sync notices
* Make Data panel scalars selectable inline, denoise float display, and move breadcrumb truncation to Rust
* Code review fixes
* Remove denoising from f32
* 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
* Collapse duplicated BezPath emission, constants, and Polynomial surface across the vector algorithms
* Fix the quadratic segment length lower bound using a control leg instead of the chord
* 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
* Let the Fill and Stroke paint inputs take Item<Graphic>, replacing the IntoPaint trait
* Rename the FIll node's "fill" input to "paint"
* Let the graphic-consuming nodes take List<Graphic> directly, relying on the embedding adapters
* Remove outdated todo comments
* Re-save the demo art
* Split 'To Graphic' and 'Wrap Graphic' into the 'As Graphic' type assertion and 'Into Group' reducer nodes
* Make 'Into Group' reduce List<DVec2> not Item<DVec2>
* Reset the Merge definition for every legacy alias of its coercion nodes
* Improve test
* 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
* Make the 'Solidify Stroke' node preserve graphic structure instead of flattening its input
* Add a shared trait letting element-wise vector modifiers recurse into graphic groups
* Make 20 element-wise vector modifier nodes accept graphic input
* Make 'Separate Subpaths' and 'Points to Polyline' accept graphic input
* Make the 'Map Points' node accept graphic input
* Add TODO comments to the measure nodes deferred until the Graphic lowering refactor
* 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
* Stop chain node insertion from stranding a node on layers without a chain
* Gate the Layers panel blending controls on whether the layer can host them
* Gate the fill and stroke setters on whether the layer can host paint nodes
* Make the tool options fill and stroke controls treat layers that cannot take paint as unselected
* Remove the unused first_selected_stroke_weight helper
* 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
* Rename the 'Sample Gradient' node to 'Evaluate Gradient'
* Let the Evaluate Gradient node's position reach the out-of-range values its spread modes handle
* 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
* Build radio widget entries from choice type metadata so variants display their icons
* Route the node properties enum radio through the shared choice type entry builder
* Let the Gradient and Fill tools paint blank layers with whole-expanse gradients and colors
* Make it work on layers with un-fed Transform nodes
* Show the Fill tool's hover pattern over the whole expanse of layers painted by a color chain
* Let the Fill and Gradient tools replace one another's whole-expanse paint on a selected layer
* Keep a shared paint node alive when a tool takes over a layer, and share the paint value lookup
* Stop a chain node from being shifted twice when a node is inserted in front of it
* Rename spread method to gradient spread so it matches the other gradient attribute names
* Keep the legacy gradient struct's spread method field name matching its on-disk key
* Add a spread method field to GradientRamp, carried at runtime as the gradient item's attribute
* Retire the Fill node's spread method input, folding its value into the gradient ramps on document upgrade
* Add an Ends spread method radio to the color picker popover, replacing the Gradient tool's control bar radio
* Update the demo art
* Introduce the GradientRamp exchange struct as the serialized TaggedValue::Gradient payload
* Unify FillChoice and FillChoiceUI into one enum generic over color format, carrying GradientRamp stops
* Rename the TaggedValue::Gradient variant to GradientRamp to match its payload
* Move the Color variant into the tagged_value macro list since its stored and wire forms match
* Rework Gradient into a newtype of List<Color> with optional position and midpoint attributes
* Fix Vello stopless-gradient fallback coverage, empty legacy gradient tables, the node docs gradient swatch, NaN position elision, and wired setter input overwrites
* Remove the dead InputAccessor traits and the uncallable test helper built on them
* Replace raw node input indices with macro-generated parameter symbols across the editor
* Audit dynamic input index usage, converting to parameter symbols and named input position constants
* Abstract the remaining input index plumbing behind ParameterRef APIs and accessors
* Build SetInputValue messages as struct literals to keep message enums impl-free
* Delete the typed parameter markers in favor of explicit-output test introspection
* Wire the interpolation control path input per chain node type
* Return no input when a parameter symbol is read against the wrong node's parameter view
* Fix parsing regressions, make parsing 2.5x faster than the old pest parser, and clean up the math-parser rewrite
* Fix review findings: whitespace-juxtaposed numbers, mixed real/complex logic, correctly rounded literals, unified NaN truthiness, and gcd/lcm range checks
* Box the `value` field of `NodeGraphMessage::SetInputValue`
* Box the `ExecutionResponse` variant of `NodeGraphUpdate`
* Box the `Layer` variant of `NodeTypeClickTargets`
* Box the `Scope` variant of `ParsedValueSource`
* Route the remaining view queries through the logging query helper
* Name the cache readers by their loading contract and stop cloning the owned nodes per collision check
* Deduplicate the port center, output count, and upstream connector helpers and drop dead accessors
* Collapse the TransientMetadata enum into the Option inside TransientCache
* Extract the shared history snapshot install from undo and redo