Browse shell

A pattern, the fourth rung, and the most worn arrangement in the product: 77 placements on 77 painted screens, holding fourteen different sets of content. A rail beside a column, and below 900 there is no rail. Measured 2026-08-08 in a browser, at 390 and 1280.

77 screens 14 sets of content 2 rails, 1 slot 1 stale line found

The arrangement, with something in it

The real .cat-layout with its rail and its main column, both themes. Below 900 this is one column and the rail sits above the grid; at 900 the rail becomes a side column, which is the one media query this pattern owns.

Vault, dark
Daylight, light

The rail is written by hand here and by a machine in the product: it ships as <nav class="subcat" id="subcatRail" hidden></nav> and a page script fills it. That 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 a stand does not run the product's scripts.

Stable arrangement, unstable content, which is the whole argument

Fourteen different sets of content across 77 screens, and that is the argument for a pattern rather than a component: the arrangement is stable and what it holds is not. A feed, a bets list, a notification list, a profile, a wallet, a document and two error screens all stand in the same two boxes. The shelf and the reason stay on the patterns page.

at 390at 1280
the layouta column, 351 widea row, 969 wide
the main column293 wide911 with no rail, 677 with one
the gap1220, and it is written apart

The gap is a second rule rather than a value in the first, and the reason is one sentence: at 900 the rail arrives, and the distance between two columns is not the distance between two stacked blocks.

Its own header named a PARENT, and nothing reads that line

The Assembled from line in this file listed feed. Measured on the markup: <main class="feed"> opens at line 361 and <div class="cat-layout"> at 469, so the feed holds this shell and not the reverse.

An "assembled from" line that names a parent is the level arithmetic's blind spot written down by hand. Nothing rendered wrong, nothing reads the line, and that is exactly why it went unnoticed until somebody built a page that had to state what this pattern holds.

It is one of two the patterns shelf turned up on the same day. The other is in the position list, and it names a file that had stopped owning the block five days earlier.

One slot, two rails, and the widening was measured

With no rail there is nothing to align to, so the main column takes the full height instead of hanging at the top of a row it is the only member of. The selector for that names BOTH rails, :not(:has(.subcat,.toc)), because the slot takes more than one: a page with a contents rail and no sub-category rail is still a page with a rail.

Widening it was a no-op on 76 of the 77, and that was measured rather than reasoned. One screen in the product has a contents rail, and it is the one the widening was written for.

Each rail declares its own width and its own sticky, and this file declares only that there are two columns, so a third rail can arrive without either file learning about it. Both existing rails use 214px, which is what makes it one slot rather than two.

The reading column, and the container owns the distance

The main column used to hold a grid or a list, and both bring their own distance: a grid has a gap and a position list has a gap. A stack of PROSE blocks has neither, and the first page that needed one showed exactly what that costs: fourteen blocks, every one touching the next.

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. The reset on the children is the same sentence from the other side: a block in this stack may not carry its own vertical margin.

at 390at 1280
the column328x8133503x6140, and the plate around it is 795 wide, which is the rail plus the column and nothing else
the measure--measure, 46ch at --text-16, which is 503px and 70 to 73 characters measured on all five documents from 640 up. It read 600px on 13px prose until 2026-08-19, with the prose capped again at 409px inside it: one question answered twice at two different numbers
children12 to 22 across the five documents, each at a 16 gap and no margin of its own. It said 21 when terms was the only one

The measure is the other half of the fix. The feed's plate uses a width that is 89 characters on this type, against the 60 to 75 the design decides, and a long document is where a reader sees the difference. So the column takes the measure itself and centres itself.

THE COLUMN CARRIES THE MEASURE ONCE, SINCE 2026-08-19. It was --container-doc at 600px with --measure on the paragraphs inside it, so a document page drew a 600px column holding 409px of text and the 191px between them was a ragged edge nobody had decided. Four more widths and two more left edges came off the same page in the same pass. The reading size went from --text-13, which is the size of a card blurb on the feed this component was born on, to --text-16: a ch scales with the face, so the character band did not move, and the column grew from 409 to 503px for it. Swept at 13, 14 and 16px over six caps from 38 to 48ch: the longest line is the same count down every size column, and 46ch is the last rung inside the band.

It stood on ONE screen and it now stands on FIVE, about, terms, privacy, cookies and responsible-betting, so the rung this pattern file enforces is cleared by three rather than missed by two. docs/backlog.md 46 said what it needed in as many words, a second and a third long document, not an edit, and it was closed by the tree growing on 2026-08-18 rather than by anybody touching the rule.

