feat: app logo
192
Projects/kompose/docs/app/components/AppIcon.vue
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: 512 // Default for PWA, can be 16, 32, 192, 512, etc.
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const iconSize = computed(() => props.size)
|
||||||
|
const strokeWidth = computed(() => props.size / 32) // Scales with size
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
:width="iconSize"
|
||||||
|
:height="iconSize"
|
||||||
|
:viewBox="`0 0 ${iconSize} ${iconSize}`"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<!-- Carbon fiber pattern -->
|
||||||
|
<pattern
|
||||||
|
id="carbon"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
:width="iconSize / 25"
|
||||||
|
:height="iconSize / 25"
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<rect :width="iconSize / 25" :height="iconSize / 25" fill="#0a0e27"/>
|
||||||
|
<path
|
||||||
|
:d="`M0,0 L${iconSize/50},${iconSize/50} M${iconSize/50},0 L${iconSize/25},${iconSize/50} M0,${iconSize/50} L${iconSize/50},${iconSize/25}`"
|
||||||
|
stroke="#060815"
|
||||||
|
:stroke-width="strokeWidth / 4"
|
||||||
|
opacity="0.5"
|
||||||
|
/>
|
||||||
|
</pattern>
|
||||||
|
|
||||||
|
<!-- Gradient for depth -->
|
||||||
|
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#1a1d2e;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#0a0e27;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Primary color gradient -->
|
||||||
|
<linearGradient id="primaryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#00DC82;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#00a86b;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow effect -->
|
||||||
|
<filter id="glow">
|
||||||
|
<feGaussianBlur :stdDeviation="strokeWidth" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Background with rounded corners -->
|
||||||
|
<rect
|
||||||
|
:width="iconSize"
|
||||||
|
:height="iconSize"
|
||||||
|
:rx="iconSize / 8"
|
||||||
|
fill="url(#bgGrad)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Carbon texture overlay -->
|
||||||
|
<rect
|
||||||
|
:width="iconSize"
|
||||||
|
:height="iconSize"
|
||||||
|
:rx="iconSize / 8"
|
||||||
|
fill="url(#carbon)"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Stylized "K" letter with geometric design -->
|
||||||
|
<g :transform="`translate(${iconSize * 0.25}, ${iconSize * 0.25})`">
|
||||||
|
<!-- Main vertical line of K -->
|
||||||
|
<line
|
||||||
|
:x1="0"
|
||||||
|
:y1="0"
|
||||||
|
:x2="0"
|
||||||
|
:y2="iconSize * 0.5"
|
||||||
|
stroke="url(#primaryGrad)"
|
||||||
|
:stroke-width="strokeWidth * 2.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
filter="url(#glow)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Upper diagonal of K -->
|
||||||
|
<line
|
||||||
|
:x1="0"
|
||||||
|
:y1="iconSize * 0.25"
|
||||||
|
:x2="iconSize * 0.3"
|
||||||
|
:y2="0"
|
||||||
|
stroke="url(#primaryGrad)"
|
||||||
|
:stroke-width="strokeWidth * 2.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
filter="url(#glow)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Lower diagonal of K -->
|
||||||
|
<line
|
||||||
|
:x1="0"
|
||||||
|
:y1="iconSize * 0.25"
|
||||||
|
:x2="iconSize * 0.3"
|
||||||
|
:y2="iconSize * 0.5"
|
||||||
|
stroke="url(#primaryGrad)"
|
||||||
|
:stroke-width="strokeWidth * 2.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
filter="url(#glow)"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated status dot (bottom right) -->
|
||||||
|
<circle
|
||||||
|
:cx="iconSize * 0.85"
|
||||||
|
:cy="iconSize * 0.85"
|
||||||
|
:r="iconSize * 0.06"
|
||||||
|
fill="#00DC82"
|
||||||
|
opacity="0.9"
|
||||||
|
>
|
||||||
|
<animate
|
||||||
|
attributeName="opacity"
|
||||||
|
values="0.6;1;0.6"
|
||||||
|
dur="2s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
|
<animate
|
||||||
|
attributeName="r"
|
||||||
|
:values="`${iconSize * 0.06};${iconSize * 0.07};${iconSize * 0.06}`"
|
||||||
|
dur="2s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- Glow ring around dot -->
|
||||||
|
<circle
|
||||||
|
:cx="iconSize * 0.85"
|
||||||
|
:cy="iconSize * 0.85"
|
||||||
|
:r="iconSize * 0.09"
|
||||||
|
fill="none"
|
||||||
|
stroke="#00DC82"
|
||||||
|
:stroke-width="strokeWidth / 2"
|
||||||
|
opacity="0.3"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Tech corner accents -->
|
||||||
|
<line
|
||||||
|
:x1="iconSize * 0.08"
|
||||||
|
:y1="iconSize * 0.08"
|
||||||
|
:x2="iconSize * 0.15"
|
||||||
|
:y2="iconSize * 0.08"
|
||||||
|
stroke="#00DC82"
|
||||||
|
:stroke-width="strokeWidth / 2"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
:x1="iconSize * 0.08"
|
||||||
|
:y1="iconSize * 0.08"
|
||||||
|
:x2="iconSize * 0.08"
|
||||||
|
:y2="iconSize * 0.15"
|
||||||
|
stroke="#00DC82"
|
||||||
|
:stroke-width="strokeWidth / 2"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<line
|
||||||
|
:x1="iconSize * 0.92"
|
||||||
|
:y1="iconSize * 0.08"
|
||||||
|
:x2="iconSize * 0.85"
|
||||||
|
:y2="iconSize * 0.08"
|
||||||
|
stroke="#00DC82"
|
||||||
|
:stroke-width="strokeWidth / 2"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
:x1="iconSize * 0.92"
|
||||||
|
:y1="iconSize * 0.08"
|
||||||
|
:x2="iconSize * 0.92"
|
||||||
|
:y2="iconSize * 0.15"
|
||||||
|
stroke="#00DC82"
|
||||||
|
:stroke-width="strokeWidth / 2"
|
||||||
|
opacity="0.4"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
189
Projects/kompose/docs/app/components/AppIconShowcase.vue
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<!--
|
||||||
|
Icon Usage Examples for Favicon & PWA
|
||||||
|
|
||||||
|
This component shows how to generate different sizes of the kompose.sh icon
|
||||||
|
for various use cases: favicon, apple-touch-icon, PWA icons, etc.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import AppIcon from './AppIcon.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="icon-showcase">
|
||||||
|
<h2>kompose.sh Icon Sizes</h2>
|
||||||
|
|
||||||
|
<div class="icon-grid">
|
||||||
|
<!-- Favicon sizes -->
|
||||||
|
<div class="icon-item">
|
||||||
|
<AppIcon :size="16" />
|
||||||
|
<p>16x16 (favicon.ico)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="icon-item">
|
||||||
|
<AppIcon :size="32" />
|
||||||
|
<p>32x32 (favicon-32x32.png)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="icon-item">
|
||||||
|
<AppIcon :size="48" />
|
||||||
|
<p>48x48 (favicon-48x48.png)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Apple Touch Icon -->
|
||||||
|
<div class="icon-item">
|
||||||
|
<AppIcon :size="180" />
|
||||||
|
<p>180x180 (apple-touch-icon.png)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PWA Icons -->
|
||||||
|
<div class="icon-item">
|
||||||
|
<AppIcon :size="192" />
|
||||||
|
<p>192x192 (PWA icon)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="icon-item">
|
||||||
|
<AppIcon :size="512" />
|
||||||
|
<p>512x512 (PWA icon)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- HTML Head Examples -->
|
||||||
|
<div class="code-section">
|
||||||
|
<h3>HTML Head Implementation</h3>
|
||||||
|
<pre><code><!-- Favicon -->
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
|
||||||
|
<!-- Apple Touch Icon -->
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
|
|
||||||
|
<!-- PWA Manifest -->
|
||||||
|
<link rel="manifest" href="/site.webmanifest"></code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Manifest.json Example -->
|
||||||
|
<div class="code-section">
|
||||||
|
<h3>site.webmanifest</h3>
|
||||||
|
<pre><code>{
|
||||||
|
"name": "kompose.sh",
|
||||||
|
"short_name": "kompose",
|
||||||
|
"description": "Component composition framework",
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#0a0e27",
|
||||||
|
"theme_color": "#00DC82",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/icon-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/icon-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Export Instructions -->
|
||||||
|
<div class="instructions">
|
||||||
|
<h3>How to Export Icons</h3>
|
||||||
|
<ol>
|
||||||
|
<li>Open the AppIcon.vue component in your browser</li>
|
||||||
|
<li>Right-click on each icon size and "Save image as..."</li>
|
||||||
|
<li>Or use a screenshot tool to capture at exact dimensions</li>
|
||||||
|
<li>Or render the SVG and convert to PNG using a tool like:
|
||||||
|
<ul>
|
||||||
|
<li>Inkscape (CLI: inkscape --export-png=output.png --export-width=512 input.svg)</li>
|
||||||
|
<li>ImageMagick (convert -background none input.svg -resize 512x512 output.png)</li>
|
||||||
|
<li>Online tools like CloudConvert</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.icon-showcase {
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
color: var(--ui-primary, #00DC82);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||||
|
gap: 2rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid rgba(0, 220, 130, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #888;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-section {
|
||||||
|
margin: 2rem 0;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
border: 1px solid rgba(0, 220, 130, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #00DC82;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instructions {
|
||||||
|
background: rgba(0, 220, 130, 0.1);
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid rgba(0, 220, 130, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.instructions ol, .instructions ul {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instructions li {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
Projects/kompose/docs/public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
Projects/kompose/docs/public/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
3
Projects/kompose/docs/public/favicon.svg
Normal file
|
After Width: | Height: | Size: 120 KiB |
BIN
Projects/kompose/docs/public/web-app-manifest-192x192.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
Projects/kompose/docs/public/web-app-manifest-512x512.png
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
Projects/kompose/icon.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
50
Projects/kompose/icon.svg
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<pattern id="carbon192" x="0" y="0" width="7.68" height="7.68" patternUnits="userSpaceOnUse">
|
||||||
|
<rect width="7.68" height="7.68" fill="#0a0e27"></rect>
|
||||||
|
<path d="M0,0 L3.84,3.84 M3.84,0 L7.68,3.84 M0,3.84 L3.84,7.68" stroke="#060815" stroke-width="1.5" opacity="0.5"></path>
|
||||||
|
</pattern>
|
||||||
|
|
||||||
|
<linearGradient id="bgGrad192" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#1a1d2e;stop-opacity:1"></stop>
|
||||||
|
<stop offset="100%" style="stop-color:#0a0e27;stop-opacity:1"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="primaryGrad192" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#00DC82;stop-opacity:1"></stop>
|
||||||
|
<stop offset="100%" style="stop-color:#00a86b;stop-opacity:1"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<filter id="glow192">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="coloredBlur"></feGaussianBlur>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"></feMergeNode>
|
||||||
|
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Background -->
|
||||||
|
<rect width="192" height="192" rx="24" fill="url(#bgGrad192)"></rect>
|
||||||
|
<rect width="192" height="192" rx="24" fill="url(#carbon192)" opacity="0.4"></rect>
|
||||||
|
|
||||||
|
<!-- Stylized K -->
|
||||||
|
<g transform="translate(48, 48)">
|
||||||
|
<line x1="0" y1="0" x2="0" y2="96" stroke="url(#primaryGrad192)" stroke-width="15" stroke-linecap="round" filter="url(#glow192)"></line>
|
||||||
|
<line x1="0" y1="48" x2="57.599999999999994" y2="0" stroke="url(#primaryGrad192)" stroke-width="15" stroke-linecap="round" filter="url(#glow192)"></line>
|
||||||
|
<line x1="0" y1="48" x2="57.599999999999994" y2="96" stroke="url(#primaryGrad192)" stroke-width="15" stroke-linecap="round" filter="url(#glow192)"></line>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated status dot -->
|
||||||
|
<circle cx="163.2" cy="163.2" r="11.52" fill="#00DC82" opacity="0.9">
|
||||||
|
<animate attributeName="opacity" values="0.6;1;0.6" dur="2s" repeatCount="indefinite"></animate>
|
||||||
|
<animate attributeName="r" values="11.52;13.440000000000001;11.52" dur="2s" repeatCount="indefinite"></animate>
|
||||||
|
</circle>
|
||||||
|
<circle cx="163.2" cy="163.2" r="17.28" fill="none" stroke="#00DC82" stroke-width="3" opacity="0.3"></circle>
|
||||||
|
|
||||||
|
<!-- Tech corners -->
|
||||||
|
<line x1="15.36" y1="15.36" x2="28.799999999999997" y2="15.36" stroke="#00DC82" stroke-width="3" opacity="0.4"></line>
|
||||||
|
<line x1="15.36" y1="15.36" x2="15.36" y2="28.799999999999997" stroke="#00DC82" stroke-width="3" opacity="0.4"></line>
|
||||||
|
<line x1="176.64000000000001" y1="15.36" x2="163.2" y2="15.36" stroke="#00DC82" stroke-width="3" opacity="0.4"></line>
|
||||||
|
<line x1="176.64000000000001" y1="15.36" x2="176.64000000000001" y2="28.799999999999997" stroke="#00DC82" stroke-width="3" opacity="0.4"></line>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |