Patterns

The fourth rung, and the only one whose criterion is repetition rather than nesting. A pattern is a composition that stands on three screens or more, adds no styles of its own, carries no colour, and imports last. Six files, 56 declarations in 288 lines, 53 declarations between them, re-counted on 2026-08-08 after the action bar went from 13 declarations to 7. This page checks that contract against the files rather than restating it.

6 patterns 53 declarations 0 colour 0 generators

What a pattern is, and why it is not a level

Levels 1 to 3 answer what does this contain. A pattern answers where do these stand, and that is a different question with a different test. An organism is an organism the first time it holds a molecule. A composition is a pattern on the third screen and not before, because two screens sharing an arrangement is a coincidence and three is a decision.

Two screens is a candidate and it stays markup. That is the rule this rung exists to enforce, and it is the reason a pattern file is thin: the file holds only the part that repeated.

They import last, and that is what "assembled from" means in a cascade. A pattern has to be able to place what it holds, so the rule that places something is read after the rule that draws it. The faces and the tokens pin the head of index.css for the mirror reason.

The contract, checked

The first half is the count. Every class each pattern owns, matched in the markup of all 106 painted screens, elements as well as screens, against the number the file's own header claims.

PatternClassScreensElementsClaimed
action-bar.cta-bar333same
browse-shell.cat-layout777776+1
browse-shell.cat-main7777-
browse-shell.read-col551+4, over the threshold since 2026-08-18
card-grid.grid232323same
detail-shell.ed-layout111111same
detail-shell.ed-main1111-
list-head.feed-head717170+1
list-head.feed-controls444444same
position-list.pos-list131313same

Five of seven claims are exact and two are one screen light, because the files were written when the painted tree was 105 screens and it is 106. A number in a comment is true on the day it is typed, and nothing here re-checks it, which is the price of the rule that every measurement is an act rather than a machine. The price is one screen and it is worth paying; the alternative cost this repository seven days.

The second half is the one that matters, and it holds exactly. Every declaration in all six files, by property:

FileDeclPropsEvery property it declares
action-bar76display, flex, gap, margin-top, padding, width
browse-shell1912align-items, display, flex, flex-direction, gap, margin-block, margin-bottom, margin-inline, max-width, min-width
card-grid44align-items, display, gap, grid-template-columns
detail-shell87align-items, display, flex, flex-direction, gap, min-width
list-head128align-items, display, flex-wrap, gap, justify-content, margin, margin-bottom, padding-bottom
position-list33display, flex-direction, gap

53 declarations, and not one of them is a colour, a face, a border or a surface. No color, no background, no border, no fill, no box-shadow, no opacity, no font-family, no font-size, no font-weight. What is there is display, flex, flex-direction, grid-template-columns, gap, align-items, justify-content, flex-wrap, padding, margin, min-width, max-width, position, bottom, width and z-index. Sixteen properties, every one of them an arrangement. The rung is clean.

Two of the six say they are assembled from something they are not

Each file opens with an Assembled from line, and nothing reads it. Read from the screens instead, by taking every element inside each pattern's own box across the 106 and asking which file owns its class:

PatternFound inside, by owning fileClaimed, not found
action-barbutton-
browse-shellcatnav, card, state-block, chip, filters, skeleton, position, options, buttonfeed
card-gridcard, skeleton, options, yesno, iconbtn, position-
detail-shellcard, chart, market, tabs, betpanel, event-detail, comments, bets-table-
list-headfilters, toggle-
position-listposition, skeletonprofile

browse-shell says it is assembled from feed, and the containment runs the other way. On event-feed.html, <main class="feed"> opens at line 361 and <div class="cat-layout"> at line 469: the feed HOLDS the browse shell. Nothing renders wrong, and it is still worth correcting, because an "assembled from" line that names a parent is the level arithmetic's blind spot written down by hand.

