This commit is contained in:
Tomas Dvorak
2026-01-26 08:13:18 +01:00
parent aa036b6550
commit dfc079288f
505 changed files with 95755 additions and 5712 deletions
Binary file not shown.
+103
View File
@@ -0,0 +1,103 @@
// Admin Sidebar Scroll Test - Run directly in browser console
// Copy and paste this entire script into the browser console on any admin page
(function adminScrollTest() {
console.clear();
console.log('=== ADMIN SIDEBAR SCROLL TEST ===\n');
// Find sidebar
const sidebar = document.querySelector('[data-sidebar="true"]');
if (!sidebar) {
console.error('❌ No sidebar found. Make sure you are on an admin page (/admin/*)');
return;
}
console.log('✅ Sidebar found');
console.log('📏 Current scroll:', sidebar.scrollTop);
console.log('📏 Scroll height:', sidebar.scrollHeight);
console.log('📏 Client height:', sidebar.clientHeight);
console.log('📏 Scrollable:', sidebar.scrollHeight > sidebar.clientHeight ? '✅ YES' : '❌ NO');
// Check if scrollable
if (sidebar.scrollHeight <= sidebar.clientHeight) {
console.log('\n⚠️ Sidebar is NOT scrollable!');
console.log(' To test scroll retention, the sidebar needs to be scrollable.');
console.log(' Try: 1) Reducing browser window height, or 2) Zoom in (Ctrl +)');
return;
}
console.log('\n🧪 Testing scroll retention...');
// Clear any existing scroll data
sessionStorage.removeItem('admin-sidebar-scroll');
sessionStorage.removeItem('admin-sidebar-scroll-emergency');
delete window.__adminSidebarScrollTarget;
// Scroll to a test position (middle of scrollable area)
const maxScroll = sidebar.scrollHeight - sidebar.clientHeight;
const testScroll = Math.floor(maxScroll * 0.5);
console.log('📍 Scrolling to test position:', testScroll, 'px');
sidebar.scrollTop = testScroll;
setTimeout(() => {
const actualScroll = sidebar.scrollTop;
console.log('📍 Current position after scroll:', actualScroll, 'px');
// Check if scroll was saved
const savedData = sessionStorage.getItem('admin-sidebar-scroll');
const emergencyData = sessionStorage.getItem('admin-sidebar-scroll-emergency');
const globalTarget = window.__adminSidebarScrollTarget;
console.log('\n💾 Storage check:');
console.log(' Main saved data:', savedData);
console.log(' Emergency saved:', emergencyData);
console.log(' Global target:', globalTarget);
console.log('\n🚀 NOW CLICK ANY ADMIN NAVIGATION LINK');
console.log(' The test will automatically detect navigation and check scroll preservation');
// Intercept navigation to test
let navDetected = false;
const originalPushState = history.pushState;
history.pushState = function(...args) {
if (!navDetected) {
navDetected = true;
const scrollBefore = sidebar.scrollTop;
console.log('\n🚦 Navigation detected!');
console.log(' Scroll position before navigation:', scrollBefore, 'px');
// Check scroll preservation at multiple intervals
const checkPoints = [100, 300, 600, 1000];
checkPoints.forEach((delay, index) => {
setTimeout(() => {
const scrollAfter = sidebar.scrollTop;
const difference = Math.abs(scrollAfter - scrollBefore);
console.log(` 📍 Check ${index + 1} (${delay}ms): ${scrollAfter}px (diff: ${difference}px)`);
if (delay === 1000) {
if (difference < 10) {
console.log('\n✅ SUCCESS: Scroll position preserved!');
console.log(' The admin sidebar scroll retention is working correctly.');
} else {
console.log('\n❌ FAILURE: Scroll position was reset');
console.log(' Difference:', difference, 'px');
console.log('\n🔍 Debugging info:');
console.log(' - Check browser console for any scroll-related errors');
console.log(' - Verify AdminScrollManager is loaded');
console.log(' - Check if CSS is interfering');
}
// Restore original history function
history.pushState = originalPushState;
}
}, delay);
});
}
return originalPushState.apply(this, args);
};
}, 500);
})();
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128px" height="128px"><path fill="#F7F7FB" d="M109.7,110H18.2c-5.1,0-9.2-4.1-9.2-9.2V22.6c0-2.5,2.1-4.6,4.6-4.6H96c2.5,0,4.6,2.1,4.6,4.6v23.1v55.2C100.6,105.9,104.7,110,109.7,110L109.7,110c5.1,0,9.2-4.1,9.2-9.2V50.2c0-2.5-2.1-4.6-4.6-4.6h-4.6"/><path fill="#DEDFE6" d="M23 31.9h63.1c1.7 0 3 1.3 3 3v16.9c0 1.7-1.3 3-3 3H23c-1.7 0-3-1.3-3-3V34.9C20 33.2 21.3 31.9 23 31.9zM109.7 110L109.7 110c5.1 0 9.2-4.1 9.2-9.2V50.2c0-2.5-2.1-4.6-4.6-4.6h-13.8v55.2C100.6 105.9 104.7 110 109.7 110z"/><path fill="#464C55" d="M109.7,113H18.2C11.5,113,6,107.5,6,100.8V22.6c0-4.2,3.4-7.6,7.6-7.6H96c4.2,0,7.6,3.4,7.6,7.6v78.3c0,3.4,2.8,6.2,6.2,6.2s6.2-2.8,6.2-6.2V50.2c0-0.9-0.7-1.6-1.6-1.6h-4.6c-1.7,0-3-1.3-3-3s1.3-3,3-3h4.6c4.2,0,7.6,3.4,7.6,7.6v50.6C121.9,107.6,116.4,113,109.7,113z M13.6,21c-0.9,0-1.6,0.7-1.6,1.6v78.3c0,3.4,2.8,6.2,6.2,6.2h81.1c-1.1-1.8-1.7-3.9-1.7-6.2V22.6c0-0.9-0.7-1.6-1.6-1.6L13.6,21z"/><path fill="#DEDFE6" d="M41.2 72.9H23c-1.7 0-3-1.3-3-3s1.3-3 3-3h18.2c1.7 0 3 1.3 3 3S42.9 72.9 41.2 72.9zM41.2 98.7H23c-1.7 0-3-1.3-3-3s1.3-3 3-3h18.2c1.7 0 3 1.3 3 3S42.9 98.7 41.2 98.7zM41.2 85.7H23c-1.7 0-3-1.3-3-3s1.3-3 3-3h18.2c1.7 0 3 1.3 3 3S42.9 85.7 41.2 85.7z"/><path fill="#464C55" d="M86,99.1H58c-1.7,0-3-1.3-3-3V68.6c0-1.7,1.3-3,3-3h28c1.7,0,3,1.3,3,3v27.5C89,97.7,87.7,99.1,86,99.1z M61,93.1h22V71.6H61V93.1z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,46 @@
// Quick debug to check if AdminScrollManager is working
// Run this in browser console
(function debugAdminScrollManager() {
console.clear();
console.log('=== DEBUGGING AdminScrollManager ===\n');
// Check if AdminScrollManager is loaded
console.log('🔍 Checking AdminScrollManager...');
// Look for AdminScrollManager logs
console.log('📋 Recent console logs:');
const logs = console.logs || [];
console.log(' - Look for "[AdminScrollManager] Component mounted" message');
console.log(' - Look for "[AdminScrollManager] Saved position" message');
console.log(' - Look for "[AdminScrollManager] Restoring position" message');
// Check if AdminLayout is being used
const adminLayout = document.querySelector('.admin-layout');
console.log('\n🏗️ AdminLayout check:');
console.log(' AdminLayout element found:', !!adminLayout);
// Check sidebar
const sidebar = document.querySelector('[data-sidebar="true"]');
console.log('\n📱 Sidebar check:');
console.log(' Sidebar element found:', !!sidebar);
console.log(' Sidebar current scroll:', sidebar?.scrollTop);
// Check if React DevTools shows AdminScrollManager
console.log('\n🔧 Manual test:');
console.log(' 1. Scroll the sidebar to any position');
console.log(' 2. Click an admin navigation link');
console.log(' 3. Watch console for AdminScrollManager messages');
console.log('\n💡 If you don\'t see AdminScrollManager logs, the component is not loading');
// Force a test
if (sidebar) {
console.log('\n🧪 Forcing a scroll test...');
sidebar.scrollTop = 300;
setTimeout(() => {
console.log(' Scroll set to:', sidebar.scrollTop);
console.log(' Now click a navigation link and watch for AdminScrollManager logs');
}, 100);
}
})();
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="144px" height="144px" baseProfile="basic"><path fill="#536dfe" d="M47.496,10.074c-0.508-0.249-0.727,0.226-1.025,0.467c-0.102,0.078-0.188,0.179-0.274,0.272 c-0.743,0.794-1.611,1.315-2.746,1.253c-1.658-0.093-3.074,0.428-4.326,1.696c-0.266-1.564-1.15-2.498-2.495-3.097 c-0.704-0.311-1.416-0.623-1.909-1.3c-0.344-0.482-0.438-1.019-0.61-1.548c-0.11-0.319-0.219-0.646-0.587-0.7 c-0.399-0.062-0.555,0.272-0.712,0.553c-0.626,1.144-0.868,2.405-0.845,3.681c0.055,2.871,1.267,5.159,3.676,6.785 c0.274,0.187,0.344,0.373,0.258,0.646c-0.164,0.56-0.36,1.105-0.532,1.665c-0.11,0.358-0.274,0.436-0.657,0.28 c-1.322-0.552-2.464-1.369-3.473-2.358c-1.713-1.657-3.262-3.486-5.194-4.918c-0.454-0.335-0.907-0.646-1.377-0.942 c-1.971-1.914,0.258-3.486,0.774-3.673c0.54-0.195,0.188-0.864-1.557-0.856c-1.744,0.008-3.34,0.591-5.374,1.369 c-0.297,0.117-0.61,0.202-0.931,0.272c-1.846-0.35-3.763-0.428-5.765-0.202c-3.77,0.42-6.782,2.202-8.996,5.245 c-2.66,3.657-3.285,7.812-2.519,12.147c0.806,4.568,3.137,8.349,6.719,11.306c3.716,3.066,7.994,4.568,12.876,4.28 c2.965-0.171,6.266-0.568,9.989-3.719c0.939,0.467,1.924,0.654,3.559,0.794c1.259,0.117,2.472-0.062,3.411-0.257 c1.471-0.311,1.369-1.673,0.837-1.922C34,36,33.471,35.441,33.471,35.441c2.19-2.591,5.491-5.284,6.782-14.007 c0.102-0.692,0.016-1.128,0-1.689c-0.008-0.342,0.07-0.475,0.462-0.514c1.079-0.125,2.128-0.42,3.09-0.949 c2.793-1.525,3.919-4.031,4.185-7.034C48.028,10.79,47.981,10.315,47.496,10.074z M23.161,37.107 c-4.177-3.284-6.203-4.365-7.04-4.319c-0.782,0.047-0.641,0.942-0.469,1.525c0.18,0.576,0.415,0.973,0.743,1.478 c0.227,0.335,0.383,0.833-0.227,1.206c-1.345,0.833-3.684-0.28-3.794-0.335c-2.722-1.603-4.998-3.72-6.602-6.614 c-1.549-2.786-2.448-5.774-2.597-8.964c-0.039-0.77,0.188-1.043,0.954-1.183c1.009-0.187,2.049-0.226,3.059-0.078 c4.263,0.623,7.893,2.529,10.936,5.548c1.737,1.72,3.051,3.774,4.404,5.782c1.439,2.132,2.988,4.163,4.959,5.828 c0.696,0.584,1.252,1.027,1.783,1.354C27.667,38.515,24.991,38.554,23.161,37.107L23.161,37.107z M25.164,24.228 c0-0.342,0.274-0.615,0.618-0.615c0.078,0,0.149,0.015,0.211,0.039c0.086,0.031,0.164,0.078,0.227,0.148 c0.11,0.109,0.172,0.265,0.172,0.428c0,0.342-0.274,0.615-0.618,0.615S25.164,24.571,25.164,24.228L25.164,24.228z M31.382,27.419 c-0.399,0.163-0.798,0.303-1.181,0.319c-0.595,0.031-1.244-0.21-1.596-0.506c-0.548-0.459-0.939-0.716-1.103-1.517 c-0.07-0.342-0.031-0.872,0.031-1.175c0.141-0.654-0.016-1.074-0.477-1.455c-0.376-0.311-0.853-0.397-1.377-0.397 c-0.196,0-0.375-0.086-0.508-0.156c-0.219-0.109-0.399-0.381-0.227-0.716c0.055-0.109,0.321-0.373,0.383-0.42 c0.712-0.405,1.533-0.272,2.292,0.031c0.704,0.288,1.236,0.817,2.003,1.564c0.782,0.903,0.923,1.152,1.369,1.829 c0.352,0.529,0.673,1.074,0.892,1.696C32.016,26.905,31.844,27.224,31.382,27.419L31.382,27.419z"/></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

