| ... | ... | @@ -1,26 +1,372 @@ |
| 1 | 1 | --- |
| 2 | 2 | import Layout from "../layouts/Layout.astro"; |
| 3 | import TuxIcon from "../components/TuxIcon.astro"; |
| 4 | import { tweets } from "../lib/tweets"; |
| 5 | |
| 6 | const desktopEndorsementRows = [ |
| 7 | tweets.filter((_, index) => index % 2 === 0), |
| 8 | tweets.filter((_, index) => index % 2 === 1), |
| 9 | ]; |
| 10 | |
| 11 | const mobileEndorsementRows = [ |
| 12 | tweets.filter((_, index) => index % 3 === 0), |
| 13 | tweets.filter((_, index) => index % 3 === 1), |
| 14 | tweets.filter((_, index) => index % 3 === 2), |
| 15 | ]; |
| 3 | 16 | --- |
| 4 | 17 | |
| 5 | 18 | <Layout> |
| 6 | | <h1 class="tagline">T3 Code is the best way to code with AI.</h1> |
| 7 | | |
| 8 | | <a |
| 9 | | id="download-btn" |
| 10 | | href="https://github.com/pingdotgg/t3code/releases" |
| 11 | | class="hero-button" |
| 12 | | > |
| 13 | | <svg class="hero-button-icon hero-button-icon--apple" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 814 1000" aria-hidden="true"><path fill="currentColor" d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"/></svg> |
| 14 | | <svg class="hero-button-icon hero-button-icon--windows" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 88 88" aria-hidden="true"><path fill="currentColor" d="m0 12.402 35.687-4.86.016 34.423-35.67.203zm35.67 33.529.028 34.453L.028 75.48.026 45.7zm4.326-39.025L87.314 0v41.527l-47.318.376zm47.329 39.349-.011 41.34-47.318-6.678-.066-34.739z"/></svg> |
| 15 | | <svg class="hero-button-icon hero-button-icon--linux" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 295" aria-hidden="true"><defs><linearGradient id="lt0" x1="48.548%" x2="51.047%" y1="115.276%" y2="41.364%"><stop offset="0%" stop-color="#FFEED7"/><stop offset="100%" stop-color="#BDBFC2"/></linearGradient><linearGradient id="lt6" x1="49.984%" x2="49.984%" y1="89.845%" y2="40.632%"><stop offset="0%" stop-color="#FFEED7"/><stop offset="100%" stop-color="#BDBFC2"/></linearGradient><linearGradient id="lt8" x1="49.841%" x2="50.241%" y1="13.229%" y2="94.673%"><stop offset="0%" stop-color="#FFF" stop-opacity=".8"/><stop offset="100%" stop-color="#FFF" stop-opacity="0"/></linearGradient><linearGradient id="ltc" x1="53.467%" x2="38.949%" y1="48.921%" y2="98.1%"><stop offset="0%" stop-color="#FFA63F"/><stop offset="100%" stop-color="#FF0"/></linearGradient><linearGradient id="lte" x1="30.581%" x2="65.887%" y1="34.024%" y2="89.175%"><stop offset="0%" stop-color="#FFA63F"/><stop offset="100%" stop-color="#FF0"/></linearGradient><linearGradient id="lti" x1="49.733%" x2="50.558%" y1="17.609%" y2="99.385%"><stop offset="0%" stop-color="#FFA63F"/><stop offset="100%" stop-color="#FF0"/></linearGradient></defs><g fill="none"><path fill="#000" d="M63.213 215.474c-11.387-16.346-13.591-69.606 12.947-102.39C89.292 97.383 92.69 86.455 93.7 71.67c.734-16.805-11.846-66.851 35.537-70.616 48.027-3.857 45.364 43.526 45.088 68.596-.183 21.12 15.52 33.15 26.355 49.68 19.927 30.303 18.274 82.461-3.765 110.745-27.916 35.354-51.791 20.018-67.678 21.304-29.752 1.745-30.762 17.54-66.024-35.905"/><path fill="url(#lt6)" d="M81.027 145.684c6.52-14.785 20.386-40.772 20.662-60.883 0-15.978 47.843-19.835 51.7-3.856 3.856 15.978 13.59 39.853 19.834 51.424 6.245 11.478 24.335 48.118 5.051 80.074-17.356 28.284-69.973 50.69-98.073-3.856-9.55-18.917-7.806-42.333.826-62.903"/><path fill="url(#lt8)" d="M166.428 151.285c0 16.162-15.519 37.1-42.15 36.916-27.456.183-39.118-20.754-39.118-36.916 0-16.161 18.182-29.293 40.588-29.293 22.498.092 40.68 13.132 40.68 29.293"/><path fill="#000" stroke="#000" stroke-width=".977" d="M176.805 117.86c13.59 11.02 38.292 49.587 2.204 74.748-11.846 7.806 10.468 32.508 23.049 19.927 43.618-43.894-1.102-94.308-16.53-111.664-13.774-15.151-25.987 3.49-8.723 16.989z"/><path fill="#000" stroke="#000" stroke-width="1.25" d="M79.925 122.727c-8.907 14.509-30.211 48.669-1.652 66.484 38.384 23.6 27.548 47.108-7.53 25.895-49.404-29.568-5.97-89.257 13.774-112.03 22.59-25.529 4.316 4.683-4.592 19.65z"/><path fill="url(#ltc)" stroke="#E68C3F" stroke-width="6.25" d="M51.835 258.542c-20.57-10.928-50.414 2.112-39.578-27.457 2.204-6.704-3.214-16.805.275-23.325 4.133-7.989 13.04-6.244 18.366-11.57 5.234-5.51 8.54-15.06 18.366-13.59 9.734 1.468 16.254 13.406 23.049 28.099 5.05 10.468 22.865 25.253 21.672 37.007-1.47 17.998-21.948 21.396-42.15 10.836z" transform="translate(10)"/><path fill="url(#lte)" stroke="#E68C3F" stroke-width="6.251" d="M194.445 253.49c15.06-18.273 48.578-14.508 25.988-39.577-4.775-5.418-3.306-16.989-9.183-21.947-6.887-6.061-14.509-1.102-21.488-4.224-6.979-3.398-14.325-9.918-22.865-5.327-8.54 4.684-9.459 16.805-10.285 32.783-.735 11.479-11.203 30.671-5.602 41.231 8.081 16.346 29.11 14.142 43.435-2.938z" transform="translate(10)"/><path fill="url(#lti)" stroke="#E68C3F" stroke-width="3.75" d="M97.107 66.344c3.673-3.398 12.58-13.774 29.477-2.939 3.122 2.02 5.693 2.204 11.662 4.775 12.03 4.96 6.336 16.897-6.52 20.937-5.51 1.745-10.468 8.449-20.386 7.806-8.54-.46-10.744-6.06-15.978-9.091-9.275-5.234-10.652-12.305-5.602-16.07 5.051-3.765 6.98-5.143 7.347-5.418z" transform="translate(10)"/><path fill="#000" d="M133.186 57.712c-.092 5.234 2.48 9.458 5.877 9.458 3.306 0 6.153-4.224 6.245-9.366.091-5.234-2.48-9.459-5.878-9.459-3.397 0-6.152 4.225-6.244 9.367m-21.212.092c.459 4.316-1.194 7.989-3.582 8.356-2.387.276-4.683-2.938-5.142-7.254-.46-4.316 1.194-7.99 3.581-8.357 2.388-.275 4.684 2.939 5.143 7.255"/></g></svg> |
| 16 | | <span id="download-label">Download now</span> |
| 17 | | </a> |
| 18 | | |
| 19 | | <a href="/download" class="other-platforms">Other platforms</a> |
| 20 | | |
| 21 | | <div class="screenshot-wrap"> |
| 22 | | <img src="/screenshot.jpeg" alt="T3 Code" class="screenshot" /> |
| 23 | | </div> |
| 19 | <!-- ── Hero ──────────────────────────────────────────────────── --> |
| 20 | <section class="hero"> |
| 21 | <div class="hero-grid" aria-hidden="true"></div> |
| 22 | |
| 23 | <div class="hero-float" aria-hidden="true"> |
| 24 | <span class="hero-float-mark hf-claude" title="Claude Code"> |
| 25 | <img src="/harnesses/claude-ai-icon.svg" alt="" /> |
| 26 | </span> |
| 27 | <span class="hero-float-mark hf-codex" title="Codex"> |
| 28 | <img src="/harnesses/openai_dark.svg" alt="" /> |
| 29 | </span> |
| 30 | <span class="hero-float-mark hf-opencode" title="OpenCode"> |
| 31 | <img src="/harnesses/opencode-dark.svg" alt="" /> |
| 32 | </span> |
| 33 | <span class="hero-float-mark hf-cursor" title="Cursor"> |
| 34 | <img src="/harnesses/cursor_light.svg" alt="" /> |
| 35 | </span> |
| 36 | </div> |
| 37 | |
| 38 | <div class="container hero-inner"> |
| 39 | <h1 class="hero-title display"> |
| 40 | The open-source<br />control plane<br />for coding agents. |
| 41 | </h1> |
| 42 | |
| 43 | <p class="hero-sub"> |
| 44 | Orchestrate Claude Code, Codex, OpenCode and Cursor from one surface. |
| 45 | Bring your own subscription. Fork the whole thing. |
| 46 | </p> |
| 47 | |
| 48 | <div class="hero-actions"> |
| 49 | <a |
| 50 | id="download-btn" |
| 51 | href="https://github.com/pingdotgg/t3code/releases" |
| 52 | class="btn btn-primary btn-lg" |
| 53 | > |
| 54 | <svg class="dl-icon dl-icon--apple" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 814 1000" aria-hidden="true"><path fill="currentColor" d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"/></svg> |
| 55 | <svg class="dl-icon dl-icon--windows" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 88 88" aria-hidden="true"><path fill="currentColor" d="m0 12.402 35.687-4.86.016 34.423-35.67.203zm35.67 33.529.028 34.453L.028 75.48.026 45.7zm4.326-39.025L87.314 0v41.527l-47.318.376zm47.329 39.349-.011 41.34-47.318-6.678-.066-34.739z"/></svg> |
| 56 | <TuxIcon class="dl-icon dl-icon--linux" idPrefix="hero-linux-" /> |
| 57 | <span id="download-label">Download for macOS</span> |
| 58 | </a> |
| 59 | <a href="https://github.com/pingdotgg/t3code" target="_blank" rel="noopener noreferrer" class="btn btn-ghost btn-lg"> |
| 60 | <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"> |
| 61 | <path d="M12 .5C5.65.5.5 5.65.5 12a11.5 11.5 0 007.86 10.93c.58.1.79-.25.79-.56v-2c-3.2.69-3.88-1.37-3.88-1.37-.52-1.33-1.27-1.69-1.27-1.69-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.18 1.76 1.18 1.02 1.76 2.68 1.25 3.33.96.1-.75.4-1.25.72-1.54-2.55-.29-5.24-1.27-5.24-5.67 0-1.25.45-2.28 1.18-3.08-.12-.29-.51-1.45.11-3.02 0 0 .96-.31 3.15 1.18a10.96 10.96 0 015.74 0c2.19-1.49 3.15-1.18 3.15-1.18.62 1.57.23 2.73.11 3.02.74.8 1.18 1.83 1.18 3.08 0 4.41-2.7 5.38-5.27 5.66.41.36.78 1.06.78 2.13v3.16c0 .31.21.67.8.56A11.5 11.5 0 0023.5 12C23.5 5.65 18.35.5 12 .5z"/> |
| 62 | </svg> |
| 63 | Star on GitHub |
| 64 | </a> |
| 65 | </div> |
| 66 | |
| 67 | <div class="hero-preview"> |
| 68 | <figure class="hero-screenshot-frame"> |
| 69 | <img |
| 70 | src="/updated-screenshot.webp" |
| 71 | alt="T3 Code app showing multiple coding agent threads in one workspace" |
| 72 | width="2508" |
| 73 | height="1682" |
| 74 | loading="eager" |
| 75 | decoding="async" |
| 76 | /> |
| 77 | </figure> |
| 78 | </div> |
| 79 | </div> |
| 80 | </section> |
| 81 | |
| 82 | <!-- ── Endorsements ─────────────────────────────────────────── --> |
| 83 | <section id="endorsements" class="sec-endorsements" aria-labelledby="endorsements-title"> |
| 84 | <div class="container"> |
| 85 | <div class="endorsements-head"> |
| 86 | <h2 id="endorsements-title">Developers love T3 Code</h2> |
| 87 | <p>Real reactions from people building with T3 Code today.</p> |
| 88 | </div> |
| 89 | </div> |
| 90 | |
| 91 | <div class="endorsement-carousel endorsement-carousel--desktop" aria-label="Developer endorsements"> |
| 92 | { |
| 93 | desktopEndorsementRows.map((row, rowIndex) => ( |
| 94 | <div class:list={["endorsement-row", rowIndex === 1 && "is-reverse"]}> |
| 95 | <div class="endorsement-track"> |
| 96 | {[0, 1].map((groupIndex) => ( |
| 97 | <div class="endorsement-track-group" aria-hidden={groupIndex === 1 ? "true" : undefined}> |
| 98 | {row.map((tweet) => ( |
| 99 | <a |
| 100 | class="endorsement-card" |
| 101 | href={tweet.link} |
| 102 | target="_blank" |
| 103 | rel="noopener noreferrer" |
| 104 | aria-label={`Read ${tweet.handle}'s post on X`} |
| 105 | tabindex={groupIndex === 1 ? "-1" : undefined} |
| 106 | > |
| 107 | <div class="endorsement-author"> |
| 108 | <img |
| 109 | src={`/pfps/${tweet.handle}.webp`} |
| 110 | alt="" |
| 111 | width="28" |
| 112 | height="28" |
| 113 | loading="lazy" |
| 114 | decoding="async" |
| 115 | /> |
| 116 | <div class="endorsement-handle">@{tweet.handle}</div> |
| 117 | </div> |
| 118 | <p>{tweet.excerpt ?? tweet.content}</p> |
| 119 | </a> |
| 120 | ))} |
| 121 | </div> |
| 122 | ))} |
| 123 | </div> |
| 124 | </div> |
| 125 | )) |
| 126 | } |
| 127 | </div> |
| 128 | |
| 129 | <div class="endorsement-carousel endorsement-carousel--mobile" aria-label="Developer endorsements"> |
| 130 | { |
| 131 | mobileEndorsementRows.map((row, rowIndex) => ( |
| 132 | <div class:list={["endorsement-row", rowIndex === 1 && "is-reverse"]}> |
| 133 | <div class="endorsement-track"> |
| 134 | {[0, 1].map((groupIndex) => ( |
| 135 | <div class="endorsement-track-group" aria-hidden={groupIndex === 1 ? "true" : undefined}> |
| 136 | {row.map((tweet) => ( |
| 137 | <a |
| 138 | class="endorsement-card" |
| 139 | href={tweet.link} |
| 140 | target="_blank" |
| 141 | rel="noopener noreferrer" |
| 142 | aria-label={`Read ${tweet.handle}'s post on X`} |
| 143 | tabindex={groupIndex === 1 ? "-1" : undefined} |
| 144 | > |
| 145 | <div class="endorsement-author"> |
| 146 | <img |
| 147 | src={`/pfps/${tweet.handle}.webp`} |
| 148 | alt="" |
| 149 | width="28" |
| 150 | height="28" |
| 151 | loading="lazy" |
| 152 | decoding="async" |
| 153 | /> |
| 154 | <div class="endorsement-handle">@{tweet.handle}</div> |
| 155 | </div> |
| 156 | <p>{tweet.excerpt ?? tweet.content}</p> |
| 157 | </a> |
| 158 | ))} |
| 159 | </div> |
| 160 | ))} |
| 161 | </div> |
| 162 | </div> |
| 163 | )) |
| 164 | } |
| 165 | </div> |
| 166 | </section> |
| 167 | |
| 168 | <!-- ── Harnesses ─────────────────────────────────────────────── --> |
| 169 | <section id="harnesses" class="sec-harness"> |
| 170 | <div class="container"> |
| 171 | <div class="section-head"> |
| 172 | <h2>Bring your own sub</h2> |
| 173 | <p> |
| 174 | T3 Code doesn't resell tokens. Plug in Claude Code, Codex, OpenCode, |
| 175 | or Cursor with the credentials you already have — we orchestrate |
| 176 | them, you keep your plan. |
| 177 | </p> |
| 178 | </div> |
| 179 | |
| 180 | <div class="harness-grid"> |
| 181 | <div class="harness"> |
| 182 | <div class="harness-mark"><img src="/harnesses/claude-ai-icon.svg" alt="" /></div> |
| 183 | <div class="harness-meta"> |
| 184 | <div class="harness-name">Claude Code</div> |
| 185 | <div class="harness-tag">claude auth login</div> |
| 186 | </div> |
| 187 | </div> |
| 188 | <div class="harness"> |
| 189 | <div class="harness-mark"><img src="/harnesses/openai_dark.svg" alt="" /></div> |
| 190 | <div class="harness-meta"> |
| 191 | <div class="harness-name">Codex CLI</div> |
| 192 | <div class="harness-tag">codex login</div> |
| 193 | </div> |
| 194 | </div> |
| 195 | <div class="harness"> |
| 196 | <div class="harness-mark"><img src="/harnesses/opencode-dark.svg" alt="" /></div> |
| 197 | <div class="harness-meta"> |
| 198 | <div class="harness-name">OpenCode</div> |
| 199 | <div class="harness-tag">opencode auth</div> |
| 200 | </div> |
| 201 | </div> |
| 202 | <div class="harness"> |
| 203 | <div class="harness-mark"><img src="/harnesses/cursor_light.svg" alt="" /></div> |
| 204 | <div class="harness-meta"> |
| 205 | <div class="harness-name">Cursor</div> |
| 206 | <div class="harness-tag">cursor-agent</div> |
| 207 | </div> |
| 208 | </div> |
| 209 | </div> |
| 210 | |
| 211 | <div class="harness-footer"> |
| 212 | <div class="harness-footer-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> No keys resold. No quota caps.</div> |
| 213 | <div class="harness-footer-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> Switch models mid-thread.</div> |
| 214 | <div class="harness-footer-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> More harnesses shipping weekly.</div> |
| 215 | </div> |
| 216 | </div> |
| 217 | </section> |
| 218 | |
| 219 | <!-- ── Git ──────────────────────────────────────────────────── --> |
| 220 | <section id="git" class="sec-git"> |
| 221 | <div class="container git-inner"> |
| 222 | <div class="git-visual"> |
| 223 | <div class="pr-card tile"> |
| 224 | <div class="pr-head"> |
| 225 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2.2"/><circle cx="6" cy="18" r="2.2"/><circle cx="18" cy="6" r="2.2"/><path d="M6 8v8M18 8v5a3 3 0 01-3 3h-3M13 13l-2 3 2 3"/></svg> |
| 226 | <span class="pr-title">Add marketing hero animation</span> |
| 227 | <span class="pr-status">Ready</span> |
| 228 | </div> |
| 229 | <div class="pr-meta"> |
| 230 | <span><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2.2"/><circle cx="6" cy="18" r="2.2"/><circle cx="18" cy="6" r="2.2"/><path d="M6 8v8M6 12a6 6 0 006-6h6"/></svg> feat/marketing-hero → main</span> |
| 231 | <span>+142 −38</span> |
| 232 | <span>3 commits</span> |
| 233 | </div> |
| 234 | <div class="pr-files"> |
| 235 | <div><code>apps/marketing/src/pages/index.astro</code> <span>+14 −2</span></div> |
| 236 | <div><code>apps/marketing/src/layouts/Layout.astro</code> <span>+8 −0</span></div> |
| 237 | <div><code>apps/marketing/public/hero.css</code> <span>+120 −36</span></div> |
| 238 | </div> |
| 239 | <div class="pr-foot"> |
| 240 | <button class="btn btn-ghost" style="font-size:12px;padding:6px 10px">View diff</button> |
| 241 | <button class="btn btn-primary" style="font-size:12px;padding:6px 12px"> |
| 242 | <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .5C5.65.5.5 5.65.5 12a11.5 11.5 0 007.86 10.93c.58.1.79-.25.79-.56v-2c-3.2.69-3.88-1.37-3.88-1.37-.52-1.33-1.27-1.69-1.27-1.69-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.18 1.76 1.18 1.02 1.76 2.68 1.25 3.33.96.1-.75.4-1.25.72-1.54-2.55-.29-5.24-1.27-5.24-5.67 0-1.25.45-2.28 1.18-3.08-.12-.29-.51-1.45.11-3.02 0 0 .96-.31 3.15 1.18a10.96 10.96 0 015.74 0c2.19-1.49 3.15-1.18 3.15-1.18.62 1.57.23 2.73.11 3.02.74.8 1.18 1.83 1.18 3.08 0 4.41-2.7 5.38-5.27 5.66.41.36.78 1.06.78 2.13v3.16c0 .31.21.67.8.56A11.5 11.5 0 0023.5 12C23.5 5.65 18.35.5 12 .5z"/></svg> |
| 243 | Open pull request |
| 244 | </button> |
| 245 | </div> |
| 246 | </div> |
| 247 | <div class="pr-trail"> |
| 248 | <div class="pr-trail-dot"></div> |
| 249 | <div class="pr-trail-line"></div> |
| 250 | <div class="pr-trail-dot"></div> |
| 251 | </div> |
| 252 | <div class="pr-button-shell"> |
| 253 | <button class="pr-button"> |
| 254 | <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2.2"/><circle cx="6" cy="18" r="2.2"/><circle cx="18" cy="6" r="2.2"/><path d="M6 8v8M18 8v5a3 3 0 01-3 3h-3M13 13l-2 3 2 3"/></svg> |
| 255 | Commit &amp; push |
| 256 | <span class="pr-button-kbd">⌘⏎</span> |
| 257 | </button> |
| 258 | </div> |
| 259 | </div> |
| 260 | |
| 261 | <div class="git-copy"> |
| 262 | <div class="section-head" style="margin-bottom:0"> |
| 263 | <h2>One button to commit, push, and make a PR.</h2> |
| 264 | <p> |
| 265 | Every agent thread writes to its own branch. When it's good, one |
| 266 | button opens the PR on GitHub with a generated title, body and |
| 267 | changelog. No terminal dance required. |
| 268 | </p> |
| 269 | <ul class="checklist" style="margin-top:24px"> |
| 270 | <li><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> Auto-generated PR titles &amp; bodies</li> |
| 271 | <li><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> Inline diff review before you push</li> |
| 272 | <li><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> Draft PRs, stack PRs, amend PRs</li> |
| 273 | <li><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg> Works with your existing GitHub auth</li> |
| 274 | </ul> |
| 275 | </div> |
| 276 | </div> |
| 277 | </div> |
| 278 | </section> |
| 279 | |
| 280 | <!-- ── Open source ───────────────────────────────────────────── --> |
| 281 | <section id="open" class="sec-open"> |
| 282 | <div class="container"> |
| 283 | <div class="section-head open-head"> |
| 284 | <div class="eyebrow">Open source</div> |
| 285 | <h2>If you don't like something, fork it.</h2> |
| 286 | <p> |
| 287 | T3 Code is as open as they come. We built this app to be modifiable, |
| 288 | customizable, and forkable. Go nuts - that's the whole point. |
| 289 | </p> |
| 290 | </div> |
| 291 | |
| 292 | <div class="open-grid"> |
| 293 | <div class="tile open-term"> |
| 294 | <div class="open-term-head"> |
| 295 | <span></span><span></span><span></span> |
| 296 | <span class="open-term-title">~/code</span> |
| 297 | </div> |
| 298 | <div class="open-term-body"> |
| 299 | <div><span class="prompt">$</span> gh repo fork pingdotgg/t3code --clone</div> |
| 300 | <div class="dim">✓ Cloned t3code into ./t3code</div> |
| 301 | <div><span class="prompt">$</span> cd t3code &amp;&amp; bun install</div> |
| 302 | <div class="dim">✓ 1 284 packages installed in 4.2s</div> |
| 303 | <div><span class="prompt">$</span> bun dev</div> |
| 304 | <div class="dim">▲ T3 Code dev server → <span class="accent">http://localhost:4001</span></div> |
| 305 | <div class="cursor"><span class="prompt">$</span><span class="caret"></span></div> |
| 306 | </div> |
| 307 | </div> |
| 308 | |
| 309 | <div class="open-stats"> |
| 310 | <div class="tile open-stat"> |
| 311 | <div class="open-stat-val">MIT</div> |
| 312 | <div class="open-stat-lbl">License · commercial-friendly</div> |
| 313 | </div> |
| 314 | <div class="tile open-stat"> |
| 315 | <div class="open-stat-val">TypeScript</div> |
| 316 | <div class="open-stat-lbl">End-to-end, strictly typed</div> |
| 317 | </div> |
| 318 | <div class="tile open-stat"> |
| 319 | <div class="open-stat-val">1 monorepo</div> |
| 320 | <div class="open-stat-lbl">Desktop · web · server · harnesses</div> |
| 321 | </div> |
| 322 | <div class="tile open-stat"> |
| 323 | <div class="open-stat-val">No telemetry</div> |
| 324 | <div class="open-stat-lbl">Unless you opt in. Full stop.</div> |
| 325 | </div> |
| 326 | </div> |
| 327 | </div> |
| 328 | |
| 329 | <div class="open-ctas"> |
| 330 | <a class="btn btn-ghost" href="https://github.com/pingdotgg/t3code" target="_blank" rel="noopener noreferrer"> |
| 331 | <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .5C5.65.5.5 5.65.5 12a11.5 11.5 0 007.86 10.93c.58.1.79-.25.79-.56v-2c-3.2.69-3.88-1.37-3.88-1.37-.52-1.33-1.27-1.69-1.27-1.69-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.18 1.76 1.18 1.02 1.76 2.68 1.25 3.33.96.1-.75.4-1.25.72-1.54-2.55-.29-5.24-1.27-5.24-5.67 0-1.25.45-2.28 1.18-3.08-.12-.29-.51-1.45.11-3.02 0 0 .96-.31 3.15 1.18a10.96 10.96 0 015.74 0c2.19-1.49 3.15-1.18 3.15-1.18.62 1.57.23 2.73.11 3.02.74.8 1.18 1.83 1.18 3.08 0 4.41-2.7 5.38-5.27 5.66.41.36.78 1.06.78 2.13v3.16c0 .31.21.67.8.56A11.5 11.5 0 0023.5 12C23.5 5.65 18.35.5 12 .5z"/></svg> |
| 332 | Star on GitHub |
| 333 | <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17L17 7M8 7h9v9"/></svg> |
| 334 | </a> |
| 335 | <a class="btn btn-ghost" href="https://github.com/pingdotgg/t3code/fork" target="_blank" rel="noopener noreferrer"> |
| 336 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="5" r="2.2"/><circle cx="18" cy="5" r="2.2"/><circle cx="12" cy="19" r="2.2"/><path d="M6 7.2v2A3 3 0 009 12.2h6A3 3 0 0018 9.2v-2M12 14v2.8"/></svg> |
| 337 | Fork the repo |
| 338 | <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17L17 7M8 7h9v9"/></svg> |
| 339 | </a> |
| 340 | <a class="btn btn-ghost" href="https://github.com/pingdotgg/t3code/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer"> |
| 341 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2.5" y="4.5" width="19" height="15" rx="2"/><path d="M7 10l3 2-3 2M12 16h5"/></svg> |
| 342 | Read CONTRIBUTING.md |
| 343 | <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17L17 7M8 7h9v9"/></svg> |
| 344 | </a> |
| 345 | </div> |
| 346 | </div> |
| 347 | </section> |
| 348 | |
| 349 | <!-- ── Final CTA ─────────────────────────────────────────────── --> |
| 350 | <section id="download" class="sec-cta"> |
| 351 | <div class="container cta-inner"> |
| 352 | <h2 class="display cta-title"> |
| 353 | Your agents deserve better than a terminal. |
| 354 | </h2> |
| 355 | <p class="cta-sub"> |
| 356 | T3 Code is free, open source and fast. Install it, plug in the harness |
| 357 | you already pay for, and let your agents get to work. |
| 358 | </p> |
| 359 | <div class="cta-actions"> |
| 360 | <a id="cta-download-btn" class="btn btn-primary btn-lg" href="https://github.com/pingdotgg/t3code/releases"> |
| 361 | <svg class="dl-icon dl-icon--apple" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 814 1000" aria-hidden="true"><path fill="currentColor" d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"/></svg> |
| 362 | <svg class="dl-icon dl-icon--windows" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 88 88" aria-hidden="true"><path fill="currentColor" d="m0 12.402 35.687-4.86.016 34.423-35.67.203zm35.67 33.529.028 34.453L.028 75.48.026 45.7zm4.326-39.025L87.314 0v41.527l-47.318.376zm47.329 39.349-.011 41.34-47.318-6.678-.066-34.739z"/></svg> |
| 363 | <TuxIcon class="dl-icon dl-icon--linux" idPrefix="cta-linux-" /> |
| 364 | <span id="cta-download-label">Download for macOS</span> |
| 365 | </a> |
| 366 | <a class="btn btn-ghost btn-lg" href="/download">Windows · Linux · other</a> |
| 367 | </div> |
| 368 | </div> |
| 369 | </section> |
| 24 | 370 | </Layout> |
| 25 | 371 | |
| 26 | 372 | <script> |
| ... | ... | @@ -32,11 +378,7 @@ import Layout from "../layouts/Layout.astro"; |
| 32 | 378 | const ua = navigator.userAgent; |
| 33 | 379 | if (/Win/i.test(ua)) return { os: "win", label: "Download for Windows" }; |
| 34 | 380 | if (/Mac/i.test(ua)) { |
| 35 | | return { |
| 36 | | os: "mac", |
| 37 | | label: `Download for macOS`, |
| 38 | | arch: "arm64", |
| 39 | | }; |
| 381 | return { os: "mac", label: "Download for macOS", arch: "arm64" }; |
| 40 | 382 | } |
| 41 | 383 | if (/Linux/i.test(ua)) return { os: "linux", label: "Download for Linux" }; |
| 42 | 384 | return null; |
| ... | ... | @@ -44,23 +386,15 @@ import Layout from "../layouts/Layout.astro"; |
| 44 | 386 | |
| 45 | 387 | function pickAsset(assets: ReleaseAsset[], platform: Platform): string | null { |
| 46 | 388 | if (platform.os === "win") { |
| 47 | | return ( |
| 48 | | assets.find((a) => a.name.endsWith("-x64.exe")) |
| 49 | | ?.browser_download_url ?? null |
| 50 | | ); |
| 389 | return assets.find((a) => a.name.endsWith("-x64.exe"))?.browser_download_url ?? null; |
| 51 | 390 | } |
| 52 | 391 | if (platform.os === "mac") { |
| 53 | | const preferred = assets.find((a) => |
| 54 | | a.name.endsWith(`-${platform.arch}.dmg`), |
| 55 | | ); |
| 392 | const preferred = assets.find((a) => a.name.endsWith(`-${platform.arch}.dmg`)); |
| 56 | 393 | const fallback = assets.find((a) => a.name.endsWith(".dmg")); |
| 57 | 394 | return (preferred ?? fallback)?.browser_download_url ?? null; |
| 58 | 395 | } |
| 59 | 396 | if (platform.os === "linux") { |
| 60 | | return ( |
| 61 | | assets.find((a) => a.name.endsWith(".AppImage")) |
| 62 | | ?.browser_download_url ?? null |
| 63 | | ); |
| 397 | return assets.find((a) => a.name.endsWith(".AppImage"))?.browser_download_url ?? null; |
| 64 | 398 | } |
| 65 | 399 | return null; |
| 66 | 400 | } |
| ... | ... | @@ -68,24 +402,33 @@ import Layout from "../layouts/Layout.astro"; |
| 68 | 402 | async function init() { |
| 69 | 403 | const btn = document.getElementById("download-btn") as HTMLAnchorElement | null; |
| 70 | 404 | const label = document.getElementById("download-label"); |
| 71 | | if (!btn || !label) return; |
| 405 | const ctaBtn = document.getElementById("cta-download-btn") as HTMLAnchorElement | null; |
| 406 | const ctaLabel = document.getElementById("cta-download-label"); |
| 72 | 407 | |
| 73 | 408 | const platform = detectPlatform(); |
| 74 | 409 | if (!platform) return; |
| 75 | | |
| 76 | 410 | document.documentElement.dataset.platform = platform.os; |
| 77 | | label.textContent = platform.label; |
| 411 | if (label) label.textContent = platform.label; |
| 412 | if (ctaLabel) ctaLabel.textContent = platform.label; |
| 78 | 413 | |
| 79 | 414 | try { |
| 80 | 415 | const release = await fetchLatestRelease(); |
| 81 | 416 | const url = pickAsset(release.assets ?? [], platform); |
| 82 | 417 | if (url) { |
| 83 | | btn.href = url; |
| 84 | | btn.removeAttribute("target"); |
| 85 | | btn.removeAttribute("rel"); |
| 418 | if (btn) { |
| 419 | btn.href = url; |
| 420 | btn.removeAttribute("target"); |
| 421 | btn.removeAttribute("rel"); |
| 422 | } |
| 423 | if (ctaBtn) { |
| 424 | ctaBtn.href = url; |
| 425 | ctaBtn.removeAttribute("target"); |
| 426 | ctaBtn.removeAttribute("rel"); |
| 427 | } |
| 86 | 428 | } |
| 87 | 429 | } catch { |
| 88 | | btn.href = RELEASES_URL; |
| 430 | if (btn) btn.href = RELEASES_URL; |
| 431 | if (ctaBtn) ctaBtn.href = RELEASES_URL; |
| 89 | 432 | } |
| 90 | 433 | } |
| 91 | 434 | |
| ... | ... | @@ -93,145 +436,693 @@ import Layout from "../layouts/Layout.astro"; |
| 93 | 436 | </script> |
| 94 | 437 | |
| 95 | 438 | <style> |
| 96 | | .main { |
| 97 | | padding-top: 10vh; |
| 439 | /* ── Section base ─────────────────────────────────────────── */ |
| 440 | section { |
| 441 | position: relative; |
| 442 | padding: 96px 0; |
| 443 | border-top: 1px solid var(--border); |
| 444 | } |
| 445 | |
| 446 | .section-head { |
| 447 | margin-bottom: 56px; |
| 448 | max-width: 720px; |
| 98 | 449 | } |
| 99 | 450 | |
| 100 | | /* ── Tagline ── */ |
| 451 | .section-head .eyebrow { |
| 452 | margin-bottom: 14px; |
| 453 | display: block; |
| 454 | } |
| 101 | 455 | |
| 102 | | .tagline { |
| 456 | .section-head h2 { |
| 457 | font-size: clamp(32px, 4vw, 48px); |
| 103 | 458 | font-weight: 500; |
| 104 | | font-size: clamp(2rem, 5vw, 3.5rem); |
| 105 | 459 | letter-spacing: -0.035em; |
| 106 | | line-height: 1.15; |
| 107 | | text-align: center; |
| 108 | | margin: 0 0 6vh; |
| 109 | | opacity: 0; |
| 110 | | animation: fade-in 1s ease-out forwards; |
| 460 | line-height: 1.05; |
| 461 | margin-bottom: 18px; |
| 462 | } |
| 463 | |
| 464 | .section-head p { |
| 465 | color: var(--fg-muted); |
| 466 | font-size: 18px; |
| 467 | max-width: 620px; |
| 468 | letter-spacing: -0.005em; |
| 111 | 469 | } |
| 112 | 470 | |
| 113 | | /* ── Hero button ── */ |
| 471 | .checklist { |
| 472 | list-style: none; |
| 473 | display: flex; |
| 474 | flex-direction: column; |
| 475 | gap: 12px; |
| 476 | } |
| 114 | 477 | |
| 115 | | .hero-button { |
| 116 | | display: inline-flex; |
| 478 | .checklist li { |
| 479 | display: flex; |
| 117 | 480 | align-items: center; |
| 118 | | gap: 0.55rem; |
| 119 | | background: #fafafa; |
| 120 | | color: #09090b; |
| 121 | | padding: 0.75rem 2rem; |
| 122 | | border-radius: 999px; |
| 123 | | font-weight: 600; |
| 124 | | font-size: 0.9rem; |
| 125 | | margin-bottom: 1.25rem; |
| 126 | | opacity: 0; |
| 127 | | animation: fade-in 1s ease-out 0.15s forwards; |
| 128 | | transition: transform 0.25s ease, box-shadow 0.25s ease; |
| 481 | gap: 10px; |
| 482 | color: var(--fg-muted); |
| 483 | font-size: 15px; |
| 484 | } |
| 485 | |
| 486 | .checklist li svg { |
| 487 | color: var(--ok); |
| 488 | flex-shrink: 0; |
| 489 | } |
| 490 | |
| 491 | /* ── Hero ─────────────────────────────────────────────────── */ |
| 492 | .hero { |
| 493 | padding: 72px 0 60px; |
| 494 | position: relative; |
| 495 | overflow: hidden; |
| 496 | border-top: 0; |
| 497 | } |
| 498 | |
| 499 | .hero-grid { |
| 500 | position: absolute; |
| 501 | inset: 0; |
| 502 | pointer-events: none; |
| 503 | background-image: |
| 504 | linear-gradient(to right, rgba(255, 255, 255, 0.035) 1px, transparent 1px), |
| 505 | linear-gradient(to bottom, rgba(255, 255, 255, 0.035) 1px, transparent 1px); |
| 506 | background-size: 48px 48px; |
| 507 | mask-image: radial-gradient(ellipse 80% 60% at 50% 40%, black 40%, transparent 100%); |
| 508 | -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 40%, black 40%, transparent 100%); |
| 509 | } |
| 510 | |
| 511 | .hero-inner { |
| 512 | position: relative; |
| 513 | text-align: center; |
| 514 | } |
| 515 | |
| 516 | .hero-title { |
| 517 | font-size: clamp(38px, 5.6vw, 76px); |
| 518 | margin: 28px auto 22px; |
| 519 | max-width: 20ch; |
| 520 | text-wrap: balance; |
| 129 | 521 | } |
| 130 | 522 | |
| 131 | | .hero-button:hover { |
| 132 | | transform: scale(1.03); |
| 133 | | box-shadow: 0 0 24px rgba(255, 255, 255, 0.08); |
| 523 | .hero-sub { |
| 524 | color: var(--fg-muted); |
| 525 | font-size: clamp(16px, 1.4vw, 19px); |
| 526 | max-width: 640px; |
| 527 | margin: 0 auto 36px; |
| 528 | letter-spacing: -0.005em; |
| 529 | line-height: 1.55; |
| 134 | 530 | } |
| 135 | 531 | |
| 136 | | .hero-button:active { |
| 137 | | transform: scale(0.98); |
| 532 | .hero-actions { |
| 533 | display: flex; |
| 534 | gap: 10px; |
| 535 | justify-content: center; |
| 536 | flex-wrap: wrap; |
| 537 | margin-bottom: 56px; |
| 138 | 538 | } |
| 139 | 539 | |
| 140 | | .hero-button-icon { |
| 540 | /* Download button icons (platform-aware) */ |
| 541 | .dl-icon { |
| 141 | 542 | display: none; |
| 142 | | width: 1em; |
| 143 | | height: 1em; |
| 543 | width: 14px; |
| 544 | height: 14px; |
| 144 | 545 | flex-shrink: 0; |
| 145 | 546 | } |
| 146 | 547 | |
| 147 | | :global([data-platform="mac"]) .hero-button-icon--apple { |
| 148 | | display: block; |
| 548 | :global([data-platform="mac"]) .dl-icon--apple { display: block; } |
| 549 | :global([data-platform="win"]) .dl-icon--windows { display: block; } |
| 550 | :global([data-platform="linux"]) .dl-icon--linux { display: block; } |
| 551 | :global(:not([data-platform])) .dl-icon--apple { display: block; } |
| 552 | |
| 553 | /* Floating harness marks */ |
| 554 | .hero-float { |
| 555 | position: absolute; |
| 556 | inset: 0; |
| 557 | pointer-events: none; |
| 558 | z-index: 1; |
| 559 | } |
| 560 | |
| 561 | .hero-float-mark { |
| 562 | position: absolute; |
| 563 | width: 96px; |
| 564 | height: 96px; |
| 565 | border-radius: 24px; |
| 566 | display: grid; |
| 567 | place-items: center; |
| 568 | background: rgba(20, 20, 24, 0.9); |
| 569 | border: 1px solid var(--border); |
| 570 | backdrop-filter: blur(10px); |
| 571 | -webkit-backdrop-filter: blur(10px); |
| 572 | box-shadow: |
| 573 | 0 20px 48px -16px rgba(0, 0, 0, 0.65), |
| 574 | 0 2px 0 0 rgba(255, 255, 255, 0.04) inset; |
| 575 | animation: floatDrift 9s ease-in-out infinite; |
| 149 | 576 | } |
| 150 | 577 | |
| 151 | | :global([data-platform="win"]) .hero-button-icon--windows { |
| 578 | .hero-float-mark img { |
| 579 | width: 54px; |
| 580 | height: 54px; |
| 152 | 581 | display: block; |
| 582 | object-fit: contain; |
| 583 | } |
| 584 | |
| 585 | .hero-float-mark.hf-claude { background: radial-gradient(circle at 30% 25%, rgba(217, 119, 87, 0.22), rgba(20, 20, 24, 0.92) 65%); top: 8%; left: 7%; animation-delay: 0s; transform: rotate(-8deg); } |
| 586 | .hero-float-mark.hf-codex { background: radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.08), rgba(20, 20, 24, 0.92) 65%); top: 6%; right: 7%; animation-delay: -2.5s; transform: rotate(6deg); } |
| 587 | .hero-float-mark.hf-opencode { background: radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.06), rgba(20, 20, 24, 0.92) 65%); top: 32%; left: 5%; animation-delay: -5s; transform: rotate(4deg); } |
| 588 | .hero-float-mark.hf-cursor { background: radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.08), rgba(20, 20, 24, 0.92) 65%); top: 30%; right: 5%; animation-delay: -7s; transform: rotate(-5deg); } |
| 589 | |
| 590 | @media (max-width: 1180px) { |
| 591 | .hero-float-mark { width: 76px; height: 76px; border-radius: 20px; } |
| 592 | .hero-float-mark img { width: 42px; height: 42px; } |
| 593 | .hero-float-mark.hf-claude { top: 4%; left: 3%; } |
| 594 | .hero-float-mark.hf-codex { top: 2%; right: 3%; } |
| 595 | .hero-float-mark.hf-opencode { top: 26%; left: 2%; } |
| 596 | .hero-float-mark.hf-cursor { top: 24%; right: 2%; } |
| 597 | } |
| 598 | |
| 599 | @media (max-width: 820px) { |
| 600 | .hero { |
| 601 | padding-top: 132px; |
| 602 | } |
| 603 | |
| 604 | .hero-title { |
| 605 | font-size: clamp(40px, 11vw, 56px); |
| 606 | margin-top: 14px; |
| 607 | } |
| 608 | |
| 609 | .hero-actions { |
| 610 | margin-bottom: 96px; |
| 611 | } |
| 612 | |
| 613 | .hero-float { |
| 614 | position: absolute; |
| 615 | inset: 0; |
| 616 | display: block; |
| 617 | } |
| 618 | |
| 619 | .hero-float-mark { |
| 620 | position: absolute; |
| 621 | width: 78px; |
| 622 | height: 78px; |
| 623 | border-radius: 20px; |
| 624 | } |
| 625 | |
| 626 | .hero-float-mark img { |
| 627 | width: 44px; |
| 628 | height: 44px; |
| 629 | } |
| 630 | |
| 631 | /* Two above the title, two flanking the call-to-action area. */ |
| 632 | .hero-float-mark.hf-claude { |
| 633 | top: 44px; |
| 634 | left: 10px; |
| 635 | transform: rotate(-10deg); |
| 636 | } |
| 637 | |
| 638 | .hero-float-mark.hf-codex { |
| 639 | top: 44px; |
| 640 | right: 10px; |
| 641 | transform: rotate(8deg); |
| 642 | } |
| 643 | |
| 644 | .hero-float-mark.hf-opencode { |
| 645 | top: 474px; |
| 646 | left: 4px; |
| 647 | right: auto; |
| 648 | transform: rotate(-6deg); |
| 649 | } |
| 650 | |
| 651 | .hero-float-mark.hf-cursor { |
| 652 | top: 474px; |
| 653 | right: 4px; |
| 654 | left: auto; |
| 655 | transform: rotate(7deg); |
| 656 | } |
| 153 | 657 | } |
| 154 | 658 | |
| 155 | | :global([data-platform="linux"]) .hero-button-icon--linux { |
| 659 | .hero-preview { |
| 660 | max-width: 1180px; |
| 661 | margin: 0 auto; |
| 662 | transform: perspective(2000px) rotateX(2deg); |
| 663 | transition: transform 0.6s ease; |
| 664 | } |
| 665 | |
| 666 | .hero-preview:hover { |
| 667 | transform: perspective(2000px) rotateX(0deg); |
| 668 | } |
| 669 | |
| 670 | .hero-screenshot-frame { |
| 671 | position: relative; |
| 672 | overflow: hidden; |
| 673 | aspect-ratio: 2508 / 1682; |
| 674 | border-radius: 14px; |
| 675 | background: #0a0a0c; |
| 676 | box-shadow: 0 28px 64px -28px rgba(0, 0, 0, 0.75); |
| 677 | } |
| 678 | |
| 679 | .hero-screenshot-frame picture { |
| 156 | 680 | display: block; |
| 681 | width: 100%; |
| 682 | height: 100%; |
| 683 | } |
| 684 | |
| 685 | .hero-screenshot-frame img { |
| 686 | width: calc(100% + 4px); |
| 687 | height: calc(100% + 4px); |
| 688 | margin: -2px; |
| 689 | object-fit: cover; |
| 690 | object-position: center top; |
| 691 | } |
| 692 | |
| 693 | /* ── Harnesses ─────────────────────────────────────────── */ |
| 694 | .sec-harness { background: #09090b; } |
| 695 | |
| 696 | .harness-grid { |
| 697 | display: grid; |
| 698 | grid-template-columns: repeat(4, 1fr); |
| 699 | gap: 0; |
| 700 | border: 1px solid var(--border); |
| 701 | border-radius: var(--radius); |
| 702 | overflow: hidden; |
| 703 | } |
| 704 | |
| 705 | .harness { |
| 706 | padding: 22px 20px; |
| 707 | display: flex; align-items: center; gap: 14px; |
| 708 | border-right: 1px solid var(--border); |
| 709 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.015), transparent); |
| 710 | transition: background 0.2s ease; |
| 157 | 711 | } |
| 712 | .harness:last-child { border-right: 0; } |
| 713 | .harness:hover { background: rgba(255, 255, 255, 0.025); } |
| 158 | 714 | |
| 159 | | /* ── Other platforms link ── */ |
| 715 | .harness-mark { |
| 716 | color: var(--fg); opacity: 0.95; |
| 717 | flex-shrink: 0; width: 28px; height: 28px; |
| 718 | display: grid; place-items: center; |
| 719 | } |
| 720 | .harness-mark img { width: 22px; height: 22px; object-fit: contain; } |
| 160 | 721 | |
| 161 | | .other-platforms { |
| 162 | | font-size: 0.825rem; |
| 163 | | color: var(--fg-dim); |
| 164 | | margin-bottom: 5vh; |
| 165 | | opacity: 0; |
| 166 | | animation: fade-in 1s ease-out 0.3s forwards; |
| 167 | | transition: color 0.3s ease; |
| 168 | | text-decoration: underline; |
| 169 | | text-decoration-color: rgba(113, 113, 122, 0.4); |
| 170 | | text-underline-offset: 3px; |
| 722 | .harness-meta { flex: 1; min-width: 0; } |
| 723 | .harness-name { |
| 724 | font-size: 14px; font-weight: 500; |
| 725 | letter-spacing: -0.01em; margin-bottom: 2px; |
| 726 | } |
| 727 | .harness-tag { |
| 728 | font-family: var(--font-mono); |
| 729 | font-size: 11px; color: var(--fg-dim); |
| 171 | 730 | } |
| 172 | 731 | |
| 173 | | .other-platforms:hover { |
| 732 | .harness-footer { |
| 733 | display: flex; gap: 24px; flex-wrap: wrap; |
| 734 | margin-top: 28px; padding-top: 24px; |
| 735 | border-top: 1px dashed var(--border); |
| 736 | font-size: 13px; color: var(--fg-muted); |
| 737 | } |
| 738 | .harness-footer-item { |
| 739 | display: inline-flex; gap: 8px; align-items: center; |
| 174 | 740 | color: var(--fg-muted); |
| 175 | | text-decoration-color: var(--fg-muted); |
| 176 | 741 | } |
| 742 | .harness-footer-item svg { color: var(--ok); } |
| 177 | 743 | |
| 178 | | /* ── Screenshot ── */ |
| 744 | /* ── Endorsements ─────────────────────────────────────── */ |
| 745 | .sec-endorsements { |
| 746 | overflow: hidden; |
| 747 | } |
| 179 | 748 | |
| 180 | | .screenshot-wrap { |
| 181 | | margin: 0 auto; |
| 182 | | width: min(95vw, 1400px); |
| 183 | | opacity: 0; |
| 184 | | transform: scale(0.98); |
| 185 | | animation: screenshot-in 1s ease-out 0.15s forwards; |
| 749 | .endorsements-head { |
| 750 | max-width: 720px; |
| 751 | margin-bottom: 56px; |
| 186 | 752 | } |
| 187 | 753 | |
| 188 | | .screenshot { |
| 189 | | width: 100%; |
| 190 | | display: block; |
| 191 | | border-radius: 16px; |
| 192 | | border: 1px solid rgba(255, 255, 255, 0.06); |
| 193 | | mask-image: linear-gradient(to bottom, black 80%, transparent 100%); |
| 194 | | -webkit-mask-image: linear-gradient(to bottom, black 80%, transparent 100%); |
| 754 | .endorsements-head h2 { |
| 755 | font-size: clamp(32px, 4vw, 48px); |
| 756 | font-weight: 500; |
| 757 | letter-spacing: -0.035em; |
| 758 | line-height: 1.05; |
| 759 | margin-bottom: 18px; |
| 195 | 760 | } |
| 196 | 761 | |
| 197 | | .screenshot-wrap::after { |
| 762 | .endorsements-head p { |
| 763 | color: var(--fg-muted); |
| 764 | font-size: 18px; |
| 765 | max-width: 620px; |
| 766 | letter-spacing: -0.005em; |
| 767 | } |
| 768 | |
| 769 | .endorsement-carousel { |
| 770 | position: relative; |
| 771 | display: flex; |
| 772 | flex-direction: column; |
| 773 | gap: 12px; |
| 774 | } |
| 775 | |
| 776 | .endorsement-carousel--mobile { |
| 777 | display: none; |
| 778 | } |
| 779 | |
| 780 | .endorsement-carousel::before, |
| 781 | .endorsement-carousel::after { |
| 198 | 782 | content: ""; |
| 199 | | display: block; |
| 200 | | width: 100%; |
| 201 | | height: 120px; |
| 202 | | background: inherit; |
| 203 | | margin-top: -1px; |
| 204 | | opacity: 0.04; |
| 205 | | transform: scaleY(-1); |
| 206 | | mask-image: linear-gradient(to bottom, black 0%, transparent 60%); |
| 207 | | -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 60%); |
| 783 | position: absolute; |
| 784 | top: 0; |
| 785 | bottom: 0; |
| 786 | z-index: 2; |
| 787 | width: max(48px, calc((100vw - 1240px) / 2 + 56px)); |
| 788 | pointer-events: none; |
| 789 | } |
| 790 | |
| 791 | .endorsement-carousel::before { |
| 792 | left: 0; |
| 793 | background: linear-gradient(90deg, var(--bg), transparent); |
| 794 | } |
| 795 | |
| 796 | .endorsement-carousel::after { |
| 797 | right: 0; |
| 798 | background: linear-gradient(270deg, var(--bg), transparent); |
| 799 | } |
| 800 | |
| 801 | .endorsement-row { |
| 802 | overflow: hidden; |
| 803 | } |
| 804 | |
| 805 | .endorsement-track { |
| 806 | width: max-content; |
| 807 | display: flex; |
| 808 | animation: endorsementMarquee 76s linear infinite; |
| 809 | will-change: transform; |
| 810 | } |
| 811 | |
| 812 | .endorsement-track-group { |
| 813 | display: flex; |
| 814 | gap: 12px; |
| 815 | padding-right: 12px; |
| 816 | } |
| 817 | |
| 818 | .endorsement-row.is-reverse .endorsement-track { |
| 819 | animation-direction: reverse; |
| 820 | animation-duration: 84s; |
| 821 | } |
| 822 | |
| 823 | .endorsement-carousel:hover .endorsement-track, |
| 824 | .endorsement-carousel:focus-within .endorsement-track { |
| 825 | animation-play-state: paused; |
| 826 | } |
| 827 | |
| 828 | .endorsement-card { |
| 829 | position: relative; |
| 830 | width: clamp(264px, 22vw, 308px); |
| 831 | height: 132px; |
| 832 | padding: 14px 16px; |
| 833 | display: flex; |
| 834 | flex-direction: column; |
| 835 | gap: 10px; |
| 836 | border: 1px solid var(--border); |
| 837 | border-radius: 10px; |
| 838 | background: rgba(255, 255, 255, 0.012); |
| 839 | transition: |
| 840 | border-color 0.18s ease, |
| 841 | background 0.18s ease; |
| 842 | } |
| 843 | |
| 844 | .endorsement-card:hover { |
| 845 | border-color: var(--border-strong); |
| 846 | background: rgba(255, 255, 255, 0.03); |
| 847 | } |
| 848 | |
| 849 | .endorsement-author { |
| 850 | display: flex; |
| 851 | align-items: center; |
| 852 | gap: 8px; |
| 853 | min-width: 0; |
| 854 | } |
| 855 | |
| 856 | .endorsement-author img { |
| 857 | width: 28px; |
| 858 | height: 28px; |
| 859 | border-radius: 50%; |
| 860 | object-fit: cover; |
| 861 | flex-shrink: 0; |
| 862 | } |
| 863 | |
| 864 | .endorsement-handle { |
| 865 | color: var(--fg-muted); |
| 866 | font-size: 13px; |
| 867 | font-weight: 500; |
| 868 | letter-spacing: -0.005em; |
| 869 | overflow: hidden; |
| 870 | text-overflow: ellipsis; |
| 871 | white-space: nowrap; |
| 872 | } |
| 873 | |
| 874 | .endorsement-card p { |
| 875 | color: var(--fg); |
| 876 | font-size: 13.5px; |
| 877 | line-height: 1.4; |
| 878 | letter-spacing: -0.003em; |
| 879 | display: -webkit-box; |
| 880 | overflow: hidden; |
| 881 | -webkit-box-orient: vertical; |
| 882 | -webkit-line-clamp: 3; |
| 883 | } |
| 884 | |
| 885 | /* ── Git ──────────────────────────────────────────────── */ |
| 886 | .git-inner { |
| 887 | display: grid; |
| 888 | grid-template-columns: 1.1fr 1fr; |
| 889 | gap: 64px; align-items: center; |
| 890 | } |
| 891 | |
| 892 | .git-visual { |
| 893 | position: relative; |
| 894 | display: flex; flex-direction: column; |
| 895 | align-items: stretch; gap: 20px; |
| 896 | } |
| 897 | |
| 898 | .pr-card { padding: 20px; } |
| 899 | .pr-head { |
| 900 | display: flex; align-items: center; gap: 10px; |
| 901 | margin-bottom: 12px; |
| 902 | } |
| 903 | .pr-head svg { color: var(--ok); } |
| 904 | .pr-title { font-weight: 500; font-size: 15px; flex: 1; } |
| 905 | .pr-status { |
| 906 | font-family: var(--font-mono); font-size: 10px; |
| 907 | color: var(--ok); padding: 2px 8px; |
| 908 | border: 1px solid var(--ok); border-radius: 999px; |
| 909 | letter-spacing: 0.08em; text-transform: uppercase; |
| 910 | } |
| 911 | .pr-meta { |
| 912 | display: flex; gap: 14px; |
| 913 | font-family: var(--font-mono); font-size: 11px; |
| 914 | color: var(--fg-dim); margin-bottom: 14px; flex-wrap: wrap; |
| 915 | } |
| 916 | .pr-meta span { display: inline-flex; align-items: center; gap: 5px; } |
| 917 | .pr-files { |
| 918 | border: 1px solid var(--border); border-radius: 8px; |
| 919 | overflow: hidden; margin-bottom: 16px; |
| 920 | } |
| 921 | .pr-files > div { |
| 922 | display: flex; justify-content: space-between; |
| 923 | padding: 8px 12px; font-family: var(--font-mono); |
| 924 | font-size: 11px; border-top: 1px solid var(--border); |
| 925 | color: var(--fg-muted); |
| 926 | } |
| 927 | .pr-files > div:first-child { border-top: 0; } |
| 928 | .pr-files span { color: var(--fg-dim); } |
| 929 | .pr-foot { display: flex; justify-content: flex-end; gap: 8px; } |
| 930 | |
| 931 | .pr-trail { |
| 932 | display: flex; flex-direction: column; |
| 933 | align-items: center; justify-content: center; |
| 934 | gap: 0; margin: -4px 0; |
| 935 | } |
| 936 | .pr-trail-dot { |
| 937 | width: 8px; height: 8px; border-radius: 999px; |
| 938 | background: var(--border-strong); |
| 939 | } |
| 940 | .pr-trail-line { |
| 941 | width: 1px; height: 28px; |
| 942 | background: linear-gradient(180deg, var(--border-strong), var(--accent)); |
| 943 | } |
| 944 | |
| 945 | .pr-button-shell { display: flex; justify-content: center; } |
| 946 | .pr-button { |
| 947 | display: inline-flex; align-items: center; gap: 10px; |
| 948 | padding: 12px 20px; |
| 949 | background: var(--fg); color: #09090b; |
| 950 | font-weight: 600; font-size: 13px; |
| 951 | border-radius: 10px; |
| 952 | box-shadow: 0 8px 24px -8px rgba(255, 255, 255, 0.2); |
| 953 | } |
| 954 | .pr-button-kbd { |
| 955 | font-family: var(--font-mono); font-size: 10px; |
| 956 | background: rgba(0, 0, 0, 0.1); |
| 957 | padding: 2px 6px; border-radius: 4px; |
| 958 | } |
| 959 | |
| 960 | /* ── Open source ──────────────────────────────────────── */ |
| 961 | .open-head { |
| 962 | text-align: center; |
| 963 | margin: 0 auto 56px; |
| 964 | } |
| 965 | .open-head p { margin: 0 auto; } |
| 966 | |
| 967 | .open-grid { |
| 968 | display: grid; |
| 969 | grid-template-columns: 1.25fr 1fr; |
| 970 | gap: 20px; margin-bottom: 32px; |
| 971 | } |
| 972 | |
| 973 | .open-term { padding: 0; overflow: hidden; } |
| 974 | .open-term-head { |
| 975 | display: flex; align-items: center; gap: 6px; |
| 976 | padding: 10px 14px; border-bottom: 1px solid var(--border); |
| 977 | background: rgba(255, 255, 255, 0.02); |
| 978 | } |
| 979 | .open-term-head span { |
| 980 | width: 10px; height: 10px; border-radius: 999px; |
| 981 | background: #2a2a30; display: block; |
| 982 | } |
| 983 | .open-term-title { |
| 984 | margin-left: 10px; |
| 985 | font-family: var(--font-mono); font-size: 11px; |
| 986 | color: var(--fg-dim); flex: 1; text-align: center; |
| 987 | background: transparent !important; |
| 988 | width: auto !important; height: auto !important; |
| 989 | border-radius: 0 !important; |
| 990 | } |
| 991 | |
| 992 | .open-term-body { |
| 993 | padding: 20px 22px; |
| 994 | font-family: var(--font-mono); font-size: 13px; |
| 995 | line-height: 1.7; color: var(--fg); |
| 996 | } |
| 997 | .open-term-body > div { |
| 998 | white-space: nowrap; overflow: hidden; text-overflow: ellipsis; |
| 999 | } |
| 1000 | .open-term-body .prompt { color: var(--accent); margin-right: 8px; } |
| 1001 | .open-term-body .dim { color: var(--fg-dim); } |
| 1002 | .open-term-body .accent { color: var(--accent); } |
| 1003 | .open-term-body .cursor { display: flex; align-items: center; } |
| 1004 | .caret { |
| 1005 | display: inline-block; |
| 1006 | width: 7px; height: 14px; |
| 1007 | background: var(--fg); |
| 1008 | margin-left: 4px; |
| 1009 | animation: blink 1s steps(2) infinite; |
| 1010 | } |
| 1011 | |
| 1012 | .open-stats { |
| 1013 | display: grid; |
| 1014 | grid-template-columns: 1fr 1fr; |
| 1015 | gap: 12px; |
| 1016 | } |
| 1017 | .open-stat { |
| 1018 | padding: 22px; |
| 1019 | display: flex; flex-direction: column; gap: 6px; |
| 1020 | } |
| 1021 | .open-stat-val { |
| 1022 | font-size: 22px; font-weight: 500; |
| 1023 | letter-spacing: -0.015em; |
| 1024 | } |
| 1025 | .open-stat-lbl { |
| 1026 | font-family: var(--font-mono); font-size: 10.5px; |
| 1027 | color: var(--fg-dim); letter-spacing: 0.04em; |
| 1028 | } |
| 1029 | |
| 1030 | .open-ctas { |
| 1031 | display: flex; gap: 10px; |
| 1032 | justify-content: center; flex-wrap: wrap; |
| 1033 | } |
| 1034 | |
| 1035 | /* ── Final CTA ────────────────────────────────────────── */ |
| 1036 | .sec-cta { |
| 1037 | text-align: center; |
| 1038 | padding: 120px 0; |
| 1039 | position: relative; |
| 1040 | overflow: hidden; |
| 1041 | } |
| 1042 | .sec-cta::before { |
| 1043 | content: ""; |
| 1044 | position: absolute; |
| 1045 | inset: auto 0 -50% 0; |
| 1046 | height: 60%; |
| 1047 | background: radial-gradient(ellipse at center, var(--accent-dim) 0%, transparent 60%); |
| 208 | 1048 | pointer-events: none; |
| 1049 | opacity: 0.6; |
| 1050 | } |
| 1051 | .cta-inner { position: relative; } |
| 1052 | .cta-title { |
| 1053 | font-size: clamp(40px, 6vw, 72px); |
| 1054 | } |
| 1055 | .cta-sub { |
| 1056 | color: var(--fg-muted); |
| 1057 | font-size: 18px; |
| 1058 | max-width: 560px; |
| 1059 | margin: 20px auto 36px; |
| 1060 | line-height: 1.55; |
| 1061 | letter-spacing: -0.005em; |
| 1062 | } |
| 1063 | .cta-actions { |
| 1064 | display: flex; gap: 10px; |
| 1065 | justify-content: center; flex-wrap: wrap; |
| 1066 | margin-bottom: 24px; |
| 209 | 1067 | } |
| 210 | 1068 | |
| 211 | | @keyframes screenshot-in { |
| 1069 | @keyframes endorsementMarquee { |
| 212 | 1070 | from { |
| 213 | | opacity: 0; |
| 214 | | transform: scale(0.98); |
| 1071 | transform: translateX(0); |
| 215 | 1072 | } |
| 216 | 1073 | to { |
| 217 | | opacity: 1; |
| 218 | | transform: scale(1); |
| 1074 | transform: translateX(-50%); |
| 219 | 1075 | } |
| 220 | 1076 | } |
| 221 | 1077 | |
| 222 | | /* ── Mobile ── */ |
| 223 | | |
| 224 | | @media (max-width: 640px) { |
| 225 | | .main { |
| 226 | | padding-top: 7vh; |
| 1078 | /* ── Responsive ────────────────────────────────────────── */ |
| 1079 | @media (max-width: 960px) { |
| 1080 | .hero-preview { |
| 1081 | width: min(860px, calc(100vw - 24px)); |
| 1082 | margin-left: 50%; |
| 1083 | transform: translateX(-50%) perspective(1600px) rotateX(1.5deg); |
| 227 | 1084 | } |
| 228 | | |
| 229 | | .tagline { |
| 230 | | margin-bottom: 4vh; |
| 1085 | .hero-preview:hover { |
| 1086 | transform: translateX(-50%) perspective(1600px) rotateX(0deg); |
| 231 | 1087 | } |
| 1088 | .harness-grid { grid-template-columns: 1fr 1fr; } |
| 1089 | .harness { border-right: 0; border-bottom: 1px solid var(--border); } |
| 1090 | .harness:nth-child(odd) { border-right: 1px solid var(--border); } |
| 1091 | .git-inner { grid-template-columns: 1fr; gap: 40px; } |
| 1092 | .open-grid { grid-template-columns: 1fr; } |
| 1093 | } |
| 232 | 1094 | |
| 233 | | .screenshot-wrap { |
| 234 | | width: 95vw; |
| 1095 | @media (max-width: 820px) { |
| 1096 | section { padding: 64px 0; } |
| 1097 | .sec-cta { padding: 96px 0; } |
| 1098 | .container { padding-left: 20px; padding-right: 20px; } |
| 1099 | .hero-preview { display: none; } |
| 1100 | .endorsements-head { |
| 1101 | margin-bottom: 40px; |
| 1102 | } |
| 1103 | .endorsement-carousel--desktop { |
| 1104 | display: none; |
| 1105 | } |
| 1106 | .endorsement-carousel--mobile { |
| 1107 | display: flex; |
| 1108 | } |
| 1109 | .endorsement-carousel::before, |
| 1110 | .endorsement-carousel::after { |
| 1111 | width: 28px; |
| 1112 | } |
| 1113 | .endorsement-track { |
| 1114 | animation-duration: 68s; |
| 1115 | } |
| 1116 | .endorsement-row.is-reverse .endorsement-track { |
| 1117 | animation-duration: 76s; |
| 1118 | } |
| 1119 | .endorsement-card { |
| 1120 | width: 268px; |
| 1121 | height: 132px; |
| 1122 | padding: 14px; |
| 1123 | } |
| 1124 | .endorsement-card p { |
| 1125 | font-size: 13px; |
| 235 | 1126 | } |
| 236 | 1127 | } |
| 237 | 1128 | </style> |