diff options
| -rw-r--r-- | packages/console/app/src/asset/lander/desktop-app-icon.png | bin | 0 -> 6172 bytes | |||
| -rw-r--r-- | packages/console/app/src/routes/index.css | 107 | ||||
| -rw-r--r-- | packages/console/app/src/routes/index.tsx | 199 |
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 Binary files differnew file mode 100644 index 000000000..a35c28f51 --- /dev/null +++ b/packages/console/app/src/asset/lander/desktop-app-icon.png 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"> |
