Eighteen marks for a coastal tide & weather station dashboard — organic readings, mechanical instruments and interface actions, held to one hand on one grid.
No cherry-picking, no enlarging. If the hand wobbles anywhere, it shows here first.
Readings the sea produces on its own, instruments bolted to a pier to measure them, and the interface chrome that lets someone act on the numbers.
Stroke width lives in viewBox units, so it scales with the mark instead of staying pinned to a pixel value.
Two wave-lines read cleanly at 24px and above. Below that they merge into noise, so swell
ships a second, one-line symbol swapped in at small sizes rather than a shape that quietly degrades.
No dark-mode duplicate set. Every stroke and the handful of solid accent dots inherit color from context.
Every icon in the set, doing an actual job: a station card with live readings, an advisory, instrument status and a toolbar.
An icon beside a visible label is decorative — assistive tech should skip it. An icon that is the control needs a spoken name on the interactive element, not buried in the sprite.
<!-- decorative: label carries the meaning -->
<svg class="icon" aria-hidden="true" focusable="false">
<use href="#icon-filter"></use>
</svg>
<span>Filter</span>
<!-- meaningful: icon-only control -->
<button aria-label="Add to favourites" aria-pressed="false">
<svg class="icon" aria-hidden="true">
<use href="#icon-favourite"></use>
</svg>
</button>
Every <symbol> still carries its own <title> for source
legibility and for tooling that inspects the sprite directly — it just isn't relied on as the
only accessible name in the UI.
<symbol id="icon-buoy" viewBox="0 0 24 24"> <title>Buoy</title> <path d="M9,15 L9.8,8.4 ..."/> </symbol>
24×24 viewBox, 2px padding on every side. Circular marks (moon, sun, compass rim, barometer dial) are allowed to press to the live-area edge — a curve at the same extent as a straight edge always looks smaller.
1.75 units, round caps, round joins, currentColor. Nothing is a baked-in fill except the marker dot described below.
Round joins stand in for a ~2-unit corner radius on every freeform turn; the two rectilinear marks (filter, export) use an explicit matching curve instead of a hard corner.
Circles are drawn 4–8% larger than a square of the "same" size would need, so the moon, sun and gauges read as equal in weight to squarer marks beside them. The favourite star keeps its inner radius at 40% of the outer so points don't needle at 16px.
Every symbol is primitives (circle/line) plus at most one or two short paths. No path exceeds 11 of the 24-command budget; most use far fewer.
One deliberate solid shape recurs across the set — alert, history, tide gauge and buoy each carry a small currentColor dot, unstroked, 0.8–1.3 units. It's the family's one fill, used the same way every time.