Compare commits

..

82 Commits

Author SHA1 Message Date
Ronny 3e02cdab3b chore: suppress markdownlint warnings in spec docs
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 19:39:53 +02:00
Ronny 75a028a43e fix: show pending tips in profile, count all tips not just evaluated
Build & Deploy Tippspiel / build (push) Successful in 50s
- Profile tip history now shows all tips (not just evaluated)
- Pending tips display  badge in blue instead of hiding
- Fun Facts "Tipps abgegeben" counts all tips (from tips API)
- Added .badgePending CSS style

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:42:26 +02:00
Ronny f8a1887c0d fix: CSP allows Google Fonts for Material Symbols icons
Build & Deploy Tippspiel / build (push) Successful in 50s
2026-04-12 18:13:44 +02:00
Ronny 8d37d8c2ab feat: premium achievement badges with Material Symbols icons
Build & Deploy Tippspiel / build (push) Successful in 50s
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
Ronny 5ab0189f04 feat: logo links to home/dashboard
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 17:34:00 +02:00
Ronny 5ec5fea80d feat: desktop layout optimization
Build & Deploy Tippspiel / build (push) Successful in 51s
Dashboard: 2-column layout (hero left 60%, stats+nudges right 40%)
Spielplan: 2-column grid for match cards on desktop
Profile: wider max-width (900px), 6-column achievement grid
Header: Admin link back in desktop nav, max-width 1200px
All via CSS media queries (min-width: 768px), no HTML restructuring.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:26:20 +02:00
Ronny 7dc66e50bf feat: local country flags replacing team crests
Build & Deploy Tippspiel / build (push) Successful in 50s
48 country flags downloaded from flagcdn.com (320px PNG, ~55KB total)
stored in frontend/public/flags/{iso-code}.png.

New utility getFlagUrl() maps team names to local flag files.
Applied to MatchCard, DashboardPage, and TipModal.
Falls back to original crest URL if no mapping exists (e.g. TBD).

