Amount
Every figure of money in the product that is not THE monthly total: the price in a row, the price on a detail screen, a past charge in a list, a plan's price on the upgrade screen. 69 of them across the grey product, which makes it the most repeated piece of text there is.
Anatomy
One zone and one content slot, which is what makes it an atom. Everything below is drawn by design/system/components/amount.css through the same entry point a product screen loads, so this page cannot drift from the screens. The host classes in the markup below (.row, .hero, .charges, .plan-opt) carry no styling on this page and are not borrowed.
The size is a DECLARED AXIS since 2026-08-14, and it used to hang on the hosts. Four rules set this atom's font-size from outside it (.row and .charges li at --type-body, .plan-opt and .hero at --type-figure), which is the exact shape CLAUDE.md forbids by name and which docs/backlog.md carried as one of four atoms sized by their hosts. The rollout of stage 12 needed a fifth host for it, cancel-win's freed figure, and adding one more occurrence of a forbidden rule is not a way to build a screen. So the base carries --type-body and .amt.figure carries --type-figure with the weight, tracking and display that travel with a figure. Zero pixels: all 66 amounts in the coloured product measured before and after on size, weight, leading, tracking, display and box, identical. What stays with the hosts is not size: flex: none in a row, weight 400 on a past charge because history is a texture, and the two leadings a container asks for.
.amtthe atom: tabular figures, weight 600, and a price that never wraps. It carries no size of its ownfont-variant-numerictabular-nums. A column of prices that does not line up is a money product asking a person to compare by eye what the type could have compared for themwhite-space: nowrapan amount broken across two lines stops reading as one number, and inside a row it takes the merchant name's space with it.hero .amtthe size, set by the container. Four of them, and this is the largest.perthe "a year" inside a plan price is a slot of the plan option, not of this atom. The amount holds one figure and nothing else
Variants and sizes
One axis and no second: size, set by the container. There is no emphasis axis and there is no tone axis, and both absences are decisions. An amount is never coloured to say a price went up (that is the wash block's amber, on the sentence, not on the number) and never coloured to say a payment failed. The number stays the same number wherever it stands; only the room it is standing in changes.
| Size Set by the CONTAINER, never by importance. Every step below has a reason that is about the room rather than about the money, and the weight moves with it |
Values | Where it stands |
|---|---|---|
13.5px .charges li .amt |
13.5px / 400 | A past charge, on 5 coloured detail pages. The one place the weight drops to 400: a column of eleven identical numbers is a texture and not eleven things to read |
| ||
14px .row .amt |
14px / 600 | The price in a subscription row. 14 of them on Home alone, and it sits beside a 15px merchant name that must stay the thing a person scans for |
| $17.99 | ||
30px .plan-opt .amt |
30px / 700 -0.02em |
A plan's price on Upgrade, three of them side by side. The number IS the card, because the decision on that screen is a comparison |
| $69 | ||
32px .hero .amt |
32px / 700 -0.02em |
The price on a subscription's own detail screen, where it is the subject of the page. 6 coloured pages, the largest this atom goes |
| $11.99 | ||
| 46px / 700 -0.02em .display |
1 coloured page | The plan's price on the landing, added 2026-08-15 on the founder's decision ("виделить цену большой такой?"). It does not break the One Number Rule, it states it properly: the rule says exactly one object on a screen is set in Display and it is the number the person came for, which in the app is the monthly total and on the landing, where there is no total, is the price. The count per screen is still one. It also closed a desync: when the size axis was declared, the modifier has to be worn, and upgrade.html wore it while the landing's three cards did not - so the landing's prices had been rendering at 14px, the size of the sentence under them, measured in the browser |
| 22px | removed | A dead declaration, deleted here with its proof. .plan-opt .amt was declared twice in kit.css, 22px at line 307 and 30px at line 680, at the same specificity and both outside any container query, so the later one won and the 22px rendered on no screen at any width. Its -0.015em tracking was dead for the same reason. One of the three outright deletions recorded in docs/inventory.md, and the only thing in this component's file that is not a straight carry |
The 30px and the 32px are the pair worth reading twice. They are two pixels apart and they are not drift: one is a price among three being compared, the other is a price with a whole screen to itself. The census measured every amount in the product at both viewports and found no third value between them, which is what makes them a size axis rather than two accidents.
When to use it
An amount is what a person is checking. On Home there are fourteen of them in one column, and the whole design of that screen is built so a person can run down the list without reading it: same weight, same alignment, tabular figures, and the merchant name doing the identifying. On a detail screen there is one, and it is the subject.
It is always --text-primary, and the calm of the product depends on that not changing. A price that went up is announced by an amber wash block with a sentence in it, and the number in the row underneath stays ink. A payment that failed is a clay wash, and the number stays ink. Colouring the figure itself would put the product's alarm in the one place a person looks fourteen times on one screen, and the audience for this product closes any app that shows them red.
Money is written the way voice/docs/microcopy.md writes it: "$17.99", "$69", and "Typically $17.99 a month" where the figure is an estimate rather than a fact. The cycle ("a month", "a year") is never inside the amount: on a row it is the .when line, on a detail screen the .cycle, on a plan card the .per. This atom holds one figure.
The rule, and the anti-rule
The price on a subscription's detail screen: one number, 32px, tracked in, tabular. It never breaks and it never carries its own cycle, so the same markup works at 360px and on a two column dashboard without a single width rule.
$192.90
a month, for what you have signed up for
The number the whole screen exists for is the big total: 46px, its own component, one per screen ever. The two are not one atom at different sizes. A total is a figure that owns a screen; an amount is a figure among others. When an amount starts wanting Display size, the screen is answering two questions and should be two screens.
The same ink for a price that rose, a price that fell and a payment that failed. What changed is said in words, above the row, and the figure stays the thing a person can scan without bracing for it.
Netflix went up by $2.50 on Jul 28. Your next charge is $17.99 instead of $15.49.
The news about a price belongs to the wash block: an amber fill with the sentence inside it, sitting above the row it is about. Tone lives on the container and never on the number, which is what lets one row component render an ordinary charge, a risen price and a failed payment with no variants at all.
States
None, and it was checked rather than assumed. An amount is a figure and never a target. On every screen that carries one it is either inside a link the ROW owns (the whole row is one anchor with one accessible name, which is what stops a list of subscriptions from being a list of four targets per line) or inside a card that has its own button. Hovering the number does nothing, focusing it is impossible, and a hover written here would document something the product cannot do.
The loading form is not a state of this component either. On the four loading screens the markup is <span class="skel amt-skel">, a skeleton bar sized to an amount, and it belongs to the skeleton bar.
The technical half
| Reads | Which token | Growing from |
|---|---|---|
| the figure | --text-primary | --ink, and --ink-dark in the dark theme. 17.4:1 on the light surface, 15.0:1 on the dark one |
| the four sizes and the tracking | literals | 13.5, 14, 30, 32px. The type scale is still a proposal awaiting the founder, so they stay as they are |
| tabular figures | declared twice, on purpose | base.css sets it for :where(table, .amt, .total) at specificity 0, as the floor that catches a figure written without this class; the component says the same thing at its own specificity so a host cannot un-align it |
Lives in design/system/components/amount.css. Stands on 13 grey pages and 14 coloured ones, 105 uses on the coloured set, 96 on the grey. Coloured screens carrying it: Home and two of its states, Subscription Detail and all five of its, Upgrade, Cancel Win, History and Trends and the landing. Recounted 2026-08-19 by design/kit/screens/counts.cjs, when the category bars became this atom's fifth host and took it onto a thirteenth screen.
<span class="amt">$17.99</span> inside a row 14px
<span class="amt">$11.99</span> inside a hero 32px
<span class="amt">$11.99</span> inside a charge 13.5px
<span class="amt">$69<span class="per">a year</span></span> inside a plan card 30px