Tabs

Level 3. Four switchers in one file, and every one of them works with no JavaScript at all: a radio, a label and a sibling selector. 36 event tabs, 6 profile tabs, 18 rules tabs and 36 range chips across 9 and 2 screens. Measured 2026-08-08 in a browser by cycling every radio, at 390 and 1280, in both pointer branches.

4 switchers 0 JavaScript 1 panel visible at a time 36 labels at 36 tall

The strips, on the panels they actually switch

A tab strip with no panel under it is half a component. 4 elements against the product's 186: the event tab set, its four panels and the content each one holds. The strip is a radio group and the panel is its sibling, so what a tab DOES is only visible with both.

Vault, dark
128 comments
you Add a comment...
mm
marketmavenHolds 320 YES2h ago

These always go to the wire. I am holding my position and adding if it dips.

dd
deadline_dan1h ago

The committee bloc looks firmer this time though.

pp
polly_predictsHolds 150 NO5h ago

Volume jumped right after the headline. Watching how it settles.

nh
newhere1d ago

First bet here. The resolution source being official notices makes this easy to trust.

Biggest YES bets

1whwhale_07$1,240
2mamarketmaven$320
3alalpha_ape$280
4sasatoshi_jr$150

Biggest NO bets

1hehedge_hannah$980
2popolly_predicts$150
3cacaut_carl$120
4ririskoff$90
Holds 320 YESSideAmount
YouYES$4.94
whale_07YES$471
hedge_hannahNO$588
marketmavenYES$121
polly_predictsNO$87

Your bet is highlighted. Bets update as the odds move.

Recent bets, largest first. Filter: over $5.

whwhale_07 bet $175 on YES2m ago
hhhedge_hannah bet $180 on NO14m ago
mmmarketmaven cashed out $31 on YES1h ago
pppolly_predicts bet $87 on NO3h ago
nhnewhere bet $4.94 on YES5h ago
Daylight, light
128 comments
you Add a comment...
mm
marketmavenHolds 320 YES2h ago

These always go to the wire. I am holding my position and adding if it dips.

dd
deadline_dan1h ago

The committee bloc looks firmer this time though.

pp
polly_predictsHolds 150 NO5h ago

Volume jumped right after the headline. Watching how it settles.

nh
newhere1d ago

First bet here. The resolution source being official notices makes this easy to trust.

Biggest YES bets

1whwhale_07$1,240
2mamarketmaven$320
3alalpha_ape$280
4sasatoshi_jr$150

Biggest NO bets

1hehedge_hannah$980
2popolly_predicts$150
3cacaut_carl$120
4ririskoff$90
Holds 320 YESSideAmount
YouYES$4.94
whale_07YES$471
hedge_hannahNO$588
marketmavenYES$121
polly_predictsNO$87

Your bet is highlighted. Bets update as the odds move.

Recent bets, largest first. Filter: over $5.

whwhale_07 bet $175 on YES2m ago
hhhedge_hannah bet $180 on NO14m ago
mmmarketmaven cashed out $31 on YES1h ago
pppolly_predicts bet $87 on NO3h ago
nhnewhere bet $4.94 on YES5h ago

Three tab families, and this page showed one of them

The strip above is not the strip. This file draws three separate tab families and until 2026-08-10 the page stood only the richest: .tabs stands on 9 screens and .ptabs on 2, and neither had ever been drawn in the kit. A reader comparing a tab against a tab was comparing one of three against nothing.

The plain strip, .tabs, from active-bets.html: two links, and the state is aria-current="page" rather than a class. It is the whole of the My Bets switch, Active against History, and it navigates: each tab is a different URL, so nothing is hidden and shown, the page changes.

