* 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
* 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
An absent read of a name the census declares now serves that name's own
default rather than its value type's, which is the rule for a declared
name. The census stages it exactly as it fills any absent field, as the
declared default's bytes, so the read reuses the census's own mechanism
instead of a second one; the compiler takes them when the name folds and
`set_layout` installs them beside the offset.
A name the census does not declare keeps the value type's default, which
is that case's own rule. One name carries one value type, checked when
the name folds, so the row's value type and width agree with the read's.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fold already holds the name and the read input's finished layout, so
the offset falls out there rather than at construction: `RecordLayout`
carries the resolved numbers and `set_layout` copies them into the read
slots. Constructors are untouched, and census-marker reads keep their
current installation.
A read meets the value type the name was written at, so a disagreement
between a read here and a write upstream is the same graph error as two
writes disagreeing; the one-name-one-type check now spans reads and
writes together. An absent attribute stays absent and the read serves
the forced default rather than reporting it.
`read_attribute` is the catalog's get half, typed and never `Option` at
the kernel boundary, with the name declared exactly as the write side
declares it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`compute_layouts` resolves every name-from-input write against the text
its name input carries, so a folded meta is indistinguishable from a
marker node's and the layout holds a `&'static str` from there on. That
leaves nowhere for a name to be computed, which is the whole of the
rule: a name input that is not a constant is refused right here, per
node, with the path the editor pins its diagnostic to.
One name carries one value type, checked across the census and the
names a node folds together, so no graph can declare one field at two
widths. `compute_layouts` returns those refusals rather than panicking.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>