A renderer-neutral drawing specification for every mark on the map. Complete enough to reproduce the shapes in any language against any 2D API, without reading the renderer. The companion to node-visual-system (grammar and policy) and rust_port_ideas (the egui argument). Each figure below renders from the same path data as the golden masters in the canonical Markdown.
This page is the presentation sibling of mark-geometry.md,
which is canonical. It shows each mark on both of the app's grounds, azure (the light
default) and navy (the dark), because the two-ground colour meaning is part of the
specification. The Markdown carries the formulas, the constants, and the full prose;
this page carries the shapes.
A dot at every 40-pixel lattice point, in the low-alpha
--grid ink; the subway paper. In the source a 40×40 CSS radial
gradient; reproduced as a tiled texture, or a loop of small filled circles over the
visible rectangle.
Where a card attaches to its line: a filled circle of diameter 11
(radius 5.5) in --line, the same size as a status glyph.
Four shapes. Each is an outer silhouette in the node colour with the
same path inset per edge and refilled in the panel colour; the band between the two
fills is the outline, thin on one edge and heavy on another (the Googie tell). Every
figure below is the outer path and its innerT-transformed copy, drawn on
both grounds. Width is a fixed 188; the height is stated per shape.
A concave cushion: each edge bows inward, top and bottom by 0.14h, sides by 0.05w.
Concave top, tapering sides, convex bottom; the curve is capped at a height of 58 so a tall card does not swallow its own label. The terminus (right) is the same hull turned a half turn, so a folded pair reads as one shape and its reflection.
The BORDERS four-tuples (top, right, bottom, left) that
set the outline weight: screen (3.5, 8, 3.5, 7); marquee
(6, 8, 4, 5); hull (4, 5, 8, 8); keystone
(3, 5, 9, 7). The inner transform is
translate(l, t) scale((w−l−r)/w, (h−t−b)/h).
An 11-pixel circle (radius 5.5) beside the label. Filled for done and in-progress; a 2px solid ring for to-do; a 1.5px dashed ring for cancelled; a filled teal ring for a project node.
Left to right: done, in-progress, to-do, cancelled, project. The ring variants draw at a smaller radius so their stroke sits inside the 11-pixel envelope.
A flagged node wears three off-axis elliptical rings centred on the card, each carrying one electron ball, plus a core, in the node's own colour. Off-axis and irregular on purpose; drawn behind the card so the rings overflow it. Shown in the done violet; the faint rounded box represents the card the decorator sits behind; it is included here so that you can see how much the decorator overflows a card.
Ring semi-axes and rotations (rx, ry, deg): (72, 12, −30), (66, 13, 40), (68, 11, 103). Ball offsets from the centre: (45.4, −34.8), (−36.6, −40.5), (−5.5, 53.7).
The branch cursor: ten solid rays of irregular length at irregular
angles off a base of 15, each tipped with a ball, around a solid core, in
--ink. The cursor draws it at 1.15× the base size.
The four-plus-spoke atmosphere burst is defined in the source but not currently mounted; see the constants in the Markdown.
A track is a polyline in --line with round caps and joins:
a riser (the vertical spine, width 3), and the branch and return laterals (width 2.3).
Where a lateral crosses another line, it yields, cut with a gap whose ends carry caps
lying parallel to the line passed under, so the cut reads as a slice of what runs on.
The illustration shows a return passing behind a riser.
Illustrative crossing; the exact gap and cap geometry is the
breakSize computation in the Markdown (air across the crossed line,
perpClear 3 plus its half-width, divided by the sine of the crossing
angle). In egui the cut becomes an explicit mitred ribbon quad, since egui clips only
to a rectangle.
A fork or merge is marked by an 8-pixel square turned 45° into a
diamond, in --line (turning to --ink on hover); a
single-branch junction also carries a transparent 13-pixel hit halo, shown faint.
A card with a note shows a memo-pad glyph in its bottom-right corner, on
a 16×16 viewbox, in --muted (turning to --ink on
hover): a rounded body, two ring ticks over the top, three ruled lines. Shown at 4×.
Every fill and stroke is a role token resolving to one of two values by
ground. Teal marks the structure of a plan (a project and its close); violet marks a
task that is done. Values from style.css.
| token | role | azure | navy |
|---|---|---|---|
--ground | canvas | #d3e6ef | #0f2334 |
--panel | card panel (task) | #f8f3e8 | #1a3a54 |
--ink | text, cursor mark | #173242 | #e8f1f6 |
--line | tracks, dots, diamonds | #365b6c | #6fb6c9 |
--muted | tags, note glyph | #5f7d8b | #93b3c2 |
--c-todo | to-do | #d9a53a | #f0bd55 |
--c-prog | in-progress | #d75f2e | #f27a44 |
--c-done | done (violet) | #7d54a6 | #bd93e6 |
--c-cancel | cancelled | #8aa0ab | #7590a0 |
--c-project | project hull (teal) | #1f8f8a | #37c2ba |
--c-project-tint | project/close panel | #cbe6e4 | #356e69 |
--cursor | HERE pill, drop hints | #d75f2e | #f27a44 |
The only renderer-specific note; the argument for egui is in
rust_port_ideas. In brief: flatten each quadratic to a
sampled polyline before any camera transform; draw the outline as two fills, never a
stroke; tessellate the concave hull and marquee with lyon into a
Shape::Mesh, since epaint fills only convex polygons; apply SVG
rotate/scale as affine operations on the point list; map
strokes to an epaint::Stroke; and replace the even-odd underpass clip with
an explicit mitred ribbon quad, because egui clips only to an axis-aligned rectangle.
Drive zoom through world coordinates and font size, or atlas-sampled text blurs while
the vector marks stay crisp.
Canonical source: docs/mark-geometry.md. This page is regenerated from it;
if they drift, the Markdown wins. Sources for every number:
render/shapes.js, render/tracks.js, render/card.js,
render/scene.js, style.css, and
node-visual-system.md.