No external API calls at runtime — all flags served statically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:31:24 +02:00
Ronny 2dabd1f958 feat: three-way theme toggle — Dark / Light / System
Build & Deploy Tippspiel / build (push) Successful in 51s
Cycles: Sun (→ Light) → Monitor (→ System) → Moon (→ Dark)
System mode follows OS prefers-color-scheme and updates live.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:17:57 +02:00
Ronny 1ebee5ef50 style: more spacing between Tippspiel and subtitle
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 16:14:03 +02:00
Ronny 79344a535f style: 'FIFA World Cup 2026' as golden subtitle under 'Tippspiel'
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 16:11:01 +02:00
Ronny 34be6546b1 style: Lucide TrendingUp/Down icons for rank change arrows
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 16:07:02 +02:00
Ronny 4dd63a6818 fix: move useEffect before early returns (React hooks rule violation)
Build & Deploy Tippspiel / build (push) Successful in 50s
2026-04-12 16:02:42 +02:00
Ronny b51282c2da feat: achievement badge placeholders on profile page (Phase 2 prep)
Build & Deploy Tippspiel / build (push) Successful in 50s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 15:57:32 +02:00
Ronny 7e05df0e92 feat: rank change arrow (↑/↓) in dashboard stats tile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 15:56:59 +02:00
Ronny 9e1a982d37 feat: WM 2026 trophy SVG without text in header
Build & Deploy Tippspiel / build (push) Successful in 50s
Extracted trophy graphic from unofficial logo SVG, removed
"FIFA WORLD CUP", "2026", and country names text.
Works in both dark and light mode (colored on transparent).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:39:33 +02:00
Ronny 876ca4d215 feat: FIFA WM 2026 unofficial logo in header (PNG)
Build & Deploy Tippspiel / build (push) Successful in 51s
Unofficial logo works in both dark and light mode (colored on transparent).
Official and white variants also included as alternatives.
Removed broken SVG files (Cloudflare blocked downloads).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:32:48 +02:00
Ronny fd3b20aff6 feat: replace trophy emoji with official FIFA WM 2026 logo
Build & Deploy Tippspiel / build (push) Successful in 50s
White SVG logo for dark mode, colored SVG for light mode.
Logo switches automatically based on theme.
Sourced from football-logos.cc (SVG, ~4.5KB each).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:20:49 +02:00
Ronny 664a39e7d1 style: comprehensive Light Mode overrides
Build & Deploy Tippspiel / build (push) Successful in 50s
Dashboard:
- Hero card: white glass (rgba 255,255,255,0.75) instead of dark glass
- Reduced shadows (no more extreme 40px shadow)
- LED digits: dark gold (#9A6500) with subtle shadow
- Countdown/tip badges: dark gold on light background
- Flag boxes: lighter shadows, no dark glow aura

MatchCards:
- LED time: dark gold for contrast on light bg
- Flag boxes: lighter shadows

BottomNav:
- White background with subtle top border
- Inactive tabs: darker for readability

Global:
- text-muted: 0.45 opacity (was 0.35) — better readability
- text-secondary: 0.65 (was 0.60)
- Gold: #B8740A (darker for light bg contrast)
- shadow-card: much lighter (was too heavy)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:11:57 +02:00
Ronny 773e27be2d feat: move Admin to bottom nav, remove from header
Build & Deploy Tippspiel / build (push) Successful in 50s
2026-04-12 15:02:58 +02:00
Ronny a65ec0c6fa style: card polish — badge spacing, no separator line, wider tip row
Build & Deploy Tippspiel / build (push) Successful in 51s
- Badges: more margin below (10px), better text centering (line-height:1)
- Removed border-top separator between flags and tip area
- Tipped row: full width to align with flag edges
- Reduced card padding for compactness

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:53:34 +02:00
Ronny d547fda51f style: dashboard uses parent padding — same width as Spielplan
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 14:36:44 +02:00
Ronny 5464eb19a1 style: fix badge centering over flags, plain theme toggle icon
Build & Deploy Tippspiel / build (push) Successful in 50s
- badgeRow now uses same gap (10px) as matchRow for exact alignment
- Theme toggle: removed button box, plain icon like admin gear
- Both icons use text-secondary color, consistent style

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:29:52 +02:00
Ronny 5a13a91d83 style: badges as row above flags, centered over each team
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>
2026-04-12 14:18:22 +02:00
Ronny 39d9e7d2e2 style: badges centered to flags, wider dashboard, mobile header actions
Build & Deploy Tippspiel / build (push) Successful in 51s
MatchCard:
- Badges (group, countdown, LIVE, BEENDET) now vertically centered
  to flag height, positioned left/right of the teams
- Removed separate topRow — all in one matchBlock flex layout

Dashboard:
- max-width increased to 800px (matches spielplan width)

Header:
- Theme toggle + admin link moved to headerActions (always visible)
- Theme toggle icon in gold color (was too dark in dark mode)
- Admin link brighter (text-secondary instead of text-muted)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:55:00 +02:00
Ronny 7c26c93905 style: dashboard LED smaller, TipModal flags fullbleed + subtle picker buttons
Build & Deploy Tippspiel / build (push) Successful in 51s
- Dashboard: LED digits 20px (was 26px) — less crowded between flags
- MatchCard: topRow margins for better badge alignment
- TipModal: flags now object-fit:cover (fullbleed)
- TipModal: picker buttons less glossy — reduced shine from 55% to 12%,
  smaller shadow, subtler hover effect

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:37:57 +02:00
Ronny 58b2c7ea86 style: unified flag+time design across Dashboard and Spielplan
Build & Deploy Tippspiel / build (push) Successful in 52s
Dashboard:
- Flags aligned to top (flex-start) — consistent height regardless of name length
- LED time centered to flag height (64px)

Match Cards:
- Flags fullbleed (object-fit: cover), larger (56px), glassmorphism shine
- LED kickoff time replaces dash separator between flags
- Score appears at same position when Live/Finished
- Removed separate kickoffRow — cards are more compact
- scoreBox height matches flag height for vertical centering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:22:13 +02:00
Ronny fd47d05ff6 style: hero card curvature shine, smaller fullbleed flags, tighter LED
Build & Deploy Tippspiel / build (push) Successful in 52s
- Hero: added glossy ::before shine gradient (top 45%) for curvature/Wölbung
- Flags: 64px, object-fit:cover (flag fills entire box), glassmorphism shine
- LED: slightly smaller (26px), tighter digit spacing (18px), stronger glow
- Backdrop blur increased to 24px

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:09:05 +02:00
Ronny b9810ca65c fix: LED digits fixed 20px width for uniform spacing
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 12:46:05 +02:00
Ronny d166808a91 fix: LED digits individually spaced — fixes '2 1:00' gap in DSEG7 font
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 12:42:47 +02:00
Ronny 0da2d665da style: stronger glow, bigger LED, fix vertical alignment, tighter spacing
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-12 12:39:23 +02:00
Ronny 3424a0152e style: remove hero border, LED time between flags like Design 2
Build & Deploy Tippspiel / build (push) Successful in 51s
- Removed visible blue border on hero card (now near-invisible white/6%)
- LED kickoff time moved between the two flags (replacing VS text)
- Layout: flag — LED time — flag centered vertically

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 12:35:38 +02:00
Ronny 23dc97bcc3 style: match Stitch glassmorphism — backdrop-blur, flag glow auras, deeper shadows
Build & Deploy Tippspiel / build (push) Successful in 51s
Hero card now uses glassmorphism (rgba + backdrop-blur) from Stitch design.
Each flag has individual blur-glow aura behind it.
Rounded corners increased to 2rem. Shadow depth increased.
Stats tiles and nudges also refined with rounder corners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 12:08:29 +02:00
Ronny 24eefef975 style: premium Dashboard redesign inspired by Stitch mockups
Build & Deploy Tippspiel / build (push) Successful in 51s
Hero Card:
- Dramatic gradient background (navy → deep blue)
- Radial glow effect behind team flags (stadium atmosphere)
- LED kickoff time with golden glow
- Larger flag icons (72px) as app-icon style boxes
- Countdown as golden badge with pulsing dot
- Bigger CTA button with gradient and shadow

Bottom Nav:
- Filled/solid SVG icons (home, soccer ball, trophy, person)
  instead of Lucide outline icons — more premium feel

Nudges:
- Icon + text layout with hover animation
- Better spacing and visual hierarchy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 11:56:29 +02:00
Ronny 3f757e712f feat: stronger visual scoring differentiation + streak fix
Build & Deploy Tippspiel / build (push) Successful in 50s
- Exakt cards: gold glow border, gold banner, trophy emoji, larger animated badge
- Tendency: green accent (was blue), clearer differentiation from Exakt
- Falsch: muted gray, reduced opacity — clearly "lost"
- Profile tip history: solid gold/green/gray badges with distinct borders
- Streak: remove utc_date <= NOW() filter so dev-finished matches count; handle PostgreSQL boolean serialization

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:31:15 +02:00
Ronny 24edb0cec5 style: BEENDET badge right-aligned, bigger score, score aligned to flag center
Build & Deploy Tippspiel / build (push) Successful in 51s
- BEENDET as subtle badge on the right (same position as LIVE/countdown)
- Score: 26px default, 32px for live matches
- Score vertically centered to flag height (52px), not flag+name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 09:11:36 +02:00
Ronny 790a2809fc style: LIVE badge right-aligned, bigger live score, remove redundant tip
Build & Deploy Tippspiel / build (push) Successful in 51s
- LIVE: pulsing red badge with dot, right-aligned in header (replaces countdown position)
- Live score: 28px instead of 22px for better visibility
- Removed duplicate tip display under live score (tip only shown in footer)
- BEENDET status stays left in header

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 09:00:55 +02:00
Ronny 5d66fb316f fix: countdown badge back in header row (right-aligned), fix LED spacing
Build & Deploy Tippspiel / build (push) Successful in 51s
- Countdown badge in header: Gruppe A ... in 60 Tagen (right side)
- Urgent countdown also in header: Gruppe A ... Noch 9 Min!
- Removed separate countdownRow (was misplaced below kickoff)
- Reduced DSEG7 letter-spacing to fix "2 1:00" gap issue

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:22:11 +02:00
Ronny 4c65329824 style: countdown badge left-aligned, separate from header
Build & Deploy Tippspiel / build (push) Successful in 50s
Countdown badge now in its own row, left-aligned to match
the left edge of the flags. Removed from header top row.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:16:17 +02:00
Ronny 5a019dfeeb style: stronger LED glow on kickoff time (4-layer text-shadow)
Build & Deploy Tippspiel / build (push) Successful in 50s
2026-04-11 23:10:35 +02:00
Ronny 25fef01a29 style: reduce LED kickoff size, center vertically between header and flags
Build & Deploy Tippspiel / build (push) Successful in 51s
2026-04-11 23:07:54 +02:00
Ronny eb764ca1bd style: real LED segment display font for kickoff time
Build & Deploy Tippspiel / build (push) Successful in 51s
- Added DSEG7 font (stadium scoreboard segment display)
- Kickoff time centered in card, no box, just glowing LED digits
- Gold color with double text-shadow glow for authentic look

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:56:56 +02:00
Ronny d0473ca143 style: stadium scoreboard kickoff display in card header
Build & Deploy Tippspiel / build (push) Successful in 49s
Kickoff time styled as LED scoreboard: monospace font, dark background,
gold text with glow effect. Placed in card header next to group badge.
Cards are more compact without the separate kickoff row.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:50:12 +02:00
Ronny e175bb8804 fix: kickoff time centered without 'Uhr', unified countdown badge, DevPanel close button
Build & Deploy Tippspiel / build (push) Successful in 50s
- Kickoff: centered "21:00" above flags (no 'Uhr' suffix)
- Countdown: always rendered as badge (was unstyled span for <60min)
- DevPanel: added close button (✕) in panel header for reliable closing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:46:53 +02:00
Ronny ea5018ab09 style: move kickoff time to card header, better date header spacing
Build & Deploy Tippspiel / build (push) Successful in 50s
- Kickoff time now in header row: "Gruppe A · 04:00 Uhr · in 61 Tagen"
  instead of centered between flags (avoids visual misalignment)
- Date timeline headers: more top padding for balanced spacing
  between cards

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:37:25 +02:00
Ronny 47ed425fc6 style: Spielplan — glassmorphism stats card, timeline date headers
Build & Deploy Tippspiel / build (push) Successful in 50s
- Stats: glass card with 2/104 progress + Punkte/Exakt/Offen details
- Date sections: timeline divider with centered label + lines
  instead of accordion (no more broken border-radius)
- Past matches: simple toggle button, separate from timeline
- Match list: clean vertical flow without section containers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:27:58 +02:00
Ronny e933e8b7f1 style: redesign Spielplan — date grouping, compact stats, less glossy
Build & Deploy Tippspiel / build (push) Successful in 51s
- Replace 3 large stat tiles with compact "2 von 104 getippt" line
- Remove phase dropdown (not useful for daily tipping)
- Group matches by actual date (Mi, 11. Juni / Do, 12. Juni)
  instead of generic "Demnächst"
- First 3 date sections open by default
- Reduce TipModal flag glossy to match MatchCard flags
- Past matches in own collapsed section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:09:38 +02:00
Ronny 446e9074e7 style: align group badge left in card header
Build & Deploy Tippspiel / build (push) Successful in 50s
2026-04-11 21:59:44 +02:00
Ronny d9e04a798e style: Match-Cards — names below flags, less glossy, cleaner header
Build & Deploy Tippspiel / build (push) Successful in 50s
- Team names centered below flags (vertical layout)
- Reduced flag box glossy effect (20% shine vs 55%)
- Removed "Terminiert" status from header (only show Live/Beendet)
- Dash separator instead of colon for upcoming matches
- Flex layout instead of grid for better centering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:44:42 +02:00
Ronny 3ed70172c7 style: redesign Match-Cards — balanced layout, better tipped state
Build & Deploy Tippspiel / build (push) Successful in 50s
- Move kickoff time above teams row instead of between flags
- Center separator: slim ":" instead of 100px time block
- Use shortName for teams (prevents overflow on mobile)
- Tipped state: clean green bar with icon, label, score, edit hint
  instead of scattered checkmark + underline link

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:29:18 +02:00
Ronny ede29ac414 fix: accuracy 1000% bug, Spiele nav icon, light mode polish
Build & Deploy Tippspiel / build (push) Successful in 50s
- Backend: parseInt for leaderboard values from PostgreSQL
  (string concatenation "1"+"0"="10" caused 1000% accuracy)
- BottomNav: Swords icon instead of emoji for Spiele tab
- Light mode: stronger card shadows and shine gradient

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:05:23 +02:00
Ronny 0af6f0aa14 fix: accuracy display, Spiele nav icon, light mode card polish
- Trefferquote: accuracy already displayed correctly as raw value (no fix needed, was already `{stats.accuracy}%`)
- BottomNav: replace  emoji with Lucide Swords icon for Spiele tab (emoji rendered as gear on some systems); remove unused .emojiIcon CSS class
- Light mode: stronger card shadows (0 4px 20px + 0 1px 4px) and brighter card shine (0.85)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 21:03:40 +02:00
Ronny a709a1ce30 fix: improve tipping user journey
Build & Deploy Tippspiel / build (push) Successful in 51s
- Dashboard "Jetzt tippen" opens TipModal directly instead of
  navigating to /spiele (no more dead-end spielplan)
- After tipping, dashboard updates to show "Dein Tipp: X:Y ✓"
- Spielplan auto-opens all sections when only 1-2 exist
  (no more collapsed "Demnächst" as only section)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:51:36 +02:00
Ronny 814392032f chore: cleanup — remove compiled .js files and .superpowers artifacts
Build & Deploy Tippspiel / build (push) Successful in 51s
Added frontend/src/**/*.js and .superpowers/ to .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:43:42 +02:00
Ronny 049aca5112 fix: simplify CI pipeline YAML to avoid parsing errors
Build & Deploy Tippspiel / build (push) Successful in 57s
Removed env: block and complex inline heredocs.
Compose file written to temp file instead of inline Python string.
2026-04-11 20:38:10 +02:00
Ronny b273c6aa7e ci: switch to Gitea Container Registry for reliable deploys
Previous pipeline built images locally via Portainer Docker API,
but Docker layer caching produced identical images. Now:
- Build with nocache=1
- Push to Gitea registry (git.home.rm-warpstation.de)
- Compose uses image: from registry instead of build:
- Redeploy with pullImage: true forces fresh container

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:18:34 +02:00
Ronny 7730345504 fix: StatsRing NaN with no data, Toast showing repeatedly, timer stability
Build & Deploy Tippspiel / build (push) Successful in 19s
- StatsRing: compute all without || 1 fallback, guard segments/legend behind hasData, use seg.count in legend to avoid NaN
- useRankChange: skip toast if already shown this session via sessionStorage
- Toast: use ref for onDismiss to prevent timer reset on every render

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:54:32 +02:00
Ronny 013b05c54e fix: restore glassmorphism card effects on new components
Build & Deploy Tippspiel / build (push) Successful in 19s
Apply global .card class to Dashboard, Profile, ConfettiReveal, and
Toast components for consistent glossy card appearance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:45:54 +02:00
Ronny 19312b010f feat: Phase 1 — Engagement & UX-Polish
Build & Deploy Tippspiel / build (push) Successful in 41s
Dashboard als Startseite, Bottom Nav, Smart Sections,
zustandsbasierte Match-Cards, Konfetti-Reveal, Streak-Tracker,
Rich Profile, Tipp-Animation, Rang-Toast.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:17:19 +02:00
Ronny 002296daf7 style: CSS polish, light mode verification, build fixes
- Add --primary-rgb, --transition-fast, --transition-normal CSS tokens to :root
- Add --primary-rgb override in [data-theme="light"] section
- Fix TS error: remove unused devUser prop from Route elements in App.tsx (API patching via window._devUser makes props redundant)
- Fix TS error: remove unused 'api' import from DevPanel.tsx

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:16:13 +02:00
Ronny 6cdcde31d3 feat: rich profile page with stats ring, tip history, fun stats
Donut chart showing exact/tendency/wrong distribution.
Scrollable tip history with point badges.
Fun stats: favorite tip, home win percentage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:14:41 +02:00
Ronny 17b86df857 feat: rank change toast + streak milestone icons
Toast notification on rank change (up/down).
Streak display with milestones: 🔥 at 3, 🔥🔥 at 10,  at 20.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:12:02 +02:00
Ronny 6c3ad56515 feat: Punkte-Reveal with confetti animation
Shows animated reveal overlay for unseen match results.
Exact match (3pts) triggers confetti explosion.
Each reveal shown only once (localStorage tracking).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:10:22 +02:00
Ronny 950f51c61b feat: tip confirmation animation with haptic feedback
Success overlay with animated checkmark and 'Dein Tipp ist drin! 🎯'
message. Haptic vibration on mobile. Auto-closes after 1.2s.

- Add showSuccess state to TipModal
- Trigger vibration feedback on successful submit
- Display success overlay with popIn animation for checkmark
- Auto-close modal after success animation completes
- Add CSS animations (fadeIn, popIn) to TipModal.module.css

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:08:39 +02:00
Ronny f0776e436b feat: zustandsbasierte Match-Cards (open/tipped/live/finished/missed)
Each card state has distinct visual treatment:
- Open: standard with countdown timer when <1h
- Tipped: green accent with tip display
- Live: pulsing red dot
- Finished: points badge (gold/green/gray)
- Missed: grayed out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:07:21 +02:00
Ronny 82619e6db3 feat: smart sections in Spielplan (Heute/Morgen/Woche/Vergangen)
Matches grouped by time relevance with collapsible accordion.
Heute and Morgen open by default. Stage filter simplified to dropdown.
2026-04-11 19:05:09 +02:00
Ronny d48bc2d449 feat: add Dashboard as new startseite
Hero card with next match + countdown, stats tiles (rank, points, streak),
and contextual nudges. Replaces match list as landing page.
2026-04-11 19:02:53 +02:00
Ronny 6b9445461d feat: add /api/dashboard endpoint with hero match, stats, streak, nudges
Returns next tippable match (hero), user rank/points from leaderboard,
consecutive-tip streak, and up to 3 contextual nudges in one request.
Mounts at /api/dashboard; adds getDashboard() + DashboardData type to
the frontend API client.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:01:01 +02:00
Ronny 636228ff04 feat: add bottom navigation bar (mobile-first)
Fixed bottom nav with Home/Spiele/Rangliste/Profil tabs.
Desktop keeps header nav. Admin hidden behind gear icon.
Main content padded to avoid overlap with bottom nav.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:59:00 +02:00
Ronny dbe71dcb97 refactor: simplify TipModal — remove Expertenblick and redundant header
Strips all insight/agent state, fetchInsight() SSE function, audio playback
logic, and the insightWrapper JSX block that called /api/agent/* routes.
Also removes the matchHeader/groupBadge and kickoffBlock from the modal
(info already visible on the match card). Cleans all corresponding CSS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:56:48 +02:00
Ronny a7efd9354d refactor: remove KI-Agent chat widget and backend route 2026-04-11 18:54:50 +02:00
Ronny 6a0b267660 docs: Phase 1 implementation plan — 14 tasks
Step-by-step plan covering:
- Cleanup (remove AgentChat, simplify TipModal)
- Bottom Nav, Dashboard, Smart Sections
- Match Card states, animations, confetti
- Streak tracker, rank toasts, rich profile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:34:24 +02:00
Ronny 053afcdc26 docs: Phase 1 Design-Spec — Engagement & UX-Polish
Umfassendes Design-Dokument für das App-Redesign:
- Dashboard als neue Startseite (Hero + Stats + Nudges)
- Bottom Navigation Bar (Mobile-First)
- Smart Sections im Spielplan
- 5 emotionale Momente (Konfetti, Countdown, Streak etc.)
- Zustandsbasierte Match-Cards
- Reiches Profil mit Stats-Ring und Tipp-Historie
- Cleanup: KI-Agent entfernen, Modal verschlanken

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:26:32 +02:00
Ronny 6b6e555e32 ci: trigger rebuild for devUser fix
Build & Deploy Tippspiel / build (push) Successful in 16s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:16:08 +02:00
Ronny d02e81851e fix: devUser-Parameter an alle API-Calls weiterleiten
Build & Deploy Tippspiel / build (push) Successful in 30s
Im Dev-Modus wurde der devUser Query-Parameter aus der Browser-URL
nicht an die Backend-API-Calls weitergegeben. Dadurch liefen alle
Requests immer als devUser=1 (Ronny), unabhängig vom gewählten User.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:03:11 +02:00
Ronny e86ae62309 fix: Health-Check vereinfacht – kein DB-Query mehr bei /health
Build & Deploy Tippspiel / build (push) Successful in 30s
Verhindert unnötige SELECT 1 Abfragen gegen Supabase alle 30s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 16:45:39 +02:00
Ronny 7be0418a3e style: Lucide Icons für Theme-Toggle + stärkerer Glossy-Effekt auf Flag-Boxen
Build & Deploy Tippspiel / build (push) Successful in 31s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:09:36 +02:00
Ronny c0c0b3bef5 style: stärkerer Glossy-Effekt auf Flag-Boxen im Light Mode
Glanz-Overlay auf 55% angehoben, inset-Highlight und Border ergänzt
für MatchCard flagBox, TipModal flagLarge und pickerBtn.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:02:21 +02:00
Ronny 04a117cb61 chore: add Claude Code config and local docs to .gitignore
Build & Deploy Tippspiel / build (push) Successful in 16s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:00:27 +02:00
Ronny 624e359d6f feat: Light Mode mit Theme-Toggle
Build & Deploy Tippspiel / build (push) Successful in 30s
Fügt vollständigen Light Mode hinzu – umschaltbar per ☀️/🌙-Button
im Header, Auswahl wird in localStorage persistiert.

- index.css: Light-Mode-Variablen unter [data-theme="light"], neue Tokens --border-subtle, --shadow-card, --card-shine
- App.tsx: Theme-State + useEffect setzt data-theme auf <html>
- App.module.css: Toggle-Button gestylt, Header-Background auf CSS-Var umgestellt
- Komponenten-CSS: Hardcodierte rgba-Werte auf CSS-Variablen migriert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 12:50:04 +02:00
Ronny 948f9800d5 ci: Credentials aus Workflow entfernen, Portainer-Config dynamisch lesen
Build & Deploy Tippspiel / build (push) Successful in 17s
Statt Credentials im Workflow hardcoden:
- Compose-File und Env-Vars werden zur Laufzeit aus Portainer gelesen
- Einziges Secret im Workflow: PORTAINER_TOKEN
- Keine sensiblen Daten mehr in git-versionierten Dateien

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 13:41:19 +02:00
Ronny 92b68a8b2e ci: curl via apk installieren (Alpine runner hat kein curl)
Build & Deploy Tippspiel / build (push) Successful in 45s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 11:48:35 +02:00
Ronny 20f61a0417 fix: Gitea CI/CD und Blank-Page-Fehler behoben
Build & Deploy Tippspiel / build (push) Successful in 15s
- Helmet CSP: upgrade-insecure-requests und HSTS für HTTP-Deployments deaktiviert
  (war die Ursache der leeren Seite - Browser versuchte JS über HTTPS zu laden)
- Backend: statische Dateien werden jetzt in allen NODE_ENV-Modi serviert
- Frontend: IS_DEV erkennt auch VITE_TEST_MODE=true (Build-Zeit Variable)
- Dockerfile: VITE_TEST_MODE=true beim Vite-Build, NODE_ENV=development
- docker-compose.yml: NODE_ENV=development, CORS_ORIGIN=*
- Gitea Workflow: Auth-Token für git clone, Build via Portainer API statt lokaler Docker CLI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 11:46:56 +02:00
-104
View File
@@ -1,104 +0,0 @@
# Supabase Credential Migration — Deployment Notes
## Hintergrund
Das Tippspiel-Repo hatte versehentlich Secrets im Git-History (alter `.gitea/workflows/build.yml`). Im Zuge der Bereinigung wurden:
- **DB-Passwort** rotiert
- **Service Role Key** vom Legacy-JWT-Format auf das neue Supabase-Schlüsselformat migriert
Die alten Werte sind ungültig — Deployments mit alter Konfiguration funktionieren nicht mehr.
## Supabase Key-System: was sich geändert hat
Supabase hat das API-Key-System umgestellt:
| Alt (Legacy, JWT) | Neu |
|---|---|
| `anon` (Browser/Public) | `sb_publishable_...` |
| `service_role` (Backend) | `sb_secret_...` |
**Wichtige Unterschiede:**
- Legacy-Keys sind JWTs (lange Strings beginnend mit `eyJ...`), neue Keys sind Tokens beginnend mit `sb_secret_...` bzw. `sb_publishable_...`
- Legacy-Keys können nur als Gruppe rotiert werden (per JWT-Secret-Reset, invalidiert alle User-Sessions)
- Neue Keys sind **einzeln** rotierbar
- Das Supabase-SDK akzeptiert beide Formate — **kein Code-Change nötig**, nur die Env-Variable austauschen
**Wir nutzen jetzt den neuen `sb_secret_...`-Key** unter dem Variablennamen `SUPABASE_SERVICE_ROLE_KEY`.
## Betroffene Variablen
| Variable | Wo zu finden |
|---|---|
| `DATABASE_URL` | Supabase Dashboard → Project Settings → Database → Connection string (**Transaction Pooler**, Port 6543) |
| `SUPABASE_URL` | Supabase Dashboard → Project Settings → API (unverändert) |
| `SUPABASE_SERVICE_ROLE_KEY` | Supabase Dashboard → Project Settings → API Keys → **Secret keys** Tab → `sb_secret_...` |
> **Wichtig:** Bei `DATABASE_URL` den **Transaction Pooler** (Port 6543, Host `aws-0-eu-west-1.pooler.supabase.com`, User `postgres.<project-ref>`) verwenden — **nicht** Direct Connection (Port 5432, Host `db.<project-ref>.supabase.co`). Direct Connection läuft nur über IPv6 und scheitert in vielen Umgebungen mit `ENOTFOUND`.
Korrektes URL-Format (Pooler):
```text
postgresql://postgres.<project-ref>:<password>@aws-0-eu-west-1.pooler.supabase.com:6543/postgres
```
## Deployment-Stellen
Die Variablen müssen an **drei Stellen** synchron gehalten werden:
### 1. Lokales Dev-Environment
Datei: `backend/.env` (gitignored, nicht im Repo).
**Wichtig bei frischem Clone / Maschinenwechsel:** `backend/.env` ist **bewusst** nicht in Git — Secrets gehören niemals ins Repo. Stattdessen liegt `backend/.env.example` als Template mit Platzhaltern bei. Auf jeder neuen Maschine einmalig:
```bash
cd backend
cp .env.example .env
# dann .env öffnen und Platzhalter durch echte Werte ersetzen
```
**Mindestens benötigte Werte für lauffähiges Dev-Setup:**
```bash
DATABASE_URL=postgresql://postgres.<project-ref>:<password>@aws-0-eu-west-1.pooler.supabase.com:6543/postgres
SUPABASE_URL=https://<project-ref>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=sb_secret_...
FOOTBALL_API_KEY=...
```
`ANTHROPIC_API_KEY` und `ELEVENLABS_API_KEY` aus `.env.example` werden aktuell **nicht** benötigt (Features wurden entfernt).
**Empfehlung:** Werte in einem Passwort-Manager (1Password, Bitwarden o.ä.) hinterlegen, damit sie beim nächsten Umzug sofort zur Hand sind. **Niemals** per E-Mail/Slack/Chat verschicken.
### 2. Portainer Stack `wm2026-tippspiel` (Stack 115)
Portainer UI → Stack → **Environment variables** → Werte ersetzen → **Update the stack**
> **Häufiger Fehler:** Beim Pasten **nicht** den Variablennamen mitkopieren. Ins Value-Feld kommt nur der reine Wert, **nicht** `DATABASE_URL=postgresql://...`. Sonst entsteht eine doppelte Präfix-Verschachtelung und der Container kann keine DB-Verbindung aufbauen.
### 3. CI/CD Workflow (`.gitea/workflows/build.yml`)
Der Workflow holt die Env-Vars **dynamisch aus der Portainer Stack-Konfig** (Schritt 2). Im Repo selbst stehen **keine** Secrets, sondern nur Referenzen wie `${{ secrets.PORTAINER_TOKEN }}` und `${{ secrets.DEPLOY_TOKEN }}`. Diese beiden Gitea-Secrets bleiben unverändert.
## Migration-Checklist für neue Umgebung
- [ ] Aktuelles DB-Passwort aus Supabase abrufen (oder neu setzen unter Project Settings → Database)
- [ ] Aktuellen `sb_secret_...`-Key aus Supabase Dashboard kopieren (API Keys → Secret keys)
- [ ] Connection String aus Pooler-Tab kopieren, `[YOUR-PASSWORD]` ersetzen
- [ ] In Ziel-Stack die drei Variablen setzen: `DATABASE_URL`, `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`
- [ ] Stack redeployen
- [ ] Smoke-Test: `curl http://<host>:<port>/api/matches` → soll JSON mit `matches`-Array liefern (kein 500)
- [ ] Falls 500: Container-Logs prüfen auf `ENOTFOUND` (→ Direct Connection statt Pooler) oder `28P01 invalid_password` (→ Passwort falsch oder Pooler-Cache braucht ~30s)
## Code-relevante Stellen
- DB-Pool wird konfiguriert in `backend/src/db/client.ts` — liest `DATABASE_URL`
- SSL ist nur in `NODE_ENV=production` aktiv, mit `rejectUnauthorized: false`
- Pool-Settings: max 10 Verbindungen, 5s Connection-Timeout, 30s Idle-Timeout
## Referenzen
- Supabase API Keys Doku: <https://supabase.com/docs/guides/getting-started/api-keys>
- Supabase Connection Pooler: <https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pooler>