feat: refactor favicon and logo assets

This commit is contained in:
Bohdan Triapitsyn
2025-12-21 22:59:06 +02:00
parent 7699aab123
commit 4ab4616dea
31 changed files with 1088 additions and 195 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# OpenChamber
# <picture><source media="(prefers-color-scheme: dark)" srcset="docs/references/badges/openchamber-logo-dark.svg"><img src="docs/references/badges/openchamber-logo-light.svg" width="32" height="32" align="absmiddle" /></picture> OpenChamber
[![GitHub stars](https://img.shields.io/github/stars/btriapitsyn/openchamber?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iI2YxZWNlYyIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGQ9Ik0yMjkuMDYsMTA4Ljc5bC00OC43LDQyLDE0Ljg4LDYyLjc5YTguNCw4LjQsMCwwLDEtMTIuNTIsOS4xN0wxMjgsMTg5LjA5LDczLjI4LDIyMi43NGE4LjQsOC40LDAsMCwxLTEyLjUyLTkuMTdsMTQuODgtNjIuNzktNDguNy00MkE4LjQ2LDguNDYsMCwwLDEsMzEuNzMsOTRMOTUuNjQsODguOGwyNC42Mi01OS42YTguMzYsOC4zNiwwLDAsMSwxNS40OCwwbDI0LjYyLDU5LjZMMjI0LjI3LDk0QTguNDYsOC40NiwwLDAsMSwyMjkuMDYsMTA4Ljc5WiIgb3BhY2l0eT0iMC4yIj48L3BhdGg%2BPHBhdGggZD0iTTIzOS4xOCw5Ny4yNkExNi4zOCwxNi4zOCwwLDAsMCwyMjQuOTIsODZsLTU5LTQuNzZMMTQzLjE0LDI2LjE1YTE2LjM2LDE2LjM2LDAsMCwwLTMwLjI3LDBMOTAuMTEsODEuMjMsMzEuMDgsODZhMTYuNDYsMTYuNDYsMCwwLDAtOS4zNywyOC44Nmw0NSwzOC44M0w1MywyMTEuNzVhMTYuMzgsMTYuMzgsMCwwLDAsMjQuNSwxNy44MkwxMjgsMTk4LjQ5bDUwLjUzLDMxLjA4QTE2LjQsMTYuNCwwLDAsMCwyMDMsMjExLjc1bC0xMy43Ni01OC4wNyw0NS0zOC44M0ExNi40MywxNi40MywwLDAsMCwyMzkuMTgsOTcuMjZabS0xNS4zNCw1LjQ3LTQ4LjcsNDJhOCw4LDAsMCwwLTIuNTYsNy45MWwxNC44OCw2Mi44YS4zNy4zNywwLDAsMS0uMTcuNDhjLS4xOC4xNC0uMjMuMTEtLjM4LDBsLTU0LjcyLTMzLjY1YTgsOCwwLDAsMC04LjM4LDBMNjkuMDksMjE1Ljk0Yy0uMTUuMDktLjE5LjEyLS4zOCwwYS4zNy4zNywwLDAsMS0uMTctLjQ4bDE0Ljg4LTYyLjhhOCw4LDAsMCwwLTIuNTYtNy45MWwtNDguNy00MmMtLjEyLS4xLS4yMy0uMTktLjEzLS41cy4xOC0uMjcuMzMtLjI5bDYzLjkyLTUuMTZBOCw4LDAsMCwwLDEwMyw5MS44NmwyNC42Mi01OS42MWMuMDgtLjE3LjExLS4yNS4zNS0uMjVzLjI3LjA4LjM1LjI1TDE1Myw5MS44NmE4LDgsMCwwLDAsNi43NSw0LjkybDYzLjkyLDUuMTZjLjE1LDAsLjI0LDAsLjMzLjI5UzIyNCwxMDIuNjMsMjIzLjg0LDEwMi43M1oiPjwvcGF0aD48L3N2Zz4%3D&logoColor=FFFCF0&labelColor=100F0F&color=66800B)](https://github.com/btriapitsyn/openchamber/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/btriapitsyn/openchamber?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iI2YxZWNlYyIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGQ9Ik04OCw2NEEyNCwyNCwwLDEsMSw2NCw0MCwyNCwyNCwwLDAsMSw4OCw2NFpNMTkyLDQwYTI0LDI0LDAsMSwwLDI0LDI0QTI0LDI0LDAsMCwwLDE5Miw0MFoiIG9wYWNpdHk9IjAuMiI%2BPC9wYXRoPjxwYXRoIGQ9Ik0yMjQsNjRhMzIsMzIsMCwxLDAtNDAsMzF2MTdhOCw4LDAsMCwxLTgsOEg4MGE4LDgsMCwwLDEtOC04Vjk1YTMyLDMyLDAsMSwwLTE2LDB2MTdhMjQsMjQsMCwwLDAsMjQsMjRoNDB2MjVhMzIsMzIsMCwxLDAsMTYsMFYxMzZoNDBhMjQsMjQsMCwwLDAsMjQtMjRWOTVBMzIuMDYsMzIuMDYsMCwwLDAsMjI0LDY0Wk00OCw2NEExNiwxNiwwLDEsMSw2NCw4MCwxNiwxNiwwLDAsMSw0OCw2NFptOTYsMTI4YTE2LDE2LDAsMSwxLTE2LTE2QTE2LDE2LDAsMCwxLDE0NCwxOTJaTTE5Miw4MGExNiwxNiwwLDEsMSwxNi0xNkExNiwxNiwwLDAsMSwxOTIsODBaIj48L3BhdGg%2BPC9zdmc%2B&logoColor=FFFCF0&labelColor=100F0F&color=BC5215)](https://github.com/btriapitsyn/openchamber/network/members)
@@ -0,0 +1,47 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Left face -->
<path d="M50 50 L8.432 26 L8.432 74 L50 98 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="2" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M50 50 L39.608 44 L39.608 56 L50 62 Z" fill="white" fill-opacity="0.07"/>
<path d="M39.608 44 L29.216 38 L29.216 50 L39.608 56 Z" fill="white" fill-opacity="0.16"/>
<path d="M29.216 38 L18.824 32 L18.824 44 L29.216 50 Z" fill="white" fill-opacity="0.05"/>
<path d="M18.824 32 L8.432 26 L8.432 38 L18.824 44 Z" fill="white" fill-opacity="0.19"/>
<path d="M50 62 L39.608 56 L39.608 68 L50 74 Z" fill="white" fill-opacity="0.12"/>
<path d="M39.608 56 L29.216 50 L29.216 62 L39.608 68 Z" fill="white" fill-opacity="0.04"/>
<path d="M29.216 50 L18.824 44 L18.824 56 L29.216 62 Z" fill="white" fill-opacity="0.18"/>
<path d="M18.824 44 L8.432 38 L8.432 50 L18.824 56 Z" fill="white" fill-opacity="0.09"/>
<path d="M50 74 L39.608 68 L39.608 80 L50 86 Z" fill="white" fill-opacity="0.14"/>
<path d="M39.608 68 L29.216 62 L29.216 74 L39.608 80 Z" fill="white" fill-opacity="0.11"/>
<path d="M29.216 62 L18.824 56 L18.824 68 L29.216 74 Z" fill="white" fill-opacity="0.16"/>
<path d="M18.824 56 L8.432 50 L8.432 62 L18.824 68 Z" fill="white" fill-opacity="0.05"/>
<path d="M50 86 L39.608 80 L39.608 92 L50 98 Z" fill="white" fill-opacity="0.19"/>
<path d="M39.608 80 L29.216 74 L29.216 86 L39.608 92 Z" fill="white" fill-opacity="0.07"/>
<path d="M29.216 74 L18.824 68 L18.824 80 L29.216 86 Z" fill="white" fill-opacity="0.12"/>
<path d="M18.824 68 L8.432 62 L8.432 74 L18.824 80 Z" fill="white" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M50 50 L91.568 26 L91.568 74 L50 98 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="2" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M50 50 L60.392 44 L60.392 56 L50 62 Z" fill="white" fill-opacity="0.11"/>
<path d="M60.392 44 L70.784 38 L70.784 50 L60.392 56 Z" fill="white" fill-opacity="0.05"/>
<path d="M70.784 38 L81.176 32 L81.176 44 L70.784 50 Z" fill="white" fill-opacity="0.16"/>
<path d="M81.176 32 L91.568 26 L91.568 38 L81.176 44 Z" fill="white" fill-opacity="0.09"/>
<path d="M50 62 L60.392 56 L60.392 68 L50 74 Z" fill="white" fill-opacity="0.18"/>
<path d="M60.392 56 L70.784 50 L70.784 62 L60.392 68 Z" fill="white" fill-opacity="0.12"/>
<path d="M70.784 50 L81.176 44 L81.176 56 L70.784 62 Z" fill="white" fill-opacity="0.04"/>
<path d="M81.176 44 L91.568 38 L91.568 50 L81.176 56 Z" fill="white" fill-opacity="0.14"/>
<path d="M50 74 L60.392 68 L60.392 80 L50 86 Z" fill="white" fill-opacity="0.07"/>
<path d="M60.392 68 L70.784 62 L70.784 74 L60.392 80 Z" fill="white" fill-opacity="0.19"/>
<path d="M70.784 62 L81.176 56 L81.176 68 L70.784 74 Z" fill="white" fill-opacity="0.11"/>
<path d="M81.176 56 L91.568 50 L91.568 62 L81.176 68 Z" fill="white" fill-opacity="0.05"/>
<path d="M50 86 L60.392 80 L60.392 92 L50 98 Z" fill="white" fill-opacity="0.16"/>
<path d="M60.392 80 L70.784 74 L70.784 86 L60.392 92 Z" fill="white" fill-opacity="0.09"/>
<path d="M70.784 74 L81.176 68 L81.176 80 L70.784 86 Z" fill="white" fill-opacity="0.14"/>
<path d="M81.176 68 L91.568 62 L91.568 74 L81.176 80 Z" fill="white" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M50 2 L8.432 26 L50 50 L91.568 26 Z" fill="none" stroke="white" stroke-width="2" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 50, 26) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="white"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="white" fill-opacity="0.4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@@ -0,0 +1,47 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Left face -->
<path d="M50 50 L8.432 26 L8.432 74 L50 98 Z" fill="black" fill-opacity="0.15" stroke="black" stroke-width="2" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M50 50 L39.608 44 L39.608 56 L50 62 Z" fill="black" fill-opacity="0.07"/>
<path d="M39.608 44 L29.216 38 L29.216 50 L39.608 56 Z" fill="black" fill-opacity="0.16"/>
<path d="M29.216 38 L18.824 32 L18.824 44 L29.216 50 Z" fill="black" fill-opacity="0.05"/>
<path d="M18.824 32 L8.432 26 L8.432 38 L18.824 44 Z" fill="black" fill-opacity="0.19"/>
<path d="M50 62 L39.608 56 L39.608 68 L50 74 Z" fill="black" fill-opacity="0.12"/>
<path d="M39.608 56 L29.216 50 L29.216 62 L39.608 68 Z" fill="black" fill-opacity="0.04"/>
<path d="M29.216 50 L18.824 44 L18.824 56 L29.216 62 Z" fill="black" fill-opacity="0.18"/>
<path d="M18.824 44 L8.432 38 L8.432 50 L18.824 56 Z" fill="black" fill-opacity="0.09"/>
<path d="M50 74 L39.608 68 L39.608 80 L50 86 Z" fill="black" fill-opacity="0.14"/>
<path d="M39.608 68 L29.216 62 L29.216 74 L39.608 80 Z" fill="black" fill-opacity="0.11"/>
<path d="M29.216 62 L18.824 56 L18.824 68 L29.216 74 Z" fill="black" fill-opacity="0.16"/>
<path d="M18.824 56 L8.432 50 L8.432 62 L18.824 68 Z" fill="black" fill-opacity="0.05"/>
<path d="M50 86 L39.608 80 L39.608 92 L50 98 Z" fill="black" fill-opacity="0.19"/>
<path d="M39.608 80 L29.216 74 L29.216 86 L39.608 92 Z" fill="black" fill-opacity="0.07"/>
<path d="M29.216 74 L18.824 68 L18.824 80 L29.216 86 Z" fill="black" fill-opacity="0.12"/>
<path d="M18.824 68 L8.432 62 L8.432 74 L18.824 80 Z" fill="black" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M50 50 L91.568 26 L91.568 74 L50 98 Z" fill="black" fill-opacity="0.15" stroke="black" stroke-width="2" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M50 50 L60.392 44 L60.392 56 L50 62 Z" fill="black" fill-opacity="0.11"/>
<path d="M60.392 44 L70.784 38 L70.784 50 L60.392 56 Z" fill="black" fill-opacity="0.05"/>
<path d="M70.784 38 L81.176 32 L81.176 44 L70.784 50 Z" fill="black" fill-opacity="0.16"/>
<path d="M81.176 32 L91.568 26 L91.568 38 L81.176 44 Z" fill="black" fill-opacity="0.09"/>
<path d="M50 62 L60.392 56 L60.392 68 L50 74 Z" fill="black" fill-opacity="0.18"/>
<path d="M60.392 56 L70.784 50 L70.784 62 L60.392 68 Z" fill="black" fill-opacity="0.12"/>
<path d="M70.784 50 L81.176 44 L81.176 56 L70.784 62 Z" fill="black" fill-opacity="0.04"/>
<path d="M81.176 44 L91.568 38 L91.568 50 L81.176 56 Z" fill="black" fill-opacity="0.14"/>
<path d="M50 74 L60.392 68 L60.392 80 L50 86 Z" fill="black" fill-opacity="0.07"/>
<path d="M60.392 68 L70.784 62 L70.784 74 L60.392 80 Z" fill="black" fill-opacity="0.19"/>
<path d="M70.784 62 L81.176 56 L81.176 68 L70.784 74 Z" fill="black" fill-opacity="0.11"/>
<path d="M81.176 56 L91.568 50 L91.568 62 L81.176 68 Z" fill="black" fill-opacity="0.05"/>
<path d="M50 86 L60.392 80 L60.392 92 L50 98 Z" fill="black" fill-opacity="0.16"/>
<path d="M60.392 80 L70.784 74 L70.784 86 L60.392 92 Z" fill="black" fill-opacity="0.09"/>
<path d="M70.784 74 L81.176 68 L81.176 80 L70.784 86 Z" fill="black" fill-opacity="0.14"/>
<path d="M81.176 68 L91.568 62 L91.568 74 L81.176 80 Z" fill="black" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M50 2 L8.432 26 L50 50 L91.568 26 Z" fill="none" stroke="black" stroke-width="2" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 50, 26) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="black"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="black" fill-opacity="0.4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

+65 -19
View File
@@ -54,39 +54,85 @@
font-family: 'IBM Plex Mono', monospace;
background-color: transparent;
}
/* Theme-aware text colors for loading screen */
html.dark body {
color: #CECDC3; /* Flexoki dark foreground */
/* Theme-aware colors for loading screen */
html.dark {
--splash-stroke: white;
--splash-face-fill: rgba(255, 255, 255, 0.15);
--splash-cell-fill: rgba(255, 255, 255, 0.35);
--splash-logo-fill: white;
}
html.light body {
color: #100F0F; /* Flexoki light foreground */
html.light {
--splash-stroke: black;
--splash-face-fill: rgba(0, 0, 0, 0.15);
--splash-cell-fill: rgba(0, 0, 0, 0.4);
--splash-logo-fill: black;
}
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 2.5rem;
font-weight: 600;
letter-spacing: 0.05em;
}
.loading span {
display: inline-block;
opacity: 0;
transform: translateY(8px);
animation: slideUp 0.5s ease-out forwards;
@keyframes logo-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
@keyframes slideUp {
to {
opacity: 1;
transform: translateY(0);
}
.logo-pulse {
animation: logo-pulse 3s ease-in-out infinite;
}
</style>
</head>
<body class="h-full">
<div id="root" class="h-full">
<div class="loading"><span style="animation-delay:0.1s">O</span><span style="animation-delay:0.15s">p</span><span style="animation-delay:0.2s">e</span><span style="animation-delay:0.25s">n</span><span style="animation-delay:0.3s">C</span><span style="animation-delay:0.35s">h</span><span style="animation-delay:0.4s">a</span><span style="animation-delay:0.45s">m</span><span style="animation-delay:0.5s">b</span><span style="animation-delay:0.55s">e</span><span style="animation-delay:0.6s">r</span></div>
<div class="loading">
<svg width="180" height="180" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OpenChamber loading">
<!-- Left face with stroke -->
<path d="M50 50 L8.432 26 L8.432 74 L50 98 Z" fill="var(--splash-face-fill)" stroke="var(--splash-stroke)" stroke-width="2" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M50 50 L39.608 44 L39.608 56 L50 62 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<path d="M39.608 44 L29.216 38 L29.216 50 L39.608 56 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M29.216 38 L18.824 32 L18.824 44 L29.216 50 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M18.824 32 L8.432 26 L8.432 38 L18.824 44 Z" fill="var(--splash-cell-fill)" opacity="0.55"/>
<path d="M50 62 L39.608 56 L39.608 68 L50 74 Z" fill="var(--splash-cell-fill)" opacity="0.35"/>
<path d="M39.608 56 L29.216 50 L29.216 62 L39.608 68 Z" fill="var(--splash-cell-fill)" opacity="0.1"/>
<path d="M29.216 50 L18.824 44 L18.824 56 L29.216 62 Z" fill="var(--splash-cell-fill)" opacity="0.5"/>
<path d="M18.824 44 L8.432 38 L8.432 50 L18.824 56 Z" fill="var(--splash-cell-fill)" opacity="0.25"/>
<path d="M50 74 L39.608 68 L39.608 80 L50 86 Z" fill="var(--splash-cell-fill)" opacity="0.4"/>
<path d="M39.608 68 L29.216 62 L29.216 74 L39.608 80 Z" fill="var(--splash-cell-fill)" opacity="0.3"/>
<path d="M29.216 62 L18.824 56 L18.824 68 L29.216 74 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M18.824 56 L8.432 50 L8.432 62 L18.824 68 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M50 86 L39.608 80 L39.608 92 L50 98 Z" fill="var(--splash-cell-fill)" opacity="0.55"/>
<path d="M39.608 80 L29.216 74 L29.216 86 L39.608 92 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<path d="M29.216 74 L18.824 68 L18.824 80 L29.216 86 Z" fill="var(--splash-cell-fill)" opacity="0.35"/>
<path d="M18.824 68 L8.432 62 L8.432 74 L18.824 80 Z" fill="var(--splash-cell-fill)" opacity="0.1"/>
<!-- Right face with stroke -->
<path d="M50 50 L91.568 26 L91.568 74 L50 98 Z" fill="var(--splash-face-fill)" stroke="var(--splash-stroke)" stroke-width="2" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M50 50 L60.392 44 L60.392 56 L50 62 Z" fill="var(--splash-cell-fill)" opacity="0.3"/>
<path d="M60.392 44 L70.784 38 L70.784 50 L60.392 56 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M70.784 38 L81.176 32 L81.176 44 L70.784 50 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M81.176 32 L91.568 26 L91.568 38 L81.176 44 Z" fill="var(--splash-cell-fill)" opacity="0.25"/>
<path d="M50 62 L60.392 56 L60.392 68 L50 74 Z" fill="var(--splash-cell-fill)" opacity="0.5"/>
<path d="M60.392 56 L70.784 50 L70.784 62 L60.392 68 Z" fill="var(--splash-cell-fill)" opacity="0.35"/>
<path d="M70.784 50 L81.176 44 L81.176 56 L70.784 62 Z" fill="var(--splash-cell-fill)" opacity="0.1"/>
<path d="M81.176 44 L91.568 38 L91.568 50 L81.176 56 Z" fill="var(--splash-cell-fill)" opacity="0.4"/>
<path d="M50 74 L60.392 68 L60.392 80 L50 86 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<path d="M60.392 68 L70.784 62 L70.784 74 L60.392 80 Z" fill="var(--splash-cell-fill)" opacity="0.55"/>
<path d="M70.784 62 L81.176 56 L81.176 68 L70.784 74 Z" fill="var(--splash-cell-fill)" opacity="0.3"/>
<path d="M81.176 56 L91.568 50 L91.568 62 L81.176 68 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M50 86 L60.392 80 L60.392 92 L50 98 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M60.392 80 L70.784 74 L70.784 86 L60.392 92 Z" fill="var(--splash-cell-fill)" opacity="0.25"/>
<path d="M70.784 74 L81.176 68 L81.176 80 L70.784 86 Z" fill="var(--splash-cell-fill)" opacity="0.4"/>
<path d="M81.176 68 L91.568 62 L91.568 74 L81.176 80 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<!-- Top face - open -->
<path d="M50 2 L8.432 26 L50 50 L91.568 26 Z" fill="none" stroke="var(--splash-stroke)" stroke-width="2" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g class="logo-pulse" transform="matrix(0.866, 0.5, -0.866, 0.5, 50, 26) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="var(--splash-logo-fill)"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="var(--splash-logo-fill)" fill-opacity="0.4"/>
</g>
</svg>
</div>
</div>
<script type="module" src="/src/main.tsx"></script>
</body>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 62 KiB

+67 -35
View File
@@ -1,35 +1,67 @@
<?xml version='1.0' encoding='utf-8'?>
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">
<ns0:defs>
<ns0:filter id="iconShadow" x="-50%" y="-50%" width="200%" height="200%">
<ns0:feDropShadow dx="0" dy="12" stdDeviation="14" flood-opacity="0.5" flood-color="#000000" />
</ns0:filter>
<ns0:filter id="glyphShadow" x="-50%" y="-50%" width="200%" height="200%">
<ns0:feDropShadow dx="2" dy="4" stdDeviation="6" flood-opacity="0.28" flood-color="#000000" />
</ns0:filter>
<ns0:linearGradient id="bgGradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="0" y2="1">
<ns0:stop offset="0%" stop-color="#151313" />
<ns0:stop offset="100%" stop-color="#151313" />
</ns0:linearGradient>
<ns0:linearGradient id="glyphGradient" x1="0" y1="0" x2="0" y2="1">
<ns0:stop offset="0%" stop-color="#F8F8F8" />
<ns0:stop offset="55%" stop-color="#DAD6D0" />
<ns0:stop offset="100%" stop-color="#BAB4AF" />
</ns0:linearGradient>
<ns0:linearGradient id="glyphStrokeGradient" x1="0" y1="0" x2="0" y2="1">
<ns0:stop offset="0%" stop-color="#FFFFFF" stop-opacity="0.08" />
<ns0:stop offset="45%" stop-color="#000000" stop-opacity="0.15" />
<ns0:stop offset="100%" stop-color="#000000" stop-opacity="0.2" />
</ns0:linearGradient>
</ns0:defs>
<ns0:g transform="translate(100, 100)">
<ns0:rect x="0" y="0" width="824" height="824" rx="185" ry="185" filter="url(#iconShadow)" fill="url(#bgGradient)" />
<ns0:g transform="translate(412, 412) scale(8.15) translate(-35, -35.5)" filter="url(#glyphShadow)">
<ns0:rect x="8.75" y="31.0" width="17.5" height="20.5" fill="#4B4646" />
<ns0:path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="url(#glyphGradient)" stroke="url(#glyphStrokeGradient)" stroke-width="1.1" stroke-linejoin="round" />
<ns0:path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="url(#glyphGradient)" stroke="url(#glyphStrokeGradient)" stroke-width="1.1" stroke-linejoin="round" />
</ns0:g>
</ns0:g>
</ns0:svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1024" height="1024" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="iconShadow" x="-50%" y="-50%" width="200%" height="200%">
<feDropShadow dx="0" dy="12" stdDeviation="14" flood-opacity="0.5" flood-color="#000000"/>
</filter>
<linearGradient id="bgGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#303030"/>
<stop offset="100%" stop-color="#141414"/>
</linearGradient>
</defs>
<!-- Icon with Apple standard padding (100px on each side) -->
<g transform="translate(100, 100)">
<!-- Background rounded square - 824x824 (Apple standard) - dark gradient -->
<rect x="0" y="0" width="824" height="824" rx="185" ry="185" fill="url(#bgGradient)" filter="url(#iconShadow)"/>
<!-- OpenChamber logo centered - larger scale (6.5 instead of 5) -->
<g transform="translate(412, 412) scale(6.5)">
<!-- Left face -->
<path d="M0 0 L-41.568 -24 L-41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M0 0 L-10.392 -6 L-10.392 6 L0 12 Z" fill="white" fill-opacity="0.07"/>
<path d="M-10.392 -6 L-20.784 -12 L-20.784 0 L-10.392 6 Z" fill="white" fill-opacity="0.16"/>
<path d="M-20.784 -12 L-31.176 -18 L-31.176 -6 L-20.784 0 Z" fill="white" fill-opacity="0.05"/>
<path d="M-31.176 -18 L-41.568 -24 L-41.568 -12 L-31.176 -6 Z" fill="white" fill-opacity="0.19"/>
<path d="M0 12 L-10.392 6 L-10.392 18 L0 24 Z" fill="white" fill-opacity="0.12"/>
<path d="M-10.392 6 L-20.784 0 L-20.784 12 L-10.392 18 Z" fill="white" fill-opacity="0.04"/>
<path d="M-20.784 0 L-31.176 -6 L-31.176 6 L-20.784 12 Z" fill="white" fill-opacity="0.18"/>
<path d="M-31.176 -6 L-41.568 -12 L-41.568 0 L-31.176 6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 24 L-10.392 18 L-10.392 30 L0 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M-10.392 18 L-20.784 12 L-20.784 24 L-10.392 30 Z" fill="white" fill-opacity="0.11"/>
<path d="M-20.784 12 L-31.176 6 L-31.176 18 L-20.784 24 Z" fill="white" fill-opacity="0.16"/>
<path d="M-31.176 6 L-41.568 0 L-41.568 12 L-31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L-10.392 30 L-10.392 42 L0 48 Z" fill="white" fill-opacity="0.19"/>
<path d="M-10.392 30 L-20.784 24 L-20.784 36 L-10.392 42 Z" fill="white" fill-opacity="0.07"/>
<path d="M-20.784 24 L-31.176 18 L-31.176 30 L-20.784 36 Z" fill="white" fill-opacity="0.12"/>
<path d="M-31.176 18 L-41.568 12 L-41.568 24 L-31.176 30 Z" fill="white" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M0 0 L41.568 -24 L41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M0 0 L10.392 -6 L10.392 6 L0 12 Z" fill="white" fill-opacity="0.11"/>
<path d="M10.392 -6 L20.784 -12 L20.784 0 L10.392 6 Z" fill="white" fill-opacity="0.05"/>
<path d="M20.784 -12 L31.176 -18 L31.176 -6 L20.784 0 Z" fill="white" fill-opacity="0.16"/>
<path d="M31.176 -18 L41.568 -24 L41.568 -12 L31.176 -6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 12 L10.392 6 L10.392 18 L0 24 Z" fill="white" fill-opacity="0.18"/>
<path d="M10.392 6 L20.784 0 L20.784 12 L10.392 18 Z" fill="white" fill-opacity="0.12"/>
<path d="M20.784 0 L31.176 -6 L31.176 6 L20.784 12 Z" fill="white" fill-opacity="0.04"/>
<path d="M31.176 -6 L41.568 -12 L41.568 0 L31.176 6 Z" fill="white" fill-opacity="0.14"/>
<path d="M0 24 L10.392 18 L10.392 30 L0 36 Z" fill="white" fill-opacity="0.07"/>
<path d="M10.392 18 L20.784 12 L20.784 24 L10.392 30 Z" fill="white" fill-opacity="0.19"/>
<path d="M20.784 12 L31.176 6 L31.176 18 L20.784 24 Z" fill="white" fill-opacity="0.11"/>
<path d="M31.176 6 L41.568 0 L41.568 12 L31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L10.392 30 L10.392 42 L0 48 Z" fill="white" fill-opacity="0.16"/>
<path d="M10.392 30 L20.784 24 L20.784 36 L10.392 42 Z" fill="white" fill-opacity="0.09"/>
<path d="M20.784 24 L31.176 18 L31.176 30 L20.784 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M31.176 18 L41.568 12 L41.568 24 L31.176 30 Z" fill="white" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M0 -48 L-41.568 -24 L0 0 L41.568 -24 Z" fill="none" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 0, -24) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="white"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="white" fill-opacity="0.4"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 62 KiB

@@ -4,7 +4,7 @@ import { RiArrowDownLine } from '@remixicon/react';
import { ChatInput } from './ChatInput';
import { useSessionStore } from '@/stores/useSessionStore';
import { Skeleton } from '@/components/ui/skeleton';
import { OpenChamberLogo } from '@/components/ui/OpenChamberLogo';
import ChatEmptyState from './ChatEmptyState';
import MessageList from './MessageList';
import { ScrollShadow } from '@/components/ui/ScrollShadow';
import { useChatScrollManager } from '@/hooks/useChatScrollManager';
@@ -151,9 +151,7 @@ export const ChatContainer: React.FC = () => {
className="flex flex-col h-full bg-background"
style={isMobile ? { paddingBottom: 'var(--oc-keyboard-inset, 0px)' } : undefined}
>
<div className="flex-1 flex items-center justify-center">
<OpenChamberLogo width={140} height={140} className="opacity-20" isAnimated />
</div>
<ChatEmptyState />
</div>
);
}
@@ -165,7 +163,7 @@ export const ChatContainer: React.FC = () => {
style={isMobile ? { paddingBottom: 'var(--oc-keyboard-inset, 0px)' } : undefined}
>
<div className="flex-1 flex items-center justify-center">
<OpenChamberLogo width={140} height={140} className="opacity-20" isAnimated />
<ChatEmptyState />
</div>
<div className="relative bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 z-10">
<ChatInput scrollToBottom={scrollToBottom} />
@@ -212,7 +210,7 @@ export const ChatContainer: React.FC = () => {
style={isMobile ? { paddingBottom: 'var(--oc-keyboard-inset, 0px)' } : undefined}
>
<div className="flex-1 flex items-center justify-center">
<OpenChamberLogo width={140} height={140} className="opacity-20" isAnimated />
<ChatEmptyState />
</div>
<div className="relative bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 z-10">
<ChatInput scrollToBottom={scrollToBottom} />
@@ -1,11 +1,53 @@
import React from 'react';
import { OpenChamberLogo } from '@/components/ui/OpenChamberLogo';
import { TextLoop } from '@/components/ui/TextLoop';
import { useOptionalThemeSystem } from '@/contexts/useThemeSystem';
const phrases = [
"Fix the failing tests",
"Refactor this to be more readable",
"Add form validation",
"Optimize this function",
"Write tests for this",
"Explain how this works",
"Add a new feature",
"Help me debug this",
"Review my code",
"Simplify this logic",
"Add error handling",
"Create a new component",
"Update the documentation",
"Find the bug here",
"Improve performance",
"Add type definitions",
];
const ChatEmptyState: React.FC = () => {
const themeContext = useOptionalThemeSystem();
let isDark = true;
if (themeContext) {
isDark = themeContext.currentTheme.metadata.variant !== 'light';
} else if (typeof window !== 'undefined') {
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
// Same colors as face fill in OpenChamberLogo, but higher opacity for text readability
const textColor = isDark ? 'rgba(255,255,255,0.4)' : 'rgba(0,0,0,0.4)';
return (
<div className="flex items-center justify-center min-h-full w-full">
<div className="flex flex-col items-center justify-center min-h-full w-full gap-6">
<OpenChamberLogo width={140} height={140} className="opacity-20" isAnimated />
<TextLoop
className="text-body-md"
interval={4}
transition={{ duration: 0.5 }}
>
{phrases.map((phrase) => (
<span key={phrase} style={{ color: textColor }}>"{phrase}…"</span>
))}
</TextLoop>
</div>
);
};
+181 -47
View File
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { useOptionalThemeSystem } from '@/contexts/useThemeSystem';
interface OpenChamberLogoProps {
@@ -8,6 +8,61 @@ interface OpenChamberLogoProps {
isAnimated?: boolean;
}
// Generate grid cells for a face (4x4 grid)
// Returns array of parallelogram paths in isometric projection
const generateFaceGrid = (
topLeft: { x: number; y: number },
topRight: { x: number; y: number },
bottomRight: { x: number; y: number },
bottomLeft: { x: number; y: number },
gridSize: number = 4
) => {
const cells: Array<{ path: string; row: number; col: number }> = [];
for (let row = 0; row < gridSize; row++) {
for (let col = 0; col < gridSize; col++) {
// Interpolate corners for this cell
const t1 = col / gridSize;
const t2 = (col + 1) / gridSize;
const s1 = row / gridSize;
const s2 = (row + 1) / gridSize;
// Bilinear interpolation for each corner of the cell
const lerp = (a: number, b: number, t: number) => a + (b - a) * t;
const bilinear = (tl: number, tr: number, br: number, bl: number, t: number, s: number) => {
const top = lerp(tl, tr, t);
const bottom = lerp(bl, br, t);
return lerp(top, bottom, s);
};
const p1 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t1, s1),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t1, s1),
};
const p2 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t2, s1),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t2, s1),
};
const p3 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t2, s2),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t2, s2),
};
const p4 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t1, s2),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t1, s2),
};
cells.push({
path: `M${p1.x} ${p1.y} L${p2.x} ${p2.y} L${p3.x} ${p3.y} L${p4.x} ${p4.y} Z`,
row,
col,
});
}
}
return cells;
};
export const OpenChamberLogo: React.FC<OpenChamberLogoProps> = ({
className = '',
width = 70,
@@ -23,67 +78,146 @@ export const OpenChamberLogo: React.FC<OpenChamberLogoProps> = ({
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
const fillColor = isDark ? 'white' : 'black';
const gradientId = 'shimmer-gradient';
const strokeColor = isDark ? 'white' : 'black';
const fillColor = isDark ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,0.15)';
const logoFillColor = isDark ? 'white' : 'black';
const cellHighlightColor = isDark ? 'rgba(255,255,255,0.35)' : 'rgba(0,0,0,0.4)';
// Isometric cube geometry (mathematically correct)
// For true isometric: horizontal edges at ±30° from horizontal
// cos(30°) ≈ 0.866, sin(30°) = 0.5
// Cube edge length = 46, center at (50, 52) - larger cube, slightly lower
const edge = 48;
const cos30 = 0.866;
const sin30 = 0.5;
const centerY = 50;
// Key points of the isometric cube
const top = { x: 50, y: centerY - edge }; // top vertex
const left = { x: 50 - edge * cos30, y: centerY - edge * sin30 }; // top-left
const right = { x: 50 + edge * cos30, y: centerY - edge * sin30 }; // top-right
const center = { x: 50, y: centerY }; // center (front vertex of top face)
const bottomLeft = { x: 50 - edge * cos30, y: centerY + edge * sin30 }; // bottom-left
const bottomRight = { x: 50 + edge * cos30, y: centerY + edge * sin30 }; // bottom-right
const bottom = { x: 50, y: centerY + edge }; // bottom vertex
// Isometric transformation matrix for top face
// Maps a flat square to the isometric rhombus (top face)
// Center of top face rhombus: average of top, left, center, right vertices
// topFaceCenter.x = (top.x + left.x + center.x + right.x) / 4 = 50
// topFaceCenter.y = (top.y + left.y + center.y + right.y) / 4
const topFaceCenterY = (top.y + left.y + center.y + right.y) / 4;
const isoMatrix = `matrix(0.866, 0.5, -0.866, 0.5, 50, ${topFaceCenterY})`;
// Generate grid cells for both faces
// Left face: center -> left -> bottomLeft -> bottom
const leftFaceCells = generateFaceGrid(left, center, bottom, bottomLeft);
// Right face: center -> right -> bottomRight -> bottom
const rightFaceCells = generateFaceGrid(center, right, bottomRight, bottom);
// Generate random opacity values for cells (stable per component instance)
const cellOpacities = useMemo(() => {
const opacities: number[] = [];
for (let i = 0; i < 32; i++) { // 16 cells per face * 2 faces
opacities.push(0.1 + Math.random() * 0.5); // Random opacity 0.1-0.6
}
return opacities;
}, []);
return (
<svg
width={width}
height={height}
viewBox="0 0 70 70"
viewBox="0 0 100 100"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
role="img"
aria-label="OpenChamber logo"
>
{isAnimated && (
<defs>
<linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor={fillColor} stopOpacity="1" />
<stop offset="50%" stopColor={fillColor} stopOpacity="0.7" />
<stop offset="100%" stopColor={fillColor} stopOpacity="1" />
<animate
attributeName="x1"
from="-100%"
to="200%"
dur="4s"
repeatCount="indefinite"
/>
<animate
attributeName="y1"
from="-100%"
to="200%"
dur="4s"
repeatCount="indefinite"
/>
<animate
attributeName="x2"
from="0%"
to="300%"
dur="4s"
repeatCount="indefinite"
/>
<animate
attributeName="y2"
from="0%"
to="300%"
dur="4s"
repeatCount="indefinite"
/>
</linearGradient>
</defs>
)}
{/* Left face - base fill */}
<path
fillRule="evenodd"
clipRule="evenodd"
d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z"
fill={isAnimated ? `url(#${gradientId})` : fillColor}
d={`M${center.x} ${center.y} L${left.x} ${left.y} L${bottomLeft.x} ${bottomLeft.y} L${bottom.x} ${bottom.y} Z`}
fill={fillColor}
stroke={strokeColor}
strokeWidth="2"
strokeLinejoin="round"
/>
{/* Left face - grid cells with varying opacity */}
{leftFaceCells.map((cell, i) => (
<path
key={`left-${i}`}
d={cell.path}
fill={cellHighlightColor}
opacity={cellOpacities[i]}
/>
))}
{/* Right face - base fill */}
<path
d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z"
fill={isAnimated ? `url(#${gradientId})` : fillColor}
d={`M${center.x} ${center.y} L${right.x} ${right.y} L${bottomRight.x} ${bottomRight.y} L${bottom.x} ${bottom.y} Z`}
fill={fillColor}
stroke={strokeColor}
strokeWidth="2"
strokeLinejoin="round"
/>
{/* Right face - grid cells with varying opacity */}
{rightFaceCells.map((cell, i) => (
<path
key={`right-${i}`}
d={cell.path}
fill={cellHighlightColor}
opacity={cellOpacities[i + 16]}
/>
))}
{/* Top face - open (no fill), only stroke */}
<path
d={`M${top.x} ${top.y} L${left.x} ${left.y} L${center.x} ${center.y} L${right.x} ${right.y} Z`}
fill="none"
stroke={strokeColor}
strokeWidth="2"
strokeLinejoin="round"
/>
{/* OpenCode logo on top face */}
<g opacity={isAnimated ? undefined : 1}>
{isAnimated && (
<animate
attributeName="opacity"
values="0.4;1;0.4"
dur="3s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.6 1; 0.4 0 0.6 1"
/>
)}
{/*
Isometric transform for top face:
OpenCode logo (32x40 viewBox) centered and projected to isometric plane
*/}
<g transform={`${isoMatrix} scale(0.75)`}>
{/* OpenCode logo - outer frame with inner square */}
{/* Outer frame (centered at origin, original: 0,0 to 32,40) */}
<path
fillRule="evenodd"
clipRule="evenodd"
d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z"
fill={logoFillColor}
/>
{/* Inner square */}
<path
d="M-8 -4 L8 -4 L8 12 L-8 12 Z"
fill={logoFillColor}
fillOpacity="0.4"
/>
</g>
</g>
</svg>
);
};
@@ -0,0 +1,83 @@
import { cn } from '@/lib/utils';
import {
motion,
AnimatePresence,
} from 'motion/react';
import type {
Transition,
Variants,
AnimatePresenceProps,
} from 'motion/react';
import { useState, useEffect, Children } from 'react';
export type TextLoopProps = {
children: React.ReactNode[];
className?: string;
interval?: number;
transition?: Transition;
variants?: Variants;
onIndexChange?: (index: number) => void;
trigger?: boolean;
mode?: AnimatePresenceProps['mode'];
};
export function TextLoop({
children,
className,
interval = 2,
transition = { duration: 0.3 },
variants,
onIndexChange,
trigger = true,
mode = 'popLayout',
}: TextLoopProps) {
const [currentIndex, setCurrentIndex] = useState(0);
const items = Children.toArray(children);
useEffect(() => {
if (!trigger) return;
const intervalMs = interval * 1000;
const timer = setInterval(() => {
setCurrentIndex((current) => {
const next = (current + 1) % items.length;
onIndexChange?.(next);
return next;
});
}, intervalMs);
return () => clearInterval(timer);
}, [items.length, interval, onIndexChange, trigger]);
const motionVariants: Variants = {
initial: { y: 20, opacity: 0 },
animate: { y: 0, opacity: 1 },
exit: { y: -20, opacity: 0 },
};
return (
<div className={cn('relative', className)}>
{/* Invisible element to maintain consistent width based on longest item */}
<div className="invisible whitespace-nowrap">
{items.map((item, i) => (
<div key={i} className={i === 0 ? '' : 'absolute'}>{item}</div>
))}
</div>
{/* Animated visible element */}
<div className="absolute inset-0 flex items-center justify-center">
<AnimatePresence mode={mode} initial={false}>
<motion.div
key={currentIndex}
initial='initial'
animate='animate'
exit='exit'
transition={transition}
variants={variants || motionVariants}
className="absolute whitespace-nowrap"
>
{items[currentIndex]}
</motion.div>
</AnimatePresence>
</div>
</div>
);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 32 KiB

+58 -7
View File
@@ -1,9 +1,60 @@
<svg width="24" height="24" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(35, 35) scale(0.95) translate(-35, -35)">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z"
fill="#808080"/>
<path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z"
fill="#808080"/>
<svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bgGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#303030"/>
<stop offset="100%" stop-color="#141414"/>
</linearGradient>
</defs>
<!-- Background -->
<rect x="0" y="0" width="128" height="128" rx="26" ry="26" fill="url(#bgGradient)"/>
<!-- OpenChamber logo centered -->
<g transform="translate(64, 64) scale(1)">
<!-- Left face -->
<path d="M0 0 L-41.568 -24 L-41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M0 0 L-10.392 -6 L-10.392 6 L0 12 Z" fill="white" fill-opacity="0.07"/>
<path d="M-10.392 -6 L-20.784 -12 L-20.784 0 L-10.392 6 Z" fill="white" fill-opacity="0.16"/>
<path d="M-20.784 -12 L-31.176 -18 L-31.176 -6 L-20.784 0 Z" fill="white" fill-opacity="0.05"/>
<path d="M-31.176 -18 L-41.568 -24 L-41.568 -12 L-31.176 -6 Z" fill="white" fill-opacity="0.19"/>
<path d="M0 12 L-10.392 6 L-10.392 18 L0 24 Z" fill="white" fill-opacity="0.12"/>
<path d="M-10.392 6 L-20.784 0 L-20.784 12 L-10.392 18 Z" fill="white" fill-opacity="0.04"/>
<path d="M-20.784 0 L-31.176 -6 L-31.176 6 L-20.784 12 Z" fill="white" fill-opacity="0.18"/>
<path d="M-31.176 -6 L-41.568 -12 L-41.568 0 L-31.176 6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 24 L-10.392 18 L-10.392 30 L0 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M-10.392 18 L-20.784 12 L-20.784 24 L-10.392 30 Z" fill="white" fill-opacity="0.11"/>
<path d="M-20.784 12 L-31.176 6 L-31.176 18 L-20.784 24 Z" fill="white" fill-opacity="0.16"/>
<path d="M-31.176 6 L-41.568 0 L-41.568 12 L-31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L-10.392 30 L-10.392 42 L0 48 Z" fill="white" fill-opacity="0.19"/>
<path d="M-10.392 30 L-20.784 24 L-20.784 36 L-10.392 42 Z" fill="white" fill-opacity="0.07"/>
<path d="M-20.784 24 L-31.176 18 L-31.176 30 L-20.784 36 Z" fill="white" fill-opacity="0.12"/>
<path d="M-31.176 18 L-41.568 12 L-41.568 24 L-31.176 30 Z" fill="white" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M0 0 L41.568 -24 L41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M0 0 L10.392 -6 L10.392 6 L0 12 Z" fill="white" fill-opacity="0.11"/>
<path d="M10.392 -6 L20.784 -12 L20.784 0 L10.392 6 Z" fill="white" fill-opacity="0.05"/>
<path d="M20.784 -12 L31.176 -18 L31.176 -6 L20.784 0 Z" fill="white" fill-opacity="0.16"/>
<path d="M31.176 -18 L41.568 -24 L41.568 -12 L31.176 -6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 12 L10.392 6 L10.392 18 L0 24 Z" fill="white" fill-opacity="0.18"/>
<path d="M10.392 6 L20.784 0 L20.784 12 L10.392 18 Z" fill="white" fill-opacity="0.12"/>
<path d="M20.784 0 L31.176 -6 L31.176 6 L20.784 12 Z" fill="white" fill-opacity="0.04"/>
<path d="M31.176 -6 L41.568 -12 L41.568 0 L31.176 6 Z" fill="white" fill-opacity="0.14"/>
<path d="M0 24 L10.392 18 L10.392 30 L0 36 Z" fill="white" fill-opacity="0.07"/>
<path d="M10.392 18 L20.784 12 L20.784 24 L10.392 30 Z" fill="white" fill-opacity="0.19"/>
<path d="M20.784 12 L31.176 6 L31.176 18 L20.784 24 Z" fill="white" fill-opacity="0.11"/>
<path d="M31.176 6 L41.568 0 L41.568 12 L31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L10.392 30 L10.392 42 L0 48 Z" fill="white" fill-opacity="0.16"/>
<path d="M10.392 30 L20.784 24 L20.784 36 L10.392 42 Z" fill="white" fill-opacity="0.09"/>
<path d="M20.784 24 L31.176 18 L31.176 30 L20.784 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M31.176 18 L41.568 12 L41.568 24 L31.176 30 Z" fill="white" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M0 -48 L-41.568 -24 L0 0 L41.568 -24 Z" fill="none" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 0, -24) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="white"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="white" fill-opacity="0.4"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 4.3 KiB

+11 -6
View File
@@ -1,6 +1,7 @@
import React from 'react';
import { useChatStore } from './stores/chatStore';
import { useNavigation } from './hooks/useNavigation';
import { OpenChamberLogo } from './components/OpenChamberLogo';
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
@@ -11,9 +12,18 @@ function ConnectionStatusBanner({ status, error, onRetry }: {
}) {
if (status === 'connected') return null;
// Show full-screen logo for connecting state
if (status === 'connecting') {
return (
<div className="flex flex-col items-center justify-center h-full gap-4">
<OpenChamberLogo width={80} height={80} isAnimated />
</div>
);
}
const messages: Record<ConnectionStatus, string> = {
disconnected: 'Not connected to OpenCode API',
connecting: 'Connecting...',
connecting: '',
connected: '',
error: error || 'Connection error',
};
@@ -22,9 +32,6 @@ function ConnectionStatusBanner({ status, error, onRetry }: {
<div className={`flex items-center justify-center gap-2 px-4 py-2 text-sm border-b ${
status === 'error' ? 'bg-destructive/10 text-destructive' : 'bg-muted text-muted-foreground'
}`}>
{status === 'connecting' && (
<span className="inline-block w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin" />
)}
<span>{messages[status]}</span>
{(status === 'disconnected' || status === 'error') && (
<button onClick={onRetry} className="px-2 py-0.5 text-xs rounded bg-primary text-primary-foreground hover:bg-primary/90">
@@ -265,8 +272,6 @@ export function VSCodeApp() {
<div className="flex-1 min-h-0">
{currentView === 'sessions' ? (
<SessionsList />
) : currentView === 'settings' ? (
<SettingsView />
) : (
<ChatPanel />
)}
@@ -0,0 +1,192 @@
import React, { useMemo } from 'react';
interface OpenChamberLogoProps {
className?: string;
width?: number;
height?: number;
isAnimated?: boolean;
}
// Generate grid cells for a face (4x4 grid)
const generateFaceGrid = (
topLeft: { x: number; y: number },
topRight: { x: number; y: number },
bottomRight: { x: number; y: number },
bottomLeft: { x: number; y: number },
gridSize: number = 4
) => {
const cells: Array<{ path: string; row: number; col: number }> = [];
for (let row = 0; row < gridSize; row++) {
for (let col = 0; col < gridSize; col++) {
const t1 = col / gridSize;
const t2 = (col + 1) / gridSize;
const s1 = row / gridSize;
const s2 = (row + 1) / gridSize;
const lerp = (a: number, b: number, t: number) => a + (b - a) * t;
const bilinear = (tl: number, tr: number, br: number, bl: number, t: number, s: number) => {
const top = lerp(tl, tr, t);
const bottom = lerp(bl, br, t);
return lerp(top, bottom, s);
};
const p1 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t1, s1),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t1, s1),
};
const p2 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t2, s1),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t2, s1),
};
const p3 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t2, s2),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t2, s2),
};
const p4 = {
x: bilinear(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x, t1, s2),
y: bilinear(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y, t1, s2),
};
cells.push({
path: `M${p1.x} ${p1.y} L${p2.x} ${p2.y} L${p3.x} ${p3.y} L${p4.x} ${p4.y} Z`,
row,
col,
});
}
}
return cells;
};
export const OpenChamberLogo: React.FC<OpenChamberLogoProps> = ({
className = '',
width = 70,
height = 70,
isAnimated = false,
}) => {
// VSCode uses CSS variables for theming
const strokeColor = 'var(--vscode-foreground)';
const fillColor = 'var(--vscode-foreground)';
const logoFillColor = 'var(--vscode-foreground)';
const cellHighlightColor = 'var(--vscode-foreground)';
// Isometric cube geometry
const edge = 48;
const cos30 = 0.866;
const sin30 = 0.5;
const centerY = 50;
const top = { x: 50, y: centerY - edge };
const left = { x: 50 - edge * cos30, y: centerY - edge * sin30 };
const right = { x: 50 + edge * cos30, y: centerY - edge * sin30 };
const center = { x: 50, y: centerY };
const bottomLeft = { x: 50 - edge * cos30, y: centerY + edge * sin30 };
const bottomRight = { x: 50 + edge * cos30, y: centerY + edge * sin30 };
const bottom = { x: 50, y: centerY + edge };
const topFaceCenterY = (top.y + left.y + center.y + right.y) / 4;
const isoMatrix = `matrix(0.866, 0.5, -0.866, 0.5, 50, ${topFaceCenterY})`;
const leftFaceCells = generateFaceGrid(left, center, bottom, bottomLeft);
const rightFaceCells = generateFaceGrid(center, right, bottomRight, bottom);
const cellOpacities = useMemo(() => {
const opacities: number[] = [];
for (let i = 0; i < 32; i++) {
opacities.push(0.1 + Math.random() * 0.5);
}
return opacities;
}, []);
return (
<svg
width={width}
height={height}
viewBox="0 0 100 100"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
role="img"
aria-label="OpenChamber logo"
>
{/* Left face */}
<path
d={`M${center.x} ${center.y} L${left.x} ${left.y} L${bottomLeft.x} ${bottomLeft.y} L${bottom.x} ${bottom.y} Z`}
fill={fillColor}
fillOpacity="0.15"
stroke={strokeColor}
strokeWidth="2"
strokeLinejoin="round"
/>
{/* Left face grid cells */}
{leftFaceCells.map((cell, i) => (
<path
key={`left-${i}`}
d={cell.path}
fill={cellHighlightColor}
fillOpacity={0.35 * cellOpacities[i]}
/>
))}
{/* Right face */}
<path
d={`M${center.x} ${center.y} L${right.x} ${right.y} L${bottomRight.x} ${bottomRight.y} L${bottom.x} ${bottom.y} Z`}
fill={fillColor}
fillOpacity="0.15"
stroke={strokeColor}
strokeWidth="2"
strokeLinejoin="round"
/>
{/* Right face grid cells */}
{rightFaceCells.map((cell, i) => (
<path
key={`right-${i}`}
d={cell.path}
fill={cellHighlightColor}
fillOpacity={0.35 * cellOpacities[i + 16]}
/>
))}
{/* Top face - open */}
<path
d={`M${top.x} ${top.y} L${left.x} ${left.y} L${center.x} ${center.y} L${right.x} ${right.y} Z`}
fill="none"
stroke={strokeColor}
strokeWidth="2"
strokeLinejoin="round"
/>
{/* OpenCode logo on top face */}
<g opacity={isAnimated ? undefined : 1}>
{isAnimated && (
<animate
attributeName="opacity"
values="0.4;1;0.4"
dur="3s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.6 1; 0.4 0 0.6 1"
/>
)}
<g transform={`${isoMatrix} scale(0.75)`}>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z"
fill={logoFillColor}
/>
<path
d="M-8 -4 L8 -4 L8 12 L-8 12 Z"
fill={logoFillColor}
fillOpacity="0.4"
/>
</g>
</g>
</svg>
);
};
export default OpenChamberLogo;
+83 -42
View File
@@ -5,11 +5,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/logo-dark.svg" />
<link rel="icon" type="image/svg+xml" href="/logo-light.svg" media="(prefers-color-scheme: dark)" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" href="/favicon-32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="/favicon-16.png" sizes="16x16" />
<link rel="mask-icon" href="/logo-dark.svg" color="#edb449" />
<link rel="mask-icon" href="/favicon.svg" color="#edb449" />
<!-- Apple touch icon - PNG format required for iOS PWA support -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png" />
@@ -31,19 +30,31 @@
"icons": [
{
"src": baseUrl + "/logo-dark.svg",
"sizes": "any",
"sizes": "512x512",
"type": "image/svg+xml",
"purpose": "any maskable"
},
{
"src": baseUrl + "/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
"src": baseUrl + "/apple-touch-icon-180x180.png",
"sizes": "180x180",
"type": "image/png",
"purpose": "any"
},
{
"src": baseUrl + "/apple-touch-icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "any"
},
{
"src": baseUrl + "/favicon-32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": baseUrl + "/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
}
],
"categories": ["developer", "tools", "productivity"],
@@ -112,32 +123,24 @@
<style>
:root {
--splash-background: #151313;
--splash-foreground: #cdccc3;
--splash-rect: #4B4646;
--splash-grad-stop1: #F8F8F8;
--splash-grad-stop2: #DAD6D0;
--splash-grad-stop3: #BAB4AF;
--splash-stroke1: rgba(255, 255, 255, 0.08);
--splash-stroke2: rgba(0, 0, 0, 0.15);
--splash-stroke3: rgba(0, 0, 0, 0.2);
--splash-stroke: white;
--splash-face-fill: rgba(255, 255, 255, 0.15);
--splash-cell-fill: rgba(255, 255, 255, 0.35);
--splash-logo-fill: white;
}
html[data-splash-variant='light'] {
--splash-background: #F6F4EF;
--splash-foreground: #453f37;
--splash-rect: #CFCDCD;
--splash-grad-stop1: #B3AEA6;
--splash-grad-stop2: #928E86;
--splash-grad-stop3: #6E6A63;
--splash-stroke1: rgba(255, 255, 255, 0.22);
--splash-stroke2: rgba(60, 56, 47, 0.25);
--splash-stroke3: rgba(43, 39, 34, 0.4);
--splash-stroke: black;
--splash-face-fill: rgba(0, 0, 0, 0.15);
--splash-cell-fill: rgba(0, 0, 0, 0.4);
--splash-logo-fill: black;
}
@keyframes pulse {
@keyframes logo-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
.loading-pulse {
animation: pulse 2s ease-in-out infinite;
.logo-pulse {
animation: logo-pulse 3s ease-in-out infinite;
}
#initial-loading {
background-color: var(--splash-background);
@@ -163,22 +166,60 @@
<!-- Loading fallback while React initializes -->
<div id="initial-loading">
<div style="display: flex; align-items: center; justify-content: center;">
<svg class="loading-pulse" width="96" height="96" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OpenChamber loading icon">
<defs>
<linearGradient id="loadingGlyphGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="var(--splash-grad-stop1)"/>
<stop offset="55%" stop-color="var(--splash-grad-stop2)"/>
<stop offset="100%" stop-color="var(--splash-grad-stop3)"/>
</linearGradient>
<linearGradient id="loadingGlyphStroke" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="var(--splash-stroke1)"/>
<stop offset="45%" stop-color="var(--splash-stroke2)"/>
<stop offset="100%" stop-color="var(--splash-stroke3)"/>
</linearGradient>
</defs>
<rect x="8.75" y="31" width="17.5" height="20.5" fill="var(--splash-rect)" />
<path d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="url(#loadingGlyphGradient)" stroke="url(#loadingGlyphStroke)" stroke-width="1.1" stroke-linejoin="round" />
<path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="url(#loadingGlyphGradient)" stroke="url(#loadingGlyphStroke)" stroke-width="1.1" stroke-linejoin="round" />
<svg width="120" height="120" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OpenChamber loading icon">
<!-- Isometric cube: edge=48, centerY=50 -->
<!-- Points: top(50,2), left(8.432,26), right(91.568,26), center(50,50), bottomLeft(8.432,74), bottomRight(91.568,74), bottom(50,98) -->
<!-- Left face - base fill with stroke -->
<path d="M50 50 L8.432 26 L8.432 74 L50 98 Z" fill="var(--splash-face-fill)" stroke="var(--splash-stroke)" stroke-width="2" stroke-linejoin="round"/>
<!-- Left face grid cells (4x4) with varying opacity -->
<path d="M50 50 L39.608 44 L39.608 56 L50 62 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<path d="M39.608 44 L29.216 38 L29.216 50 L39.608 56 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M29.216 38 L18.824 32 L18.824 44 L29.216 50 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M18.824 32 L8.432 26 L8.432 38 L18.824 44 Z" fill="var(--splash-cell-fill)" opacity="0.55"/>
<path d="M50 62 L39.608 56 L39.608 68 L50 74 Z" fill="var(--splash-cell-fill)" opacity="0.35"/>
<path d="M39.608 56 L29.216 50 L29.216 62 L39.608 68 Z" fill="var(--splash-cell-fill)" opacity="0.1"/>
<path d="M29.216 50 L18.824 44 L18.824 56 L29.216 62 Z" fill="var(--splash-cell-fill)" opacity="0.5"/>
<path d="M18.824 44 L8.432 38 L8.432 50 L18.824 56 Z" fill="var(--splash-cell-fill)" opacity="0.25"/>
<path d="M50 74 L39.608 68 L39.608 80 L50 86 Z" fill="var(--splash-cell-fill)" opacity="0.4"/>
<path d="M39.608 68 L29.216 62 L29.216 74 L39.608 80 Z" fill="var(--splash-cell-fill)" opacity="0.3"/>
<path d="M29.216 62 L18.824 56 L18.824 68 L29.216 74 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M18.824 56 L8.432 50 L8.432 62 L18.824 68 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M50 86 L39.608 80 L39.608 92 L50 98 Z" fill="var(--splash-cell-fill)" opacity="0.55"/>
<path d="M39.608 80 L29.216 74 L29.216 86 L39.608 92 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<path d="M29.216 74 L18.824 68 L18.824 80 L29.216 86 Z" fill="var(--splash-cell-fill)" opacity="0.35"/>
<path d="M18.824 68 L8.432 62 L8.432 74 L18.824 80 Z" fill="var(--splash-cell-fill)" opacity="0.1"/>
<!-- Right face - base fill with stroke -->
<path d="M50 50 L91.568 26 L91.568 74 L50 98 Z" fill="var(--splash-face-fill)" stroke="var(--splash-stroke)" stroke-width="2" stroke-linejoin="round"/>
<!-- Right face grid cells (4x4) with varying opacity -->
<path d="M50 50 L60.392 44 L60.392 56 L50 62 Z" fill="var(--splash-cell-fill)" opacity="0.3"/>
<path d="M60.392 44 L70.784 38 L70.784 50 L60.392 56 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M70.784 38 L81.176 32 L81.176 44 L70.784 50 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M81.176 32 L91.568 26 L91.568 38 L81.176 44 Z" fill="var(--splash-cell-fill)" opacity="0.25"/>
<path d="M50 62 L60.392 56 L60.392 68 L50 74 Z" fill="var(--splash-cell-fill)" opacity="0.5"/>
<path d="M60.392 56 L70.784 50 L70.784 62 L60.392 68 Z" fill="var(--splash-cell-fill)" opacity="0.35"/>
<path d="M70.784 50 L81.176 44 L81.176 56 L70.784 62 Z" fill="var(--splash-cell-fill)" opacity="0.1"/>
<path d="M81.176 44 L91.568 38 L91.568 50 L81.176 56 Z" fill="var(--splash-cell-fill)" opacity="0.4"/>
<path d="M50 74 L60.392 68 L60.392 80 L50 86 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<path d="M60.392 68 L70.784 62 L70.784 74 L60.392 80 Z" fill="var(--splash-cell-fill)" opacity="0.55"/>
<path d="M70.784 62 L81.176 56 L81.176 68 L70.784 74 Z" fill="var(--splash-cell-fill)" opacity="0.3"/>
<path d="M81.176 56 L91.568 50 L91.568 62 L81.176 68 Z" fill="var(--splash-cell-fill)" opacity="0.15"/>
<path d="M50 86 L60.392 80 L60.392 92 L50 98 Z" fill="var(--splash-cell-fill)" opacity="0.45"/>
<path d="M60.392 80 L70.784 74 L70.784 86 L60.392 92 Z" fill="var(--splash-cell-fill)" opacity="0.25"/>
<path d="M70.784 74 L81.176 68 L81.176 80 L70.784 86 Z" fill="var(--splash-cell-fill)" opacity="0.4"/>
<path d="M81.176 68 L91.568 62 L91.568 74 L81.176 80 Z" fill="var(--splash-cell-fill)" opacity="0.2"/>
<!-- Top face - open (no fill), only stroke -->
<path d="M50 2 L8.432 26 L50 50 L91.568 26 Z" fill="none" stroke="var(--splash-stroke)" stroke-width="2" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g class="logo-pulse" transform="matrix(0.866, 0.5, -0.866, 0.5, 50, 26) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="var(--splash-logo-fill)"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="var(--splash-logo-fill)" fill-opacity="0.4"/>
</g>
</svg>
</div>
</div>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 B

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 990 B

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 B

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 B

After

Width:  |  Height:  |  Size: 11 KiB

+59 -17
View File
@@ -1,18 +1,60 @@
<svg width="180" height="180" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(8.75, 8.75) scale(0.75)">
<!-- Letter O with white fill and thin black stroke -->
<path fill-rule="evenodd" clip-rule="evenodd"
d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z"
fill="white"
stroke="black"
stroke-width="1.1"
stroke-linejoin="round"/>
<!-- Letter C with white fill and thin black stroke -->
<path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z"
fill="white"
stroke="black"
stroke-width="1.1"
stroke-linejoin="round"/>
<svg width="180" height="180" viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bgGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#303030"/>
<stop offset="100%" stop-color="#141414"/>
</linearGradient>
</defs>
<!-- Background -->
<rect x="0" y="0" width="180" height="180" rx="40" ry="40" fill="url(#bgGradient)"/>
<!-- OpenChamber logo centered -->
<g transform="translate(90, 90) scale(1.4)">
<!-- Left face -->
<path d="M0 0 L-41.568 -24 L-41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M0 0 L-10.392 -6 L-10.392 6 L0 12 Z" fill="white" fill-opacity="0.07"/>
<path d="M-10.392 -6 L-20.784 -12 L-20.784 0 L-10.392 6 Z" fill="white" fill-opacity="0.16"/>
<path d="M-20.784 -12 L-31.176 -18 L-31.176 -6 L-20.784 0 Z" fill="white" fill-opacity="0.05"/>
<path d="M-31.176 -18 L-41.568 -24 L-41.568 -12 L-31.176 -6 Z" fill="white" fill-opacity="0.19"/>
<path d="M0 12 L-10.392 6 L-10.392 18 L0 24 Z" fill="white" fill-opacity="0.12"/>
<path d="M-10.392 6 L-20.784 0 L-20.784 12 L-10.392 18 Z" fill="white" fill-opacity="0.04"/>
<path d="M-20.784 0 L-31.176 -6 L-31.176 6 L-20.784 12 Z" fill="white" fill-opacity="0.18"/>
<path d="M-31.176 -6 L-41.568 -12 L-41.568 0 L-31.176 6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 24 L-10.392 18 L-10.392 30 L0 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M-10.392 18 L-20.784 12 L-20.784 24 L-10.392 30 Z" fill="white" fill-opacity="0.11"/>
<path d="M-20.784 12 L-31.176 6 L-31.176 18 L-20.784 24 Z" fill="white" fill-opacity="0.16"/>
<path d="M-31.176 6 L-41.568 0 L-41.568 12 L-31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L-10.392 30 L-10.392 42 L0 48 Z" fill="white" fill-opacity="0.19"/>
<path d="M-10.392 30 L-20.784 24 L-20.784 36 L-10.392 42 Z" fill="white" fill-opacity="0.07"/>
<path d="M-20.784 24 L-31.176 18 L-31.176 30 L-20.784 36 Z" fill="white" fill-opacity="0.12"/>
<path d="M-31.176 18 L-41.568 12 L-41.568 24 L-31.176 30 Z" fill="white" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M0 0 L41.568 -24 L41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M0 0 L10.392 -6 L10.392 6 L0 12 Z" fill="white" fill-opacity="0.11"/>
<path d="M10.392 -6 L20.784 -12 L20.784 0 L10.392 6 Z" fill="white" fill-opacity="0.05"/>
<path d="M20.784 -12 L31.176 -18 L31.176 -6 L20.784 0 Z" fill="white" fill-opacity="0.16"/>
<path d="M31.176 -18 L41.568 -24 L41.568 -12 L31.176 -6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 12 L10.392 6 L10.392 18 L0 24 Z" fill="white" fill-opacity="0.18"/>
<path d="M10.392 6 L20.784 0 L20.784 12 L10.392 18 Z" fill="white" fill-opacity="0.12"/>
<path d="M20.784 0 L31.176 -6 L31.176 6 L20.784 12 Z" fill="white" fill-opacity="0.04"/>
<path d="M31.176 -6 L41.568 -12 L41.568 0 L31.176 6 Z" fill="white" fill-opacity="0.14"/>
<path d="M0 24 L10.392 18 L10.392 30 L0 36 Z" fill="white" fill-opacity="0.07"/>
<path d="M10.392 18 L20.784 12 L20.784 24 L10.392 30 Z" fill="white" fill-opacity="0.19"/>
<path d="M20.784 12 L31.176 6 L31.176 18 L20.784 24 Z" fill="white" fill-opacity="0.11"/>
<path d="M31.176 6 L41.568 0 L41.568 12 L31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L10.392 30 L10.392 42 L0 48 Z" fill="white" fill-opacity="0.16"/>
<path d="M10.392 30 L20.784 24 L20.784 36 L10.392 42 Z" fill="white" fill-opacity="0.09"/>
<path d="M20.784 24 L31.176 18 L31.176 30 L20.784 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M31.176 18 L41.568 12 L41.568 24 L31.176 30 Z" fill="white" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M0 -48 L-41.568 -24 L0 0 L41.568 -24 Z" fill="none" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 0, -24) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="white"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="white" fill-opacity="0.4"/>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 689 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

+15
View File
@@ -0,0 +1,15 @@
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<!-- Simplified isometric cube for favicon - maximized -->
<g transform="translate(16, 15.5) scale(0.50)">
<!-- Left face -->
<path d="M0 0 L-26 -15 L-26 15 L0 30 Z" fill="white" fill-opacity="0.25" stroke="white" stroke-width="2.5" stroke-linejoin="round"/>
<!-- Right face -->
<path d="M0 0 L26 -15 L26 15 L0 30 Z" fill="white" fill-opacity="0.4" stroke="white" stroke-width="2.5" stroke-linejoin="round"/>
<!-- Top face - open -->
<path d="M0 -30 L-26 -15 L0 0 L26 -15 Z" fill="none" stroke="white" stroke-width="2.5" stroke-linejoin="round"/>
<!-- O logo - hollow rectangle frame on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 0, -15) scale(0.45)">
<rect x="-12" y="-14" width="24" height="28" fill="none" stroke="white" stroke-width="6"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 908 B

+59 -3
View File
@@ -1,4 +1,60 @@
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="black"/>
<path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="black"/>
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bgGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#303030"/>
<stop offset="100%" stop-color="#141414"/>
</linearGradient>
</defs>
<!-- Background -->
<rect x="0" y="0" width="512" height="512" rx="102" ry="102" fill="url(#bgGradient)"/>
<!-- OpenChamber logo centered -->
<g transform="translate(256, 256) scale(4)">
<!-- Left face -->
<path d="M0 0 L-41.568 -24 L-41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M0 0 L-10.392 -6 L-10.392 6 L0 12 Z" fill="white" fill-opacity="0.07"/>
<path d="M-10.392 -6 L-20.784 -12 L-20.784 0 L-10.392 6 Z" fill="white" fill-opacity="0.16"/>
<path d="M-20.784 -12 L-31.176 -18 L-31.176 -6 L-20.784 0 Z" fill="white" fill-opacity="0.05"/>
<path d="M-31.176 -18 L-41.568 -24 L-41.568 -12 L-31.176 -6 Z" fill="white" fill-opacity="0.19"/>
<path d="M0 12 L-10.392 6 L-10.392 18 L0 24 Z" fill="white" fill-opacity="0.12"/>
<path d="M-10.392 6 L-20.784 0 L-20.784 12 L-10.392 18 Z" fill="white" fill-opacity="0.04"/>
<path d="M-20.784 0 L-31.176 -6 L-31.176 6 L-20.784 12 Z" fill="white" fill-opacity="0.18"/>
<path d="M-31.176 -6 L-41.568 -12 L-41.568 0 L-31.176 6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 24 L-10.392 18 L-10.392 30 L0 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M-10.392 18 L-20.784 12 L-20.784 24 L-10.392 30 Z" fill="white" fill-opacity="0.11"/>
<path d="M-20.784 12 L-31.176 6 L-31.176 18 L-20.784 24 Z" fill="white" fill-opacity="0.16"/>
<path d="M-31.176 6 L-41.568 0 L-41.568 12 L-31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L-10.392 30 L-10.392 42 L0 48 Z" fill="white" fill-opacity="0.19"/>
<path d="M-10.392 30 L-20.784 24 L-20.784 36 L-10.392 42 Z" fill="white" fill-opacity="0.07"/>
<path d="M-20.784 24 L-31.176 18 L-31.176 30 L-20.784 36 Z" fill="white" fill-opacity="0.12"/>
<path d="M-31.176 18 L-41.568 12 L-41.568 24 L-31.176 30 Z" fill="white" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M0 0 L41.568 -24 L41.568 24 L0 48 Z" fill="white" fill-opacity="0.15" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M0 0 L10.392 -6 L10.392 6 L0 12 Z" fill="white" fill-opacity="0.11"/>
<path d="M10.392 -6 L20.784 -12 L20.784 0 L10.392 6 Z" fill="white" fill-opacity="0.05"/>
<path d="M20.784 -12 L31.176 -18 L31.176 -6 L20.784 0 Z" fill="white" fill-opacity="0.16"/>
<path d="M31.176 -18 L41.568 -24 L41.568 -12 L31.176 -6 Z" fill="white" fill-opacity="0.09"/>
<path d="M0 12 L10.392 6 L10.392 18 L0 24 Z" fill="white" fill-opacity="0.18"/>
<path d="M10.392 6 L20.784 0 L20.784 12 L10.392 18 Z" fill="white" fill-opacity="0.12"/>
<path d="M20.784 0 L31.176 -6 L31.176 6 L20.784 12 Z" fill="white" fill-opacity="0.04"/>
<path d="M31.176 -6 L41.568 -12 L41.568 0 L31.176 6 Z" fill="white" fill-opacity="0.14"/>
<path d="M0 24 L10.392 18 L10.392 30 L0 36 Z" fill="white" fill-opacity="0.07"/>
<path d="M10.392 18 L20.784 12 L20.784 24 L10.392 30 Z" fill="white" fill-opacity="0.19"/>
<path d="M20.784 12 L31.176 6 L31.176 18 L20.784 24 Z" fill="white" fill-opacity="0.11"/>
<path d="M31.176 6 L41.568 0 L41.568 12 L31.176 18 Z" fill="white" fill-opacity="0.05"/>
<path d="M0 36 L10.392 30 L10.392 42 L0 48 Z" fill="white" fill-opacity="0.16"/>
<path d="M10.392 30 L20.784 24 L20.784 36 L10.392 42 Z" fill="white" fill-opacity="0.09"/>
<path d="M20.784 24 L31.176 18 L31.176 30 L20.784 36 Z" fill="white" fill-opacity="0.14"/>
<path d="M31.176 18 L41.568 12 L41.568 24 L31.176 30 Z" fill="white" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M0 -48 L-41.568 -24 L0 0 L41.568 -24 Z" fill="none" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 0, -24) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="white"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="white" fill-opacity="0.4"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 4.3 KiB

+59 -3
View File
@@ -1,4 +1,60 @@
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 13H35V58H0V13ZM26.25 22.1957H8.75V48.701H26.25V22.1957Z" fill="white"/>
<path d="M43.75 13H70V22.1957H52.5V48.701H70V57.8967H43.75V13Z" fill="white"/>
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bgGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#F8F8F8"/>
<stop offset="100%" stop-color="#E8E8E8"/>
</linearGradient>
</defs>
<!-- Background -->
<rect x="0" y="0" width="512" height="512" rx="102" ry="102" fill="url(#bgGradient)"/>
<!-- OpenChamber logo centered -->
<g transform="translate(256, 256) scale(4)">
<!-- Left face -->
<path d="M0 0 L-41.568 -24 L-41.568 24 L0 48 Z" fill="black" fill-opacity="0.15" stroke="black" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Left face grid cells -->
<path d="M0 0 L-10.392 -6 L-10.392 6 L0 12 Z" fill="black" fill-opacity="0.07"/>
<path d="M-10.392 -6 L-20.784 -12 L-20.784 0 L-10.392 6 Z" fill="black" fill-opacity="0.16"/>
<path d="M-20.784 -12 L-31.176 -18 L-31.176 -6 L-20.784 0 Z" fill="black" fill-opacity="0.05"/>
<path d="M-31.176 -18 L-41.568 -24 L-41.568 -12 L-31.176 -6 Z" fill="black" fill-opacity="0.19"/>
<path d="M0 12 L-10.392 6 L-10.392 18 L0 24 Z" fill="black" fill-opacity="0.12"/>
<path d="M-10.392 6 L-20.784 0 L-20.784 12 L-10.392 18 Z" fill="black" fill-opacity="0.04"/>
<path d="M-20.784 0 L-31.176 -6 L-31.176 6 L-20.784 12 Z" fill="black" fill-opacity="0.18"/>
<path d="M-31.176 -6 L-41.568 -12 L-41.568 0 L-31.176 6 Z" fill="black" fill-opacity="0.09"/>
<path d="M0 24 L-10.392 18 L-10.392 30 L0 36 Z" fill="black" fill-opacity="0.14"/>
<path d="M-10.392 18 L-20.784 12 L-20.784 24 L-10.392 30 Z" fill="black" fill-opacity="0.11"/>
<path d="M-20.784 12 L-31.176 6 L-31.176 18 L-20.784 24 Z" fill="black" fill-opacity="0.16"/>
<path d="M-31.176 6 L-41.568 0 L-41.568 12 L-31.176 18 Z" fill="black" fill-opacity="0.05"/>
<path d="M0 36 L-10.392 30 L-10.392 42 L0 48 Z" fill="black" fill-opacity="0.19"/>
<path d="M-10.392 30 L-20.784 24 L-20.784 36 L-10.392 42 Z" fill="black" fill-opacity="0.07"/>
<path d="M-20.784 24 L-31.176 18 L-31.176 30 L-20.784 36 Z" fill="black" fill-opacity="0.12"/>
<path d="M-31.176 18 L-41.568 12 L-41.568 24 L-31.176 30 Z" fill="black" fill-opacity="0.04"/>
<!-- Right face -->
<path d="M0 0 L41.568 -24 L41.568 24 L0 48 Z" fill="black" fill-opacity="0.15" stroke="black" stroke-width="1.5" stroke-linejoin="round"/>
<!-- Right face grid cells -->
<path d="M0 0 L10.392 -6 L10.392 6 L0 12 Z" fill="black" fill-opacity="0.11"/>
<path d="M10.392 -6 L20.784 -12 L20.784 0 L10.392 6 Z" fill="black" fill-opacity="0.05"/>
<path d="M20.784 -12 L31.176 -18 L31.176 -6 L20.784 0 Z" fill="black" fill-opacity="0.16"/>
<path d="M31.176 -18 L41.568 -24 L41.568 -12 L31.176 -6 Z" fill="black" fill-opacity="0.09"/>
<path d="M0 12 L10.392 6 L10.392 18 L0 24 Z" fill="black" fill-opacity="0.18"/>
<path d="M10.392 6 L20.784 0 L20.784 12 L10.392 18 Z" fill="black" fill-opacity="0.12"/>
<path d="M20.784 0 L31.176 -6 L31.176 6 L20.784 12 Z" fill="black" fill-opacity="0.04"/>
<path d="M31.176 -6 L41.568 -12 L41.568 0 L31.176 6 Z" fill="black" fill-opacity="0.14"/>
<path d="M0 24 L10.392 18 L10.392 30 L0 36 Z" fill="black" fill-opacity="0.07"/>
<path d="M10.392 18 L20.784 12 L20.784 24 L10.392 30 Z" fill="black" fill-opacity="0.19"/>
<path d="M20.784 12 L31.176 6 L31.176 18 L20.784 24 Z" fill="black" fill-opacity="0.11"/>
<path d="M31.176 6 L41.568 0 L41.568 12 L31.176 18 Z" fill="black" fill-opacity="0.05"/>
<path d="M0 36 L10.392 30 L10.392 42 L0 48 Z" fill="black" fill-opacity="0.16"/>
<path d="M10.392 30 L20.784 24 L20.784 36 L10.392 42 Z" fill="black" fill-opacity="0.09"/>
<path d="M20.784 24 L31.176 18 L31.176 30 L20.784 36 Z" fill="black" fill-opacity="0.14"/>
<path d="M31.176 18 L41.568 12 L41.568 24 L31.176 30 Z" fill="black" fill-opacity="0.07"/>
<!-- Top face - open -->
<path d="M0 -48 L-41.568 -24 L0 0 L41.568 -24 Z" fill="none" stroke="black" stroke-width="1.5" stroke-linejoin="round"/>
<!-- OpenCode logo on top face -->
<g transform="matrix(0.866, 0.5, -0.866, 0.5, 0, -24) scale(0.75)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M-16 -20 L16 -20 L16 20 L-16 20 Z M-8 -12 L-8 12 L8 12 L8 -12 Z" fill="black"/>
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="black" fill-opacity="0.4"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 4.3 KiB

+14 -8
View File
@@ -10,25 +10,31 @@
"icons": [
{
"src": "/logo-dark.svg",
"sizes": "any",
"sizes": "512x512",
"type": "image/svg+xml",
"purpose": "any maskable"
},
{
"src": "/logo-light.svg",
"sizes": "any",
"type": "image/svg+xml",
"purpose": "any maskable"
"src": "/apple-touch-icon-180x180.png",
"sizes": "180x180",
"type": "image/png",
"purpose": "any"
},
{
"src": "/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
"src": "/apple-touch-icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "any"
},
{
"src": "/favicon-32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
}
],
"categories": ["developer", "tools", "productivity"],