games: the casino moves out, and gets a clock of its own

The tables were living in the news app's shell: Pete's face in the header
and the footer, the channel nav, search, the reader, the weather canvas,
the PWA. A casino is not a news page with a felt on it.

So it gets its own layout. What carries over is the design language — the
four palette vars, Fredoka/Nunito, the fat rounded cards, the dropped
shadow. What doesn't is every control it has no use for. gamesPage stops
embedding the news pageData, which is what keeps the furniture from
drifting back one convenient field at a time.

It keeps a clock, but tells a different joke with it: Casinopolis by day,
Casino Night Zone from six, palette and felt and the sign over the door all
changing together. The rule lives in roomAt() for the first paint and again
in the browser, so a player abroad gets their own evening.

And the cards are cards now — corner indices in both corners, the bottom
one upside down as printed, pips on the three-by-seven grid every real deck
has used for four hundred years, courts as a letter with the suit over each
shoulder. Driven in a real browser, both rooms, dealt through to a payout.
This commit is contained in:
prosolis
2026-07-13 23:40:33 -07:00
parent c69fbb63db
commit 8ec13eab5b
10 changed files with 538 additions and 52 deletions

View File

@@ -78,23 +78,39 @@ type Server struct {
salt [16]byte
}
// New builds the server. Templates are parsed once at startup. Each page
// gets its own template set sharing layout.html + _card.html, which avoids
// `main` define collisions between pages.
// New builds the server. Templates are parsed once at startup. Each page gets
// its own template set sharing a layout, which avoids `main` define collisions
// between pages.
//
// There are two layouts, and they are not the same site. The news pages hang off
// layout.html: Pete's face, the channel nav, search, the reader, the weather
// canvas. The casino hangs off games_layout.html, which shares the *design* —
// the palette vars, the fonts, the fat rounded cards — and none of the
// furniture. games.parodia.dev is its own place, not a news page with a felt on
// it, so it doesn't inherit a single control it has no use for.
func New(cfg config.WebConfig, sources []config.SourceConfig, postingEnabled bool, adv config.AdventureConfig, advPost PriorityPoster) (*Server, error) {
pages := []string{"index", "channel", "weather", "bookmarks", "for-you", "status", "story", "games", "blackjack"}
tpls := make(map[string]*template.Template, len(pages))
for _, p := range pages {
t, err := template.New("").Funcs(funcs).ParseFS(templateFS,
"templates/layout.html",
"templates/_card.html",
"templates/_chipbar.html",
"templates/"+p+".html",
)
if err != nil {
return nil, err
sets := []struct {
layout string
shared []string
pages []string
}{
{"layout", []string{"_card"}, []string{"index", "channel", "weather", "bookmarks", "for-you", "status", "story"}},
{"games_layout", []string{"_chipbar"}, []string{"games", "blackjack"}},
}
tpls := make(map[string]*template.Template)
for _, set := range sets {
for _, p := range set.pages {
files := []string{"templates/" + set.layout + ".html"}
for _, s := range set.shared {
files = append(files, "templates/"+s+".html")
}
files = append(files, "templates/"+p+".html")
t, err := template.New("").Funcs(funcs).ParseFS(templateFS, files...)
if err != nil {
return nil, err
}
tpls[p] = t
}
tpls[p] = t
}
infos := make([]SourceInfo, 0, len(sources))
for _, sc := range sources {