Foundations · 05
Iconography
The manual draws its icons the same way it draws everything else: 1 px contours, the isometric rhombus, the four angles. This is that plate built for the screen — one 24 × 24 box, one live area, one stroke weight that never changes. The CF arrow stays what it always was, a filled glyph and a thing apart; every icon here is drawn.
The set
Forty-three glyphs in six families: direction, operators, primitives, the solid weight, objects and instruments. Hover a tile to see the construction grid it was built on, or turn the keylines on for all of them. Click any tile to copy its markup.
Against the plate
The set is the manual's Icon System plate, and it is worth being able to check that claim rather than take it. The plate is four rows; this is what each one is and where it went.
| Plate row | Is | In the set |
|---|---|---|
| 01 — nine solid marks | the second weight: four chevrons, the X, the rhombus, the nested rhombus, the dot, the ring | *-solid ×7 plus cf-dot, which was already solid |
| 02 — ten line marks | the same marks drawn, plus the cylinder; the chevrons are doubled here | the four doubles, cf-converge, and the primitives |
| 03 — eight objects | globe, coin, cut sphere, node, triangle, pyramid, house, wedge | all eight |
| 04 — nine instruments | signal, X, cube, plane, layers, pin, hourglass, overlap, expand | all nine |
cf-converge, and the objects and instruments the plate draws and the set
did not — globe, cut sphere, coin, triangle, wedge, house, overlap, signal, expand.
Two glyphs in the set are not on the plate and are deliberate:
cf-plus and cf-minus. An accordion needs them, they are 90°
axes and nothing else, and inventing them is cheaper than borrowing a foreign icon set
for two marks. Everything else here is drawn from the plate.
Two weights
The plate's first two rows are the same nine marks twice — once solid, once drawn. That is not a style choice to pick between: they do different jobs. The line weight is the working set, and it is what an interface uses at 16 px and up. The solid weight is the mark at label scale, where a 1 px contour inside a 12 px glyph stops resolving and a drawn rhombus turns into a grey smudge.
The solid marks are not redrawn — they are one construction: the isometric rhombus with a rhombus notch cut out of one of its four vertices. Cut the bottom vertex and the rhombus becomes a chevron pointing up; cut the left one and it points right. The ends stay pointed because they are the rhombus's own vertices, which is exactly what the plate draws and what a stroked-and-capped band could not give you.
fill-rule, not painted.
cf-ring-solid and cf-diamond-nested-solid have a hole in the
middle, and the obvious way to get one — a second shape in the page colour — does not
work here: the page is a vertical wash from CF-Grau to white, so a patch matching it at
one scroll position matches nothing at any other. Both are a single path with two
subpaths and fill-rule="evenodd", so the hole is genuinely a hole and
whatever is behind the icon shows through it.
Construction
Every glyph is drawn in a 24 × 24 box with a 2 px margin, so the live area is 20 × 20. Inside it sit three keylines, and an icon is built on one of them: the isometric rhombus (20 × 10), the isometric circle — an ellipse at 2:1 — and the upright square (18 × 18, inset because a square reads heavier than a rhombus of the same width). Diagonals use only 26.57°, 63.43°, 45° and 90°. A 26.57° line rotated by 90° is a 63.43° line, which is why the four chevrons are one drawing turned four times rather than four drawings.
| Element | Value |
|---|---|
| Box | 24 × 24 |
| Margin | 2 — nothing crosses it |
| Live area | 20 × 20 |
| Rhombus keyline | 20 × 10 (2:1) |
| Circle keyline | rx 10 / ry 5 (2:1) |
| Square keyline | 18 × 18, optically inset |
| Angles | 26.57° · 63.43° · 45° · 90° |
| Stroke | 1 px, non-scaling-stroke |
| Caps / joins | square / miter |
vector-effect="non-scaling-stroke" is set on every
shape in the sprite. This is the same rule the process illustrations follow — a
contour that thickens with the artwork stops being a contour and becomes a shape.
Sizes
Four sizes on the 4 px unit. 16 px is the floor: below it the counters inside the isometric objects close up and the glyph turns into a smudge. Use the object icons at 40 px and above; the direction and operator glyphs work at any size.
The light layer
One icon per screen may stop being a line and become a source. .cf-icon--light
switches the contour to lime and lets it glow — the Licht-Ebene applied to a glyph,
a temporary effect rather than a fill.
--gradient-light. It cannot be done through a sprite: a
paint server referenced from inside a <use> shadow tree resolves
inconsistently across engines — the stroke computes to url(#…) and then
paints nothing at all. An icon that silently disappears in one browser is worse than
one that never promised the gradient, so the light layer here is lime plus
--glow-lime. If a single hero-scale glyph genuinely needs the gradient,
inline that one symbol instead of referencing it.
In use
An icon sits next to a label, or it carries an accessible name of its own. It never floats without either.
- Sensordaten aus der Anlage
- Instandhaltungshistorie
- Betriebsparameter — laufend
<!-- next to a label: the icon is decoration, hide it --> <span class="icon-inline"> <svg class="cf-icon cf-icon--sm" aria-hidden="true"><use href="#cf-pin"></use></svg> <span>Werk Ludwigshafen</span> </span> <!-- alone: the name goes on the control, not on the svg --> <button type="button" aria-label="Dialog schließen"> <svg class="cf-icon" aria-hidden="true"><use href="#cf-close"></use></svg> </button>
The sprite
One file defines the set: assets/js/cf-icons.js. Unlike
docs.js it ships. Include it once per page and it injects the sprite
after <body>, or paste the block below into the page template and
drop the script.
<script src="/design-system/assets/js/cf-icons.js"></script>
Its markup, generated from the same array the gallery above reads — there is no second copy of any glyph anywhere in the system:
Anatomy
| Class | Effect | When |
|---|---|---|
.cf-icon | 24 px box, 1 px currentColor contour, no fill | always |
.cf-icon--sm | 16 px | inline with 14 px body copy, inside buttons |
.cf-icon--md | 24 px | the default; explicit when it sits next to a modifier |
.cf-icon--lg | 40 px | list markers, card headers, the object glyphs |
.cf-icon--xl | 80 px | section openers, empty states |
.cf-icon--bold | 2 px contour | large format, or a surface too busy for 1 px |
.cf-icon--light | lime contour + glow | one per screen, dark surfaces, decorative |
.cf-icon--motion | +4 px on the parent's hover or :focus-visible | only inside a link or button |
Drawing a new one
The set is meant to grow, and it grows in one place: the ICONS array in
assets/js/cf-icons.js. An entry records the id, a label, what the glyph
is for, and the keyline it was built on — that last field is not bookkeeping, it is
the constraint. If a new glyph cannot name the keyline it stands on, it does not
belong to this system yet.
{ id: 'cf-cube', label: 'Cube', use: 'An asset, a machine, one unit of anything',
keyline: 'rhombus 16 x 8 + 8 px extrusion',
shapes: '<path d="M12 4 L20 8 L12 12 L4 8 Z"/>…' }
Write the shapes without stroke or size attributes — those come from
.cf-icon. The build step that would normally add
vector-effect to every shape is four lines of JavaScript in the same
file, so a new glyph inherits the 1 px rule for free.
Rules
Do
- Draw on a keyline. Rhombus, ellipse or square — name it in the entry.
- Keep to the four angles. A rotation of a sanctioned angle is sanctioned.
- Contour before fill. The only solid marks in the set are dots.
- Hide decorative icons with
aria-hidden="true"and name the control instead. - One weight per context — do not mix 1 px and 2 px in the same row.
Don't
- No third-party icon set, ever. If it is not in the array, it is not drawn yet.
- No rounded caps, no rounded joins, no corner radii.
- No perspective and no true 30° isometry — this system is 2:1, at 26.57°.
- No lit icon on CF-Grau, and never a lit icon carrying meaning on its own.
- No icon inside a button next to the CF arrow — one mark per control.