13 KiB
SolidCraft UI icon specification
This is the binding specification for new and revised icons. Use it with the
actual SVG references in design/references.toml; http://127.0.0.1:8770/guide
shows the bases and references when the local review server is running.
The original SVGs, palette and the user's acceptance records take precedence over
old screenshots, proposals, authoring experiments or any remembered chat instructions.
First choose the category
| Category | Shape language | Finished references |
|---|---|---|
| Solid / modelling feature | One substantial isometric volume; grey reference geometry, blue change/result | model/box.svg, extrude.svg, hole.svg, rib.svg, contact_sets.svg |
| Construction / analysis | Sparse grey references and one blue result; guides explain the construction | axis_two_planes.svg, axis_normal_to_face.svg, point_three_planes.svg, plane_midplane.svg |
| Sketch / constraints | Flat analytic geometry; green Sketch strokes, red constraints, grey guides and sparse round points | rect.svg, circle.svg, polygon_circumscribed.svg, slot.svg, sketch_fillet.svg, c_parallel.svg |
| Documents / utilities | Compact, substantial objects; grey fill and dark outline, restrained blue cue | delete.svg, copy.svg, paste.svg, library.svg, new.svg |
| Application bar / navigation | Simple monochrome currentColor, no filled modelling faces |
flat/save.svg, undo.svg, orbit.svg, fit.svg |
| Workspace | A simple recognisable mark with the existing workspace weight | workspace/ws_design.svg, ws_animate.svg |
Unqualified references in the table are in design/svg/model/. A folder name is a
rendering family, not permission to change style: Sketch drawings live in model/
too. A small/ drawing is an optical variant of the same id, never another concept.
Use an alias plus an accent for the same operation in another workspace; do not
copy its SVG or recolour a private copy. Do not add a filled cube to a flat control.
Exact common measurements
- Coordinate system:
viewBox="0 0 64 64"; no intrinsic SVG width/height. - Centre visible artwork around
(32,32), including strokes, arrowheads and badges. Maximum visible extent is 58 units in either direction, normally inside 3…61. Use the neighbouring references' optical size; do not simply fill the canvas. - Geometry outline: 2.55; action / Sketch stroke: 4.25; navigation: 5.6.
Parameters retain their existing 4.2 weight. These values are in
palette.toml. Sparse guides may use 2.0–2.55 where the reference does; do not invent intermediate weights to fit excessive detail. Every stroke has round caps and round joins. - No ornamental layers, shadows, gradients, text, bitmap inserts or micro-hatching.
Aim for one base object plus one result/action cue. Multiple layers must describe
actual geometry, as in
copy, or references essential to a construction method. - Curves must be smooth at joins. Use analytic ellipses/arcs or matched Bézier tangents. Do not approximate a round face with a visibly irregular polygon.
Canonical grey cube — do not redraw it by eye
design/tools/author/bases.py::grey_cube(icon) is the exact common base.
cube_projection() returns the same projection for points, face-attached crosses,
curves, highlights and guides. lib.py::Iso and Icon are the low-level helpers.
The physical cube is x/y = −12…12, z = 0…24. Default scale is 1.125. Projection:
screen_x = 32 + (x-y) * sqrt(3)/2 * 1.125
screen_y = 32 + (x+y)/2 * 1.125 - (z-12) * 1.125
| Vertex | Screen coordinates |
|---|---|
| back top | (32, 5) |
| left top | (8.62, 18.5) |
| front top | (32, 32) |
| right top | (55.38, 18.5) |
| left bottom | (8.62, 45.5) |
| front bottom | (32, 59) |
| right bottom | (55.38, 45.5) |
Axes are x right/down, y left/down, z straight up. Diagonals have 30° slopes;
equal physical dimensions remain equal. Screen-left face is y=+12; screen-right
face is x=+12. Default passive fills are top P1, left P2, right P3. Never swap
them to make an individual drawing prettier. Do not use perspective convergence.
grey_slab() uses the same axes and shading with a four-unit thickness. Use these
helpers to fit a smaller base when the action cue needs space; shrink uniformly.
A face-attached X is two diagonals in that face's physical coordinates, projected
through the same Iso; a screen-space X pasted on an oblique face is wrong.
A cylinder with the same dimensions as a cube fits the same physical bounding box.
Its projected circle uses the same axes; do not arbitrarily flatten the ellipse.
Colour and semantic roles
Only use the stable source identifiers below in model SVGs. The renderer maps roles to
light/dark theme values. currentColor is the background line-art role, not a way
to add arbitrary colours. All values and accents come from design/palette.toml.
| Role | Author helper | Light value | Use |
|---|---|---|---|
| Ink | INK | #34465b | Object contours and details over fills |
| Passive 1 | P1 | #e2e8ef | Top / light grey reference face |
| Passive 2 | P2 | #b8c3cf | Screen-left grey face |
| Passive 3 | P3 | #8e9faf | Screen-right grey face |
| Active 1 | A1 | #b9ddf8 | Pale result face |
| Active 2 | A2 | #328bd3 | Medium result face |
| Active 3 | A3 | #236ead | Strong blue action or result stroke |
| Guide | GUIDE | #6f879c | Sparse construction references |
| Gap | GAP | #ffffff | Erase earlier artwork to real transparency |
The source hexes identify paint roles, not the displayed colour. Never recolour an
SVG to apply a workspace accent. Keep these identifiers and every finished shape
unchanged; the runtime and review page resolve them through design/palette.toml.
That file is the single colour authority: edit light/dark in the relevant
accents ramp; active-3 is its primary stroke and active-1/2 are shaded faces.
Do not edit a role's source identifier. variants holds colour-vision adjustments.
A role with use = "active-3" follows that stroke automatically.
| Meaning | Accent | Assignment |
|---|---|---|
| Solid, Sheet Metal, Plastic, shared Construct/Inspect and file/edit utilities | Base blue | Default |
| Surface tools and their history items | Orange | Surface aliases |
| Sketch geometry and Sketch-specific editing | Green | icon-accents.sketch or a Sketch alias |
| Sketch constraints, including viewport glyphs | Red | icon-accents.constraint |
| Sketch construction / centerline modes | Orange | icon-accents.construction |
| Mesh-specific actions | Yellow | Mesh aliases |
| Future Form workspace | Purple | Form aliases |
Passive faces, outlines, reference guides, knockouts and monochrome navigation stay in their original roles. Non-blue dotted or dashed reference lines use Guides. Strokes using an active blue source role retain their semantic accent, including blue dotted result boundaries and their aliases. A wider knockout beneath such a line erases earlier artwork. Draw manual reference dashes and dots with GUIDE. Construct planes/axes/points remain blue. The active workspace never recolours shared tools. Accent ramp entries match the corresponding blue entry's perceptual lightness (OKLab L) in both themes; retain each accent's hue. Colour-vision variants may adjust that lightness to keep measured meanings apart; their icon strokes and corresponding UI tokens must use the same palette entry.
Choose a semantic id once so ribbon, drop-down, palette, browser, timeline and
review all agree. An explicit alias accent wins over an id's default. Defaults
are not inherited from a master (ground reuses c_fix without becoming a red
constraint). Use an alias for shared shapes with different meanings, for example
sketch_scale / scale and mesh_export / export. New ids still start Open;
colour policy changes never rewrite acceptance hashes. Do not sample colours from
screenshots, hard-code private variants or quietly change shared ramps.
Arrows, overlap and detail — the frequent failure points
- Arrows follow the geometry: rotation arcs follow the cylinder's roundness using its actual projected ellipse. Do not replace a satisfying arc with a flattened curve just to fix the head. Preserve the shaft and correct the tangent/head.
- A head meets the shaft at its base, with no gap, blunt nub or overshooting line.
Its direction follows the curve's final tangent.
bases.arrowsupplies the straight version. Standard small heads are around 8–10 units long/wide. - A knockout around an overlaid arrow/X is normally about 1–1.2 units per side.
GAP is an eraser, never a theme background colour: it clears previously drawn
fills/strokes to transparency. Draw the coloured foreground after the knockout.
Existing binary masks use literal
white/blackfor coverage, not GAP. Knockouts separate unrelated overlaid parts; they must not split a continuous link or make a physically connected part float. Wider borders need a clear semantic reason, as in the infinity symbol. - Compute visibility before outlining. Draw distant opaque faces first, then near faces. A hook must cover both the stem's hidden fill and its hidden edges. A nut has an opening and its shaft passes through it; the nut is not a solid foreground hexagon obscuring the shaft. Never fix an occlusion error with a stray patch.
- Face removal: the missing face is unfilled. Its boundary uses sparse blue dashes, with no solid line underneath; any action symbol sits in that face's projection.
- Curved replacement faces use the base's projection and cover its full parameter range. Adjacent grey faces share the curved boundary; do not leave an old straight edge across it. Extend a surface slightly and consistently beyond all intended edges.
- Use round Sketch points sparingly: regular points are about radius 3–3.4. Construction reference points should stay subordinate to the result. Do not mark every sample.
- Dashes and dots must have even spacing, including the closing seam. Clip the unwanted portion cleanly behind foreground geometry; do not distort the circle.
- Utility icons follow
delete,copyandpasteproportions and roundness. Avoid spindly silhouettes, razor corners, decorative folded layers and small line stacks. - Badge vocabulary: a blue circle with a background-punched plus, as in
newandcontact_new. Maintain the main object's silhouette and a clear small-size gap.
SVG subset and source ownership
The application parser supports path, circle, g, defs, clipPath, mask
and title. Use paths for ellipses (lib.ell); native <ellipse> is unsupported.
Paths use absolute M/L/C/Q/A/Z. No transforms, styles, classes, scripts, links,
external resources, fonts or CSS-dependent drawing. Use explicit palette paints.
Keep clip ids unique inside each SVG. One id has one primary master; small/ may
supply an optical variant. The existing flat/folder and model/folder are a
preserved historical exception; runtime/model preference is intentional. Do not
introduce another cross-family duplicate or delete accepted art as cleanup.
SVGs are editable masters. Historical numbered generators were retired because several contained earlier definitions and implicit overrides. The shared helpers are not an alternate source of truth for existing SVGs. Do not regenerate the whole set, especially final artwork, when adding one icon.
First-pass workflow and acceptance rubric
- Read the command/interaction and two closest finished references. Choose a distinct concept and the category above. Check final/master/alias protection.
- Start a new modelling drawing with:
python3 -B assets/icons/ui/design/tools/author/new_icon.py my_icon --base cube. Choose--base slabor--base emptywhen appropriate. The starter is not a completed icon. The tool refuses an existing master/alias and adds attribution. - Add the smallest clear operation cue. Wire
.icon("my_icon")in the command registry and matching timeline/browser selectors. Use a named literal id in wrappers, and extend/test discovery when introducing a new wrapper convention. - Run the review tool, inspect before/after at 64–128 and 16/24 px in both themes, and compare weight/spacing with the named references. At 16 px the operation must remain distinct. Add a small variant only if simplification is necessary.
- Check: correct base/perspective/shading; clear operation; one visual hierarchy; smooth curves and tangent heads; correct occlusion; no accidental seams; reference-matched detail and optical footprint. Fix these before owner review.
- Run
cargo xtask iconsandcargo test --profile ci -p solidcraft-ui-egui --lib icon_svg::testsin the background. Run normal repository gates before committing. Never claim visual quality from lint alone. Keep review evidence under ignored target/. - Leave the icon Open. The owner uses the review page to finalise the exact artwork revision. Do not add acceptance hashes or copy another icon's hash.
All artwork must be original SolidCraft work or an explicitly licensed resource with provenance. Commercial CAD artwork, screenshots and extracted assets are forbidden even as hidden references. This guide and the local finished set provide all required visual context for future agents.