position-list says profile, and that stopped being true on 2026-08-03. The record block in the stack is .pos-record with its .pos-figures and .pos-fig, and those moved from profile.css to position.css in the pass that fixed five misfiled classes. The block is still there; the file that owns it is not. profile.css owns seven classes today, .av, .edit, .gallery, .handle, .idrow, .name and .who, and none of them stands in a position list.

Both lines were true when they were typed. That is what a prose claim with no reader does, and it is the argument for a page like this one existing at all rather than for a check that runs on every edit. Backlog 46.

The slot that stood below the threshold is over it, and it was the tree that moved

.read-col is the reading column, declared in browse-shell.css, and it stood on ONE screen, ui-visual/terms.html, from the day it was written until 2026-08-18. The rule this rung enforces is that two screens is a candidate and it stays markup, so one screen was two short, and it was filed rather than tidied: backlog 46 said what would close it in as many words, a second and a third long document, not an edit.

Four arrived at once, about, privacy, cookies and responsible-betting, and the row closed without anybody touching the rule. It stands on FIVE screens in the paint and five grey twins, counted from the rendered DOM of all 61 kit pages, 115 painted documents and 114 grey ones on 2026-08-19, so the rung is cleared by three rather than missed by two. This is the shape a threshold is supposed to have: the register below is not a to-do list, it is a statement about the product, and the product is what moves it.

The reason it was written there was good and it was not the same question. The file says it: the container owns the distance, not the block. A margin on a block is a fact about that block, so the next block dropped into the stack arrives with no distance again and the defect returns one screen later. That argument is about WHERE the rule goes if it exists. The threshold is about WHETHER it exists yet, and the two were answered as one. Both answers are now the same answer, which is the only reason this section can be read as closed.

And the four new screens found what one screen had hidden. A slot with one placement is a slot nobody can disagree with. On 2026-08-19 the five documents were measured together and the column was carrying six widths and three left edges on one page: the column at 600px, the prose capped again at 409 inside it, .protect-page at 346, .related-more centred at 300, and every .feed-seo shrink-wrapped to 417 and offset 91px, because an auto inline margin cancels stretch on a flex item and the pair that centres the block on the feed was written for a block box. The column carries the measure once now, at --text-16, and every block in it fills it. Backlog 46 is closed twice over: by the tree, and by what the tree exposed.

The candidates, waiting for the third screen

A threshold with nothing standing below it is a threshold nobody can check. This is the register: what would be a pattern if one more screen carried it, counted from the screens rather than from the file list, 2026-08-10.

classdeclared inscreensoccurrencesshort by
.ptab-paneltabs.css2, my-profile and public-profile3 per screenone screen
.read-colpatterns/browse-shell.css5, about, terms, privacy, cookies, responsible-betting1 per screenOVER, by three, 2026-08-18

.ptab-panel is two things at once and neither of them is decided, which is why it is here and not in a component row. It is a pattern candidate at two screens of the three, and it is also a component boundary: tabs.css holds an L1 switcher and an L3 tab panel in one file, and the profile set is the second of the two. Six occurrences is not three screens. The threshold counts SCREENS, because what a pattern claims is that an arrangement repeats across the product and not that a page uses it three times. Backlog 16b.

card-grid

display grid align-items stretch grid-template-columns repeat(auto-fit, minmax(min(100%, 300px), 1fr)) gap var(--space-16)

One brick, many of it, and that is still a composition: what the pattern decides is the track, and the card decides nothing about where it stands. It has no media query, and that is the finding rather than an omission. Four rules used to sit beside these: three breakpoints stepping the grid two, three, four columns, and a category variant at auto-fill 240px. All four were already dead, the breakpoints losing to the auto-fit rule on source order and the variant held off only by an !important. A fluid track needs no breakpoints, so deleting the four is what made the shout removable without a card moving.

Vault, dark
Daylight, light

Rule. The track is fluid and the card decides its own height, which is what align-items:stretch buys: a card with a two-line question stands as tall as one with three, so the row of buttons is at one height across the row. Anti-rule. The grid never orders by anything but the list it was given. A track that promotes a card is a track with an opinion, and the sort control above it is where an opinion belongs.

