mancala/docs/specs/theme-polish/design.md

50 lines
3.8 KiB
Markdown
Raw Permalink Normal View History

# 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/login.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/login.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.
### Messages and the theme cookie
- `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.