Replace PicoCSS with DaisyUI + Tailwind v4

Use gotailwind (standalone Tailwind v4 via Go tool) with DaisyUI
plugin files — no npm needed. CSS is compiled at build time and
embedded via a Via Plugin that serves it as a static file.

Custom "connect4" theme: light, warm, playful palette with red/yellow
accents matching game pieces and board blue accent.
This commit is contained in:
Ryan Hamamura
2026-01-31 07:31:29 -10:00
parent dcab4343e5
commit f590a2444a
11 changed files with 2897 additions and 471 deletions

View File

@@ -26,11 +26,11 @@ func GameList(games []GameListItem, deleteClick func(id string) h.H) h.H {
items = append(items, gameListEntry(g, deleteClick))
}
listItems := []h.H{h.Class("game-list-items")}
listItems := []h.H{h.Class("flex flex-col gap-2")}
listItems = append(listItems, items...)
return h.Div(h.Class("game-list"),
h.H3(h.Text("Your Games")),
return h.Div(h.Class("mt-8 text-left"),
h.H3(h.Class("mb-4 text-center text-lg font-bold"), h.Text("Your Games")),
h.Div(listItems...),
)
}
@@ -38,21 +38,21 @@ func GameList(games []GameListItem, deleteClick func(id string) h.H) h.H {
func gameListEntry(g GameListItem, deleteClick func(id string) h.H) h.H {
statusText, statusClass := getStatusDisplay(g)
return h.Div(h.Class("game-entry"),
return h.Div(h.Class("flex items-center gap-2 p-2 bg-base-200 rounded-lg transition-colors hover:bg-base-300"),
h.A(
h.Href("/game/"+g.ID),
h.Class("game-entry-link"),
h.Div(h.Class("game-entry-main"),
h.Span(h.Class("opponent-name"), h.Text(getOpponentDisplay(g))),
h.Span(h.Class("game-status "+statusClass), h.Text(statusText)),
h.Class("flex-1 flex justify-between items-center px-2 py-1 no-underline text-base-content"),
h.Div(h.Class("flex flex-col gap-1"),
h.Span(h.Class("font-bold"), h.Text(getOpponentDisplay(g))),
h.Span(h.Class(statusClass), h.Text(statusText)),
),
h.Div(h.Class("game-entry-meta"),
h.Span(h.Class("time-ago"), h.Text(formatTimeAgo(g.LastPlayed))),
h.Div(
h.Span(h.Class("text-xs opacity-60"), h.Text(formatTimeAgo(g.LastPlayed))),
),
),
h.Button(
h.Type("button"),
h.Class("game-delete-btn"),
h.Class("btn btn-ghost btn-sm btn-square hover:btn-error"),
h.Text("\u00d7"),
deleteClick(g.ID),
),
@@ -62,12 +62,12 @@ func gameListEntry(g GameListItem, deleteClick func(id string) h.H) h.H {
func getStatusDisplay(g GameListItem) (string, string) {
switch game.GameStatus(g.Status) {
case game.StatusWaitingForPlayer:
return "Waiting for opponent", "waiting"
return "Waiting for opponent", "text-sm opacity-60"
case game.StatusInProgress:
if g.IsMyTurn {
return "Your turn!", "your-turn"
return "Your turn!", "text-sm text-success font-bold"
}
return "Opponent's turn", "opponent-turn"
return "Opponent's turn", "text-sm"
}
return "", ""
}