style: badges as row above flags, centered over each team

Badge row uses same flex proportions as match row (flex:1 | spacer | flex:1)
so left badge centers over left flag, right badge over right flag.
Full team names restored (no more truncation from 5-column layout).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ronny
2026-04-12 14:18:22 +02:00
parent 799239dcc1
commit d44927ec23
2 changed files with 45 additions and 57 deletions
+12 -12
View File
@@ -21,21 +21,21 @@
inset 0 1px 0 rgba(255,255,255,0.07) !important;
}
/* Badge columns — vertically centered to flags */
.badgeLeft, .badgeRight {
/* Badge row — same flex proportions as matchRow so badges align over flags */
.badgeRow {
display: flex;
align-items: center;
align-self: flex-start;
height: 56px; /* match flag height */
min-width: 0;
margin-bottom: 8px;
}
.badgeLeft {
justify-content: flex-start;
.badgeSlot {
flex: 1;
display: flex;
justify-content: center;
}
.badgeRight {
justify-content: flex-end;
.badgeSpacer {
min-width: 60px; /* matches scoreBox width */
}
.status {
@@ -123,12 +123,12 @@
0 0 16px rgba(254, 174, 50, 0.25);
}
/* Match block — badges + teams + time/score */
.matchBlock {
/* Match row — Teams + time/score */
.matchRow {
display: flex;
align-items: flex-start;
justify-content: center;
gap: 6px;
gap: 10px;
margin-bottom: 16px;
}
+33 -45
View File
@@ -34,16 +34,6 @@ function useCountdown(minutesUntilKickoff: number) {
return remaining;
}
const STATUS_LABELS: Record<string, string> = {
SCHEDULED: 'Geplant',
TIMED: 'Terminiert',
IN_PLAY: 'Live',
PAUSED: 'Pause',
FINISHED: 'Beendet',
POSTPONED: 'Verschoben',
CANCELLED: 'Abgesagt',
};
function formatKickoff(utcDate: string): string {
return new Date(utcDate).toLocaleString('de-DE', {
hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Berlin',
@@ -84,24 +74,49 @@ export default function MatchCard({ match, onTip }: Props) {
return (
<div className={`card ${styles.card} ${styles[`card_${state}`]} ${isLive ? styles.live : ''} ${glowClass}`}>
{/* Main layout: badges + teams + time/score in one block */}
<div className={styles.matchBlock}>
{/* Left badge — group */}
<div className={styles.badgeLeft}>
{/* Badge row — centered above each flag */}
<div className={styles.badgeRow}>
<span className={styles.badgeSlot}>
{match.group && (
<span className={styles.group}>
{match.group.replace('GROUP_', 'Gr. ')}
{match.group.replace('GROUP_', 'Gruppe ')}
</span>
)}
</div>
</span>
<span className={styles.badgeSpacer} />
<span className={styles.badgeSlot}>
{isLive && (
<span className={styles.liveBadge}>
<span className={styles.liveDot} />
LIVE
</span>
)}
{isFinished && (
<span className={styles.finishedBadge}>Beendet</span>
)}
{(state === 'open' || state === 'tipped') && match.tippable && (
<span className={`${styles.countdownBadge} ${remainingMins < 60 ? styles.countdownUrgent : ''}`}>
{match.minutesUntilKickoff < 60
? `Noch ${remainingMins} Min!`
: (() => {
const h = Math.floor(match.minutesUntilKickoff / 60);
if (h < 24) return `in ${h}h`;
const d = Math.floor(h / 24);
return `in ${d} Tag${d > 1 ? 'en' : ''}`;
})()
}
</span>
)}
</span>
</div>
{/* Home team */}
{/* Teams + Center (time or score) */}
<div className={styles.matchRow}>
<div className={styles.teamHome}>
<FlagBox crest={match.homeTeam.crest} name={match.homeTeam.name} />
<span className={styles.teamName}>{match.homeTeam.shortName}</span>
</div>
{/* Center: LED time or Score */}
<div className={styles.scoreBox}>
{isFinished || isLive ? (
<span className={`${styles.score} ${isLive ? styles.scoreLive : ''}`}>
@@ -112,37 +127,10 @@ export default function MatchCard({ match, onTip }: Props) {
)}
</div>
{/* Away team */}
<div className={styles.teamAway}>
<FlagBox crest={match.awayTeam.crest} name={match.awayTeam.name} />
<span className={styles.teamName}>{match.awayTeam.shortName}</span>
</div>
{/* Right badge — status/countdown */}
<div className={styles.badgeRight}>
{isLive && (
<span className={styles.liveBadge}>
<span className={styles.liveDot} />
LIVE
</span>
)}
{isFinished && (
<span className={styles.finishedBadge}>{STATUS_LABELS[match.status] ?? match.status}</span>
)}
{(state === 'open' || state === 'tipped') && match.tippable && (
<span className={`${styles.countdownBadge} ${remainingMins < 60 ? styles.countdownUrgent : ''}`}>
{match.minutesUntilKickoff < 60
? `${remainingMins}m`
: (() => {
const h = Math.floor(match.minutesUntilKickoff / 60);
if (h < 24) return `${h}h`;
const d = Math.floor(h / 24);
return `${d}d`;
})()
}
</span>
)}
</div>
</div>
{/* Tipp area — wird zum farbigen Banner wenn Punkte ausgewertet */}