And a column measured in a table on a page that never drew it is a number with no subject. FOUR blocks since 2026-08-20, when B3's lede was built on all five and this quotation had to be re-taken: ia/docs/blocks.md banks `H1 + one-line lede` MVP for both body profiles and it had stood on none of them. .read-col .doc-lede is the one rule this pattern owns for it, because a lede on five screens is a composition rather than a part. The blocks below are the head of terms.html, the longest of the five that carry it: .cat-main.read-col with prose children at the container's gap and no margin of their own.

Vault, dark

Terms of Service

What you agree to when you back an event here: your account, your funds, how an event resolves, and what happens when something goes wrong.

Draft for review. The structure, the headings and the dates are real, and the wording below is a first draft written from what this product has already decided rather than an operative term: it has not been through legal review and nothing here is in force. Where a fact is not settled yet, the section that needs it says so.
Last updated 3 August 2026Effective immediately for accounts opened from this date. Effective 3 October 2026 for accounts opened before it.What changed: the resolution section now names the fallback source, and the dispute window moved from 24 to 72 hours.The previous version stays available.
Daylight, light

Terms of Service

What you agree to when you back an event here: your account, your funds, how an event resolves, and what happens when something goes wrong.

Draft for review. The structure, the headings and the dates are real, and the wording below is a first draft written from what this product has already decided rather than an operative term: it has not been through legal review and nothing here is in force. Where a fact is not settled yet, the section that needs it says so.
Last updated 3 August 2026Effective immediately for accounts opened from this date. Effective 3 October 2026 for accounts opened before it.What changed: the resolution section now names the fallback source, and the dispute window moved from 24 to 72 hours.The previous version stays available.

What it does with width

Its own width query: 900 RAIL, and since 2026-08-19 there are two rules at that rung rather than one. The first is the one this pattern has always had: the shell turns from a column into a row at RAIL and takes a 20px gap, it decides the arrangement and the rail decides its own 214px. The second is the first thing this shell has ever decided about its own width, .cat-layout:has(.read-col){width:fit-content;max-width:100%;margin-inline:auto}, and it applies on the five document pages only, because .read-col stands on those and nowhere else. The reason is quoted rather than reasoned: ia/docs/blocks.md says that on desktop the contents is promoted to a sticky left column and "the body keeps its 60 to 75 character measure rather than filling the remaining width", so the leftover width is DECLARED to go unused, and a plate that goes on drawing a border, a bevel and a shadow around width nobody asked for is drawing a page around nothing. Measured at 1440: terms.html is a 795px plate against 1140 before, and about.html, which carries no rail, is 561.

A pattern still adds no styles of its own beyond the arrangement, and the count moved. Counted on 2026-08-19 by reading the six files in components/patterns/ with comments stripped: 75 declarations over 23 properties, where this line said 59 and the pattern shelf said 59 over 16 on 2026-08-08. Not one of the 75 is a colour, a border, a background or a surface, which is the half of the claim that holds unchanged. Eight of them are neither an arrangement nor a colour and are worth naming rather than counting past: four font-size, three line-height and one text-align, every one of them inside .read-col and every one of them from the reading-column repair. A column that sets its own reading size is a pattern holding a type decision, and it is written here rather than in a component because the size is a property of the arrangement, not of the block, exactly as the gap already was: --measure is in ch, so the column's font-size and the column's cap are one decision and splitting them across two files is how a page ends up asking the same question twice at two numbers.

The rule

A pattern says where, a rail says how wide, a component says what it looks like. Three files, and none of them has to know about the others.

The container owns the distance. Otherwise every new block has to remember to bring one.

The surface is not the arrangement. The two-stone plate these boxes stand on is the page's material and it is in the frame, not here.

The anti-rule

Never write a provenance line nothing reads. This one named a parent as a child and was true of nothing, and it survived because no instrument and no page ever looked at it.

Never put the rhythm of a stack on its blocks. Fourteen blocks touched, and a margin would have fixed those fourteen and nothing after them.

Never let a slot know which rail is in it. The selector names both, and the third one costs nothing.

Where the rest of it is

The shelf: the patterns page. The stylesheet: components/patterns/browse-shell.css. The two rails: category nav and contents. What stands in the column: card grid, position list, state block and SEO plate. The plate underneath: components/base.css. The open row: docs/backlog.md 46.