Harbour / Icons
Tide & weather station · v1.0 · 18 glyphs
Coastal observing dashboard

One grid, one hand.
Eighteen tide-station icons.

Organic, mechanical and interface forms drawn with the same 1.7px rounded stroke on a 24px grid. No fills except three signal dots, no text, no assembly — every mark is authored geometry that inherits currentColor and survives a CSS stroke-width.

24×24 · live 20×20 · 2px padding1.7px · round cap + join≤ 24 commands / iconsprite <12KB gzipped

The row test

All eighteen at 24px in one line. If the mechanical icons feel heavier than the wind, or the interface icons drift lighter, the family fails — this is the test the set was drawn against.

24px · currentColor · 1.7px strokeswell → temp

Full set

Organic first (swell, wind, moon, rain, tide, current), then mechanical (anemometer, buoy, gauge, mooring, compass, temp), then interface (filter, export, alert, history, compare, favourite). Hover to inspect.

Swell#i-swell
Wind#i-wind
Moon phase#i-moon
Rainfall#i-rain
Tide range#i-tide
Current#i-current
Anemometer#i-anemometer
Buoy#i-buoy
Tide gauge#i-tide-gauge
Mooring#i-mooring
Compass#i-compass
Water temp#i-temp
Filter#i-filter
Export#i-export
Alert#i-alert
History#i-history
Compare#i-compare
Favourite#i-favourite

Scale honestly

Readable at 16px, composed at 96px. Two masters ship a deliberate small form where curls and ticks would clog: wind and tide-gauge. Everything else holds without simplification.

96px
48px
24px
16px
Small masters — deliberate, not automatic
DefaultSmall (16px)Why
Curls close up; three bars keep rhythm.
Four ticks + wave → two ticks + rule.
Themeable stroke

Stroke width lives in CSS (--sw), never in the sprite. Drag to prove it:

1.7px

Light & dark — one copy

No inverted duplicates. Every glyph is currentColor strokes (plus three solid signal dots), so the same sprite works on both grounds.

In context

A harbour-master station card. Decorative icons are hidden from assistive technology; the gale-warning icon carries a name.

Port Isley — Tide & Weather Station
Live · updated 2 min ago · 43.38°N 70.20°W
Filter Compare History Export
Gale warning in effect until 18:00 — gusts 34 kt from SW. Harbour notice
Swell
2.3 m
9 s · WSW
Wind
18 kt
Gusts 26 · SW
High tide
14:32
+3.1 m · rising
Water
11.4°
Rain 2 mm ·
High 14:32
Buoy 4 · on stationWaxing gibbousMooring tension nominal

Construction

One grid for all three families. Optical correction beats maths: circles overshoot the live area, waves run edge to edge, dots are drawn 2px and never stroked.

RuleValue
Grid / live / padding24 · 20 × 20 (2–22) · 2px safe
Stroke1.7px · round caps + joins · set in CSS via --sw, never in sprite
Corners / radii2px nominal; joins do the rounding — no chamfers
Optical correctionCircles r 6.5–7.2 centred 12/12; squares inset extra 0.5px; waves span 3–21 to look full; buoy body narrowed 1px to offset water weight
Density2–3 strokes per glyph; solid dots only for alert, anemometer hub, thermometer bulb
Node budgetMax 8 commands in set (mooring flukes); all ≤ 24 · 2-decimal coords · no transforms · titled symbols

Usage

Copy the sprite once, reference anywhere. Decorative instances are hidden; meaningful ones are named.

<svg class="icon" aria-hidden="true"><use href="#i-wind"/></svg>

<!-- meaningful: name it -->
<svg class="icon" role="img" aria-label="Gale warning">
  <use href="#i-alert"/>
</svg>

<style>
.icon{
  width:24px; height:24px;
  color:#14313d;               /* currentColor */
  fill:none; stroke:currentColor;
  stroke-width:var(--sw,1.7);
  stroke-linecap:round; stroke-linejoin:round;
}
.dark .icon{ color:#e8f2f3; }
</style>
Accessibility demonstrated

Left: decorative swell hidden from AT. Right: alert exposed with a name.

2.3 m (decorative icon)named icon

Each <symbol> carries a <title> so the source is self-describing; instances decide exposure via aria-hidden or aria-label.