+1
View File
@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Grok</title><path d="M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815"></path></svg>

After

Width:  |  Height:  |  Size: 756 B

@@ -0,0 +1,4 @@
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#f7fafc"/>
<text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="#a0aec0" font-family="Arial, sans-serif" font-size="14">Club Logo</text>
</svg>

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 2.9 KiB

+36
View File
@@ -0,0 +1,36 @@
<svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Clean white background -->
<rect width="192" height="192" fill="#ffffff"/>
<!-- Enhanced Football/Soccer Ball Design -->
<g transform="translate(96,96)">
<!-- Outer circle with bold stroke -->
<circle cx="0" cy="0" r="48" fill="none" stroke="#000000" stroke-width="3"/>
<!-- Pentagon pattern - cleaner design -->
<g>
<!-- Center pentagon -->
<path d="M 0,-20 L 19,-6 L 12,16 L -12,16 L -19,-6 Z"
fill="#000000" stroke="#000000" stroke-width="2"/>
<!-- Surrounding hexagons with cleaner lines -->
<g stroke="#000000" stroke-width="2" fill="none">
<path d="M 0,-20 L 19,-6 L 19,-32 L 0,-45 L -19,-32 L -19,-6 Z"/>
<path d="M 19,-6 L 12,16 L 34,16 L 41,-6 L 19,-6 Z"/>
<path d="M 12,16 L -12,16 L -19,38 L 3,46 L 25,38 L 12,16 Z"/>
<path d="M -12,16 L -19,-6 L -41,-6 L -34,16 L -12,16 Z"/>
<path d="M -19,-6 L -19,-32 L -41,-32 L -34,-6 L -19,-6 Z"/>
</g>
</g>
<!-- Add subtle texture lines -->
<g stroke="#000000" stroke-width="0.5" opacity="0.3">
<circle cx="0" cy="0" r="35" fill="none"/>
<circle cx="0" cy="0" r="25" fill="none"/>
</g>
</g>
<!-- Enhanced text with better typography -->
<text x="96" y="165" font-family="Arial, sans-serif" font-size="16" font-weight="900"
text-anchor="middle" fill="#000000" letter-spacing="1">FC CLUB</text>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

