Level 1. A row a person taps that GOES somewhere and draws NOTHING until it is pointed at: transparent, no edge, no corner, as wide as whatever holds it. 995 placements on 105 painted screens, three faces, 0 bare. Measured 2026-08-08 in a browser, at 390 and 1280, in both pointer branches.
The level page is the shelf and this page is the depth, and the two answer different questions. Comparing this atom against the other nine is work the shelf does, so it stays on the atoms page together with the level and the reason for it. Taking one component apart needs room the shelf does not have: the shelf gives every component one specimen, and one specimen cannot show three faces, two elements and a state that is reached from an ancestor.
So nothing here is repeated from the shelf, and the shelf keeps what a page of its own would only copy. A fact written twice drifts.
Six declarations, and every one of them is an ABSENCE: no ground, no border, no corner, no underline. What is left is a full-width block with a pointer. The whole control is what happens when somebody points at it, which is the next section but one.
display:block is the fourth value this atom had been WEARING
without writing down, and it is the reason the file says so out loud. width:100%
is why this class exists as a row, and width does nothing to an inline box. The
<button> element supplied inline-block for free, so the
declaration worked for exactly as long as every one of these was a button, and stopped the moment
the account dropdown's 365 became links. Measured on the day: 194x33 collapsed to 66x30,
the row shrinking to its own text.
A value the element supplies is a value the component has not chosen. Two of the three faces here declared a display of their own, so the gap stayed invisible until a face that declared none crossed over.
| element | placements | what it is |
|---|---|---|
<a> | 899 | it goes to a screen, and the href is the destination |
<button> | 96 | it opens a dialog: data-open="signin" on 32 logged-out screens, three slots each |
The same atom, and the drawing does not know the difference. That is
the correct answer for a bar where the Sign in slot sits beside three navigation slots and has to
look like them, and it is also what made the missing display above a real defect
rather than a tidy-up: the atom cannot rely on the tag when it stands in both.
slot, 420 placements, the only navigation a phone has
A mark over a label, 10px, centred, muted. The first one is the current tab.
In the product aria-current sits on the <li> and the state
is reached from an ancestor, so the specimen is the bar's own markup and not an imitation of it:
<nav class="bottom-nav"><ul><li>, exactly as the 105 screens ship
it.
It was three loose anchors in a bare
<div> until 2026-08-09, and that is why this cell was broken.
.nav-item is display:block;width:100%, and its own file says
width:100% is the whole reason this class exists as a row. The width it fills is the
<li>'s, and .bottom-nav li is flex:1 inside a
ul that is display:flex. With no list around them each anchor filled
the whole cell instead: 477px each, three of them wrapping onto three lines, and the
current one squeezed to 41px because its wrapper <div> was a flex item
that shrank to its text. A stand class standing in for a product container does not show the
atom, it shows the atom with its arrangement removed.
One thing differs from the product and it is declared: the bar is
display:none from 640px up and position:sticky, so the cell pins it
visible and static through .tk-show-nav. That is the same bargain
.tk-dlg makes for a dialog and the dock makes on vitrine.html. The
ABSENCE is the bar's fact and it is shown where the bar is the subject, on
bottomnav; here the subject is the slot, and a slot nobody on a
desktop can see is not a specimen.
row, 365 placements, a line of a menu that drops out of the header
Full width, left aligned, 11px, the strong ink because a menu is read rather than glanced at.
row-stack, 210 placements, a notification
It is the row with one declaration changed, and the declaration is the
display. A menu line is one line; a notification is a title and a detail under it. The title and
the detail themselves stay in components/header.css, because they are the row's
CONTENT and not the control's face, the same way a card keeps its own title.
Which is why this is the one specimen on the page that stands inside its
container, and it had to. Lifted out of .notif-drop the same markup renders 33
tall instead of 49: the <strong> and the <span> take their
display:block from the dropdown's file, so the two parts sit on one line and the
stack is not a stack. The boundary this page describes is visible in the specimen rather than
only stated in it, and the honest way to show a control whose content belongs to somebody
else is to borrow the somebody else.
It joined this file on 2026-08-06 and two values had held it back, both of
which were measured to draw nothing. Its font-size was the browser's 16 where the row is 11,
and nothing inside it reads a font size: it holds a <strong> and a
<span>, both block, both with sizes of their own, and no bare text node
between them. So it took the row's 11 and no glyph moved.
The slot's ink is the current-tab signal and nothing else. So the ground answers the pointer here and the colour does not, and that is a decision with a phone behind it: if pointing at a slot pulled its label toward brass, the one thing the bar says at a glance would be said by two different things, and a hover can stick after a tap on a touch screen, so the wrong slot would go on claiming to be current until something else was touched.
[aria-current="page"] is written with the attribute alone rather
than with the bar's class. Being the current item is the atom's state wherever the atom
stands, and naming .bottom-nav here would be this file holding a region's
name.
The order of four rules is load bearing. Each hover is written at the
face's own two-class weight so it can reach the slot a person is standing on: at
.nav-slot:hover it would be (0,2,0) and would die under the current-page rule at
(0,3,0), on exactly the tab that gets tapped most. The press is last and at the same weight
as the hovers, so a tie is broken by source order and a held control shows the press rather than
the hover.
| face | worn | hover | press |
|---|---|---|---|
.nav-slot | 420 | --tint-hover, a quiet neutral wash | --bg-pressed, one rule for both, and it is the system's one pressed ground |
.nav-row | 365 | --tint-brass-09, the wash the rest of the header uses |
Neither is a majority and both have an argument, so both are kept and
the question is written down rather than settled by whoever edited last. The bar is the only
navigation a phone has and its brass is spoken for by the current tab; the menu is a header
surface and the header is brass. docs/backlog.md 45.
Read on 106 screens at 390 and at 1280, and again with touch emulation on and
matchMedia('(pointer:coarse)') asserted true before every read.
| face | worn | 390 | 1280 | with a finger |
|---|---|---|---|---|
.nav-slot | 420 | 94x55 | 0x0, the bar is a phone control | 94x55, unchanged |
.nav-row | 365 | 194x33 | 194x33 | 194x33, unchanged |
.nav-row-stack | 210 | 258x49 | 258x49 | 258x49, unchanged |
365 rows stand 33 tall with a finger on them, and nothing in the system
lifts them. The one touch floor in components/base.css names fourteen families
and .nav-item is not one of them, which was not a decision: the floor was written
from the six per-file lists that existed, and no file had ever written a floor for this atom.
33 clears WCAG 2.5.8 AA at 24x24 and fails 2.5.5 AAA and this product's own standard at
44.
It is not a one-line fix, which is why it is a backlog row rather than an edit
made here. Five rows at 44 make the account dropdown 55px taller, and that is a layout decision
about a panel rather than a floor. docs/backlog.md 54.
The slot at 55 and the stack at 49 are both above the floor already, and neither got there from a rule: the slot is a mark over a label with 8px of padding, and the stack is two lines. A box that clears a floor by accident clears it until somebody edits the padding, which is the argument for the floor naming the family rather than the exception.
The sub-category row, .subcat button, 234 placements.
It measures as a hairline PILL at 380 and a 10px full-width row above 860: an edge and a corner
at both widths, which is neither this atom's rest face nor one modifier away from it. It was
moved out of chip on the strength of the desktop rule alone, which is the same
half-measurement that put the social mark in the wrong atom. docs/backlog.md 46
holds it, with both widths written down.
The bar, the dropdown and the list are not here either.
components/bottomnav.css keeps the bar, its sticky position, the groove along its
top edge, the dividing rules between slots and the centring on the <li>;
components/header.css keeps the panel, its shadow, its corner and where it opens.
Neither says what the control inside it looks like any more, and that sentence is the test
a migration passes or fails.
A face is a modifier, and a region is a place. What differs between these three is a direction, a size, an ink and an alignment, and all four are the control. Where the control sits, what holds it and how that thing is lifted off the page are the region's, and the region is allowed to keep exactly those.
The state comes from above. Being current is not something this control can know about itself, so the selector reads an ancestor and names no region while doing it.
Never let the element supply a value. A display that arrives
from <button> is a value the component did not choose and cannot keep, and it
left 365 rows collapsed to their own text the day they became links.
Never move the ink to say two things. The slot's colour is the current tab. A hover that also moves it makes the bar say the same thing twice and, on a touch screen where a hover sticks, say it wrongly.
Never name the container in the control's file. The moment
this file writes .bottom-nav it stops being an atom and starts being a second copy
of the bar.
Never file a row here on one width. Two rows in this product look like this atom at 900 and do not at 380, and both were nearly filed here on the desktop reading alone.
The level and its reason: the atoms page.
The stylesheet and the argument for every value: components/navitem.css. The
regions that hold it: components/bottomnav.css and
components/header.css. The open questions: docs/backlog.md 45, 46 and
54.