Row test
the whole family in one line, no hiding placesOrganic forms carry the same stroke as the machinery and the chrome. The 16 px row swaps barometer for its small-size form — the only icon that needs one.
The set
18 symbols · 19 with the small-size formGrid & construction
24 × 24 · live 20 × 20 · stroke 2barometer on the keylines — dashed teal: live area (2 px clear all round).
dashed orange: 18 × 18 square keyline vs Ø 17.5 circle keyline.
- Canvas24 × 24 viewBox. Live area 20 × 20 — 2 units of clear water on every side, nothing clips.
- StrokeWeight 2, round caps, round joins, everywhere. No stroke-width lives in the sprite: it inherits from CSS, so a theme can thin or fatten the whole family in one line.
- OpticsA circle and a square of equal measure don’t weigh the same. Round forms ride the Ø 17.5 keyline (3.25 – 20.75), squares sit at 17 – 18 wide; rings overshoot flat forms by ~0.5 so neither reads small. The star sinks 0.5 low; the triangle’s apex rides the live edge.
- RadiiOne corner radius — 2 units — for every rectilinear bend (export tray, and nowhere else cheats it).
- DensityEach glyph keeps 2–5 elements. Mechanical icons are held to the same stroke count as organic ones so the row doesn’t wobble.
- NodesBudget of 24 path commands per icon; heaviest glyph (tide-gauge) spends 18. Circles are true <circle> geometry, not traced arcs.
- ColourEverything strokes currentColor. One sprite serves light and dark; recolour with the CSS color property.
Scale
16 px honest, 96 px unembarrassedDeliberate small-size form
At 16 px the gauge ticks collapse into the rim. #ic-barometer-sm keeps dial, hub and needle only. Swap it by hand below 20 px — the 16 px row above already does.
Why only one variant
The rest of the set was drawn loose enough — long strokes, open counters, no micro-ticks — to survive 16 px as-is. Shipping eighteen “small” twins would be tourism, not a system.
Light & dark
one sprite, no second copyDay watch · inherited colour
Night watch · same symbols
Flip the whole page with the Night watch toggle in the masthead — every glyph, chart and button follows currentColor down.
In service
a plausible station panel, 16 px working sizeNow & next water
- 14.2 knWind · SW 5
- 1.8 mSwell · 9 s period
- 1009 hPaFalling slowly
- 16:41Next high · 4.9 m
| Time | Height | Event | Sky |
|---|---|---|---|
| 04:37 | 4.7 m | High water | |
| 11:02 | 1.1 m | Low water | |
| 16:41 | 4.9 m | High water · springs | |
| 23:18 | 0.9 m | Low water |
Decorative instances are aria-hidden and the surrounding control carries the name; the advisory’s icon is the message itself, so it is named with role="img".
Usage
sprite → <use> → currentColor<!-- 1 · sprite once, near the top of <body> --> <svg width="0" height="0" style="position:absolute" aria-hidden="true"> … nineteen <symbol>s … </svg> <!-- 2 · decorative: the control is named, the glyph hides --> <button class="ibtn" aria-label="Export observations as CSV"> <svg class="i" aria-hidden="true"><use href="#ic-export"/></svg> </button> <!-- 3 · meaningful: the glyph itself is the message --> <svg class="i" role="img" aria-label="Gale warning"> <use href="#ic-alert"/> </svg> /* 4 · the contract — strokes ride currentColor, weight stays themeable from CSS */ .i { width: 24px; height: 24px; stroke-width: var(--sw, 2); color: inherit; } /* below 20 px, prefer the small-size form */ <use href="#ic-barometer-sm"/>
Accessibility, in two rules
- Decorative: aria-hidden="true" on the svg; name lives on the button or the text beside it.
- Meaningful: role="img" + aria-label on the svg itself. Each symbol also carries a <title> for source-readers and debuggers.
Node ledger · path commands
- swell 6
- wind 8
- rain 12
- moon 4
- sun 16
- anemometer 6
- buoy 12
- tide-gauge 18
- mooring 12
- barometer 8
- barometer-sm 2
- compass 5
- filter 7
- export 11
- alert 8
- history 8
- compare 14
- favorite 11
- tide-clock 8
- budget ≤ 24