browse-shell

display flex flex-direction column, row from 900px gap 12, 20 from 900px align-items flex-start, stretch with no rail flex 1 min-width 0

A rail beside a column, on 77 screens with fourteen different sets of content in the column. That ratio is the argument for a pattern rather than a component: the arrangement is stable and what it holds is not. The plate the two stand on did not come here with them, because a two-stone surface is the page's material and not this arrangement's.

The rail is empty in every screen's markup and hidden. The real file is <nav class="subcat" id="subcatRail" hidden></nav>, and a page script fills it from a table of sub-categories and drops the hidden. So the specimen below carries the markup that script produces. It is the third component in this system whose visible content is not in its markup, after the card's odds bar and the chart's line, and all three were found by putting the thing on a stand.

Vault, dark

Politics

Daylight, light

Politics

The one rule here with a raised specificity has its reason at the rule. .app-case .cat-layout:not(:has(.subcat,.toc)){align-items:stretch} is 0,3,0 against the 0,1,0 above it, so specificity decides it and not the order of the files, which is what a pattern is supposed to avoid needing. With no rail there is nothing to align to, so the column takes the full height instead of hanging at the top of a row it is the only member of. The selector names both rails because the slot takes more than one, and widening it was measured rather than reasoned: a no-op on 76 of the 77.

Rule. One rail, one column, and the column is min-width:0 so a long word in it cannot push the rail off the screen. Anti-rule. The rail is never the only route to a sub-category. It vanishes below 900px, and a destination that exists only in a block the narrow screen does not draw is a destination half the users do not have.

detail-shell

display flex flex-direction column, row from 760px gap var(--space-16) align-items stretch, flex-start from 760px flex 1 min-width 0

A content column beside a panel, on every one of the eleven event-detail states. Eight declarations, and the whole of what they say is stacked below 760 and side by side above it. The plate .ed-main stands on and the edge it drops did not come here: those are the page's surface and they are in base.css.

Vault, dark
Politics · One-time event

Will the US government shut down before March 1, 2027?

YES 38%   NO 62%

100%75%50%25%0%
Daylight, light
Politics · One-time event

Will the US government shut down before March 1, 2027?

YES 38%   NO 62%

100%75%50%25%0%

Rule. The panel is second in the DOM and first in importance, which is the mobile-first decision made once: stacked, the question and the odds come before the form, because a person cannot decide an amount before they have read what they are deciding. Anti-rule. The panel never scrolls out of reach on the wide layout and never covers the question on the narrow one. It is a dock at the foot below 760px for exactly that reason.

list-head

display flex flex-wrap wrap align-items center justify-content space-between gap 8 / 16 margin 0 margin-bottom 8, then 0 padding-bottom 0

A title on one side and the controls that act on the list on the other, wrapping to two rows when there is no room for one. It stands on 71 screens and 44 of them carry controls; the other 27 are a title with nothing to sort, which is why the row is space-between and not a two-column grid: one child has to look right alone.

The heading's TYPE is not in this file and that is the boundary. A display face and its colour are what the block looks like, so they stay in feed.css. This file is the row. Everything it says about the heading is margin:0, which is an arrangement.

Vault, dark

Trending

Sort: Trending
How often: Any
Daylight, light

Trending

Sort: Trending
How often: Any

The radio group names differ between the two rows above, and that is the same lesson the organisms page paid for. A form control name is document-wide, so two copies of one specimen share a group unless they are told apart, and clicking a sort option in one row would uncheck the other. Here it is fixable because filters.css keys off :checked and never off a name; the tab set could not be fixed that way and is drawn once. Backlog 45.

Rule. Each control shows its CURRENT value in its label, so the state of the list is readable without opening anything. Anti-rule. The head never holds an action that creates something. It describes and it filters; a control that adds belongs where the thing is added.

position-list

display flex flex-direction column gap var(--space-8)

