Bläddra i källkod

ignore: lander tweaks

Jay V 6 månader sedan
förälder
incheckning
c93d50e8c7

BIN
packages/web/src/assets/lander/screenshot-github.png


BIN
packages/web/src/assets/lander/screenshot-vscode.png


+ 224 - 19
packages/web/src/components/Lander.astro

@@ -5,7 +5,9 @@ import type { Props } from '@astrojs/starlight/props';
 
 import CopyIcon from "../assets/lander/copy.svg";
 import CheckIcon from "../assets/lander/check.svg";
-import Screenshot from "../assets/lander/screenshot-splash.png";
+import TuiScreenshot from "../assets/lander/screenshot-splash.png";
+import VscodeScreenshot from "../assets/lander/screenshot-vscode.png";
+import GithubScreenshot from "../assets/lander/screenshot-github.png";
 
 const { data } = Astro.locals.starlightRoute.entry;
 const { title = data.title, tagline, image, actions = [] } = data.hero || {};
@@ -36,7 +38,7 @@ if (image) {
         lightImage = image.light;
     } else {
         rawHtml = image.html;
-    }
+  }
 }
 ---
 <div class="hero">
@@ -80,24 +82,81 @@ if (image) {
       </ul>
     </section>
 
+    <section class="alternatives">
+      <div class="col1">
+        <h3>npm</h3>
+        <button class="command" data-command="npm install -g opencode-ai">
+          <code>
+            <span>npm install -g</span> <span class="highlight">opencode-ai</span>
+          </code>
+          <span class="copy">
+            <CopyIcon />
+            <CheckIcon />
+          </span>
+        </button>
+      </div>
+      <div class="col2">
+        <h3>Bun</h3>
+        <button class="command" data-command="bun install -g opencode-ai">
+          <code>
+            <span>bun install -g</span> <span class="highlight">opencode-ai</span>
+          </code>
+          <span class="copy">
+            <CopyIcon />
+            <CheckIcon />
+          </span>
+        </button>
+      </div>
+      <div class="col3">
+        <h3>Homebrew</h3>
+        <button class="command" data-command="brew install sst/tap/opencode">
+          <code>
+            <span>brew install</span> <span class="highlight">sst/tap/opencode</span>
+          </code>
+          <span class="copy">
+            <CopyIcon />
+            <CheckIcon />
+          </span>
+        </button>
+      </div>
+      <div class="col4">
+        <h3>Paru</h3>
+        <button class="command" data-command="paru -S opencode-bin">
+          <code>
+            <span>paru -S</span> <span class="highlight">opencode-bin</span>
+          </code>
+          <span class="copy">
+            <CopyIcon />
+            <CheckIcon />
+          </span>
+        </button>
+      </div>
+    </section>
+
     <section class="images">
       <div class="left">
         <figure>
           <figcaption>opencode TUI with the tokyonight theme</figcaption>
-          <Image src={Screenshot} alt="opencode TUI with the tokyonight theme" />
+          <a href="/docs/cli">
+            <Image src={TuiScreenshot} alt="opencode TUI with the tokyonight theme" />
+          </a>
         </figure>
       </div>
       <div class="right">
         <div class="row1">
           <figure>
             <figcaption>opencode in VS Code</figcaption>
-            <Image src={Screenshot} alt="opencode in VS Code" />
+            <a href="/docs/ide">
+              <Image src={VscodeScreenshot} alt="opencode in VS Code" />
+            </a>
           </figure>
         </div>
         <div class="row2">
           <figure>
-            <figcaption>opencode TUI with the tokyonight theme</figcaption>
-            <Image src={Screenshot} alt="opencode TUI with the tokyonight theme" />
+            <figcaption>opencode in GitHub</figcaption>
+            <a href="/docs/github">
+              <Image src={GithubScreenshot} alt="opencode in GitHub" />
+            </a>
           </figure>
         </div>
       </div>
@@ -105,13 +164,13 @@ if (image) {
 
     <section class="footer">
       <div class="col1">
-        <a href={github.href}>GitHub</a>
+        <a href={github.href} target="_blank" rel="noopener noreferrer">GitHub</a>
       </div>
       <div class="col2">
-        <a href={discord.href}>Discord</a>
+        <a href={discord.href} target="_blank" rel="noopener noreferrer">Discord</a>
       </div>
       <div class="col3">
-      <span>&copy;2025 <a href="https://anoma.ly">Anomaly Innovations</a></span>
+      <span>&copy;2025 <a href="https://anoma.ly" target="_blank" rel="noopener noreferrer">Anomaly Innovations</a></span>
       </div>
     </section>
 </div>
@@ -301,7 +360,7 @@ section.images {
       border-bottom: 2px solid var(--sl-color-border);
       height: calc(var(--images-height) / 2);
     }
-    
+
     & > div.row2 {
       display: flex;
       grid-row: 2;
@@ -334,6 +393,16 @@ section.images {
       justify-content: center;
     }
 
+    a {
+      display: flex;
+      flex: 1;
+      min-height: 0;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+    }
+
     figcaption {
       letter-spacing: -0.03125rem;
       text-transform: uppercase;
@@ -408,6 +477,140 @@ section.images {
   }
 }
 
+section.alternatives {
+  border-top: 2px solid var(--sl-color-border);
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  grid-template-rows: 1fr 1fr;
+
+  @media (max-width: 40rem) {
+    grid-template-columns: 1fr;
+    grid-template-rows: auto;
+  }
+
+  & > div {
+    display: flex;
+    flex-direction: column;
+    padding: calc(var(--vertical-padding) / 2) calc(var(--padding) / 2) calc(var(--vertical-padding) / 2 + 0.125rem);
+    text-align: left;
+    gap: 0.5rem;
+
+    @media (max-width: 40rem) {
+      text-align: left;
+    }
+  }
+
+  & > div.col1 {
+    border-bottom: 2px solid var(--sl-color-border);
+
+    @media (max-width: 40rem) {
+      border-bottom: none;
+    }
+  }
+
+  & > div.col2 {
+    border-left: 2px solid var(--sl-color-border);
+    border-bottom: 2px solid var(--sl-color-border);
+
+    @media (max-width: 40rem) {
+      border-left: none;
+      border-bottom: none;
+      border-top: 2px solid var(--sl-color-border);
+    }
+  }
+
+  & > div.col3 {
+    @media (max-width: 40rem) {
+      border-top: 2px solid var(--sl-color-border);
+    }
+  }
+
+  & > div.col4 {
+    border-left: 2px solid var(--sl-color-border);
+    @media (max-width: 40rem) {
+      border-left: none;
+      border-top: 2px solid var(--sl-color-border);
+    }
+  }
+
+  h3 {
+    letter-spacing: -0.03125rem;
+    text-transform: uppercase;
+    color: var(--sl-color-text-dimmed);
+    font-weight: normal;
+    font-size: 1rem;
+    flex-shrink: 0;
+  }
+
+  .command {
+    all: unset;
+    display: flex;
+    align-items: center;
+    gap: 0.625rem;
+    justify-content: flex-start;
+    cursor: pointer;
+    width: 100%;
+
+    @media (max-width: 40rem) {
+      justify-content: flex-start;
+    }
+    
+    @media (max-width: 30rem) {
+      justify-content: center;
+    }
+
+    code {
+      color: var(--sl-color-text-secondary);
+      font-size: 1rem;
+
+      @media (max-width: 24rem) {
+        font-size: 0.875rem;
+      }
+    }
+
+    code .highlight {
+      color: var(--sl-color-text);
+      font-weight: 500;
+    }
+
+    .copy {
+      line-height: 1;
+      padding: 0;
+
+      @media (max-width: 40rem) {
+        display: none;
+      }
+    }
+
+    .copy svg {
+      width: 1rem;
+      height: 1rem;
+      vertical-align: middle;
+    }
+
+    .copy svg:first-child {
+      color: var(--sl-color-text-dimmed);
+    }
+
+    .copy svg:last-child {
+      color: var(--sl-color-text);
+      display: none;
+    }
+
+    &.success .copy {
+      pointer-events: none;
+    }
+
+    &.success .copy svg:first-child {
+      display: none;
+    }
+
+    &.success .copy svg:last-child {
+      display: inline;
+    }
+  }
+}
+
 section.footer {
   border-top: 2px solid var(--sl-color-border);
   display: flex;
@@ -475,13 +678,15 @@ section.footer {
 </style>
 
 <script>
-  const button = document.querySelector("button.command") as HTMLButtonElement;
-
-  button?.addEventListener("click", () => {
-    navigator.clipboard.writeText(button.dataset.command!);
-    button.classList.toggle("success");
-    setTimeout(() => {
-      button.classList.toggle("success");
-    }, 1500);
-  });
+  const buttons = document.querySelectorAll("button.command") as NodeListOf<HTMLButtonElement>
+
+  buttons.forEach(button => {
+    button.addEventListener("click", () => {
+      navigator.clipboard.writeText(button.dataset.command!)
+      button.classList.toggle("success")
+      setTimeout(() => {
+        button.classList.toggle("success");
+      }, 1500)
+    })
+  })
 </script>