Tideline icon system · v1.0

Eighteen marks, one hand

Line icons for a coastal tide and weather station dashboard. Organic weather, mechanical instruments and interface verbs drawn on one 24-pixel grid, with one 1.5-unit stroke, so they can sit in the same toolbar without arguing.

  • 18 icons + 2 small forms
  • 24 × 24 · live 20 × 20
  • stroke 1.5 · round / round
  • sprite … raw · — gzip
  • heaviest icon … commands

01 · The row test

All eighteen at 24 px, in a line

This is the view the set is judged in. Weight, cap, join and density have to read as one afternoon's work whether the subject is a swell, a bollard or a funnel — on either ground.

light · currentColor = ink

dark · same sprite, no second copy

02 · The set

Three kinds of form, one family

Grouped by the kind of thing they depict. Command counts are measured from the sprite in this page at load; the budget is 24 per icon.

03 · Scale

Honest at 16, composed at 96

The stroke scales with the icon — 1 px at 16, 2 px at 32, 6 px at 96 — so the family keeps its weight relative to the type beside it.

Small forms

Two icons carry detail that collapses below 20 px: the anemometer's cup arcs become 1.3 px blobs, and the gauge's 3-unit tick rhythm turns into a comb. Each ships a deliberate -sm form (shown in green): cups become vanes, ticks halve. Swap at the breakpoint in CSS or by id; nothing else in the set needs it.

Stroke weight from CSS

No symbol carries a stroke-width. Set --icon-stroke on any ancestor and every instance follows.

04 · Construction

Grid and rules

Circle keyline Ø20 — compass sits on r 9.5 so the stroke's outer edge lands on it.

Square keyline 18 — the funnel's mouth fills it; circles overshoot it by one unit a side.

Landscape keyline 20 × 16 — containers take r 2; every other corner is the round join.

  • Grid. 24 × 24 viewBox. Live area 20 × 20 (2–22) measured at the stroke centre, 2 units of padding. The stroke adds 0.75 outboard, so no ink crosses 1.25 from the edge and nothing is ever clipped.
  • Stroke. 1.5 units, round caps, round joins, fill: none. Dots (gauge hub, buoy lamp) are small circles or closed strokes, never fills, so they inherit colour and weight with everything else.
  • Keylines. Circle Ø20, square 18, landscape 20 × 16, portrait 16 × 20. Container corners r 2.
  • Optical correction. Circular forms overshoot square ones by 1 unit per side. The star is drawn around (12, 12.75) because its mass sits low; the crescent's centre is nudged to x 13 so the hollow side doesn't read heavier; the barometer arc sits half a unit low to balance its open bottom.
  • Density. Parallel strokes keep at least 2 units of clear space at the 24 size (3 in the swell, wind and rain). No detail finer than 2 units; detail that needs it gets a -sm form.
  • Economy. ≤ 24 path commands per icon, implicit repeats counted. Coordinates to two decimals, relative commands where they read better, no transforms, one <path> per object plus primitives where a primitive is the honest shape.

05 · In context

A station card

Toolbar buttons carry their names on the control and hide the icon; the advisory icon is content, so it is named. Metric icons are decorative — the label beside them does the work.

Porthleven — station 0427Updated 14:20 BST · next high water 16:48

Small-craft advisory in force until 18:00 — gusts to 34 kn from the south-west.

  • Tide height4.2 mrising · springs
  • Wind18 knSW 225° · gust 34
  • Pressure1 012 hPafalling slowly
  • Swell1.4 m9 s period · W
  • Sea temperature11.4 °Cair 13.8 °C
  • MoonWaxing gibbousfull in 4 days

dark · the same fragment, cloned

06 · Usage

Drop the sprite in once, reference by id

The sprite is the <svg class="sprite"> at the top of this document. Instances are empty <svg> elements with a <use>; colour and weight come from the .icon class and cascade from wherever the icon sits.

<!-- decorative: the control owns the name, the icon is hidden -->
<button type="button" aria-label="Export as CSV">
  <svg class="icon" aria-hidden="true"><use href="#i-export"/></svg>
</button>

<!-- meaningful: the icon is the content, so it is named -->
<svg class="icon" role="img" aria-label="Alert"><use href="#i-alert"/></svg>

<!-- small form below 20 px -->
<svg class="icon" style="--icon-size:16px" aria-hidden="true"><use href="#i-anemometer-sm"/></svg>

.icon {
  width: var(--icon-size, 24px); height: var(--icon-size, 24px);
  fill: none; stroke: currentColor; stroke-width: var(--icon-stroke, 1.5);
  stroke-linecap: round; stroke-linejoin: round;
}