IT WORE role="tablist" AND role="tab" UNTIL 2026-08-11 AND OWNED NOTHING. A tablist owns elements with role="tab"; here the tabs were one level down inside the links, so the relationship was broken on 9 screens per tree. Two more things were true at once: there is no role="tabpanel" anywhere in that family, in either tree, so the tabs controlled nothing; and they navigate to another document, which a tab does not do. Moving the role up onto the anchor would have fixed the ownership and left a tab with no panel that leaves the page. So the roles came OFF, the container is a <nav> so its label still names something, and the state is the idiom this product already writes 1,228 times. Backlog 89.

AND THE OPPOSITE HAPPENED TO A DIFFERENT STRIP ON 2026-08-16, WHICH IS WHY BOTH SENTENCES BELONG ON ONE PAGE. That pass removed the role from the strip that could not own one; it did not look at the other two bars in this file, and both were still declaring role="tablist" over children with 0 role="tab" and 0 aria-selected in either tree. .rules-tabs is the one of the three that CAN own the role, because it is two real <button>s over two real panels with a script that swaps them, so it has role="tab", aria-selected and role="tabpanel" now, kept in step by the same handler that was already toggling the class. .ed-tabbar and .ptab-bar are <label for> over hidden radios, and a label is not a tab because a label is not focusable, so the role came off both and their panels lost role="tabpanel" with it. The third of the three was missed by the sweep that fixed the first two and was caught by re-running the check, which is the only way a role can be found: nothing in a stylesheet can see one.

Vault, dark
Daylight, light

The profile strip, .ptabs, from my-profile.html: three radios, three labels and three panels, CSS only, exactly the mechanism the event strip uses and at a different size. Its panels hold different components again, which is why it is here whole rather than as a bare bar: a record card, a gallery and a list of resolved positions.

Vault, dark
Total bets23 Win rate61% Resolved18 Member since2026
Win rate is % correct on resolved bets (public). Reputation = the track record, not the balance.
US government shutdown before Jul 1, 2026 WON
YES · resolved Jun 27, 2026 · net +$8.16
Spot ETH ETF before Jul 1, 2026 LOST
NO · resolved Jun 12, 2026 · net -$5.00
Daylight, light
Total bets23 Win rate61% Resolved18 Member since2026
Win rate is % correct on resolved bets (public). Reputation = the track record, not the balance.
US government shutdown before Jul 1, 2026 WON
YES · resolved Jun 27, 2026 · net +$8.16
Spot ETH ETF before Jul 1, 2026 LOST
NO · resolved Jun 12, 2026 · net -$5.00

The radio names and ids are suffixed per cell. A radio group is keyed by name and a label reaches its input by id, so two theme cells sharing either would be one group across both: pressing a label in daylight would move the dark cell. That is the kit's id rule arriving through a second door, and it is the reason this specimen is not a copy of the screen's attribute values.

What this page is for

The level and its reason stay on the organisms page. This page holds the thing a shelf can never show about this component: what is behind each tab, which needed the radios cycled one at a time and every panel measured, and the one place the system's single focus ring could not land.

One panel at a time, and each holds a different component

tabwhat is behind itpanel at 390at 1280
Commentscomments, the thread310x498590x420
Biggest betsbets table, the holders list310x186590x186
Betsthe positions table310x248590x248
Activitythe activity list310x277590x266

Measured by setting each radio in turn and reading what stops being display:none. A static reading of this screen sees one of the four and reports the other three as 0x0, which is what the first pass of this batch did before the radios were cycled: the positions table, the holders rows and the activity rows all measured 0x0 at both widths and none of them is missing.

A zero behind a tab is not a defect, it is a tab. Same sentence as the six skeleton marks in a hidden bet panel, and the same instrument correction: ask whether the host is on the screen.

The one place the system's single ring could not land

base.css draws the ring once, on the element that HAS focus, and the element that has focus here is the RADIO, which this file parks at left:-9999px. So the indicator was painted off the left edge of the document, and a person tabbing into the tab strip saw nothing at all.

The radio is still focusable, which is the part that matters: it is offscreen rather than removed, so the keyboard still reaches it. What was missing was only the sign that it had. The ring is drawn on the LABEL now, which is the thing a person can see.

