Numbered steps

The ordered instructions on the cancel guide. It is the only component whose content is a procedure a person follows somewhere else, on the merchant's own site, with this screen open beside it. Its numerals are generated by a CSS counter, so they cannot drift from the order.

Molecule3 grey pages0 coloured1 form, no axesno states

Anatomy

This component has never been drawn in colour. docs/census.md names it as one of nine with no occurrence in the coloured sample at all, so its form comes from the grey and nothing below is invented: every value is carried from kit.css and put through the founder's mapping. That is stated first because a component with no colour precedent is exactly where a builder starts guessing.

  1. Go to netflix.com and sign in.
  2. Open Account, then Membership and Billing.
  3. Choose Cancel Membership.
  4. Netflix will offer to pause instead. Keep choosing Cancel, and watch for the confirmation email.

Variants and sizes

One form and no axes. The inventory records none and the stylesheet declares none: one marker, one size, one ink pair, and all three grey pages render the same thing. There is no matrix to draw, and drawing an empty one would suggest variants are missing rather than unnecessary.

What the three pages do vary is the CONTENT, and putting them side by side is the argument for the component: the same four numbered lines carry a tailored procedure, a generic one, and a list of things to try when the procedure was refused. Nothing about the form moves.

ScreenWhat the steps areWhat it means for the form
Cancel guideGo to netflix.com and sign in. / Open Account, then Membership and Billing. / Choose Cancel Membership. / Netflix will offer to pause instead...A named merchant and a real path. The fourth step is longer than the other three, which is why the marker is top aligned rather than centred on the line
Cancel guide, no guideOpen the service's website and sign in. / Go to Account or Subscription settings. / Look for Cancel or Manage plan. / Confirm, and watch for a confirmation email.The general path, when we have nothing tailored. Same component, and the screen says so in a strip above rather than by looking different
Cancel guide, blockedSkip the "special offers" screen and keep choosing Cancel, not Pause. / Try cancelling from a web browser instead of the app. / ...Not a procedure at all but a list of things to try, and it still numbers them, because a person who has already been refused once needs an order to work through rather than a set of options

The mapping moves this component, and it is the only one in this group it visibly moves. The step's left padding was 36px, which is not on the 8px grid, and it goes to --space-40, nearest step. The marker's box stays 26px wide at left zero, so the gap between the box and the text opens from 10px to 14px and every line of every step shifts 4px right. That is the second of the three legal sources of a visual change on this stage, it is recorded centrally in the scales note, and it is written here rather than absorbed silently. Nothing else about the block moves.

The 26px box has no token, and it is reported rather than invented. The system's size primitives are --tap at 44px and --row at 56px, and this is neither. It is also not a spacing: a width is not a margin, a padding or a gap, which is the whole scope of the 8px grid. Rounding it down to --space-24 to make it look tidy would shrink the marker by 2px, which is a pixel move with no named decision behind it, and this stage promises the product does not move except from three named sources. It is carried at its measured value with a comment, and a marker size primitive is on the list for whoever owns the geometry page.

When to use it

This is the only place in the product where a person is doing something on another screen while reading ours. Everything else here is a thing to look at; this is a thing to work through, with a merchant's own cancellation flow open in another tab and a retention offer trying to talk them out of it. That is the whole design brief for the component, and it explains every decision in it.

It is full ink, not muted, because the second tier is the wrong place for an instruction being followed. The marker is muted inside a hairline box, quieter than the line it marks, because the number is an index and the sentence is the content: a marker louder than the thing it marks is the same defect as a badge shouting on a calm row. And the steps are numbered at all because losing your place is the failure mode. A bulleted list of four things is a set; a numbered list of four things is a position you can come back to.

The steps are free and always will be, which is the other reason this component matters more than its three pages suggest. D3 puts the paywall at depth and names the cancel moment as a place it must never sit, so the Pro gate on that screen offers screenshots and a direct link and sits under a procedure that already works. The component that carries the free half has to be the calm one.

The rule, and the anti-rule

Let the counter number them
  1. Open the service's website and sign in.
  2. Go to Account or Subscription settings.
  3. Look for Cancel or Manage plan.
  4. Confirm, and watch for a confirmation email.

Four li elements and no digit anywhere in the markup. Insert a step in the middle and the numbers are still right, because they are produced by the order rather than described alongside it.

Never type the number in
1  Connect or add  ·  2  See it all, calmly  ·  3  Cancel and save

The landing page writes exactly this: <span class="sord">1</span>, three times, in wireframes/index.html. It renders correctly today and it is wrong on the day somebody inserts a step, silently, with nothing in the code able to say so.

