Spaces:
Running
Running
v0 Anay commited on
Commit ·
13fe1f0
1
Parent(s): 6f593ca
style: enhance UI readability for cards and badges
Browse filesIncrease card and badge sizes, adjust text sizes for better legibility.
Co-authored-by: Anay <129646663+anay1104@users.noreply.github.com>
frontend/src/components/PitchView.jsx
CHANGED
|
@@ -9,20 +9,20 @@ import { DraggablePlayer } from "./DraggablePlayer";
|
|
| 9 |
proportions identical across every screen size (no element gets relatively
|
| 10 |
bigger or smaller than another when the viewport changes).
|
| 11 |
|
| 12 |
-
Card:
|
| 13 |
-
Label strip: ~
|
| 14 |
-
Card slot total ≈
|
| 15 |
|
| 16 |
-
DESIGN_WIDTH =
|
| 17 |
-
4 starter rows + gaps ≈
|
| 18 |
-
Bench ≈
|
| 19 |
|
| 20 |
MAX_SCALE > 1 lets the pitch scale modestly on wide screens without badges
|
| 21 |
and labels becoming disproportionately large.
|
| 22 |
*/
|
| 23 |
-
const DESIGN_WIDTH =
|
| 24 |
-
const STARTERS_H =
|
| 25 |
-
const BENCH_H =
|
| 26 |
// Gap between player card wrappers in px (in design space)
|
| 27 |
const CARD_GAP = 24;
|
| 28 |
// Allow the pitch to scale up to 1.1× on wide screens so cards don't look
|
|
|
|
| 9 |
proportions identical across every screen size (no element gets relatively
|
| 10 |
bigger or smaller than another when the viewport changes).
|
| 11 |
|
| 12 |
+
Card: 88×106px (larger for better legibility)
|
| 13 |
+
Label strip: ~52px
|
| 14 |
+
Card slot total ≈ 158px per row
|
| 15 |
|
| 16 |
+
DESIGN_WIDTH = 620: fits widest row (5 mids/defs) = 5×88 + 4×24 = 536 ≤ 620 ✓
|
| 17 |
+
4 starter rows + gaps ≈ 780px total height
|
| 18 |
+
Bench ≈ 230px
|
| 19 |
|
| 20 |
MAX_SCALE > 1 lets the pitch scale modestly on wide screens without badges
|
| 21 |
and labels becoming disproportionately large.
|
| 22 |
*/
|
| 23 |
+
const DESIGN_WIDTH = 620;
|
| 24 |
+
const STARTERS_H = 780;
|
| 25 |
+
const BENCH_H = 230;
|
| 26 |
// Gap between player card wrappers in px (in design space)
|
| 27 |
const CARD_GAP = 24;
|
| 28 |
// Allow the pitch to scale up to 1.1× on wide screens so cards don't look
|
frontend/src/components/PlayerCardVisual.jsx
CHANGED
|
@@ -5,15 +5,15 @@ import { getPlayerPrice } from "../utils/fplLogic";
|
|
| 5 |
import { PlayerContext } from "../PlayerContext";
|
| 6 |
|
| 7 |
// Fixed card dimensions — these are design-space pixels (before PitchView scaling).
|
| 8 |
-
// Sized to be prominent on desktop
|
| 9 |
-
// PitchView scale transform. Keeps proportions consistent across devices.
|
| 10 |
-
const CARD_W =
|
| 11 |
-
const CARD_H =
|
| 12 |
|
| 13 |
// Badge sizing — using percentage of card width ensures badges scale proportionally
|
| 14 |
// with the card rather than being fixed pixels that iOS may try to inflate.
|
| 15 |
-
//
|
| 16 |
-
const BADGE_PCT = 0.
|
| 17 |
|
| 18 |
export const PlayerCardVisual = ({
|
| 19 |
player,
|
|
@@ -61,17 +61,17 @@ export const PlayerCardVisual = ({
|
|
| 61 |
className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transition-colors border border-red-400 shadow-lg cursor-pointer select-none"
|
| 62 |
title="Undo transfer"
|
| 63 |
>
|
| 64 |
-
<RotateCcw size={
|
| 65 |
</div>
|
| 66 |
</div>
|
| 67 |
)}
|
| 68 |
-
<Plus className="text-slate-500 group-hover:text-emerald-400 transition-colors mb-1" size={
|
| 69 |
-
<span className="text-[
|
| 70 |
{player.Pos}
|
| 71 |
</span>
|
| 72 |
</div>
|
| 73 |
{/* Placeholder label area so blank slots have identical height to real cards */}
|
| 74 |
-
<div style={{ height:
|
| 75 |
</div>
|
| 76 |
);
|
| 77 |
}
|
|
@@ -153,11 +153,11 @@ export const PlayerCardVisual = ({
|
|
| 153 |
};
|
| 154 |
|
| 155 |
// EV text sizes — primary GW gets the strongest visual weight, subsequent
|
| 156 |
-
// GWs taper down.
|
| 157 |
const evStyles = [
|
| 158 |
-
"text-emerald-400 text-[
|
| 159 |
-
"text-emerald-500 text-[
|
| 160 |
-
"text-emerald-600 text-[
|
| 161 |
];
|
| 162 |
|
| 163 |
const isTransferIn = Boolean(player.replacedPlayer || onSolverUndo);
|
|
@@ -215,7 +215,7 @@ export const PlayerCardVisual = ({
|
|
| 215 |
minHeight: 0,
|
| 216 |
touchAction: "manipulation",
|
| 217 |
}}
|
| 218 |
-
className={`flex items-center justify-center rounded-full text-[
|
| 219 |
${isCap
|
| 220 |
? activeChipType === "tc"
|
| 221 |
? "bg-purple-500 text-white border border-purple-300"
|
|
@@ -237,7 +237,7 @@ export const PlayerCardVisual = ({
|
|
| 237 |
minHeight: 0,
|
| 238 |
touchAction: "manipulation",
|
| 239 |
}}
|
| 240 |
-
className={`flex items-center justify-center rounded-full text-[
|
| 241 |
${isVice ? "bg-slate-300 text-slate-900 border border-white" : "bg-slate-900/90 text-slate-400 border border-slate-700 hover:text-white"}`}
|
| 242 |
>
|
| 243 |
V
|
|
@@ -259,7 +259,7 @@ export const PlayerCardVisual = ({
|
|
| 259 |
}}
|
| 260 |
className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transform-gpu transition-colors border border-red-400 shadow-md cursor-pointer select-none"
|
| 261 |
>
|
| 262 |
-
<RotateCcw size={
|
| 263 |
</div>
|
| 264 |
) : player.replacedPlayer ? (
|
| 265 |
<div
|
|
@@ -276,7 +276,7 @@ export const PlayerCardVisual = ({
|
|
| 276 |
}}
|
| 277 |
className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transform-gpu transition-colors border border-red-400 shadow-md cursor-pointer select-none"
|
| 278 |
>
|
| 279 |
-
<RotateCcw size={
|
| 280 |
</div>
|
| 281 |
) : null}
|
| 282 |
</div>
|
|
@@ -337,21 +337,21 @@ export const PlayerCardVisual = ({
|
|
| 337 |
textSizeAdjust: "none",
|
| 338 |
}}
|
| 339 |
>
|
| 340 |
-
<div className={`w-full text-center py-[
|
| 341 |
${isTransferIn ? "bg-cyan-600 text-white" : "bg-slate-950 text-slate-100 border border-slate-700"}`}>
|
| 342 |
{player.Name}
|
| 343 |
</div>
|
| 344 |
-
<div className="w-full bg-slate-200 border-x border-slate-700 flex justify-center items-center gap-1 py-[
|
| 345 |
-
<span className={`text-[
|
| 346 |
{isBlankThisGw ? "-" : (player[`${activeGW}_xMins`] ?? 90)}
|
| 347 |
-
<span className="text-[
|
| 348 |
</span>
|
| 349 |
-
<span className="text-slate-400 font-light text-[
|
| 350 |
-
<span className="text-[
|
| 351 |
£{getPlayerPrice(player).toFixed(1)}
|
| 352 |
</span>
|
| 353 |
</div>
|
| 354 |
-
<div className="w-full bg-slate-900 border-x border-b border-slate-700 flex items-center rounded-b shadow-md px-0.5 overflow-hidden" style={{ height:
|
| 355 |
<div className="flex items-center justify-center w-full whitespace-nowrap overflow-hidden">
|
| 356 |
{renderFixtures(player.Team, activeGW)}
|
| 357 |
</div>
|
|
|
|
| 5 |
import { PlayerContext } from "../PlayerContext";
|
| 6 |
|
| 7 |
// Fixed card dimensions — these are design-space pixels (before PitchView scaling).
|
| 8 |
+
// Sized to be prominent and legible on desktop, scaling gracefully on mobile via
|
| 9 |
+
// the PitchView scale transform. Keeps proportions consistent across devices.
|
| 10 |
+
const CARD_W = 88;
|
| 11 |
+
const CARD_H = 106; // photo card height only (label strip is separate, in flow below)
|
| 12 |
|
| 13 |
// Badge sizing — using percentage of card width ensures badges scale proportionally
|
| 14 |
// with the card rather than being fixed pixels that iOS may try to inflate.
|
| 15 |
+
// 15% of 88px = ~13px at design scale — large enough to read and tap comfortably.
|
| 16 |
+
const BADGE_PCT = 0.15;
|
| 17 |
|
| 18 |
export const PlayerCardVisual = ({
|
| 19 |
player,
|
|
|
|
| 61 |
className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transition-colors border border-red-400 shadow-lg cursor-pointer select-none"
|
| 62 |
title="Undo transfer"
|
| 63 |
>
|
| 64 |
+
<RotateCcw size={7} strokeWidth={2.5} />
|
| 65 |
</div>
|
| 66 |
</div>
|
| 67 |
)}
|
| 68 |
+
<Plus className="text-slate-500 group-hover:text-emerald-400 transition-colors mb-1" size={24} />
|
| 69 |
+
<span className="text-[10px] font-black text-slate-500 group-hover:text-emerald-400 uppercase tracking-widest">
|
| 70 |
{player.Pos}
|
| 71 |
</span>
|
| 72 |
</div>
|
| 73 |
{/* Placeholder label area so blank slots have identical height to real cards */}
|
| 74 |
+
<div style={{ height: 55 }} />
|
| 75 |
</div>
|
| 76 |
);
|
| 77 |
}
|
|
|
|
| 153 |
};
|
| 154 |
|
| 155 |
// EV text sizes — primary GW gets the strongest visual weight, subsequent
|
| 156 |
+
// GWs taper down. Sized for comfortable reading at the larger card scale.
|
| 157 |
const evStyles = [
|
| 158 |
+
"text-emerald-400 text-[12px] font-extrabold",
|
| 159 |
+
"text-emerald-500 text-[10px] font-bold",
|
| 160 |
+
"text-emerald-600 text-[8px] font-semibold",
|
| 161 |
];
|
| 162 |
|
| 163 |
const isTransferIn = Boolean(player.replacedPlayer || onSolverUndo);
|
|
|
|
| 215 |
minHeight: 0,
|
| 216 |
touchAction: "manipulation",
|
| 217 |
}}
|
| 218 |
+
className={`flex items-center justify-center rounded-full text-[6px] font-bold leading-none transition-colors shadow-md transform-gpu cursor-pointer select-none
|
| 219 |
${isCap
|
| 220 |
? activeChipType === "tc"
|
| 221 |
? "bg-purple-500 text-white border border-purple-300"
|
|
|
|
| 237 |
minHeight: 0,
|
| 238 |
touchAction: "manipulation",
|
| 239 |
}}
|
| 240 |
+
className={`flex items-center justify-center rounded-full text-[6px] font-bold leading-none transition-colors shadow-md cursor-pointer select-none
|
| 241 |
${isVice ? "bg-slate-300 text-slate-900 border border-white" : "bg-slate-900/90 text-slate-400 border border-slate-700 hover:text-white"}`}
|
| 242 |
>
|
| 243 |
V
|
|
|
|
| 259 |
}}
|
| 260 |
className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transform-gpu transition-colors border border-red-400 shadow-md cursor-pointer select-none"
|
| 261 |
>
|
| 262 |
+
<RotateCcw size={7} strokeWidth={2.5} />
|
| 263 |
</div>
|
| 264 |
) : player.replacedPlayer ? (
|
| 265 |
<div
|
|
|
|
| 276 |
}}
|
| 277 |
className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transform-gpu transition-colors border border-red-400 shadow-md cursor-pointer select-none"
|
| 278 |
>
|
| 279 |
+
<RotateCcw size={7} strokeWidth={2.5} />
|
| 280 |
</div>
|
| 281 |
) : null}
|
| 282 |
</div>
|
|
|
|
| 337 |
textSizeAdjust: "none",
|
| 338 |
}}
|
| 339 |
>
|
| 340 |
+
<div className={`w-full text-center py-[3px] truncate px-1 font-bold text-[9px] leading-tight rounded-t shadow-md
|
| 341 |
${isTransferIn ? "bg-cyan-600 text-white" : "bg-slate-950 text-slate-100 border border-slate-700"}`}>
|
| 342 |
{player.Name}
|
| 343 |
</div>
|
| 344 |
+
<div className="w-full bg-slate-200 border-x border-slate-700 flex justify-center items-center gap-1 py-[3px] shadow-inner">
|
| 345 |
+
<span className={`text-[9px] font-black flex items-baseline gap-[2px] leading-none ${isBlankThisGw ? "text-slate-400" : "text-slate-800"}`}>
|
| 346 |
{isBlankThisGw ? "-" : (player[`${activeGW}_xMins`] ?? 90)}
|
| 347 |
+
<span className="text-[7px] font-bold text-slate-500 uppercase tracking-tight">xMins</span>
|
| 348 |
</span>
|
| 349 |
+
<span className="text-slate-400 font-light text-[9px] leading-none">|</span>
|
| 350 |
+
<span className="text-[9px] font-black text-emerald-700 leading-none">
|
| 351 |
£{getPlayerPrice(player).toFixed(1)}
|
| 352 |
</span>
|
| 353 |
</div>
|
| 354 |
+
<div className="w-full bg-slate-900 border-x border-b border-slate-700 flex items-center rounded-b shadow-md px-0.5 overflow-hidden" style={{ height: 19 }}>
|
| 355 |
<div className="flex items-center justify-center w-full whitespace-nowrap overflow-hidden">
|
| 356 |
{renderFixtures(player.Team, activeGW)}
|
| 357 |
</div>
|