Detail sheet

There is one sheet per page, and every surface opens it: tiles, ledger rows, cards. That is what makes "a heading and one value" affordable, because the facts, the paragraph, and the links are always exactly one tap away rather than crowded onto the page.

On the page

The one number people came for. Nothing else. This tile is live: it carries data-sheet="parking-sheet", so it opens the real sheet at the foot of this page.

In the sheet

Matchday

Parking

Member
$7 a match
Gameday
$10 to $15
Lots
Green Lot, Holland Park, Five Forks Methodist, and Mauldin High

Buy the member rate ahead of the match. Your season parking pass sits in your wallet next to the tickets.

Facts as label and value, never a paragraph poured into a box. The sheet takes 0 to N links, so one component serves a single link and the two app stores alike. This copy is the open state drawn inline, so it carries no data-sheet-close and does nothing when you click it.

Not this

Parking

Member parking is $7 a match and gameday parking runs $10 to $15. Lots are Green Lot, Holland Park, Five Forks Methodist, and Mauldin High. Buy the member rate ahead of the match. Your season parking pass is in your wallet.

PARKING DETAILS

Banned. Everything dumped on the surface. Six of these side by side is a wall of text, and the one number anybody wanted is buried in sentence three.

Three attributes, and the controller does the rest

The trigger is any element with data-sheet="<id>". The scrim is <div class="sheet-scrim" id="<id>" aria-hidden="true"> at the end of the body. Every closer is a button carrying data-sheet-close, which the .sheet-close corner button needs as well as its class.

screen.js toggles .open and aria-hidden, moves focus to the first closer, returns it to the trigger, and closes on the closer, on a click on the scrim itself, and on Escape. It also locks the scroll with position: fixed on body and restores the offset on close, because iOS ignores overflow: hidden. No page hand-rolls the lock.