feat: Ergebnis-Banner, Dev-Simulations-Panel & Spiele-Reset

- MatchCard: farbiger Ergebnis-Banner (Exakt/Tendenz/Falsch) ersetzt
  tipRow, passender Card-Glow je Ergebnis; Lucide-Icons (lucide-react)
- MatchCard: Ändern-Button links, vertikal mittig zur Tipp-Box ausgerichtet
- DevPanel: Simulationsmodus mit User-Switcher, Zeit- & Status-Presets
- DevPanel: Reset-Section mit "Spiel zurücksetzen", "Alle Spiele" und
  "Tipps löschen" (3 Buttons, farblich differenziert)
- Backend: dev.ts mit set-time, set-status, reset-tips, reset-match
- reset-match stellt Original-Datum wieder her (original_utc_date Spalte)
- set-time sichert Original-Datum per COALESCE beim ersten Aufruf
- Supabase Migration: original_utc_date TIMESTAMPTZ zu matches hinzugefügt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ronny
2026-04-04 01:10:55 +02:00
parent e27a62a37b
commit 3d3ff097cf
13 changed files with 1023 additions and 72 deletions
+108 -16
View File
@@ -183,6 +183,13 @@
min-height: 44px;
}
/* Wenn tipRow zum Banner wird */
.tipRow.resultBanner {
border-top: none;
padding-top: 0;
min-height: unset;
}
.tipBtn {
width: 100%;
max-width: 260px;
@@ -191,20 +198,36 @@
letter-spacing: 0.02em;
}
/* Existing tip display */
/* Existing tip display — 3-column grid so center stays centered */
.tipDisplay {
display: flex;
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 10px;
flex-wrap: wrap;
justify-content: center;
width: 100%;
gap: 8px;
}
.tipLeft { display: flex; justify-content: flex-start; align-items: center; }
.tipRight { display: flex; justify-content: flex-end; align-items: center; }
/* Banner-Variante: Icon + Label als Zeile */
.bannerLeft {
gap: 6px;
flex-direction: row;
}
.tipCenter {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.tipLabel {
font-size: 12px;
font-size: 10px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
letter-spacing: 0.08em;
}
.tipScore {
@@ -213,21 +236,90 @@
font-size: 17px;
color: var(--primary);
background: var(--primary-dim);
padding: 3px 12px;
padding: 3px 14px;
border-radius: 8px;
border: 1px solid rgba(75,183,248,0.15);
}
.points {
font-size: 12px;
font-weight: 700;
padding: 4px 10px;
border-radius: 20px;
/* ── Ergebnis-Banner ──────────────────────────────────────────── */
.resultBanner {
margin: 0 -24px -20px !important;
padding: 10px 24px !important;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
}
.exact { background: rgba(52,211,153,0.12); color: var(--success); border: 1px solid rgba(52,211,153,0.2); }
.tendency { background: rgba(75,183,248,0.12); color: var(--primary); border: 1px solid rgba(75,183,248,0.2); }
.wrong { background: rgba(248,113,113,0.10); color: var(--error); border: 1px solid rgba(248,113,113,0.15); }
.resultIcon {
display: flex;
align-items: center;
flex-shrink: 0;
}
.resultLabel {
text-transform: uppercase;
letter-spacing: 0.06em;
font-size: 12px;
font-weight: 700;
}
/* tipScore-Variante im Banner: dunkler Hintergrund statt Primary-Blau */
.tipScoreBanner {
font-family: 'Plus Jakarta Sans', sans-serif;
font-weight: 800;
font-size: 17px;
padding: 3px 14px;
border-radius: 8px;
background: rgba(0,0,0,0.18);
border: 1px solid rgba(255,255,255,0.08);
}
.resultPoints {
font-size: 14px;
font-weight: 800;
letter-spacing: 0.01em;
opacity: 0.95;
}
/* Farb-Varianten Banner */
.exact {
background: linear-gradient(90deg, rgba(52,211,153,0.18) 0%, rgba(52,211,153,0.08) 100%);
color: #4ade80;
border-top: 1px solid rgba(52,211,153,0.20);
}
.tendency {
background: linear-gradient(90deg, rgba(75,183,248,0.18) 0%, rgba(75,183,248,0.08) 100%);
color: var(--primary);
border-top: 1px solid rgba(75,183,248,0.20);
}
.wrong {
background: linear-gradient(90deg, rgba(248,113,113,0.15) 0%, rgba(248,113,113,0.06) 100%);
color: var(--error);
border-top: 1px solid rgba(248,113,113,0.18);
}
/* Card-Glow je Ergebnis */
.glowExact {
box-shadow:
0 0 0 1px rgba(52,211,153,0.18),
0 10px 30px rgba(52,211,153,0.07),
inset 0 1px 0 rgba(255,255,255,0.07) !important;
}
.glowTendency {
box-shadow:
0 0 0 1px rgba(75,183,248,0.18),
0 10px 30px rgba(75,183,248,0.07),
inset 0 1px 0 rgba(255,255,255,0.07) !important;
}
.glowWrong {
box-shadow:
0 0 0 1px rgba(248,113,113,0.15),
0 10px 30px rgba(248,113,113,0.05),
inset 0 1px 0 rgba(255,255,255,0.07) !important;
}
.editBtn {
background: transparent;