Three declarations, and it is a pattern. That is the clearest case on this page for why the rung exists at all: the row carries its own stone, its own edge and its own ink, and the one thing a row cannot know about itself is that there are others and how far away they are. Thirteen screens, one list each.

Vault, dark
Will the US government shut down before March 1, 2027?YES
Stake$5.00Avg price38%Price now38%Potential payout$13.16
Open · just placed
Will Bitcoin close above $150,000 before October 1, 2026?YES
Stake$25.00Avg price58%Price now61%Potential payout$43.10
Open
Which party will win the most seats in the next UK general election?NO · Conservatives
Stake$10.00Avg price67%Price now67%Potential payout$14.93
Open
Daylight, light
Will the US government shut down before March 1, 2027?YES
Stake$5.00Avg price38%Price now38%Potential payout$13.16
Open · just placed
Will Bitcoin close above $150,000 before October 1, 2026?YES
Stake$25.00Avg price58%Price now61%Potential payout$43.10
Open
Which party will win the most seats in the next UK general election?NO · Conservatives
Stake$10.00Avg price67%Price now67%Potential payout$14.93
Open

Rule. One distance between every row, and it is the same distance whether the row is open, won or lost. Anti-rule. An open position is never green or red. Those two colours mean resolved, and a row that is merely up today borrowing the winning colour tells a person they have won something they have not.

action-bar

display flex padding 8 0 0 gap 8 margin-top 12 >a, >button flex 1 >a>button width 100%

Three screens is the threshold and this clears it exactly. The file says that out loud rather than rounding up, which is the right way to carry a number that could fall: lose one of my-profile, wallet or how-it-works and the rule is that these seven declarations go back to being markup.

THE ONE EXCEPTION THIS RUNG MADE HAS DISSOLVED, 2026-08-08. The bar's surface used to stay in components/account.css: a stone, a top hairline and two rounded top corners are not the page plate and are not composition either, so they went with the component that drew them, and .flat was split across two files, the position here and the three declarations that removed the surface there. Walked on the screens, the surface stood once of three placements and its shape was an open-bottomed dock on a page that does not dock. It was deleted, account.css emptied and was deleted with it, and this file now holds the whole of the bar. The rung has no exception left to declare. The reasoning is on the page, backlog 63.

Vault, dark
Open Wallet
Daylight, light
Open Wallet

Two selectors for one sentence, and the difference is real. .cta-bar>a{flex:1} and .cta-bar>button{flex:1}, because the bar holds a bare button as often as an anchor. The second is written as a CHILD selector, unlike the rule it came from: a button nested inside the anchor is not a flex item of this bar, and flex:1 on it would mean nothing. That is one character deciding whether a rule does anything.

Rule. One or two actions, never three, and the primary one first. Anti-rule. The bar never holds a destructive action beside a commit. Sticky means a thumb is already near it, and the two things a thumb can reach should not be "confirm" and "delete".

The rung is clean, and what is still open on it

The contract holds where it counts. 53 declarations, 18 distinct properties, and every one of them an arrangement: no colour, no face, no border, no surface, in any of the six. The totals were re-taken on 2026-08-08 with every prop:value outside a comment counted, including inside a media query; the 59 and the 16 recorded earlier the same day were read another way, and a count is only as good as the reader named beside it. Five of seven screen counts are exact and two are one screen light because the tree grew from 105 to 106.

Three things were open and one of them closed by itself. Two Assembled from lines have gone stale, one naming a parent as a child and one naming a file that stopped owning the classes on 2026-08-03. .read-col was a slot in a pattern file standing on one screen, two short of the threshold the rung enforces, and backlog 46 closed on 2026-08-19 by the condition it named: four more long documents landed on 2026-08-18 and it stands on five. Section 03 above carries the reading, including the six widths the five screens turned out to be carrying between them.

And the kit has a shelf on every rung. Ten atoms, fourteen molecules, thirteen organisms, six patterns, on top of the four foundation pages. Since 2026-08-08 each component also gets a page of its own, which is not an exception to the shelf but the thing a shelf has no room for: all 43 have one, including the six patterns on this page.