+1 -25
View File
@@ -1,25 +1 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
{"short_name": "Fotbal Club", "name": "Fotbal Club - Oficiální aplikace", "description": "Oficiální webové stránky fotbalového klubu - aktuality, zápasy, tabulky, hráči a fotogalerie", "icons": [{"src": "favicon.ico", "sizes": "64x64 32x32 24x24 16x16", "type": "image/x-icon"}, {"src": "logo192.png", "type": "image/png", "sizes": "192x192"}, {"src": "logo512.png", "type": "image/png", "sizes": "512x512"}], "start_url": ".", "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff"}
Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+42
View File
@@ -0,0 +1,42 @@
<svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Clean white background -->
<rect width="192" height="192" fill="#ffffff"/>
<!-- Enhanced Player Silhouette -->
<g transform="translate(96,96)">
<!-- Athletic pose silhouette -->
<g fill="#000000">
<!-- Head -->
<circle cx="0" cy="-28" r="14"/>
<!-- Body with athletic build -->
<path d="M -10,-14 L -7,8 L -4,30 L 4,30 L 7,8 L 10,-14 Z"/>
<!-- Defined arms in athletic position -->
<path d="M -10,-10 L -22,-8 L -24,2 L -18,6 L -10,2 M 10,-10 L 22,-8 L 24,2 L 18,6 L 10,2"/>
<!-- Strong legs in running stance -->
<path d="M -4,30 L -8,52 L -14,52 M 4,30 L 8,52 L 14,52"/>
<!-- Muscle definition lines -->
<g stroke="#ffffff" stroke-width="1" fill="none">
<line x1="-7" y1="-5" x2="-5" y2="5"/>
<line x1="7" y1="-5" x2="5" y2="5"/>
<line x1="-4" y1="15" x2="-4" y2="25"/>
<line x1="4" y1="15" x2="4" y2="25"/>
</g>
</g>
<!-- Motion lines -->
<g stroke="#000000" stroke-width="2" opacity="0.3">
<line x1="-30" y1="-20" x2="-20" y2="-18"/>
<line x1="-32" y1="-10" x2="-22" y2="-8"/>
<line x1="30" y1="-20" x2="20" y2="-18"/>
<line x1="32" y1="-10" x2="22" y2="-8"/>
</g>
</g>
<!-- Enhanced typography -->
<text x="96" y="165" font-family="Arial, sans-serif" font-size="14" font-weight="900"
text-anchor="middle" fill="#000000" letter-spacing="2">PLAYER</text>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+40 -4
View File
@@ -1,9 +1,13 @@
/* eslint-disable no-restricted-globals */
// Service Worker for PWA support and offline functionality
const CACHE_VERSION = 'v1.0.1';
const CACHE_VERSION = 'v1.0.2';
const CACHE_NAME = `fotbal-club-cache-${CACHE_VERSION}`;
// Rate limiting for background updates
const BACKGROUND_UPDATE_INTERVAL = 5000; // 5 seconds minimum between updates
const lastBackgroundUpdates = new Map();
// Assets to cache on install
const STATIC_ASSETS = [
'/',
@@ -84,6 +88,11 @@ self.addEventListener('fetch', (event) => {
return;
}
// Skip background update requests to prevent infinite loops
if (request.headers.get('X-SW-Background-Update') === 'true') {
return;
}
// Handle SPA navigations with app shell fallback
if (request.mode === 'navigate') {
event.respondWith(handleNavigationRequest(request));
@@ -106,8 +115,16 @@ async function handleStaticRequest(request) {
// Try cache first
const cachedResponse = await caches.match(request);
if (cachedResponse) {
// Return cached response and update in background
fetchAndUpdateCache(request);
// For static assets with long cache headers, don't update in background
const url = new URL(request.url);
const isStaticAsset = url.pathname.match(/\.(png|jpg|jpeg|gif|svg|webp|ico|woff|woff2|ttf|eot)$/);
const hasLongCache = cachedResponse.headers.get('cache-control')?.includes('max-age=31536000');
// Only update in background if it's not a static asset with long cache
if (!isStaticAsset || !hasLongCache) {
fetchAndUpdateCache(request);
}
return cachedResponse;
}
@@ -198,9 +215,28 @@ async function handleAPIRequest(request) {
// Update cache in background
async function fetchAndUpdateCache(request) {
try {
const response = await fetch(request);
// Skip if this is already a background update request to prevent infinite loops
if (request.headers.get('X-SW-Background-Update') === 'true') {
return;
}
// Rate limit background updates to prevent excessive requests
const now = Date.now();
const lastUpdate = lastBackgroundUpdates.get(request.url);
if (lastUpdate && (now - lastUpdate) < BACKGROUND_UPDATE_INTERVAL) {
return;
}
lastBackgroundUpdates.set(request.url, now);
// Use fetch with cache: 'no-store' to bypass service worker and avoid infinite loops
const response = await fetch(request.url, {
cache: 'no-store',
headers: { 'X-SW-Background-Update': 'true' }
});
if (response.ok) {
const cache = await caches.open(CACHE_NAME);
// Use the original request as key, but the new response
cache.put(request, response);
}
} catch (error) {
+49
View File
@@ -0,0 +1,49 @@
<svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Clean white background -->
<rect width="192" height="192" fill="#ffffff"/>
<!-- Enhanced Sponsor/Partner placeholder -->
<g transform="translate(96,96)">
<!-- Premium shield shape with better proportions -->
<g>
<!-- Shadow -->
<path d="M 2,-47 L 37,-27 L 37,12 L 2,47 L -33,12 L -33,-27 Z"
fill="#000000" opacity="0.1"/>
<!-- Main shield -->
<path d="M 0,-45 L 35,-25 L 35,10 L 0,45 L -35,10 L -35,-25 Z"
fill="#ffffff" stroke="#000000" stroke-width="3"/>
<!-- Inner decorative border -->
<path d="M 0,-38 L 28,-20 L 28,8 L 0,38 L -28,8 L -28,-20 Z"
fill="none" stroke="#000000" stroke-width="1.5"/>
<!-- Enhanced star with better geometry -->
<g transform="scale(1.2)">
<path d="M 0,-18 L 5,-5 L 18,-3 L 9,6 L 11,19 L 0,13 L -11,19 L -9,6 L -18,-3 L -5,-5 Z"
fill="#000000"/>
<!-- Inner star detail -->
<path d="M 0,-10 L 2,-3 L 9,-2 L 4,3 L 5,10 L 0,7 L -5,10 L -4,3 L -9,-2 L -2,-3 Z"
fill="#ffffff"/>
</g>
<!-- Ribbon with better design -->
<g>
<path d="M -12,38 L 0,48 L 12,38 L 8,45 L 0,50 L -8,45 Z" fill="#000000"/>
<text x="0" y="44" font-family="Arial, sans-serif" font-size="8" font-weight="bold"
text-anchor="middle" fill="#ffffff">PREMIUM</text>
</g>
</g>
<!-- Decorative corner elements -->
<g stroke="#000000" stroke-width="1.5" fill="none">
<circle cx="-25" cy="-35" r="3"/>
<circle cx="25" cy="-35" r="3"/>
<circle cx="-25" cy="30" r="3"/>
<circle cx="25" cy="30" r="3"/>
</g>
</g>
<!-- Enhanced typography -->
<text x="96" y="165" font-family="Arial, sans-serif" font-size="14" font-weight="900"
text-anchor="middle" fill="#000000" letter-spacing="2">SPONSOR</text>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB