summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Hill <[email protected]>2025-12-10 23:57:11 +0000
committerDavid Hill <[email protected]>2025-12-10 23:57:11 +0000
commitfba0aad2f812818d9503ec35791cfd7d6aa3b4f3 (patch)
tree5aaca424f1e05755ee1c78381cd8c74e9a3d3572
parent0ab3b882507c44522b574a4cf5e4199ee58f93d1 (diff)
downloadopencode-fba0aad2f812818d9503ec35791cfd7d6aa3b4f3.tar.gz
opencode-fba0aad2f812818d9503ec35791cfd7d6aa3b4f3.zip
wip: lander updates
-rw-r--r--packages/console/app/src/asset/lander/desktop-app-icon.pngbin0 -> 6172 bytes
-rw-r--r--packages/console/app/src/routes/index.css107
-rw-r--r--packages/console/app/src/routes/index.tsx199
3 files changed, 213 insertions, 93 deletions
diff --git a/packages/console/app/src/asset/lander/desktop-app-icon.png b/packages/console/app/src/asset/lander/desktop-app-icon.png
new file mode 100644
index 000000000..a35c28f51
--- /dev/null
+++ b/packages/console/app/src/asset/lander/desktop-app-icon.png
Binary files differ
diff --git a/packages/console/app/src/routes/index.css b/packages/console/app/src/routes/index.css
index 92de172e1..dc296e4d4 100644
--- a/packages/console/app/src/routes/index.css
+++ b/packages/console/app/src/routes/index.css
@@ -16,6 +16,8 @@
--color-background-strong-hover: hsl(0, 5%, 18%);
--color-background-interactive: hsl(62, 84%, 88%);
--color-background-interactive-weaker: hsl(64, 74%, 95%);
+ --color-surface-raised-base: hsla(0, 100%, 3%, 0.01);
+ --color-surface-raised-base-active: hsla(0, 100%, 17%, 0.06);
--color-text: hsl(0, 1%, 39%);
--color-text-weak: hsl(0, 1%, 60%);
@@ -24,7 +26,7 @@
--color-text-inverted: hsl(0, 20%, 99%);
--color-border: hsl(30, 2%, 81%);
- --color-border-weak: hsl(0, 1%, 85%);
+ --color-border-weak: hsla(0, 100%, 3%, 0.12);
--color-icon: hsl(0, 1%, 55%);
}
@@ -62,6 +64,14 @@ body {
}
}
+[data-slot="br"] {
+ display: block;
+
+ @media (max-width: 60rem) {
+ display: none;
+ }
+}
+
[data-page="opencode"] {
background: var(--color-background);
--padding: 5rem;
@@ -465,6 +475,68 @@ body {
}
}
+ [data-component="desktop-app-available"] {
+ background: var(--color-surface-raised-base);
+ border: 1px solid var(--color-border-weak);
+ display: flex;
+ margin-bottom: 48px;
+
+ [data-slot="desktop-icon"] {
+ border-right: 1px solid var(--color-border-weak);
+ width: 56px;
+ height: 72px;
+ background: var(--color-surface-raised-base-active);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+
+ img {
+ width: 40px;
+ height: 40px;
+ opacity: 100%;
+ }
+
+ [data-slot="dot"] {
+ border-radius: 100px;
+ width: 6px;
+ height: 6px;
+ background: var(--color-background-strong);
+ position: absolute;
+ bottom: 5px;
+ left: 24px;
+ opacity: 0;
+ }
+ }
+
+ &:has([data-slot="desktop-copy"]:hover) [data-slot="desktop-icon"] img {
+ animation: iconBounce 1s ease-in-out forwards;
+ }
+
+ &:has([data-slot="desktop-copy"]:hover) [data-slot="desktop-icon"] [data-slot="dot"] {
+ opacity: 0.4;
+ transition: opacity 0.3s ease-out 1s;
+ }
+
+
+
+ [data-slot="desktop-copy"] {
+ display: flex;
+ align-items: center;
+ padding: 20px;
+ gap: 16px;
+
+ span {
+ color: var(--color-text-strong);
+ line-height: 1;
+ }
+
+ a {
+ color: var(--color-text-weak);
+ }
+ }
+ }
+
[data-slot="hero-copy"] {
[data-slot="releases"] {
background: none;
@@ -502,7 +574,7 @@ body {
p {
color: var(--color-text);
- margin-bottom: 40px;
+ margin-bottom: 32px;
max-width: 82%;
@media (max-width: 50rem) {
@@ -518,7 +590,6 @@ body {
border-radius: 4px;
font-weight: 500;
cursor: pointer;
- margin-bottom: 80px;
display: flex;
width: fit-content;
gap: 12px;
@@ -1140,3 +1211,33 @@ body {
}
}
}
+
+@keyframes iconBounce {
+ 0%, 100% {
+ transform: translateY(0);
+ }
+ 50% {
+ transform: translateY(-10px);
+ }
+}
+ 25% {
+ transform: translateY(-10px);
+ }
+ 50% {
+ transform: translateY(0);
+ }
+ 75% {
+ transform: translateY(-10px);
+ }
+}
+
+@keyframes dotAppear {
+ 0% {
+ opacity: 0;
+ transform: scale(0);
+ }
+ 100% {
+ opacity: 0.5;
+ transform: scale(1);
+ }
+}
diff --git a/packages/console/app/src/routes/index.tsx b/packages/console/app/src/routes/index.tsx
index 56f078562..bcd538420 100644
--- a/packages/console/app/src/routes/index.tsx
+++ b/packages/console/app/src/routes/index.tsx
@@ -3,6 +3,7 @@ import { Title, Meta, Link } from "@solidjs/meta"
// import { HttpHeader } from "@solidjs/start"
import video from "../asset/lander/opencode-min.mp4"
import videoPoster from "../asset/lander/opencode-poster.png"
+import desktopAppIcon from "../asset/lander/desktop-app-icon.png"
import { IconCopy, IconCheck } from "../component/icon"
import { A, createAsync } from "@solidjs/router"
import { EmailSignup } from "~/component/email-signup"
@@ -14,6 +15,7 @@ import { Legal } from "~/component/legal"
import { github } from "~/lib/github"
import { createMemo } from "solid-js"
import { config } from "~/config"
+import avatarDavid from "~/asset/lander/avatar-david.png"
function CopyStatus() {
return (
@@ -52,100 +54,117 @@ export default function Home() {
<div data-component="content">
<section data-component="hero">
+ <div data-component="desktop-app-available">
+ <div data-slot="desktop-icon">
+ <img src={desktopAppIcon} alt="" />
+ <div data-slot="dot"></div>
+ </div>
+ <div data-slot="desktop-copy">
+ <span>Now available on desktop for macOS, Windows, and Linux.</span> <a href="/download">Learn more</a>
+ </div>
+ </div>
+
<div data-slot="hero-copy">
- <a data-slot="releases" href={release()?.url ?? `${config.github.repoUrl}/releases`} target="_blank">
- What’s new in {release()?.name ?? "the latest release"}
- </a>
- <h1>The open source coding agent</h1>
+ {/*<a data-slot="releases"*/}
+ {/* href={release()?.url ?? `${config.github.repoUrl}/releases`}*/}
+ {/* target="_blank">*/}
+ {/* What’s new in {release()?.name ?? "the latest release"}*/}
+ {/*</a>*/}
+ <h1>The open source AI coding agent</h1>
<p>
- OpenCode includes free models or connect from any provider to <br />
- use other models, including Claude, GPT, Gemini and more.
+ Free models by default or connect any model from any provider, <span data-slot="br"></span>including
+ Claude, GPT, Gemini and more.
</p>
+ <a href="/download">
+ <span>Get started for free</span>
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path
+ d="M6.5 12L17 12M13 16.5L17.5 12L13 7.5"
+ stroke="currentColor"
+ stroke-width="1.5"
+ stroke-linecap="square"
+ />
+ </svg>
+ </a>
</div>
- <p data-slot="installation-instructions">Install and use. No account, no email, and no credit card.</p>
- <div data-slot="installation">
- <Tabs
- as="section"
- aria-label="Install options"
- class="tabs"
- data-component="tabs"
- data-active="curl"
- defaultValue="curl"
- >
- <Tabs.List data-slot="tablist">
- <Tabs.Trigger value="curl" data-slot="tab">
- curl
- </Tabs.Trigger>
- <Tabs.Trigger value="npm" data-slot="tab">
- npm
- </Tabs.Trigger>
- <Tabs.Trigger value="bun" data-slot="tab">
- bun
- </Tabs.Trigger>
- <Tabs.Trigger value="brew" data-slot="tab">
- brew
- </Tabs.Trigger>
- <Tabs.Trigger value="paru" data-slot="tab">
- paru
- </Tabs.Trigger>
- <Tabs.Indicator />
- </Tabs.List>
- <div data-slot="panels">
- <Tabs.Content as="pre" data-slot="panel" value="curl">
- <button data-copy data-slot="command" onClick={handleCopyClick}>
- <span data-slot="command-script">
- <span>curl -fsSL </span>
- <span data-slot="protocol">https://</span>
- <span data-slot="highlight">opencode.ai/install</span>
- <span> | bash</span>
- </span>
- <CopyStatus />
- </button>
- </Tabs.Content>
- <Tabs.Content as="pre" data-slot="panel" value="npm">
- <button data-copy data-slot="command" onClick={handleCopyClick}>
- <span>
- <span data-slot="protocol">npm i -g </span>
- <span data-slot="highlight">opencode-ai</span>
- </span>
- <CopyStatus />
- </button>
- </Tabs.Content>
- <Tabs.Content as="pre" data-slot="panel" value="bun">
- <button data-copy data-slot="command" onClick={handleCopyClick}>
- <span>
- <span data-slot="protocol">bun add -g </span>
- <span data-slot="highlight">opencode-ai</span>
- </span>
- <CopyStatus />
- </button>
- </Tabs.Content>
- <Tabs.Content as="pre" data-slot="panel" value="brew">
- <button data-copy data-slot="command" onClick={handleCopyClick}>
- <span>
- <span data-slot="protocol">brew install </span>
- <span data-slot="highlight">opencode</span>
- </span>
- <CopyStatus />
- </button>
- </Tabs.Content>
- <Tabs.Content as="pre" data-slot="panel" value="paru">
- <button data-copy data-slot="command" onClick={handleCopyClick}>
- <span>
- <span data-slot="protocol">paru -S </span>
- <span data-slot="highlight">opencode</span>
- </span>
- <CopyStatus />
- </button>
- </Tabs.Content>
- </div>
- </Tabs>
- </div>
- <p data-slot="installation-options">
- Available in terminal, web, and desktop (coming soon).
- <br />
- Extensions for VS Code, Cursor, Windsurf, and more.
- </p>
+ {/*<div data-slot="installation">*/}
+ {/* <Tabs*/}
+ {/* as="section"*/}
+ {/* aria-label="Install options"*/}
+ {/* class="tabs"*/}
+ {/* data-component="tabs"*/}
+ {/* data-active="curl"*/}
+ {/* defaultValue="curl"*/}
+ {/* >*/}
+ {/* <Tabs.List data-slot="tablist">*/}
+ {/* <Tabs.Trigger value="curl" data-slot="tab">*/}
+ {/* curl*/}
+ {/* </Tabs.Trigger>*/}
+ {/* <Tabs.Trigger value="npm" data-slot="tab">*/}
+ {/* npm*/}
+ {/* </Tabs.Trigger>*/}
+ {/* <Tabs.Trigger value="bun" data-slot="tab">*/}
+ {/* bun*/}
+ {/* </Tabs.Trigger>*/}
+ {/* <Tabs.Trigger value="brew" data-slot="tab">*/}
+ {/* brew*/}
+ {/* </Tabs.Trigger>*/}
+ {/* <Tabs.Trigger value="paru" data-slot="tab">*/}
+ {/* paru*/}
+ {/* </Tabs.Trigger>*/}
+ {/* <Tabs.Indicator />*/}
+ {/* </Tabs.List>*/}
+ {/* <div data-slot="panels">*/}
+ {/* <Tabs.Content as="pre" data-slot="panel" value="curl">*/}
+ {/* <button data-copy data-slot="command" onClick={handleCopyClick}>*/}
+ {/* <span data-slot="command-script">*/}
+ {/* <span>curl -fsSL </span>*/}
+ {/* <span data-slot="protocol">https://</span>*/}
+ {/* <span data-slot="highlight">opencode.ai/install</span>*/}
+ {/* <span> | bash</span>*/}
+ {/* </span>*/}
+ {/* <CopyStatus />*/}
+ {/* </button>*/}
+ {/* </Tabs.Content>*/}
+ {/* <Tabs.Content as="pre" data-slot="panel" value="npm">*/}
+ {/* <button data-copy data-slot="command" onClick={handleCopyClick}>*/}
+ {/* <span>*/}
+ {/* <span data-slot="protocol">npm i -g </span>*/}
+ {/* <span data-slot="highlight">opencode-ai</span>*/}
+ {/* </span>*/}
+ {/* <CopyStatus />*/}
+ {/* </button>*/}
+ {/* </Tabs.Content>*/}
+ {/* <Tabs.Content as="pre" data-slot="panel" value="bun">*/}
+ {/* <button data-copy data-slot="command" onClick={handleCopyClick}>*/}
+ {/* <span>*/}
+ {/* <span data-slot="protocol">bun add -g </span>*/}
+ {/* <span data-slot="highlight">opencode-ai</span>*/}
+ {/* </span>*/}
+ {/* <CopyStatus />*/}
+ {/* </button>*/}
+ {/* </Tabs.Content>*/}
+ {/* <Tabs.Content as="pre" data-slot="panel" value="brew">*/}
+ {/* <button data-copy data-slot="command" onClick={handleCopyClick}>*/}
+ {/* <span>*/}
+ {/* <span data-slot="protocol">brew install </span>*/}
+ {/* <span data-slot="highlight">opencode</span>*/}
+ {/* </span>*/}
+ {/* <CopyStatus />*/}
+ {/* </button>*/}
+ {/* </Tabs.Content>*/}
+ {/* <Tabs.Content as="pre" data-slot="panel" value="paru">*/}
+ {/* <button data-copy data-slot="command" onClick={handleCopyClick}>*/}
+ {/* <span>*/}
+ {/* <span data-slot="protocol">paru -S </span>*/}
+ {/* <span data-slot="highlight">opencode</span>*/}
+ {/* </span>*/}
+ {/* <CopyStatus />*/}
+ {/* </button>*/}
+ {/* </Tabs.Content>*/}
+ {/* </div>*/}
+ {/* </Tabs>*/}
+ {/*</div>*/}
</section>
<section data-component="video">