Bottom nav

Level 2. Four slots in a sticky bar, and the one control in the product that is only ever touched: it is display:none from 640px up. 105 bars and 73 balances on 105 painted screens. Measured 2026-08-08 in a browser, at 390 and 1280.

105 bars 420 slots 73 balances 0x0 above 640

The bar, with its balance slot

The four slots the product ships, including the balance figure the other placements do not carry.

The two logged-out slots carry the screen's own href, re-rooted to ../ui-visual/: the target is the product's and the prefix is a fact about which folder this document sits in.

Vault, dark

not rendered from 640px up, exactly as on a screen: this bar is mobile only

Daylight, light

not rendered from 640px up, exactly as on a screen: this bar is mobile only

What this page is for

The level and its reason stay on the molecules page. The SLOT inside it is an atom with a page of its own, nav item, and none of what that page says is repeated here. What is left for this one is the bar: where it sits, what it keeps, and the two states it did not have.

The bar

Vault, darkDaylight, light

not rendered from 640px up, exactly as on a screen: this bar is mobile only

not rendered from 640px up, exactly as on a screen: this bar is mobile only

In the product the bar is sticky at the foot of the window; here it stands in the flow, because a stand cannot show a thing that is pinned to a viewport it does not own. Measured on a screen: 379x56 at 390, and 0x0 from 640px up, which is where bottomnav.css switches it off. That is why the cell above holds a sentence rather than a bar on a desktop, and this page printed that number under an empty plate until 2026-08-09: the number was measured, written down, and never carried to the specimen standing beside it.

The fourth slot is a figure rather than a mark: 73 of the 105 screens are logged in and carry a balance in the slot. It is the one part of a slot that stays where it is, and the reason is measurable: no rule anywhere changes it when the slot is hovered or current, so it is a figure the region puts inside a control rather than a part of the control's face. The category chip's mark and count went the other way, into chip, on exactly that test.

The press matters and the hover is the one nobody will see

This bar had no state on either axis, on all 104 screens, and it is the only navigation a phone has. A tap got no reply at all. Both states arrived together, and the order of their importance is inverted from everywhere else in the product: the press is the one that will be used, and the hover exists so a desktop debugging session is not lying to you.

The ground answers and the colour does not. In this bar colour is the current-tab signal and nothing else. If pointing at a tab pulled its label toward brass, the one thing the bar says at a glance would be said by two different things, and on a phone a hover can stick after a tap, so the wrong tab would keep claiming to be current.

roleon graphiteon chalk
--tint-hoverwhite at 6 per cent over #1c1f24#211f19 at 10 per cent, which DARKENS
--bg-pressed#191b1f#f3f1eb over #f8f6f0

On chalk both darken and the wash is the bigger step of the two, and that inverts nothing under a finger: a tap fires both states at once and the press, written later at equal specificity, is the one that shows. It would only read backwards as a hover LEFT behind after the finger lifts, which is the platform's sticky-hover behaviour and every hover's problem rather than this one's.

Both rules name the <li> to reach (0,2,2), which is what the current-page rule costs. Written at the control's own (0,2,1) they would die on the tab you are standing on, and that is the tab a person taps most.

No focus rule, and it was measured rather than assumed

A fixed bar is where a ring gets cut, so the question was put to a browser rather than to an opinion. Chromium at 360x720 with the bar stuck: the ring computes to 2px at a 2px offset, no ancestor of the control clips anything the whole way up to <body>, and the bar's own stacking paints the ring OVER the feed rather than under it, so the top stroke shows 3px above the bar.

Only the bottom stroke falls past the viewport edge, 4px of it, and a ring with three sides on screen is a ring you can see. An inset offset would buy that fourth stroke by moving the other three onto the control, which is a worse trade. So this file adds nothing, and the absence is a reading rather than an oversight.

The wrapper that left, and why it was a defect rather than a tidy-up

Until 2026-08-07 each slot was a <button> inside an <a>, and this file carried three declarations to undo the anchor's own look so the button could show through. Interactive content is not allowed as a descendant of an anchor: both elements were in the tab order, and a screen reader announced a link containing a button.

The slot is one element now, an <a> where it navigates and a <button> where it opens the sign-in dialog, and all three of those declarations belong to the atom. It was also the last rule in this file that drew a control, which is what let the slot become an atom with one file behind it.

What it does with width

Its own width query: 640 DESK. One declaration, and it is the divide the whole ladder is named around: display:none from DESK up. Measured with a Tab walk rather than with a stylesheet, the bar holds 4 tab stops below the rung and 0 above, and its Primary (mobile) landmark leaves the accessibility tree at the same pixel. The carrier goes from the paint, the tab order and the tree together, which is the property that makes the swap safe.

The rule

The bar owns where, the slot owns what. This file keeps the sticky position, the groove along the top edge, the list, the dividing rules and the centring. It says nothing about what the control inside it looks like.

On a control that is only ever touched, the press is the state. Design the finger's answer first and let the mouse inherit it.

The anti-rule

Never wrap a button in a link. Two tab stops, one control, and a screen reader announcing a link that contains a button.

Never write a state at the control's own weight when an ancestor rule outranks it. It dies on exactly the tab a person taps most.

Never assume a ring is clipped because the bar is fixed. Measured, three of its four strokes are on screen, and the fix would have cost the other three.

Where the rest of it is

The level and its reason: the molecules page. The stylesheet: components/bottomnav.css. The slot, in full: nav item. The test that kept the balance here and moved the chip's mark away: chip.