mancala/docs/specs/theme-polish/design.md
Halit Aksoy 6f88658c60 feat(frontend): simplify the header as in the updated design
The header is now the logo, the page's actions, how to play, settings
and the account. The theme swatches move into a settings menu; the
account shows the player's initials and is on every page through an
AuthUserContext. On phones the home page's actions leave the header for
a row of two buttons. Checked menu items get a check at their end.
2026-10-17 02:59:26 +03:00

3.8 KiB

Theme polish: design

See requirements.md; requirement ids (R1.1, …) are referenced below.

Decisions

Decision Reason
The web app writes the theme's id to a mancala_theme cookie; a small script in the login theme reads it and puts the theme's class on <html> Keycloak's pages are on another origin (localhost:8080, auth.playmancala.app), so they cannot read the app's localStorage. Cookies are shared: host-only cookies across the ports of localhost, and a cookie for playmancala.app with its subdomains (R1.2).
The script runs in <head>, before the page is drawn No flash of another theme.
Without the cookie, the script picks Ceviz or Yeşim from prefers-color-scheme (R1.3) The app's default theme is Ceviz (dark); Yeşim is its only light theme.
darkMode=false in the theme; the script adds PatternFly's pf-v5-theme-dark itself for the dark themes Keycloak's own dark mode follows the system and would fight the chosen theme.
The theme stays a stylesheet on top of keycloak.v2, now with the three themes' tokens copied from apps/frontend/src/styles/app.css Templates stay Keycloak's, so upgrades need no template changes.
The logo and the small board on the card are masks filled with the theme's colors One image each for all three themes.
The app's name comes from CSS by the page's language The realm's display name is one string; the header shows "Köçürme" for Turkish and "Mancala" otherwise, like the web app.
Notyf stays for messages, configured for the top centre and restyled with the theme's variables (R2) It is used from plain functions (Util.checkConnectionAndMaybeAlert), not only components; a React toast would need a context everywhere.

Login theme (apps/keycloak/themes/mancala/login)

  • theme.properties: darkMode=false, scripts=js/theme.js, styles css/styles.css css/mancala.css.
  • js/theme.js: reads mancala_theme (ceviz, gece, yesim), falls back to the color scheme, adds t-<id> and, for Ceviz and Gece, pf-v5-theme-dark to <html>.
  • css/mancala.css: the Bricolage Grotesque font; the tokens of .t-ceviz, .t-gece, .t-yesim; PatternFly's variables mapped to them; the header like the app's (logo, name), the card on --surface, inputs on --surface2, primary buttons in --accent, secondary ones outlined, links in --ink, errors in --live.
  • img/logo-mask.svg, img/board-mask.svg: alpha masks.

Web app

Header (R3)

  • AppHeader: logo, the page's actions (children), how to play, SettingsMenu, AccountMenu. The signed-in user comes from an AuthUserContext that MancalaApp provides, so pages need not pass it down.
  • SettingsMenu (new) replaces ThemeSwatches: a @szhsin/react-menu menu like the account menu, with a "Theme" header and one checkbox item per theme (swatch, name). Checked items in every menu (the theme, the last bot level) show a check at their end instead of the library's mark in front.
  • Icon buttons in the header use .ibtn (round, no outline, a surface on hover and while open); the account button shows getInitials in an accent circle.
  • Home: the header's actions get hide-m; a .qa.show-m row at the top of the page holds New Game and the bot menu (BotLevelMenu with a full button) below 640 px.
  • theme/themes.ts: saveThemeCookie(theme), called with applyThemeClass at start and on every theme change. The cookie lasts a year, SameSite=Lax, Secure on https, and on a real domain is set for the last two labels of the host (playmancala.app).
  • util/Notyf.ts: position: { x: "center", y: "top" }, a shorter duration, no icons, dismissible by click.
  • styles/app.css: Notyf's container below the header; the toast in --ink on --bg (an inverted chip, readable on every theme), the app's font, rounded.