diff --git a/apps/frontend/src/components/GameClockView.tsx b/apps/frontend/src/components/GameClockView.tsx
new file mode 100644
index 0000000..72660ff
--- /dev/null
+++ b/apps/frontend/src/components/GameClockView.tsx
@@ -0,0 +1,40 @@
+import * as React from 'react';
+import { FunctionComponent } from 'react';
+import { CLOCK_LOW_TIME_MS, formatClock, getColorByBrightness } from "@mancala/core";
+import { Context } from '../context/context';
+
+// Readable on every theme; the themes have no warning color of their own.
+const LOW_TIME_COLOR = "#b3261e";
+const LOW_TIME_TEXT_COLOR = "#ffffff";
+
+// One player's clock: highlighted while it runs, in a warning color when the running clock is low.
+const GameClockView: FunctionComponent<{
+ context: Context,
+ timeMs: number,
+ running: boolean,
+}> = ({ context, timeMs, running }) => {
+ const theme = context.themeManager.theme;
+ const lowTime = running && timeMs < CLOCK_LOW_TIME_MS;
+ const background = lowTime ? LOW_TIME_COLOR : running ? theme.playerTurnColor : "transparent";
+ const color = lowTime ? LOW_TIME_TEXT_COLOR : running
+ ? getColorByBrightness(theme.playerTurnColor, theme.textColor, theme.textLightColor)
+ : getColorByBrightness(theme.background, theme.textColor, theme.textLightColor);
+ return (
+
+ {formatClock(timeMs)}
+
+
+ );
+}
+
+export default GameClockView;
diff --git a/apps/frontend/src/components/UserStatus.tsx b/apps/frontend/src/components/UserStatus.tsx
index c4f767c..a9ddc98 100644
--- a/apps/frontend/src/components/UserStatus.tsx
+++ b/apps/frontend/src/components/UserStatus.tsx
@@ -13,8 +13,10 @@ const UserStatus: FunctionComponent<{
user: User,
layoutMode: LayoutMode,
visible?: boolean,
- style?: React.CSSProperties
-}> = ({ context, user, layoutMode, visible, style }) => {
+ style?: React.CSSProperties,
+ // Shown after the online status, e.g. the player's clock.
+ accessory?: React.ReactNode,
+}> = ({ context, user, layoutMode, visible, style, accessory }) => {
if (visible === false) return <>>;
const { t } = useTranslation();
@@ -29,6 +31,7 @@ const UserStatus: FunctionComponent<{
{user.isAnonymous ? t("Anonymous") : user.name}