The profile strip needed the same answer with the input hidden a different way. There the radio is a 1px box at zero opacity, so the ring is drawn in the right place and then painted at zero alpha, which is the same nothing arrived at from the other direction. Its bar is a scroller and the pill fills its content box, so the offset turns inward there, exactly as it does in the filter panel.

The strips

Vault, darkDaylight, light
stripwornmousefinger
.ed-tablabel, the event tabs3636 tall36 tall, unchanged
.ptab-lbl, the profile tabs638 tall44
.rules-tab1831 tall44
.ed-range button3636 tall44, it is a chip

Three of the four take the floor and one does not. The one touch floor in components/base.css names fourteen families, including .tabs button, .ptab-lbl and .rules-tab, and .ed-tablabel is not one of them: it is a <label>, not a button, so the tag-based half of the list misses it. Those 36 labels are the main navigation of the event screen, on a phone, at 36 tall. docs/backlog.md 64.

The range rail and the comment sorter are one chip

Measured 2026-08-04: the two agree on padding, radius, size, height, ground and selected ground down to the pixel, and disagreed on the two things left, the face and the weight. One rail was mono at 400 rising to 600 when chosen; the sorter was the body face. Two files, one control, and neither file could take the other without styling another component's classes.

Both are chip's rail face now. What stayed here is the row: the sorter's markup stands in the comments file and its styling has always stood here, so its press stands here too, next to the hover it answers rather than in the other file.

Both selected grounds in this file were a colour function at 16 per cent, which IS a rung and was still off the ladder, because a value spelled as a function is not a token and does not get the theme. On graphite nothing moved; on chalk they now step up like every other brass tint and the label reads 5.72:1 there.

The press, and it is worth most where there is no hover

Every tab in this file was missing it. A tab is a quiet control, so it settles onto the one held-down role in the system, and each press mirrors the hover it answers so the two sit at equal specificity and source order hands the pointer to the press.

It is worth most on a phone, where there is no hover at all: until it arrived, a tap on a tab said nothing until the panel underneath had already changed.

What it does with width

One query, at DESK, and it takes the FRAME off the chart's range group and not a pixel off its buttons. Measured on a coarse pointer at 320, 360, 390, 640 and 1280, every .ed-range chip is exactly 44 x 44, which is the touch floor base.css declares once for the whole family. The row was 54 and the ten pixels were never the buttons: 4px of padding and a hairline a side, 44 + 8 + 2, and the group is 198 wide for the same arithmetic, 4 x 44 + 3 x 4 + 8 + 2. Below the rung the well, the edge and the corner go and the row is 44, the group 182.

The four chips still read as one control with the frame gone, because the chosen one carries a brass ground and the other three carry none: a segmented control is told apart by its selection, and the box around it is what a desk has room for. Anything below 44 is the floor's decision and not this file's, and a component that shrank under it would be the .btn-md defect again, the same control at 48 under a mouse and 47 under a finger.

The rule

A switcher needs no script. A radio, a label and a sibling selector, and the state lives in the document rather than in a variable.

Hide the input where the ring can still be drawn. Offscreen is focusable and invisible, and it takes the indicator with it, so the indicator moves to the label.

Two strips that measure identically are one control. The face and the weight were the only disagreements, and neither had an argument.

The anti-rule

Never park a focusable element offscreen and leave the ring on it. The indicator was painted at -9999px, which is a keyboard user seeing nothing.

Never measure a tabbed screen without cycling the tabs. Three of four panels read 0x0 at both widths and all three are correct.

Never write a floor as a list of tags. Three of these four strips take the touch floor and the fourth is a label rather than a button.

Where the rest of it is

The level and its reason: the organisms page. The stylesheet: components/tabs.css. The chip both rails wear: chip. What is behind the four panels: comments and bets table. The floor and the family it misses: components/base.css and docs/backlog.md 64.