Add comprehensive favicon and PWA support

- Created SVG favicons in multiple sizes (16x16, 32x32, 192x192, 512x512)
- Added web app manifest for PWA functionality
- Implemented Apple Touch Icon support for iOS devices
- Added theme color and mobile web app meta tags
- Used gear/cogs design matching UnitForge branding with blue gradient
- Supports modern browsers with SVG and fallback compatibility
- Enables 'Add to Home Screen' functionality on mobile devices

All favicon files use the same blue gradient (#0d6efd to #0b5ed7)
as the main UI theme for consistent branding.
This commit is contained in:
William Valentin
2025-09-14 15:08:50 -07:00
parent 860f60591c
commit 115e344157
8 changed files with 243 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
<defs>
<linearGradient id="gear-gradient-16" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0d6efd;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0b5ed7;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Background circle -->
<circle cx="8" cy="8" r="7.5" fill="url(#gear-gradient-16)" stroke="#ffffff" stroke-width="0.5"/>
<!-- Main gear -->
<g fill="#ffffff" transform="translate(8,8)">
<!-- Simplified gear teeth for 16x16 -->
<path d="M-4,-5 L-2,-5 L-2,-6 L-1,-6 L-1,-5 L1,-5 L1,-6 L2,-6 L2,-5 L4,-5 L5,-4 L5,-2 L6,-2 L6,-1 L5,-1 L5,1 L6,1 L6,2 L5,2 L5,4 L4,5 L2,5 L2,6 L1,6 L1,5 L-1,5 L-1,6 L-2,6 L-2,5 L-4,5 L-5,4 L-5,2 L-6,2 L-6,1 L-5,1 L-5,-1 L-6,-1 L-6,-2 L-5,-2 L-5,-4 Z"/>
<!-- Inner circle -->
<circle cx="0" cy="0" r="2" fill="url(#gear-gradient-16)" stroke="#ffffff" stroke-width="0.3"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 988 B

View File

@@ -0,0 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
<defs>
<linearGradient id="gear-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0d6efd;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0b5ed7;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Background circle -->
<circle cx="16" cy="16" r="15" fill="url(#gear-gradient)" stroke="#ffffff" stroke-width="1"/>
<!-- Main gear -->
<g fill="#ffffff" transform="translate(16,16)">
<!-- Gear teeth -->
<path d="M-8,-10 L-6,-10 L-6,-12 L-3,-12 L-3,-10 L-1,-10 L-1,-8 L1,-8 L1,-10 L3,-10 L3,-12 L6,-12 L6,-10 L8,-10 L10,-8 L10,-6 L12,-6 L12,-3 L10,-3 L10,-1 L8,-1 L8,1 L10,1 L10,3 L12,3 L12,6 L10,6 L10,8 L8,8 L6,10 L3,10 L3,12 L1,12 L1,10 L-1,10 L-1,8 L-3,8 L-3,10 L-6,10 L-6,12 L-8,12 L-10,10 L-10,8 L-12,8 L-12,6 L-10,6 L-10,3 L-12,3 L-12,1 L-10,1 L-10,-1 L-8,-1 L-8,-3 L-10,-3 L-10,-6 L-12,-6 L-12,-8 L-10,-8 Z"/>
<!-- Inner circle -->
<circle cx="0" cy="0" r="4" fill="url(#gear-gradient)" stroke="#ffffff" stroke-width="0.5"/>
</g>
<!-- Small accent gear -->
<g fill="#ffffff" opacity="0.8" transform="translate(23,9) scale(0.4)">
<path d="M-4,-5 L-3,-5 L-3,-6 L-1.5,-6 L-1.5,-5 L-0.5,-5 L-0.5,-4 L0.5,-4 L0.5,-5 L1.5,-5 L1.5,-6 L3,-6 L3,-5 L4,-5 L5,-4 L5,-3 L6,-3 L6,-1.5 L5,-1.5 L5,-0.5 L4,-0.5 L4,0.5 L5,0.5 L5,1.5 L6,1.5 L6,3 L5,3 L5,4 L4,4 L3,5 L1.5,5 L1.5,6 L0.5,6 L0.5,5 L-0.5,5 L-0.5,4 L-1.5,4 L-1.5,5 L-3,5 L-3,6 L-4,6 L-5,5 L-5,4 L-6,4 L-6,3 L-5,3 L-5,1.5 L-6,1.5 L-6,0.5 L-5,0.5 L-5,-0.5 L-4,-0.5 L-4,-1.5 L-5,-1.5 L-5,-3 L-6,-3 L-6,-4 L-5,-4 Z"/>
<circle cx="0" cy="0" r="2" fill="#0d6efd"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,38 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 192" width="192" height="192">
<defs>
<linearGradient id="gear-gradient-192" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0d6efd;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0b5ed7;stop-opacity:1" />
</linearGradient>
<filter id="shadow-192">
<feDropShadow dx="2" dy="2" stdDeviation="4" flood-opacity="0.2"/>
</filter>
</defs>
<!-- Background circle with shadow -->
<circle cx="96" cy="96" r="88" fill="url(#gear-gradient-192)" stroke="#ffffff" stroke-width="6" filter="url(#shadow-192)"/>
<!-- Main gear -->
<g fill="#ffffff" transform="translate(96,96)">
<!-- Detailed gear teeth for high resolution -->
<path d="M-48,-60 L-36,-60 L-36,-72 L-18,-72 L-18,-60 L-6,-60 L-6,-48 L6,-48 L6,-60 L18,-60 L18,-72 L36,-72 L36,-60 L48,-60 L60,-48 L60,-36 L72,-36 L72,-18 L60,-18 L60,-6 L48,-6 L48,6 L60,6 L60,18 L72,18 L72,36 L60,36 L60,48 L48,48 L36,60 L18,60 L18,72 L6,72 L6,60 L-6,60 L-6,48 L-18,48 L-18,60 L-36,60 L-36,72 L-48,72 L-60,60 L-60,48 L-72,48 L-72,36 L-60,36 L-60,18 L-72,18 L-72,6 L-60,6 L-60,-6 L-48,-6 L-48,-18 L-60,-18 L-60,-36 L-72,-36 L-72,-48 L-60,-48 Z"/>
<!-- Inner circle with gradient -->
<circle cx="0" cy="0" r="24" fill="url(#gear-gradient-192)" stroke="#ffffff" stroke-width="3"/>
<!-- Center bolt -->
<circle cx="0" cy="0" r="8" fill="#ffffff"/>
</g>
<!-- Small accent gear -->
<g fill="#ffffff" opacity="0.9" transform="translate(138,54) scale(2.4)">
<path d="M-8,-10 L-6,-10 L-6,-12 L-3,-12 L-3,-10 L-1,-10 L-1,-8 L1,-8 L1,-10 L3,-10 L3,-12 L6,-12 L6,-10 L8,-10 L10,-8 L10,-6 L12,-6 L12,-3 L10,-3 L10,-1 L8,-1 L8,1 L10,1 L10,3 L12,3 L12,6 L10,6 L10,8 L8,8 L6,10 L3,10 L3,12 L1,12 L1,10 L-1,10 L-1,8 L-3,8 L-3,10 L-6,10 L-6,12 L-8,12 L-10,10 L-10,8 L-12,8 L-12,6 L-10,6 L-10,3 L-12,3 L-12,1 L-10,1 L-10,-1 L-8,-1 L-8,-3 L-10,-3 L-10,-6 L-12,-6 L-12,-8 L-10,-8 Z"/>
<circle cx="0" cy="0" r="4" fill="#0d6efd"/>
</g>
<!-- Additional small gear -->
<g fill="#ffffff" opacity="0.7" transform="translate(54,138) scale(1.6)">
<path d="M-6,-8 L-4,-8 L-4,-9 L-2,-9 L-2,-8 L0,-8 L0,-6 L2,-6 L2,-8 L4,-8 L4,-9 L6,-9 L6,-8 L8,-8 L9,-6 L9,-4 L10,-4 L10,-2 L9,-2 L9,0 L8,0 L8,2 L9,2 L9,4 L10,4 L10,6 L9,6 L9,8 L8,8 L6,9 L4,9 L4,10 L2,10 L2,9 L0,9 L0,8 L-2,8 L-2,9 L-4,9 L-4,10 L-6,10 L-8,9 L-8,8 L-9,8 L-9,6 L-8,6 L-8,4 L-9,4 L-9,2 L-8,2 L-8,0 L-6,0 L-6,-2 L-8,-2 L-8,-4 L-9,-4 L-9,-6 L-8,-6 Z"/>
<circle cx="0" cy="0" r="3" fill="#0d6efd"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,70 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
<defs>
<linearGradient id="gear-gradient-512" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0d6efd;stop-opacity:1" />
<stop offset="50%" style="stop-color:#0b63d7;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0b5ed7;stop-opacity:1" />
</linearGradient>
<linearGradient id="accent-gradient-512" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ffffff;stop-opacity:1" />
<stop offset="100%" style="stop-color:#e8f1ff;stop-opacity:1" />
</linearGradient>
<filter id="shadow-512">
<feDropShadow dx="4" dy="4" stdDeviation="8" flood-opacity="0.3"/>
</filter>
<filter id="inner-shadow-512">
<feDropShadow dx="2" dy="2" stdDeviation="4" flood-opacity="0.2"/>
</filter>
</defs>
<!-- Background circle with shadow -->
<circle cx="256" cy="256" r="240" fill="url(#gear-gradient-512)" stroke="#ffffff" stroke-width="12" filter="url(#shadow-512)"/>
<!-- Main gear -->
<g fill="url(#accent-gradient-512)" transform="translate(256,256)">
<!-- Detailed gear teeth for ultra high resolution -->
<path d="M-128,-160 L-96,-160 L-96,-192 L-48,-192 L-48,-160 L-16,-160 L-16,-128 L16,-128 L16,-160 L48,-160 L48,-192 L96,-192 L96,-160 L128,-160 L160,-128 L160,-96 L192,-96 L192,-48 L160,-48 L160,-16 L128,-16 L128,16 L160,16 L160,48 L192,48 L192,96 L160,96 L160,128 L128,128 L96,160 L48,160 L48,192 L16,192 L16,160 L-16,160 L-16,128 L-48,128 L-48,160 L-96,160 L-96,192 L-128,192 L-160,160 L-160,128 L-192,128 L-192,96 L-160,96 L-160,48 L-192,48 L-192,16 L-160,16 L-160,-16 L-128,-16 L-128,-48 L-160,-48 L-160,-96 L-192,-96 L-192,-128 L-160,-128 Z"/>
<!-- Secondary inner gear ring -->
<circle cx="0" cy="0" r="80" fill="none" stroke="url(#gear-gradient-512)" stroke-width="8"/>
<!-- Inner circle with gradient and shadow -->
<circle cx="0" cy="0" r="64" fill="url(#gear-gradient-512)" stroke="#ffffff" stroke-width="6" filter="url(#inner-shadow-512)"/>
<!-- Center bolt with details -->
<circle cx="0" cy="0" r="24" fill="#ffffff"/>
<circle cx="0" cy="0" r="16" fill="url(#gear-gradient-512)"/>
<circle cx="0" cy="0" r="8" fill="#ffffff"/>
<!-- Bolt holes -->
<circle cx="0" cy="-40" r="6" fill="url(#gear-gradient-512)"/>
<circle cx="35" cy="20" r="6" fill="url(#gear-gradient-512)"/>
<circle cx="-35" cy="20" r="6" fill="url(#gear-gradient-512)"/>
</g>
<!-- Large accent gear -->
<g fill="url(#accent-gradient-512)" opacity="0.9" transform="translate(380,132) scale(6)">
<path d="M-8,-10 L-6,-10 L-6,-12 L-3,-12 L-3,-10 L-1,-10 L-1,-8 L1,-8 L1,-10 L3,-10 L3,-12 L6,-12 L6,-10 L8,-10 L10,-8 L10,-6 L12,-6 L12,-3 L10,-3 L10,-1 L8,-1 L8,1 L10,1 L10,3 L12,3 L12,6 L10,6 L10,8 L8,8 L6,10 L3,10 L3,12 L1,12 L1,10 L-1,10 L-1,8 L-3,8 L-3,10 L-6,10 L-6,12 L-8,12 L-10,10 L-10,8 L-12,8 L-12,6 L-10,6 L-10,3 L-12,3 L-12,1 L-10,1 L-10,-1 L-8,-1 L-8,-3 L-10,-3 L-10,-6 L-12,-6 L-12,-8 L-10,-8 Z"/>
<circle cx="0" cy="0" r="4" fill="#0d6efd"/>
</g>
<!-- Medium accent gear -->
<g fill="url(#accent-gradient-512)" opacity="0.8" transform="translate(132,380) scale(4)">
<path d="M-6,-8 L-4,-8 L-4,-9 L-2,-9 L-2,-8 L0,-8 L0,-6 L2,-6 L2,-8 L4,-8 L4,-9 L6,-9 L6,-8 L8,-8 L9,-6 L9,-4 L10,-4 L10,-2 L9,-2 L9,0 L8,0 L8,2 L9,2 L9,4 L10,4 L10,6 L9,6 L9,8 L8,8 L6,9 L4,9 L4,10 L2,10 L2,9 L0,9 L0,8 L-2,8 L-2,9 L-4,9 L-4,10 L-6,10 L-8,9 L-8,8 L-9,8 L-9,6 L-8,6 L-8,4 L-9,4 L-9,2 L-8,2 L-8,0 L-6,0 L-6,-2 L-8,-2 L-8,-4 L-9,-4 L-9,-6 L-8,-6 Z"/>
<circle cx="0" cy="0" r="3" fill="#0d6efd"/>
</g>
<!-- Small accent gear -->
<g fill="url(#accent-gradient-512)" opacity="0.7" transform="translate(420,350) scale(2.5)">
<path d="M-4,-5 L-3,-5 L-3,-6 L-1.5,-6 L-1.5,-5 L-0.5,-5 L-0.5,-4 L0.5,-4 L0.5,-5 L1.5,-5 L1.5,-6 L3,-6 L3,-5 L4,-5 L5,-4 L5,-3 L6,-3 L6,-1.5 L5,-1.5 L5,-0.5 L4,-0.5 L4,0.5 L5,0.5 L5,1.5 L6,1.5 L6,3 L5,3 L5,4 L4,4 L3,5 L1.5,5 L1.5,6 L0.5,6 L0.5,5 L-0.5,5 L-0.5,4 L-1.5,4 L-1.5,5 L-3,5 L-3,6 L-4,6 L-5,5 L-5,4 L-6,4 L-6,3 L-5,3 L-5,1.5 L-6,1.5 L-6,0.5 L-5,0.5 L-5,-0.5 L-4,-0.5 L-4,-1.5 L-5,-1.5 L-5,-3 L-6,-3 L-6,-4 L-5,-4 Z"/>
<circle cx="0" cy="0" r="2" fill="#0d6efd"/>
</g>
<!-- Decorative elements - screws/bolts -->
<g fill="#ffffff" opacity="0.6">
<circle cx="80" cy="80" r="4"/>
<circle cx="432" cy="80" r="4"/>
<circle cx="80" cy="432" r="4"/>
<circle cx="432" cy="432" r="4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,62 @@
{
"name": "UnitForge",
"short_name": "UnitForge",
"description": "Systemd Unit File Creator - Create, validate, and manage systemd unit files with ease",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0d6efd",
"orientation": "portrait-primary",
"categories": ["productivity", "developer", "utilities"],
"icons": [
{
"src": "/static/img/favicon-16x16.svg",
"sizes": "16x16",
"type": "image/svg+xml"
},
{
"src": "/static/img/favicon.svg",
"sizes": "32x32",
"type": "image/svg+xml"
},
{
"src": "/static/img/icon-192x192.svg",
"sizes": "192x192",
"type": "image/svg+xml"
},
{
"src": "/static/img/icon-512x512.svg",
"sizes": "512x512",
"type": "image/svg+xml",
"purpose": "any maskable"
}
],
"shortcuts": [
{
"name": "Visual Editor",
"short_name": "Editor",
"description": "Create unit files with the visual form editor",
"url": "/editor",
"icons": [
{
"src": "/static/img/icon-192x192.svg",
"sizes": "96x96",
"type": "image/svg+xml"
}
]
},
{
"name": "Templates",
"short_name": "Templates",
"description": "Browse pre-built unit file templates",
"url": "/templates",
"icons": [
{
"src": "/static/img/icon-192x192.svg",
"sizes": "96x96",
"type": "image/svg+xml"
}
]
}
]
}