The pair closed on 2026-08-15, and not by the landing giving in. Until that day this file also drew the landing's marker, held identical to the one above (26px box, hairline, meta, muted) on the ground that two step markers differing by four pixels is drift. The founder's rebuild of that section made its ordinal a display element on a rail (--type-step, 800, muted), and this one stayed a small quiet box in a gutter beside an instruction a person is following on somebody else's site. Same word, two jobs, so two components: .snum is deleted here and landing steps owns .sord. What is not resolved is the paragraph above it - a hand-written ordinal can be set at 40px and put on a rail, a generated one cannot without the counter becoming the layout, and three steps that have not moved since the sitemap is what buys that risk.

An order to work through
  1. Skip the "special offers" screen and keep choosing Cancel, not Pause.
  2. Try cancelling from a web browser instead of the app.
  3. If you are billed through Apple or Google, cancel in your device subscriptions instead.

Even where the items are alternatives rather than a sequence, they are numbered. Somebody on this screen has already been refused once. Four things to try in a stated order is a plan; four things to try in no order is a decision they now have to make while frustrated.

Use a promise list instead
  • What you can undoDisconnect at any time, and your bank data goes with it.

Three claims that are all true at once, in no order, are a promise list: marked by a rule down the side rather than by a numeral, because numbering them would say the first matters most or comes first, and neither is true. The test is whether reordering the items changes the meaning. Here it does; there it does not.

States

None, and it was checked rather than assumed. A step is an instruction and never a target: a sweep of every .steps list on all three grey pages returns zero anchors inside one, even where the text names a destination ("Go to netflix.com and sign in"). The way off the screen is the filled button in the action row below the list, "Open netflix.com and cancel", so the procedure can be read to the end without a target inside it to leave by. There is no completed state and no current step either: the product does not know where a person has got to on somebody else's website, and a checkbox here would claim it does.

One backlog line this component cannot fix on its own. list-style: none on an ol removes the list role in Safari with VoiceOver, so the ordering the ol element carries is announced on some screen reader and browser pairs and not others, and where it is not, the generated numeral is the only order left. Every list in this system writes the same line, so it is not this component's to decide alone; it is written down here because this is the one list where losing the order loses the meaning.

The technical half

ReadsWhich tokenGrowing from
the instruction--text-primary--ink. 17.4:1 on the light surface, 15.0:1 on the dark one. Full ink, because an instruction being followed does not belong in the second tier
the numeral--text-muted--muted. 5.8:1 light, 6.4:1 dark. Quieter than the line it marks, on purpose
the marker's box--line-container--hairline. Decorative: the box is not a control and nothing has to be found by touch
the instruction, the numeral--type-body, --type-meta14px and 12px, both unmoved by the founder's review
the gutter and the gaps--space-40, --space-16, --space-4, --space-24the 8px grid. 36 to 40 is the one fold that shows on screen; 3 to 4 and 22 to 24 do not
the marker's sizeliteral, and reported26 by 26. Not --tap, not --row, and not a spacing. The system has no primitive for a marker box, and inventing one here would either move a pixel or sit unread
the marker's borderliteral1px. A border width, explicitly outside both scales
the cornernoneno radius at all, by the decision stated on the rule in kit.css: three radii, and a circle is not one of them

Lives in design/system/components/numbered-steps.css. Stands on 3 grey pages: cancel-guide, cancel-guide-no-guide and cancel-guide-blocked. All three are coloured now, since the rollout: cancel guide, no guide, blocked. Until 2026-08-17 this page said there was no coloured screen to link and called the absence the finding, which was true of the corpus it was written on and is worth keeping in one line: the form arrived already decided rather than being invented three times, and what the colour then found was not a form problem but a measure, above.

<ol class="steps"> <li>Go to netflix.com and sign in.</li> <li>Open Account, then Membership and Billing.</li> <li>Choose Cancel Membership.</li> <li>Netflix will offer to pause instead. Keep choosing Cancel, and watch for the confirmation email.</li> </ol>

The step took a reading measure on 2026-08-17, and it is the one computed width in the system. The stage 12 width sweep read a step at 81.2 characters to a line on the coloured cancel guide at a 750 window, 718px: the worst line in the product, on the one component whose own brief says it is read a line at a time while a person works in another tab. The cap is calc(var(--container-text) + var(--space-40)) and not the token alone, because box-sizing is border-box and the numeral's 40px gutter would otherwise eat eight characters out of the measure. The words land at 52ch; the box is 499px. Nothing moves at 360, where there is no room to move.