Skip to content

feat: a shared game shell header, starting with the top row - #40

Open
oyuh wants to merge 8 commits into
player-hover-cardfrom
game-shell-header
Open

feat: a shared game shell header, starting with the top row#40
oyuh wants to merge 8 commits into
player-hover-cardfrom
game-shell-header

Conversation

@oyuh

@oyuh oyuh commented Aug 5, 2026

Copy link
Copy Markdown
Owner

No description provided.

Imposter and Password each carried their own header with their own copy of
the phase maps, the copy-to-clipboard dance and the badge markup. This is one
header for both, and for the three games after them.

Four things live up there and each is now drawn as what it is rather than all
four being pills.

The phase is a track. A pill can say the phase is called Voting; it cannot
say voting is the third of four and the game is nearly done, which is the
question people actually have. The current step is taller and brightest, the
ones behind it are filled, and a line underneath says what to do rather than
repeating what it is called.

The clock is its own reading, big tabular figures over a bar that drains,
because it is the only thing on the header that is always moving. It scales
the bar rather than resizing it, since this runs every second all game. Under
ten seconds it goes red and pulses.

Host and spectator sit in one bordered case split by a hairline, so what you
are is one object on the header instead of two loose icons.

The code is shut until asked for. Mid-game the only reason to want it is to
pull a spectator in, and a code sitting open all match is readable by whoever
is stood behind you. Revealing copies too, and it shuts itself after ten
seconds.

Everything else a game wants to say is still a pill, through the pills slot.
Dev page at /dev/game-shell.
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
games-admin Ready Ready Preview Aug 7, 2026 4:17pm
games-frontend Ready Ready Preview Aug 7, 2026 4:17pm

oyuh added 7 commits August 5, 2026 08:00
Only the phase and the clock keep a container now. They are the pair you
keep glancing back at, so they are the pair that earns an edge; the title,
the pills, the role case and the code sit straight on the page. Boxing both
rows was a box inside the page's other boxes saying nothing by it.

The clock is nearly twice the size and its bar has moved out from under the
figures to span the bottom edge of the container. Time left is about the
whole phase, so it reads better as the whole thing emptying out.

The phase track is gone. Four segments and a count were two ways of saying
the same thing, and the count was the one that already fit. Phases take an
icon instead, standing in the shell the game icon wears up top. They are
passed in for now and belong in each game's metadata later, so a phase can
look the same everywhere it is named.

The header takes its accent from the game's own metadata rather than the
default primary, so every game already wears its colour with nothing passed.
The dev page has a row of all five to show it.
The line was retreating from the end of the phase. Now it fills toward it,
which is the direction a progress bar is read in.

A bar that creeps a percent a second is motion nobody can see, so the head of
the fill breathes: 0.15 to 0.7 over two and a bit seconds, enough to say the
thing is running and not enough to look at. Progress rides on a var so the
fill and the head read the same number and arrive together, and the track is
clipped so the head never escapes at either end.

The phase icon has lost its case. The game icon up top is a badge standing in
for the whole game, but this one is only the phase's mark, so it sits beside
the name at the size of the name and lets the name be the thing you read.
Both headings sit centre now, with a hairline running out either side to the
edge of the section. A centred label floats without something to give it the
width of the thing it names, and the hairline is what the cards already use
to separate one part from the next.

Display Name is just Display, and it has a mark of its own like Join Game
does. Both icons take the label colour rather than being the same grey
knocked back with an inline opacity.

The recents heading is left alone: it lives inside a toggle with a chevron
after it, so it keeps its row.
The rules either side of the centred headings were a second line saying what
was already said. On desktop the sections are split by .hc-divider, and on
mobile each section is its own card with a border, so the hairline landed a
couple of pixels inside one and read as a doubled edge. Centring stays, the
rules go, and the line count is back to what it was.

The icons were centred on the text box correctly, but the labels are
uppercase and caps carry no descender, so the glyphs sit about a pixel above
the middle of that box and the icon looked low. They are nudged onto the cap
centre, which leaves a residual under half a pixel on both breakpoints.

Transform rather than a negative margin: a margin on a centre-aligned flex
item only moves it half as far, and does it by resizing the item.
Not everyone wants the phase panel on screen for a whole match, so a
collapsible header grows a button that puts it away.

Folded, the container is the thing being given up, so it goes entirely: no
border, no fill, no corners. The line moves from the bottom edge to the top,
where it picks up a second job separating the title row from what is under
it, and the pills come down off the top row to sit beneath it with the clock
on the right. The clock loses a few points with nothing left to sit beside.

The phase name is what folding costs you, so the button that gives it back
carries it in its tooltip.

The narrow-screen rule that drops the pills onto their own line is now scoped
to the top row. It was catching the folded pills too and ordering them past
the clock, which put the clock on the left on a phone.
The clock keeps its size. It is meant to be the loudest thing on the header,
and folding the panel away only makes that more true, so the rule that shrank
it is gone.

Around it, everything else gets quieter. The game icon drops its badge shell
and sits as a mark beside the title, since the shell was there to hold its
own against a panel that is no longer on screen. The pills lose their fills
and outlines and read as plain text, because chips with their own outlines
next to a clock that size start arguing with it.

Folding animates now. The panel is kept mounted and closed with a row of 1fr
to 0fr, which is what lets a panel of unknown height shut without a
max-height guessed at from outside, and it goes inert while closed so nothing
in there is still reachable. The container fades its fill, its corners and
its padding on the same curve.

Two things that only showed up once it moved. Taking the panel to no width
rewraps its sentence into a tall column in the frame before the row starts
closing, so the panel shoots up before it goes down; while shut it is held on
one line, which costs nothing as it is being clipped anyway. And the row gap
still counts a panel of no width, walking the pills in off the left edge, so
the gap moves onto the clock where it was wanted.
… colour

The code and the fold button now share one case, split by a hairline, the way
the two roles do. Two things you press, one object.

In the lobby the code is the point of the screen, so it stays readable. Once
play starts it is down to its key, and clicking widens it back out to the
code and copies at the same time, then it shuts itself again. The width
animates rather than snapping, and the label carries its own margin so it can
go to nothing without leaving the gap behind. The lobby is taken to be the
phase a game opens on.

The pills are chips again. Plain text was too far: folded they are most of
what is left beside the clock, so they get a size you can read and the game's
own colour instead of grey, which under a coloured clock was reading as
disabled.

The hairline in the new case had to move below both button rules. Each of
them zeroes its own border and they sit at the same specificity, so whichever
comes last wins, and it has to be this one.
@oyuh
oyuh marked this pull request as ready for review August 8, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant