Exhibit 13 of 17

The stockroom maze

Find the lamp glass in the stockroom behind the showroom. Each room is a section of this page; going through a door is following a link to the next one.

The exhibit

Loading bay

Pallets, a roll-cage and a sign that says DELIVERIES 9–5. It is neither.

Returns desk

A bell, a pen on a chain, and a queue of chairs waiting to be returned to themselves.

Aisle of chairs

Every chair faces the wall. You don’t check whether they turn round when you leave.

Pallet of lamps

Forty lamps, none of them on. Not the lamp you want, and none of them have glass.

Aisle of mirrors

You, forty times, slightly behind schedule.

Staff room

A kettle, a rota nobody follows, and a staff vest on a hook. The vest is empty. Probably.

Boxes of nothing

Boxes labelled NOTHING, stacked to the ceiling. One of them is lighter than nothing.

The glass shelf

One lamp glass, on display. You take it anyway. Found it: the lamp can go back on.

The stockroom door

The door from the showroom swings shut behind you. Somewhere in here is a lamp glass. Everything is on display; nothing is in stock.

How it works

Every room is a <section> with an id, and only .room:target is shown. The way in is the last room in the HTML, so .room:target ~ #room-door hides it whenever another room is the target, without :has(). The little map does use :has() to find which room is the target, and just isn’t drawn without it.

The key CSS

Cut from this exhibit’s stylesheet as it is served.

/* only the room the URL names is shown */
.x-maze .room { display: none; }
.x-maze .room:target { display: block; }

/* the way in is the last room in the document: shown until any other room becomes the target */
.x-maze #room-door { display: block; }
.x-maze .room:target ~ #room-door { display: none; }

/* the map: where the target is (needs :has(); without it, there's no map) */
@supports selector(:has(*)) {
  .x-maze .map { display: grid; }
  .x-maze .maze:not(:has(.room:target)) .m-door { background: var(--ink); }
  .x-maze .maze:has(#room-door:target) .m-door,
  .x-maze .maze:has(#room-loading:target) .m-loading,
  .x-maze .maze:has(#room-returns:target) .m-returns,
  .x-maze .maze:has(#room-chairs:target) .m-chairs,
  .x-maze .maze:has(#room-lamps:target) .m-lamps,
  .x-maze .maze:has(#room-mirrors:target) .m-mirrors,
  .x-maze .maze:has(#room-staff:target) .m-staff,
  .x-maze .maze:has(#room-boxes:target) .m-boxes,
  .x-maze .maze:has(#room-glass:target) .m-glass { background: var(--ink); }
}

Accessibility

Quite good: rooms are headed sections and exits are links, so it is ordinary navigation. Following a fragment link moves keyboard focus to the room. The URL and history change with every step (Back goes back a room, which is arguably a feature), and the page may scroll to the room.

Browser support

  • :target Works in this browser.Not in this browser: Universal. Checked 2026-10-14: Chromium 149 yes, Firefox 141 yes.
  • :has() Works in this browser.Not in this browser: Without :has() it can’t work; the page says so instead of half-working. Checked 2026-10-14: Chromium 149 yes, Firefox 141 yes.
Slop at the top