diff --git a/src/components/PlayerTab.jsx b/src/components/PlayerTab.jsx
index 93ae9c8..1142997 100755
--- a/src/components/PlayerTab.jsx
+++ b/src/components/PlayerTab.jsx
@@ -2,6 +2,7 @@ import { useState, useEffect, useMemo, useCallback } from 'react';
import axios from 'axios';
import logger, { debug, info, warn, logApiCall, logApiError, logUserAction } from '../utils/logger';
import { Tooltip } from './DeathwatchRoller';
+import { XPBar, XPSummary } from './XPBar';
const STORAGE_SHOP_AUTHED = 'dw:shop:authedPlayer';
const STORAGE_SHOP_PLAYERS = 'dw:shop:players:v1';
@@ -936,6 +937,82 @@ function PlayerTab({
)}
+ {/* Experience Points Display - Minecraft-style XP Bar */}
+
+
Experience Points (XP)
+
+ {/* XP Bar */}
+
+
+
+ 1 Characteristic = 500 XP | 1 Skill Rank = 100 XP | 1 Talent = 50 XP
+
+
+
+ {/* XP Summary */}
+
+
+
+
+ {/* GM Controls */}
+ {isGMLoggedIn() && (
+
+
GM Controls
+
+
+ Set Total XP:
+
+
+
+ Set Spent XP:
+
+
+
+
+
+
+
+
+
+ )}
+
+
{/* Characteristics */}
Characteristics
@@ -1168,10 +1245,20 @@ function PlayerTab({
diff --git a/src/components/XPBar.jsx b/src/components/XPBar.jsx
new file mode 100644
index 0000000..91b28eb
--- /dev/null
+++ b/src/components/XPBar.jsx
@@ -0,0 +1,95 @@
+/**
+ * XP Bar Component - Minecraft-style progress bar for experience points
+ * Shows progress toward next "level" with customizable thresholds
+ */
+
+export function XPBar({
+ currentXP = 0,
+ xpSpent = 0,
+ thresholdXP = 500,
+ showLabel = true,
+ compact = false
+}) {
+ // Available XP is current minus spent
+ const availableXP = Math.max(0, currentXP - xpSpent);
+
+ // Calculate progress toward next threshold
+ // Each "level" is thresholdXP points
+ const currentLevel = Math.floor(currentXP / thresholdXP);
+ const nextLevelThreshold = (currentLevel + 1) * thresholdXP;
+ const xpIntoLevel = currentXP % thresholdXP;
+ const progress = (xpIntoLevel / thresholdXP) * 100;
+
+ const barHeight = compact ? 'h-2' : 'h-4';
+ const textSize = compact ? 'text-xs' : 'text-sm';
+
+ return (
+
+ {/* XP Bar */}
+
+ {/* Green fill */}
+
+ {/* Optional inner glow effect */}
+ {progress > 10 && (
+
+ )}
+
+
+ {/* Label overlay */}
+ {showLabel && (
+
+
+ {currentXP}/{nextLevelThreshold} XP
+ {availableXP > 0 && ({availableXP} avail)}
+
+
+ )}
+
+
+ {/* Debug info - only show if spent XP is tracked */}
+ {xpSpent > 0 && !compact && (
+
+ Lvl {currentLevel}
+ Spent: {xpSpent}
+
+ )}
+
+ );
+}
+
+/**
+ * XP Summary Card - Shows overall player XP status
+ */
+export function XPSummary({ currentXP = 0, xpSpent = 0, thresholdXP = 500 }) {
+ const availableXP = Math.max(0, currentXP - xpSpent);
+ const currentLevel = Math.floor(currentXP / thresholdXP);
+
+ return (
+
+
+
+
Total XP
+
{currentXP}
+
+
+
Available XP
+
{availableXP}
+
+
+
Current Level
+
Level {currentLevel}
+
+
+ {xpSpent > 0 && (
+
+ Spent: {xpSpent} XP | Remaining: {availableXP} XP
+
+ )}
+
+ );
+}
+
+export default XPBar;