lib
Trainer theme
Action and grade colors for the trainer, shared with the solver grid, plus suit helpers for card faces.
Installation
$ npx shadcn@latest add https://www.pokerstudy.ai/r/trainer-theme.jsonSource
components/trainer/theme.ts
/**
* Trainer palette — the web app's colors, not the mobile app's.
*
* The action colors are literally the ones the solver's strategy grid uses
* ([solver/strategy-grid.tsx]) so an action reads the same whether you meet it
* in a solve, an Explorer range, or a drill. Everything else (table felt, seats,
* chrome) comes from the zinc/token palette in globals.css, so the trainer sits
* inside the app instead of importing the mobile app's navy + teal.
*/
import type { ActionKind } from "@/lib/trainer/types";
import { ACTION_COLORS, GRADE_COLORS, type Grade } from "@/lib/pokerstudy/poker";
export { ACTION_COLORS } from "@/lib/pokerstudy/poker";
/**
* Color for a preflop/postflop action. `kind` decides the family; the label
* splits raises into bets ("Bet 5.8") and re-raises ("Raise"/"3B"/"60%"), which
* the solver grid already distinguishes.
*/
export function actionColor(kind: ActionKind | "check", label?: string): string {
switch (kind) {
case "fold":
return ACTION_COLORS.Fold;
case "check":
return ACTION_COLORS.Check;
case "call":
return ACTION_COLORS.Call;
case "allin":
return ACTION_COLORS.AllIn;
case "raise":
return label?.toLowerCase().startsWith("bet") ? ACTION_COLORS.Bet : ACTION_COLORS.Raise;
default:
return "var(--secondary)";
}
}
/**
* Grade ramp. Deliberately a five-step semantic scale (the one thing that can't
* be monochrome — the whole point is reading severity at a glance), anchored at
* both ends by the action palette above: perfect is the Call green, a blunder is
* the Raise crimson.
*/
export const TIER_COLORS: Record<Grade, string> = GRADE_COLORS;
/** Broadcast-style card tiles (suit-colored faces); shared with the registry. */
export { suitTile } from "@/lib/pokerstudy/poker";
/** Suit colors, matching the hand replayer's four-color deck. */
export function suitMeta(s: string): { sym: string; color: string } {
switch (s.toLowerCase()) {
case "h":
return { sym: "♥", color: "text-red-600" };
case "d":
return { sym: "♦", color: "text-blue-600" };
case "c":
return { sym: "♣", color: "text-emerald-700" };
case "s":
return { sym: "♠", color: "text-zinc-900" };
default:
return { sym: s, color: "text-zinc-900" };
}
}