The Quiet Sky icon family. Every glyph is assembled from the same primitives against one of four keylines, measured after rendering, and generated from a single script — so the sprite and the files can never drift apart again.
A 24 × 24 grid with a 20 × 20 live area. Every form is fitted to one of four templates, and the template it was fitted to is recorded in icons.json. A circle is drawn larger than a square because it carries less optical weight at the same measurement — that difference is the whole reason the table exists.
The manifest records one of four optical templates for every icon: square, circle, portrait, or landscape.
| Constant | Value | Why |
|---|---|---|
| Grid | 24 × 24 | Live area 20 × 20 — a 2px trim on every side so icons never touch their box. |
| Stroke | 1.5 | Round cap, round join. One weight; the family has no light or bold cut. |
| Corner | r = 2 | Every rectangular form. The system has no sharp corners at any scale, and 24px is not an exception. |
| The particle | Ø 3, filled | The only filled element in the family. It means what it means in the logotype: alive, now. |
| Keylines | 18.5 / 20 / 16.5×20 / 20×16.5 | Square · circle · portrait · landscape. Outer extent, stroke included. |
The build rasterises all 106 drawings and measures each one's tight bounding box against its declared keyline. An icon 2px short of its keyline reads as a mistake in a row of icons that aren't — and that is invisible to the eye until the row exists. Every drawing now lands within 2px, apart from the exemptions below, which are exempt because the geometry says so: a checkmark is not a square, an arrow has a length rather than a width, and a bold B that filled its box would be wider than any B ever drawn.
Run it yourself: python3 brand/doc/build_icons.py --audit
Including the fourteen composer icons the application spec has always specified and no previous set contained.
14 inline · 16 buttons and meta · 18 navigation · 20 headers. The family is drawn to survive 16px without an optical cut — verified by rendering, not assumed.
Every glyph consumes currentColor. Set the text colour on the parent and the icon follows — there is no fill to override and no second colour anywhere in the family.
<use href="#ic-name">) or import the SVG. Never paste path data into a component.aria-label and a tooltip.particle and halo for agent presence. They are the logotype's dot, at icon scale.| Path | What |
|---|---|
| brand/icons/svg/ | 108 files — 106 drawings plus aliases. 24×24, currentColor, stroke 1.5. |
| brand/icons/sprite.svg | All 108 as <symbol id="ic-{name}">. One request, one cache entry. |
| brand/icons/icons.json | Manifest: group, keyline, aliases and intent for every glyph. |
| brand/doc/build_icons.py | The generator and the audit. Change a constant, rebuild the family. |
brand/doc/migrate_assets.py ships this family to assets/icons/, so the product paths and these masters are the same files. The v1 set — 35 icons, two of which rendered identically — is preserved at archive/assets-v1/.