mancala/apps/frontend/src/theme/themes.ts
Halit Aksoy 6279b5a820 feat(frontend): add the new themes and header
Ceviz, Gece and Yeşim themes as CSS variables on <html>, Bricolage
Grotesque, shared styles, and one header for every page with theme
swatches, the account menu and the page's main action. The lobby,
privacy page and status panels use the new look.
2026-10-16 09:35:39 +03:00

95 lines
2.9 KiB
TypeScript

import { Theme } from "@mancala/core";
// The web app's themes. Pages are coloured by the CSS variables of the theme's class (styles/app.css); the colours
// here are for code that still reads core's Theme, such as PitAnimator.
export type WebTheme = Theme & {
// CSS class on <html>.
className: string;
// Translation key of the theme's name.
labelKey: string;
// Colours of the theme's swatch.
swatch: { board: string, accent: string };
};
const walnut: WebTheme = {
id: "ceviz",
name: "Ceviz",
className: "t-ceviz",
labelKey: "ThemeWalnut",
swatch: { board: "#6e4a30", accent: "#f2b84b" },
themePreviewColor: "#6e4a30",
background: "#1f1712",
appBarBgColor: "#2a2019",
textColor: "#2a1a0a",
textLightColor: "#f6ead8",
playerTurnColor: "#f2b84b",
boardColor: "#6e4a30",
pitColor: "#2c1d13",
pitSelectedColor: "#f2b84b",
stoneColor: "#e39a32",
stoneLightColor: "#fff1c9",
pitGameMoveAnimateColor: "#f2b84b",
pitEmptyPitAnimateColor: "#ff8a73",
pitLastStoneInBankPitAnimateColor: "#f2b84b",
pitGetRivalStonePitAnimateColor: "#ff8a73",
};
const night: WebTheme = {
id: "gece",
name: "Gece",
className: "t-gece",
labelKey: "ThemeNight",
swatch: { board: "#1d2a4d", accent: "#e2b36a" },
themePreviewColor: "#1d2a4d",
background: "#0c1220",
appBarBgColor: "#141c30",
textColor: "#241707",
textLightColor: "#eef1f8",
playerTurnColor: "#e2b36a",
boardColor: "#1d2a4d",
pitColor: "#0b1020",
pitSelectedColor: "#e2b36a",
stoneColor: "#dfe3ee",
stoneLightColor: "#ffffff",
pitGameMoveAnimateColor: "#e2b36a",
pitEmptyPitAnimateColor: "#ff8a7a",
pitLastStoneInBankPitAnimateColor: "#e2b36a",
pitGetRivalStonePitAnimateColor: "#ff8a7a",
};
const jade: WebTheme = {
id: "yesim",
name: "Yeşim",
className: "t-yesim",
labelKey: "ThemeJade",
swatch: { board: "#cfd2c3", accent: "#2a7650" },
themePreviewColor: "#cfd2c3",
background: "#e9ebe3",
appBarBgColor: "#f7f8f3",
textColor: "#1d2721",
textLightColor: "#ffffff",
playerTurnColor: "#2a7650",
boardColor: "#cfd2c3",
pitColor: "#c3c7b6",
pitSelectedColor: "#2a7650",
stoneColor: "#3f9f6f",
stoneLightColor: "#e2ffee",
pitGameMoveAnimateColor: "#2a7650",
pitEmptyPitAnimateColor: "#b43a26",
pitLastStoneInBankPitAnimateColor: "#2a7650",
pitGetRivalStonePitAnimateColor: "#b43a26",
};
// The first one is the default.
export const webThemes: WebTheme[] = [walnut, night, jade];
export function getWebTheme(theme: Theme): WebTheme {
return webThemes.find((webTheme) => webTheme.id === theme.id) ?? walnut;
}
export function applyThemeClass(theme: Theme) {
const root = document.documentElement;
webThemes.forEach((webTheme) => root.classList.remove(webTheme.className));
root.classList.add(getWebTheme(theme).className);
}