style: badges as row above flags, centered over each team
Build & Deploy Tippspiel / build (push) Successful in 51s
Build & Deploy Tippspiel / build (push) Successful in 51s
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
</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 */}
|
||||
|
||||
Reference in New Issue
Block a user