Destination icon

Four destinations, four marks. It was five for three days: Trends joined on 2026-08-18 and Save left on 2026-08-21, when the founder asked why a tab landed on a screen 84 per cent identical to the one it left. It is the only icon set the product owns, it is painted with currentColor, and the one thing it must never do is clip the unread dot that lives inside it.

Atom28 grey pages112 places4 values, one per destinationno states, not interactive

Anatomy

One zone, one mark, and one optional child. Everything below is drawn by design/system/components/destination-icon.css through the same entry point a product screen loads. The mark itself is a CSS mask over a solid fill, so a screen carries nothing but the class: the kit owns the shape.

The mask does not render on a bare demo, and it is not faked here

Measured on this page: a bare <span class="ic ic-home"> inside a stand scene reports content: none on its ::before, and the element itself measures 0 by 0. That is correct rather than broken. The box (22px) and the mask machinery (content, position, the currentColor fill) are both selected as .app .tabbar a .ic, so they need a tab bar link in the ancestor chain; only the mask image is on .app .ic-home, and an image with nothing to paint on paints nothing. Icons and marks hit the same wall and answered it the same way, so this page answers it twice: once with the shapes, and once with the real markup.

The four shapes, drawn as inline SVG at 22px

Not the component: the same path data as the four masks, drawn in currentColor at the size the product uses. What you see is the shape the mask cuts. Painting a solid square instead would have said nothing.

.ic-home .ic-trends .ic-alerts .ic-you

The component itself, live, with the mask actually cutting

Four real .ic boxes, cut by the four real masks, drawn by destination-icon.css through the same entry point a product screen loads. They take the muted ink of the text around them, because the whole colour story of this component is currentColor and it names no token.

This block used to show a bare <nav class="tabbar">, and it rendered as four blue underlined links. The reason was in the CSS, not on the page: the base rules were chained to .app .tabbar a .ic while the four mask modifiers needed only .app, so an atom could not render without the markup of an organism that had not been built at the time. The page imported that markup, the tab bar's own CSS did not exist to style it, and a paragraph here argued the result was proof rather than a defect. It was a defect. The selector is now .app .ic, verified against all 72 occurrences in the corpus so that zero pixels move, and the component stands on its own because an atom should.

The live instance in its real host belongs to the Tab bar organism, and this page links to it rather than rebuilding the scene: an anatomy that exists only inside its own scope is shown on the scene that holds it, never on a canvas faked here.

The lesson, and it cost a screen once

Quoted from kit.css, unchanged: "The mask sits on a pseudo-element, not on .ic itself. A mask clips its own children, and .ic hosts the unread dot, so masking the element erased the one thing GC2 has to be able to show." GC2 is the global tab bar. A mask establishes a clip on the element it is applied to, so the dot, which overhangs the square by 3 and 4 pixels, was cut away entirely. The screen still looked right, because a tab bar with no unread alerts is the normal case: the defect appeared only on the one state the component exists to be able to show. Moving the mask down one level to ::before leaves the element itself unmasked, and the dot survives.

Variants and sizes

One axis, four values, and the axis is which destination. There is no tone axis, no size axis and no emphasis axis: everything a person would expect those to do is done by inheritance from the link, which is what makes this component four declarations long instead of sixteen.

Destination

One icon per destination in the tab bar, and the tab bar is the only place they appear. An icon that is not a destination is not this component

The mark Class What else it carries
Home, the calm view .ic-home a roof over a doorway. Nothing else
Trends, the same money over time .ic-trends an axis corner with the product's own curve rising off it. Framed until 2026-08-21, when the founder chose the open form off four drawn candidates and the mark went 23.82 to 14.71 per cent of ink
Alerts .ic-alerts a bell with a clapper, and the only one that hosts .dot. DESIGN.md: "A quiet dot may sit on Alerts; there is never a count"
You, settings and account .ic-you a head and shoulders. Nothing else
A fifth destination forbidden - The prohibition worked exactly as written, and then it was spent. It said: "the tab bar is four destinations because four is what a thumb reaches and what a person can hold. A fifth is not an icon problem, it is a navigation model changing, and that is a decision for ia/docs/sitemap.md and not for this file." On 2026-08-18 the founder asked twice why Trends was not a destination, sitemap.md changed first and this file second - which is the order the rule demanded. It went to five that day and back to four on 2026-08-21, and the rule held in both directions: the sitemap changed first, this file second. Save was retired because its destination was Home wearing a hat - 2099px tall at 390 with 331 of them its own, 84 per cent of its scroll a repeat of the screen it left - and the cancel nudge it carried came back onto Home as a conditional block. Measured at both counts: at a 320px viewport an item is 64px wide with no wrap and no overflow, and on the desktop rail an item is 219px whatever the count. The rule stands for a fifth

