|
|
@@ -21,17 +21,33 @@ import wordmarkLightSvg from "../../asset/brand/opencode-wordmark-light.svg"
|
|
|
import wordmarkDarkSvg from "../../asset/brand/opencode-wordmark-dark.svg"
|
|
|
import wordmarkSimpleLightSvg from "../../asset/brand/opencode-wordmark-simple-light.svg"
|
|
|
import wordmarkSimpleDarkSvg from "../../asset/brand/opencode-wordmark-simple-dark.svg"
|
|
|
-import brandAssets from "../../asset/brand/opencode-brand-assets.zip"
|
|
|
-
|
|
|
+const brandAssets = "/opencode-brand-assets.zip"
|
|
|
|
|
|
export default function Brand() {
|
|
|
- const downloadFile = (url: string, filename: string) => {
|
|
|
- const link = document.createElement("a")
|
|
|
- link.href = url
|
|
|
- link.download = filename
|
|
|
- document.body.appendChild(link)
|
|
|
- link.click()
|
|
|
- document.body.removeChild(link)
|
|
|
+ const downloadFile = async (url: string, filename: string) => {
|
|
|
+ try {
|
|
|
+ const response = await fetch(url)
|
|
|
+ const blob = await response.blob()
|
|
|
+ const blobUrl = window.URL.createObjectURL(blob)
|
|
|
+
|
|
|
+ const link = document.createElement("a")
|
|
|
+ link.href = blobUrl
|
|
|
+ link.download = filename
|
|
|
+ document.body.appendChild(link)
|
|
|
+ link.click()
|
|
|
+ document.body.removeChild(link)
|
|
|
+
|
|
|
+ window.URL.revokeObjectURL(blobUrl)
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Download failed:", error)
|
|
|
+ const link = document.createElement("a")
|
|
|
+ link.href = url
|
|
|
+ link.target = "_blank"
|
|
|
+ link.rel = "noopener noreferrer"
|
|
|
+ document.body.appendChild(link)
|
|
|
+ link.click()
|
|
|
+ document.body.removeChild(link)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
@@ -44,182 +60,283 @@ export default function Brand() {
|
|
|
<div data-component="content">
|
|
|
<section data-component="brand-content">
|
|
|
<h2>Brand guidelines</h2>
|
|
|
- <p>Resources and assets to help you work with the OpenCode
|
|
|
- brand.</p>
|
|
|
- <button data-component="download-button" onClick={() => downloadFile(brandAssets, "opencode-brand-assets.zip")}>
|
|
|
+ <p>Resources and assets to help you work with the OpenCode brand.</p>
|
|
|
+ <button
|
|
|
+ data-component="download-button"
|
|
|
+ onClick={() => downloadFile(brandAssets, "opencode-brand-assets.zip")}
|
|
|
+ >
|
|
|
Download all assets
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
|
|
|
-
|
|
|
<div data-component="brand-grid">
|
|
|
<div>
|
|
|
- <img src={previewLogoLight} alt="OpenCode brand guidelines"/>
|
|
|
+ <img src={previewLogoLight} alt="OpenCode brand guidelines" />
|
|
|
<div data-component="actions">
|
|
|
- <button
|
|
|
- onClick={() => downloadFile(logoLightPng, "opencode-logo-light.png")}>
|
|
|
+ <button onClick={() => downloadFile(logoLightPng, "opencode-logo-light.png")}>
|
|
|
PNG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
- <button
|
|
|
- onClick={() => downloadFile(logoLightSvg, "opencode-logo-light.svg")}>
|
|
|
+ <button onClick={() => downloadFile(logoLightSvg, "opencode-logo-light.svg")}>
|
|
|
SVG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <img src={previewLogoDark} alt="OpenCode brand guidelines"/>
|
|
|
+ <img src={previewLogoDark} alt="OpenCode brand guidelines" />
|
|
|
<div data-component="actions">
|
|
|
- <button
|
|
|
- onClick={() => downloadFile(logoDarkPng, "opencode-logo-dark.png")}>
|
|
|
+ <button onClick={() => downloadFile(logoDarkPng, "opencode-logo-dark.png")}>
|
|
|
PNG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
- <button
|
|
|
- onClick={() => downloadFile(logoDarkSvg, "opencode-logo-dark.svg")}>
|
|
|
+ <button onClick={() => downloadFile(logoDarkSvg, "opencode-logo-dark.svg")}>
|
|
|
SVG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <img src={previewWordmarkLight}
|
|
|
- alt="OpenCode brand guidelines"/>
|
|
|
+ <img src={previewWordmarkLight} alt="OpenCode brand guidelines" />
|
|
|
<div data-component="actions">
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkLightPng, "opencode-wordmark-light.png")}>
|
|
|
+ onClick={() => downloadFile(wordmarkLightPng, "opencode-wordmark-light.png")}
|
|
|
+ >
|
|
|
PNG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkLightSvg, "opencode-wordmark-light.svg")}>
|
|
|
+ onClick={() => downloadFile(wordmarkLightSvg, "opencode-wordmark-light.svg")}
|
|
|
+ >
|
|
|
SVG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <img src={previewWordmarkDark} alt="OpenCode brand guidelines"/>
|
|
|
+ <img src={previewWordmarkDark} alt="OpenCode brand guidelines" />
|
|
|
<div data-component="actions">
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkDarkPng, "opencode-wordmark-dark.png")}>
|
|
|
+ onClick={() => downloadFile(wordmarkDarkPng, "opencode-wordmark-dark.png")}
|
|
|
+ >
|
|
|
PNG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkDarkSvg, "opencode-wordmark-dark.svg")}>
|
|
|
+ onClick={() => downloadFile(wordmarkDarkSvg, "opencode-wordmark-dark.svg")}
|
|
|
+ >
|
|
|
SVG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <img src={previewWordmarkSimpleLight}
|
|
|
- alt="OpenCode brand guidelines"/>
|
|
|
+ <img src={previewWordmarkSimpleLight} alt="OpenCode brand guidelines" />
|
|
|
<div data-component="actions">
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkSimpleLightPng, "opencode-wordmark-simple-light.png")}>
|
|
|
+ onClick={() =>
|
|
|
+ downloadFile(wordmarkSimpleLightPng, "opencode-wordmark-simple-light.png")
|
|
|
+ }
|
|
|
+ >
|
|
|
PNG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkSimpleLightSvg, "opencode-wordmark-simple-light.svg")}>
|
|
|
+ onClick={() =>
|
|
|
+ downloadFile(wordmarkSimpleLightSvg, "opencode-wordmark-simple-light.svg")
|
|
|
+ }
|
|
|
+ >
|
|
|
SVG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <img src={previewWordmarkSimpleDark}
|
|
|
- alt="OpenCode brand guidelines"/>
|
|
|
+ <img src={previewWordmarkSimpleDark} alt="OpenCode brand guidelines" />
|
|
|
<div data-component="actions">
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkSimpleDarkPng, "opencode-wordmark-simple-dark.png")}>
|
|
|
+ onClick={() =>
|
|
|
+ downloadFile(wordmarkSimpleDarkPng, "opencode-wordmark-simple-dark.png")
|
|
|
+ }
|
|
|
+ >
|
|
|
PNG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
<button
|
|
|
- onClick={() => downloadFile(wordmarkSimpleDarkSvg, "opencode-wordmark-simple-dark.svg")}>
|
|
|
+ onClick={() =>
|
|
|
+ downloadFile(wordmarkSimpleDarkSvg, "opencode-wordmark-simple-dark.svg")
|
|
|
+ }
|
|
|
+ >
|
|
|
SVG
|
|
|
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none"
|
|
|
- xmlns="http://www.w3.org/2000/svg">
|
|
|
+ <svg
|
|
|
+ width="20"
|
|
|
+ height="20"
|
|
|
+ viewBox="0 0 20 20"
|
|
|
+ fill="none"
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ >
|
|
|
<path
|
|
|
d="M13.9583 10.6247L10 14.583L6.04167 10.6247M10 2.08301V13.958M16.25 17.9163H3.75"
|
|
|
- stroke="currentColor" stroke-width="1.5"
|
|
|
- stroke-linecap="square"/>
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="1.5"
|
|
|
+ stroke-linecap="square"
|
|
|
+ />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
@@ -227,9 +344,9 @@ export default function Brand() {
|
|
|
</div>
|
|
|
</section>
|
|
|
</div>
|
|
|
- <Footer/>
|
|
|
+ <Footer />
|
|
|
</div>
|
|
|
- <Legal/>
|
|
|
+ <Legal />
|
|
|
</main>
|
|
|
)
|
|
|
}
|