Leeward · icon system · specimen 1.0

Eighteen marks, one hand.

A stroke icon set for a coastal tide & weather station dashboard. Organic forms (swell, wind, moon, rain), instruments (anemometer, buoy, tide gauge, mooring) and interface verbs (filter, export, alert, history) drawn on one grid, to one weight, with one curve grammar.

24×24 viewBox · 20×20 live area · 1.75 stroke · round caps & joins · ≤24 path commands per icon · currentColor throughout

01 The row test

All eighteen at 24 px, one line, both grounds. The set should read as a single voice — no icon heavier, lighter, larger or smaller than its neighbours.


02 The set

Symbol id, name and family. Instruments borrow the organic icons’ curves (the buoy floats on the swell’s own wave; the tide gauge reads it against ruled ticks), which is what holds the three families together.


03 Construction

The keylines, and the rules every icon was drawn to.


  • Grid. 24×24 canvas, 20×20 live area (2 px padding). Full-width horizontals — the swell, a horizon — may run the whole 20.
  • Stroke. 1.75 at 24 px, round caps and joins everywhere. Corners are rounded by the joint, not by extra arc geometry; only containers (the export tray) take an explicit r2.
  • Optical sizing. Circular silhouettes run to Ø18–19 (moon, compass), boxy ones stop near 16–17, stars and triangles overshoot the keyline — mathematically unequal, optically equal.
  • One curve grammar. Every wave is the same flat-in/flat-out half-period cubic, scaled: swell, buoy waterline, tide-gauge level.
  • Economy. ≤24 path commands per icon, coordinates to two decimals, no transforms, no groups. Dots are zero-length round-cap strokes, not filled circles.
  • Weight is CSS. The sprite bakes colour and caps; stroke-width is left to the class so products can retune it.

04 Scale

16 → 96 px on the same geometry. Two icons carry deliberate small-size cuts, swapped in below 20 px rather than letting detail clog.


05 Colour

Everything inherits currentColor — one sprite serves ink, accent, semantic and on-dark uses with no second copy.


06 In context

A station card. Icons beside text are decorative and hidden from assistive technology; icon-only controls carry names; the advisory glyph is a named image.


Nazaré · N-01

offshore buoy — 39.61°N 9.39°W

07 Usage & accessibility

Inline the sprite once; reference by id. Size and weight belong to one class.


<!-- 1 · Paste the sprite once, right after <body> -->
<svg style="display:none" aria-hidden="true">
  <symbol id="i-swell" viewBox="0 0 24 24" fill="none"
          stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
    <title>Swell</title> …
  </symbol>
  … seventeen more …
</svg>

/* 2 · One class carries size and weight. Weight stays in CSS,
     never in the sprite, so it can always be themed. */
.ic{width:24px;height:24px;stroke-width:1.75}

<!-- 3 · Decorative (a text label exists): hide the glyph -->
<button><svg class="ic" aria-hidden="true"><use href="#i-filter"/></svg> Filter</button>

<!-- 4 · Meaningful (the icon is the label): name the control or the image -->
<button aria-label="Add to favourites">
  <svg class="ic" aria-hidden="true"><use href="#i-favourite"/></svg>
</button>
<svg class="ic" role="img" aria-label="Small-craft advisory"><use href="#i-alert"/></svg>

/* 5 · Theme with currentColor; retune weight freely */
.warning{color:#b3541e}   .dense{stroke-width:2}

<!-- 6 · Below 20 px, swap the two dense instruments for their cuts -->
<use href="#i-tide-sm"/>   <use href="#i-anemometer-sm"/>