There is no size axis, and the desktop is the proof. Past a 760px container the tab bar becomes a 220px left rail and lays the same square beside its label instead of above it. The square stays 22px. Nothing about this component changes with the viewport, which is why it carries no responsive rule at all.

There is no colour axis either, and that is the same fact stated twice. The mask is filled with currentColor and the encoded SVG's own stroke='%23000' is ignored, because a mask reads alpha and not hue. The current tab turns petrol because its link turns petrol. Give this component a colour of its own and that stops being true, silently, in exactly one state.

When to use it

A destination icon marks a place inside the product, and it appears in exactly one object: the global tab bar, on 29 of the 57 screens. Its job is recognition rather than explanation, which is why it always has its label under it and never replaces one: DESIGN.md describes the bar as "four destinations with an icon over an 11px label", and a bar of unlabelled glyphs is a small memory test given to a person who came here to stop thinking about money.

Authored, not extracted, and that is unusual enough to record. The grey wireframes draw .ic as an empty 18px bordered box on purpose, because greyscale cannot express a mark. This set could not be extracted from them and was drawn at stage 07; it is one of the five authored things listed in docs/inventory.md, alongside the filled button and the invalid field. The 112 places in the grey are 112 empty boxes waiting for it.

The rule, and the anti-rule

Use a destination icon
a place in the product, in the tab bar, with its label under it

Four marks for four destinations, each one a mask in currentColor, each one over its own word. The mark carries no colour, no fill and no border of its own, so it costs the One Voice Rule nothing.

Use a logo instead

A merchant is not a destination, and it takes the logo, .logo: a real mark, in full brand colour, inside a fixed square with a fill behind it. The tell is ownership. A destination mark belongs to Tendd, so it inherits the one voice; a merchant mark belongs to somebody else, so it is allowed to be saturated and is contained instead. Masking a merchant's logo to currentColor would turn the person's own Netflix into interface furniture.

Let the dot say there is something new
a 7px dot, overhanging the bell, and never a number

One dot, no count. A number on a bell is a debt a person is being asked to clear, and this product does not hand out homework. The dot is why the mask sits on the pseudo-element, so the two decisions are really one.

Use a wash block instead
Netflix went up by $2.50 on Jul 28.

When there is something to say, say it. An icon on a banner is forbidden by DESIGN.md outright ("Don't put an icon on a banner. The sentence carries it"), and the object that carries the sentence is the wash block, .wash.attention. This component never illustrates a message, never sits inside a button and never stands next to a heading: it marks a place, and that is its whole vocabulary.

States

None, and the reason is the most interesting thing about this component. The icon is not the control: the tab bar's anchor is, and the anchor owns hover, focus and the current destination. What looks like a state here, the mark going petrol on the tab a person is standing in, is inheritance: the link takes --text-action and the mask fills with currentColor. Declaring a state on the icon would either duplicate the link's rule or quietly disagree with it, and the second is the kind of bug that shows up in one theme only. destination-icon.css therefore declares no :hover, no :focus-visible and no [disabled].

The technical half

ReadsWhich tokenGrowing from
the mark itselfcurrentColor, no tokenthe link it stands in. This is the only component in the system that reads no colour token at all, and it is the reason the current tab needs no second rule
the unread dot--text-body--slate. An open hole, named rather than papered over: this is an ink role painting a fill, which the architecture forbids even at an identical value, because ink and fill answer to different thresholds. The system has no fill role on --slate. It would have two consumers, not one, since .newdot on the alert item is byte-identical geometry under another owner
the box and the dotno primitive: 22px and 7px are literalsthe geometry scale is still a proposal awaiting the founder, so both stay as they are written today

Lives in design/system/components/destination-icon.css. The four path definitions are also catalogued on Icons and marks, together with the fourteen merchant files. Stands on 30 grey pages in 116 places, and on 29 coloured ones in 116 places, which is every screen the shell frames. Recounted twice in two days: it said 28 and 112 on 2026-08-19, went to 30 and 150 when Trends made the set five, and is 29 and 116 since Save was retired on 2026-08-21. A sample: Home, Home, empty, History and trends, Settings, Subscription Detail, Alerts and its three states.

<nav class="tabbar" aria-label="Global navigation"> <a class="cur" href="home.html" aria-current="page"><span class="ic ic-home"></span>Home</a> <a href="alerts.html"><span class="ic ic-alerts"><span class="dot" role="img" aria-label="new alerts"></span></span>Alerts</a> <a href="settings.html"><span class="ic ic-you"></span>You</a> </nav> The span is empty on purpose. The screen carries the class and nothing else: the shape, the fill and the box all belong to the kit.