| ... | @@ -1,26 +1,372 @@ | ... | @@ -1,26 +1,372 @@ |
| 1 | --- | 1 | --- |
| 2 | import Layout from "../layouts/Layout.astro"; | 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 | <Layout> | 18 | <Layout> |
| 6 | <h1 class="tagline">T3 Code is the best way to code with AI.</h1> | 19 | <!-- ── Hero ──────────────────────────────────────────────────── --> |
| 7 | | 20 | <section class="hero"> |
| 8 | <a | 21 | <div class="hero-grid" aria-hidden="true"></div> |
| 9 | id="download-btn" | 22 | |
| 10 | href="https://github.com/pingdotgg/t3code/releases" | 23 | <div class="hero-float" aria-hidden="true"> |
| 11 | class="hero-button" | 24 | <span class="hero-float-mark hf-claude" title="Claude Code"> |
| 12 | > | 25 | <img src="/harnesses/claude-ai-icon.svg" alt="" /> |
| 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> | 26 | </span> |
| 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> | 27 | <span class="hero-float-mark hf-codex" title="Codex"> |
| 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> | 28 | <img src="/harnesses/openai_dark.svg" alt="" /> |
| 16 | <span id="download-label">Download now</span> | 29 | </span> |
| 17 | </a> | 30 | <span class="hero-float-mark hf-opencode" title="OpenCode"> |
| 18 | | 31 | <img src="/harnesses/opencode-dark.svg" alt="" /> |
| 19 | <a href="/download" class="other-platforms">Other platforms</a> | 32 | </span> |
| 20 | | 33 | <span class="hero-float-mark hf-cursor" title="Cursor"> |
| 21 | <div class="screenshot-wrap"> | 34 | <img src="/harnesses/cursor_light.svg" alt="" /> |
| 22 | <img src="/screenshot.jpeg" alt="T3 Code" class="screenshot" /> | 35 | </span> |
| 23 | </div> | 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 | </Layout> | 370 | </Layout> |
| 25 | | 371 | |
| 26 | <script> | 372 | <script> |
| ... | @@ -32,11 +378,7 @@ import Layout from "../layouts/Layout.astro"; | ... | @@ -32,11 +378,7 @@ import Layout from "../layouts/Layout.astro"; |
| 32 | const ua = navigator.userAgent; | 378 | const ua = navigator.userAgent; |
| 33 | if (/Win/i.test(ua)) return { os: "win", label: "Download for Windows" }; | 379 | if (/Win/i.test(ua)) return { os: "win", label: "Download for Windows" }; |
| 34 | if (/Mac/i.test(ua)) { | 380 | if (/Mac/i.test(ua)) { |
| 35 | return { | 381 | return { os: "mac", label: "Download for macOS", arch: "arm64" }; |
| 36 | os: "mac", | | |
| 37 | label: `Download for macOS`, | | |
| 38 | arch: "arm64", | | |
| 39 | }; | | |
| 40 | } | 382 | } |
| 41 | if (/Linux/i.test(ua)) return { os: "linux", label: "Download for Linux" }; | 383 | if (/Linux/i.test(ua)) return { os: "linux", label: "Download for Linux" }; |
| 42 | return null; | 384 | return null; |
| ... | @@ -44,23 +386,15 @@ import Layout from "../layouts/Layout.astro"; | ... | @@ -44,23 +386,15 @@ import Layout from "../layouts/Layout.astro"; |
| 44 | | 386 | |
| 45 | function pickAsset(assets: ReleaseAsset[], platform: Platform): string | null { | 387 | function pickAsset(assets: ReleaseAsset[], platform: Platform): string | null { |
| 46 | if (platform.os === "win") { | 388 | if (platform.os === "win") { |
| 47 | return ( | 389 | return assets.find((a) => a.name.endsWith("-x64.exe"))?.browser_download_url ?? null; |
| 48 | assets.find((a) => a.name.endsWith("-x64.exe")) | | |
| 49 | ?.browser_download_url ?? null | | |
| 50 | ); | | |
| 51 | } | 390 | } |
| 52 | if (platform.os === "mac") { | 391 | if (platform.os === "mac") { |
| 53 | const preferred = assets.find((a) => | 392 | const preferred = assets.find((a) => a.name.endsWith(`-${platform.arch}.dmg`)); |
| 54 | a.name.endsWith(`-${platform.arch}.dmg`), | | |
| 55 | ); | | |
| 56 | const fallback = assets.find((a) => a.name.endsWith(".dmg")); | 393 | const fallback = assets.find((a) => a.name.endsWith(".dmg")); |
| 57 | return (preferred ?? fallback)?.browser_download_url ?? null; | 394 | return (preferred ?? fallback)?.browser_download_url ?? null; |
| 58 | } | 395 | } |
| 59 | if (platform.os === "linux") { | 396 | if (platform.os === "linux") { |
| 60 | return ( | 397 | return assets.find((a) => a.name.endsWith(".AppImage"))?.browser_download_url ?? null; |
| 61 | assets.find((a) => a.name.endsWith(".AppImage")) | | |
| 62 | ?.browser_download_url ?? null | | |
| 63 | ); | | |
| 64 | } | 398 | } |
| 65 | return null; | 399 | return null; |
| 66 | } | 400 | } |
| ... | @@ -68,24 +402,33 @@ import Layout from "../layouts/Layout.astro"; | ... | @@ -68,24 +402,33 @@ import Layout from "../layouts/Layout.astro"; |
| 68 | async function init() { | 402 | async function init() { |
| 69 | const btn = document.getElementById("download-btn") as HTMLAnchorElement | null; | 403 | const btn = document.getElementById("download-btn") as HTMLAnchorElement | null; |
| 70 | const label = document.getElementById("download-label"); | 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 | const platform = detectPlatform(); | 408 | const platform = detectPlatform(); |
| 74 | if (!platform) return; | 409 | if (!platform) return; |
| 75 | | | |
| 76 | document.documentElement.dataset.platform = platform.os; | 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 | try { | 414 | try { |
| 80 | const release = await fetchLatestRelease(); | 415 | const release = await fetchLatestRelease(); |
| 81 | const url = pickAsset(release.assets ?? [], platform); | 416 | const url = pickAsset(release.assets ?? [], platform); |
| 82 | if (url) { | 417 | if (url) { |
| 83 | btn.href = url; | 418 | if (btn) { |
| 84 | btn.removeAttribute("target"); | 419 | btn.href = url; |
| 85 | btn.removeAttribute("rel"); | 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 | } catch { | 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,145 +436,693 @@ import Layout from "../layouts/Layout.astro"; |
| 93 | </script> | 436 | </script> |
| 94 | | 437 | |
| 95 | <style> | 438 | <style> |
| 96 | .main { | 439 | /* ── Section base ─────────────────────────────────────────── */ |
| 97 | padding-top: 10vh; | 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 | font-weight: 500; | 458 | font-weight: 500; |
| 104 | font-size: clamp(2rem, 5vw, 3.5rem); | | |
| 105 | letter-spacing: -0.035em; | 459 | letter-spacing: -0.035em; |
| 106 | line-height: 1.15; | 460 | line-height: 1.05; |
| 107 | text-align: center; | 461 | margin-bottom: 18px; |
| 108 | margin: 0 0 6vh; | 462 | } |
| 109 | opacity: 0; | 463 | |
| 110 | animation: fade-in 1s ease-out forwards; | 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 { | 478 | .checklist li { |
| 116 | display: inline-flex; | 479 | display: flex; |
| 117 | align-items: center; | 480 | align-items: center; |
| 118 | gap: 0.55rem; | 481 | gap: 10px; |
| 119 | background: #fafafa; | 482 | color: var(--fg-muted); |
| 120 | color: #09090b; | 483 | font-size: 15px; |
| 121 | padding: 0.75rem 2rem; | 484 | } |
| 122 | border-radius: 999px; | 485 | |
| 123 | font-weight: 600; | 486 | .checklist li svg { |
| 124 | font-size: 0.9rem; | 487 | color: var(--ok); |
| 125 | margin-bottom: 1.25rem; | 488 | flex-shrink: 0; |
| 126 | opacity: 0; | 489 | } |
| 127 | animation: fade-in 1s ease-out 0.15s forwards; | 490 | |
| 128 | transition: transform 0.25s ease, box-shadow 0.25s ease; | 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 { | 523 | .hero-sub { |
| 132 | transform: scale(1.03); | 524 | color: var(--fg-muted); |
| 133 | box-shadow: 0 0 24px rgba(255, 255, 255, 0.08); | 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 { | 532 | .hero-actions { |
| 137 | transform: scale(0.98); | 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 | display: none; | 542 | display: none; |
| 142 | width: 1em; | 543 | width: 14px; |
| 143 | height: 1em; | 544 | height: 14px; |
| 144 | flex-shrink: 0; | 545 | flex-shrink: 0; |
| 145 | } | 546 | } |
| 146 | | 547 | |
| 147 | :global([data-platform="mac"]) .hero-button-icon--apple { | 548 | :global([data-platform="mac"]) .dl-icon--apple { display: block; } |
| 148 | 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 | display: block; | 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 | display: block; | 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 { | 722 | .harness-meta { flex: 1; min-width: 0; } |
| 162 | font-size: 0.825rem; | 723 | .harness-name { |
| 163 | color: var(--fg-dim); | 724 | font-size: 14px; font-weight: 500; |
| 164 | margin-bottom: 5vh; | 725 | letter-spacing: -0.01em; margin-bottom: 2px; |
| 165 | opacity: 0; | 726 | } |
| 166 | animation: fade-in 1s ease-out 0.3s forwards; | 727 | .harness-tag { |
| 167 | transition: color 0.3s ease; | 728 | font-family: var(--font-mono); |
| 168 | text-decoration: underline; | 729 | font-size: 11px; color: var(--fg-dim); |
| 169 | text-decoration-color: rgba(113, 113, 122, 0.4); | | |
| 170 | text-underline-offset: 3px; | | |
| 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 | color: var(--fg-muted); | 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 { | 749 | .endorsements-head { |
| 181 | margin: 0 auto; | 750 | max-width: 720px; |
| 182 | width: min(95vw, 1400px); | 751 | margin-bottom: 56px; |
| 183 | opacity: 0; | | |
| 184 | transform: scale(0.98); | | |
| 185 | animation: screenshot-in 1s ease-out 0.15s forwards; | | |
| 186 | } | 752 | } |
| 187 | | 753 | |
| 188 | .screenshot { | 754 | .endorsements-head h2 { |
| 189 | width: 100%; | 755 | font-size: clamp(32px, 4vw, 48px); |
| 190 | display: block; | 756 | font-weight: 500; |
| 191 | border-radius: 16px; | 757 | letter-spacing: -0.035em; |
| 192 | border: 1px solid rgba(255, 255, 255, 0.06); | 758 | line-height: 1.05; |
| 193 | mask-image: linear-gradient(to bottom, black 80%, transparent 100%); | 759 | margin-bottom: 18px; |
| 194 | -webkit-mask-image: linear-gradient(to bottom, black 80%, transparent 100%); | | |
| 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 | content: ""; | 782 | content: ""; |
| 199 | display: block; | 783 | position: absolute; |
| 200 | width: 100%; | 784 | top: 0; |
| 201 | height: 120px; | 785 | bottom: 0; |
| 202 | background: inherit; | 786 | z-index: 2; |
| 203 | margin-top: -1px; | 787 | width: max(48px, calc((100vw - 1240px) / 2 + 56px)); |
| 204 | opacity: 0.04; | 788 | pointer-events: none; |
| 205 | transform: scaleY(-1); | 789 | } |
| 206 | mask-image: linear-gradient(to bottom, black 0%, transparent 60%); | 790 | |
| 207 | -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 60%); | 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 | pointer-events: none; | 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 | from { | 1070 | from { |
| 213 | opacity: 0; | 1071 | transform: translateX(0); |
| 214 | transform: scale(0.98); | | |
| 215 | } | 1072 | } |
| 216 | to { | 1073 | to { |
| 217 | opacity: 1; | 1074 | transform: translateX(-50%); |
| 218 | transform: scale(1); | | |
| 219 | } | 1075 | } |
| 220 | } | 1076 | } |
| 221 | | 1077 | |
| 222 | /* ── Mobile ── */ | 1078 | /* ── Responsive ────────────────────────────────────────── */ |
| 223 | | 1079 | @media (max-width: 960px) { |
| 224 | @media (max-width: 640px) { | 1080 | .hero-preview { |
| 225 | .main { | 1081 | width: min(860px, calc(100vw - 24px)); |
| 226 | padding-top: 7vh; | 1082 | margin-left: 50%; |
| | 1083 | transform: translateX(-50%) perspective(1600px) rotateX(1.5deg); |
| 227 | } | 1084 | } |
| 228 | | 1085 | .hero-preview:hover { |
| 229 | .tagline { | 1086 | transform: translateX(-50%) perspective(1600px) rotateX(0deg); |
| 230 | margin-bottom: 4vh; | | |
| 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 { | 1095 | @media (max-width: 820px) { |
| 234 | width: 95vw; | 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 | </style> | 1128 | </style> |