feat: refactor favicon and logo assets
@@ -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
|
||||
|
||||
[](https://github.com/btriapitsyn/openchamber/stargazers)
|
||||
[](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 |
@@ -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>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 62 KiB |
@@ -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 |
|
Before Width: | Height: | Size: 19 KiB |
|
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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 32 KiB |
@@ -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 |
@@ -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;
|
||||
@@ -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>
|
||||
|
||||
|
Before Width: | Height: | Size: 858 B After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 990 B After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 999 B After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 11 KiB |
@@ -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 |
|
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 401 B |
|
Before Width: | Height: | Size: 582 B After Width: | Height: | Size: 904 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.9 KiB |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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"],
|
||||
|
||||