This repository has been archived on 2026-05-06. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
tippspiel/frontend/src/components/AchievementBadge.module.css
T
Ronny edf33fa932 feat: premium achievement badges with Material Symbols icons
Backend:
- New /api/achievements endpoint calculating 6 badges:
  Scharfschütze, Serien-Tipper, Tabellenführer, Frühtipper,
  Globetrotter, Diamant
- Each with progress tracking (current/target)

Frontend:
- AchievementBadge component with Stitch-inspired design
- Material Symbols Outlined font (filled icons)
- Unlocked: colored icon with glow + drop-shadow, rank label
- Locked: grayscale, lock overlay, progress bar
- ProfilePage: real badges replacing emoji placeholders
- Progress bar showing X/6 collected
- Mobile: 2-col grid, Desktop: 6-col grid

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:09:25 +02:00

168 lines
2.9 KiB
CSS

/* ═══ Achievement Badge — Premium Gaming Style ═══ */
.badge {
position: relative;
background: var(--surface-mid);
border-radius: var(--radius-md);
padding: 20px 12px 16px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.05);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
transition: transform 0.2s;
}
.badge:active {
transform: scale(0.97);
}
/* ── Unlocked ── */
.unlocked {
border-color: rgba(255, 255, 255, 0.08);
}
.glow {
position: absolute;
inset: -4px;
border-radius: inherit;
filter: blur(20px);
opacity: 0.5;
pointer-events: none;
z-index: 0;
}
/* ── Locked ── */
.locked {
opacity: 0.45;
filter: grayscale(0.7);
}
.lockOverlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
.lockCircle {
width: 36px;
height: 36px;
border-radius: 50%;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
justify-content: center;
color: rgba(255, 255, 255, 0.7);
}
/* ── Icon ── */
.iconWrap {
position: relative;
width: 56px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
z-index: 1;
}
.iconGlow {
position: absolute;
inset: -8px;
border-radius: 50%;
filter: blur(16px);
pointer-events: none;
}
.icon {
font-size: 42px;
position: relative;
z-index: 1;
}
/* ── Text ── */
.name {
font-size: 0.7rem;
font-weight: 700;
color: var(--text-primary);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: 2px;
position: relative;
z-index: 1;
}
.desc {
font-size: 0.6rem;
color: var(--text-muted);
margin-bottom: 8px;
position: relative;
z-index: 1;
}
/* ── Rank Badge (unlocked) ── */
.rankBadge {
font-size: 0.55rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 3px 10px;
border-radius: 20px;
border: 1px solid;
position: relative;
z-index: 1;
}
/* ── Progress (locked) ── */
.progress {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
position: relative;
z-index: 1;
}
.progressBar {
flex: 1;
height: 4px;
background: var(--surface-high);
border-radius: 2px;
overflow: hidden;
}
.progressFill {
height: 100%;
border-radius: 2px;
transition: width 0.5s ease;
}
.progressText {
font-size: 0.55rem;
color: var(--text-muted);
font-weight: 600;
white-space: nowrap;
}
/* ── Light Mode ── */
:global([data-theme="light"]) .badge {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
:global([data-theme="light"]) .locked {
opacity: 0.35;
}
:global([data-theme="light"]) .lockCircle {
background: rgba(255, 255, 255, 0.8);
color: rgba(0, 0, 0, 0.4);
}