Unified · Split
| @@ -0,0 +1,228 @@ | ||
| 1 | +--- | |
| 2 | +interface Props { | |
| 3 | + title?: string; | |
| 4 | + description?: string; | |
| 5 | +} | |
| 6 | + | |
| 7 | +const { | |
| 8 | + title = "T3 Code", | |
| 9 | + description = "T3 Code — The best way to code with AI.", | |
| 10 | +} = Astro.props; | |
| 11 | +--- | |
| 12 | + | |
| 13 | +<html lang="en"> | |
| 14 | + <head> | |
| 15 | + <meta charset="UTF-8" /> | |
| 16 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 17 | + <meta name="description" content={description} /> | |
| 18 | + <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| 19 | + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| 20 | + <link | |
| 21 | + href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600&display=swap" | |
| 22 | + rel="stylesheet" | |
| 23 | + /> | |
| 24 | + <link rel="icon" href="/favicon.ico" sizes="48x48" /> | |
| 25 | + <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32" /> | |
| 26 | + <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16" /> | |
| 27 | + <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> | |
| 28 | + <title>{title}</title> | |
| 29 | + </head> | |
| 30 | + <body> | |
| 31 | + <div class="page"> | |
| 32 | + <nav class="nav"> | |
| 33 | + <a href="/" class="nav-brand"> | |
| 34 | + <img src="/icon.png" alt="T3" class="nav-icon" /> | |
| 35 | + </a> | |
| 36 | + <a | |
| 37 | + href="https://github.com/pingdotgg/t3code" | |
| 38 | + target="_blank" | |
| 39 | + rel="noopener noreferrer" | |
| 40 | + class="nav-github" | |
| 41 | + > | |
| 42 | + GitHub | |
| 43 | + <span class="nav-github-arrow" aria-hidden="true">↗</span> | |
| 44 | + </a> | |
| 45 | + </nav> | |
| 46 | + | |
| 47 | + <main class="main"> | |
| 48 | + <slot /> | |
| 49 | + </main> | |
| 50 | + | |
| 51 | + <footer class="footer"> | |
| 52 | + <span class="footer-copy">© {new Date().getFullYear()} T3 Tools Inc</span> | |
| 53 | + <div class="footer-links"> | |
| 54 | + <a href="https://github.com/pingdotgg/t3code" target="_blank" rel="noopener noreferrer">GitHub</a> | |
| 55 | + <a href="https://discord.gg/jn4EGJjrvv" target="_blank" rel="noopener noreferrer">Discord</a> | |
| 56 | + </div> | |
| 57 | + </footer> | |
| 58 | + </div> | |
| 59 | + </body> | |
| 60 | +</html> | |
| 61 | + | |
| 62 | +<style is:global> | |
| 63 | + :root { | |
| 64 | + --bg: #09090b; | |
| 65 | + --fg: #fafafa; | |
| 66 | + --fg-muted: #a1a1aa; | |
| 67 | + --fg-dim: #71717a; | |
| 68 | + --border: rgba(255, 255, 255, 0.08); | |
| 69 | + } | |
| 70 | + | |
| 71 | + * { | |
| 72 | + box-sizing: border-box; | |
| 73 | + margin: 0; | |
| 74 | + padding: 0; | |
| 75 | + } | |
| 76 | + | |
| 77 | + html { | |
| 78 | + color-scheme: dark; | |
| 79 | + } | |
| 80 | + | |
| 81 | + body { | |
| 82 | + background: var(--bg); | |
| 83 | + color: var(--fg); | |
| 84 | + font-family: "DM Sans", -apple-system, BlinkMacSystemFont, system-ui, sans-serif; | |
| 85 | + -webkit-font-smoothing: antialiased; | |
| 86 | + -moz-osx-font-smoothing: grayscale; | |
| 87 | + min-height: 100vh; | |
| 88 | + overflow-x: hidden; | |
| 89 | + } | |
| 90 | + | |
| 91 | + body::after { | |
| 92 | + content: ""; | |
| 93 | + position: fixed; | |
| 94 | + inset: 0; | |
| 95 | + pointer-events: none; | |
| 96 | + opacity: 0.035; | |
| 97 | + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); | |
| 98 | + background-repeat: repeat; | |
| 99 | + background-size: 256px 256px; | |
| 100 | + z-index: 9999; | |
| 101 | + } | |
| 102 | + | |
| 103 | + a { | |
| 104 | + color: inherit; | |
| 105 | + text-decoration: none; | |
| 106 | + } | |
| 107 | + | |
| 108 | + img { | |
| 109 | + display: block; | |
| 110 | + max-width: 100%; | |
| 111 | + } | |
| 112 | + | |
| 113 | + @keyframes fade-in { | |
| 114 | + from { | |
| 115 | + opacity: 0; | |
| 116 | + transform: translateY(8px); | |
| 117 | + } | |
| 118 | + to { | |
| 119 | + opacity: 1; | |
| 120 | + transform: translateY(0); | |
| 121 | + } | |
| 122 | + } | |
| 123 | +</style> | |
| 124 | + | |
| 125 | +<style> | |
| 126 | + /* ── Page ── */ | |
| 127 | + | |
| 128 | + .page { | |
| 129 | + min-height: 100vh; | |
| 130 | + display: flex; | |
| 131 | + flex-direction: column; | |
| 132 | + overflow-x: hidden; | |
| 133 | + } | |
| 134 | + | |
| 135 | + /* ── Navbar ── */ | |
| 136 | + | |
| 137 | + .nav { | |
| 138 | + display: flex; | |
| 139 | + align-items: center; | |
| 140 | + justify-content: space-between; | |
| 141 | + padding: 1.5rem 2.5rem; | |
| 142 | + opacity: 0.5; | |
| 143 | + transition: opacity 0.4s ease; | |
| 144 | + } | |
| 145 | + | |
| 146 | + .nav:hover { | |
| 147 | + opacity: 1; | |
| 148 | + } | |
| 149 | + | |
| 150 | + .nav-brand { | |
| 151 | + display: flex; | |
| 152 | + align-items: center; | |
| 153 | + } | |
| 154 | + | |
| 155 | + .nav-icon { | |
| 156 | + width: 28px; | |
| 157 | + height: 28px; | |
| 158 | + border-radius: 6px; | |
| 159 | + } | |
| 160 | + | |
| 161 | + .nav-github { | |
| 162 | + display: flex; | |
| 163 | + align-items: center; | |
| 164 | + gap: 0.35rem; | |
| 165 | + color: var(--fg-muted); | |
| 166 | + font-size: 0.875rem; | |
| 167 | + transition: color 0.3s ease; | |
| 168 | + } | |
| 169 | + | |
| 170 | + .nav-github:hover { | |
| 171 | + color: var(--fg); | |
| 172 | + } | |
| 173 | + | |
| 174 | + .nav-github-arrow { | |
| 175 | + display: inline-block; | |
| 176 | + transition: transform 0.3s ease; | |
| 177 | + } | |
| 178 | + | |
| 179 | + .nav-github:hover .nav-github-arrow { | |
| 180 | + transform: translateX(2px) translateY(-1px); | |
| 181 | + } | |
| 182 | + | |
| 183 | + /* ── Main content ── */ | |
| 184 | + | |
| 185 | + .main { | |
| 186 | + flex: 1; | |
| 187 | + display: flex; | |
| 188 | + flex-direction: column; | |
| 189 | + align-items: center; | |
| 190 | + } | |
| 191 | + | |
| 192 | + /* ── Footer ── */ | |
| 193 | + | |
| 194 | + .footer { | |
| 195 | + display: flex; | |
| 196 | + align-items: center; | |
| 197 | + justify-content: space-between; | |
| 198 | + padding: 1.5rem 2.5rem; | |
| 199 | + font-size: 0.8rem; | |
| 200 | + color: var(--fg-dim); | |
| 201 | + } | |
| 202 | + | |
| 203 | + .footer-links { | |
| 204 | + display: flex; | |
| 205 | + gap: 1.25rem; | |
| 206 | + } | |
| 207 | + | |
| 208 | + .footer-links a { | |
| 209 | + color: var(--fg-dim); | |
| 210 | + transition: color 0.3s ease; | |
| 211 | + } | |
| 212 | + | |
| 213 | + .footer-links a:hover { | |
| 214 | + color: var(--fg); | |
| 215 | + } | |
| 216 | + | |
| 217 | + /* ── Mobile ── */ | |
| 218 | + | |
| 219 | + @media (max-width: 640px) { | |
| 220 | + .nav { | |
| 221 | + padding: 1.25rem; | |
| 222 | + } | |
| 223 | + | |
| 224 | + .footer { | |
| 225 | + padding: 1.25rem; | |
| 226 | + } | |
| 227 | + } | |
| 228 | +</style> | |
| @@ -0,0 +1,30 @@ | ||
| 1 | +const REPO = "pingdotgg/t3code"; | |
| 2 | + | |
| 3 | +export const RELEASES_URL = `https://github.com/${REPO}/releases`; | |
| 4 | + | |
| 5 | +const API_URL = `https://api.github.com/repos/${REPO}/releases/latest`; | |
| 6 | +const CACHE_KEY = "t3code-latest-release"; | |
| 7 | + | |
| 8 | +export interface ReleaseAsset { | |
| 9 | + name: string; | |
| 10 | + browser_download_url: string; | |
| 11 | +} | |
| 12 | + | |
| 13 | +export interface Release { | |
| 14 | + tag_name: string; | |
| 15 | + html_url: string; | |
| 16 | + assets: ReleaseAsset[]; | |
| 17 | +} | |
| 18 | + | |
| 19 | +export async function fetchLatestRelease(): Promise<Release> { | |
| 20 | + const cached = sessionStorage.getItem(CACHE_KEY); | |
| 21 | + if (cached) return JSON.parse(cached); | |
| 22 | + | |
| 23 | + const data = await fetch(API_URL).then((r) => r.json()); | |
| 24 | + | |
| 25 | + if (data?.assets) { | |
| 26 | + sessionStorage.setItem(CACHE_KEY, JSON.stringify(data)); | |
| 27 | + } | |
| 28 | + | |
| 29 | + return data; | |
| 30 | +} | |
| @@ -0,0 +1,271 @@ | ||
| 1 | +--- | |
| 2 | +import Layout from "../layouts/Layout.astro"; | |
| 3 | +--- | |
| 4 | + | |
| 5 | +<Layout title="Download — T3 Code" description="Download T3 Code for macOS, Windows, or Linux."> | |
| 6 | + <h1 class="heading">Download T3 Code</h1> | |
| 7 | + <p class="subheading"> | |
| 8 | + <span id="version-label">Loading latest release…</span> | |
| 9 | + <a id="changelog-link" class="changelog-link" href="#" target="_blank" rel="noopener noreferrer" style="display:none">View changelog<span aria-hidden="true"> ↗</span></a> | |
| 10 | + </p> | |
| 11 | + | |
| 12 | + <div class="platforms" id="platforms"> | |
| 13 | + <!-- macOS --> | |
| 14 | + <section class="platform-section"> | |
| 15 | + <div class="platform-header"> | |
| 16 | + <svg class="platform-icon" 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> | |
| 17 | + <h2 class="platform-name">macOS</h2> | |
| 18 | + </div> | |
| 19 | + <div class="download-cards"> | |
| 20 | + <a class="download-card" data-asset="arm64.dmg" href="#"> | |
| 21 | + <span class="card-arch">Apple Silicon (arm64)</span> | |
| 22 | + <span class="card-format">.dmg</span> | |
| 23 | + </a> | |
| 24 | + <a class="download-card" data-asset="x64.dmg" href="#"> | |
| 25 | + <span class="card-arch">Intel (x64)</span> | |
| 26 | + <span class="card-format">.dmg</span> | |
| 27 | + </a> | |
| 28 | + </div> | |
| 29 | + </section> | |
| 30 | + | |
| 31 | + <!-- Windows --> | |
| 32 | + <section class="platform-section"> | |
| 33 | + <div class="platform-header"> | |
| 34 | + <svg class="platform-icon" 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> | |
| 35 | + <h2 class="platform-name">Windows</h2> | |
| 36 | + </div> | |
| 37 | + <div class="download-cards"> | |
| 38 | + <a class="download-card" data-asset="x64.exe" href="#"> | |
| 39 | + <span class="card-arch">Windows 10, 11</span> | |
| 40 | + <span class="card-format">.exe</span> | |
| 41 | + </a> | |
| 42 | + </div> | |
| 43 | + </section> | |
| 44 | + | |
| 45 | + <!-- Linux --> | |
| 46 | + <section class="platform-section"> | |
| 47 | + <div class="platform-header"> | |
| 48 | + <svg class="platform-icon" 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> | |
| 49 | + <h2 class="platform-name">Linux</h2> | |
| 50 | + </div> | |
| 51 | + <div class="download-cards"> | |
| 52 | + <a class="download-card" data-asset="x86_64.AppImage" href="#"> | |
| 53 | + <span class="card-arch">x86_64</span> | |
| 54 | + <span class="card-format">AppImage</span> | |
| 55 | + </a> | |
| 56 | + </div> | |
| 57 | + </section> | |
| 58 | + </div> | |
| 59 | + | |
| 60 | + <p class="releases-link"> | |
| 61 | + Looking for older versions? Check the | |
| 62 | + <a href="https://github.com/pingdotgg/t3code/releases" target="_blank" rel="noopener noreferrer"> | |
| 63 | + GitHub releases page<span aria-hidden="true"> ↗</span> | |
| 64 | + </a> | |
| 65 | + </p> | |
| 66 | +</Layout> | |
| 67 | + | |
| 68 | +<script> | |
| 69 | + import { fetchLatestRelease, RELEASES_URL } from "../lib/releases"; | |
| 70 | + | |
| 71 | + async function init() { | |
| 72 | + const versionLabel = document.getElementById("version-label"); | |
| 73 | + const cards = document.querySelectorAll<HTMLAnchorElement>(".download-card"); | |
| 74 | + | |
| 75 | + try { | |
| 76 | + const release = await fetchLatestRelease(); | |
| 77 | + | |
| 78 | + if (versionLabel && release.tag_name) { | |
| 79 | + versionLabel.textContent = `Latest (${release.tag_name})`; | |
| 80 | + } | |
| 81 | + | |
| 82 | + const changelogLink = document.getElementById("changelog-link") as HTMLAnchorElement | null; | |
| 83 | + if (changelogLink && release.html_url) { | |
| 84 | + changelogLink.href = release.html_url; | |
| 85 | + changelogLink.style.display = ""; | |
| 86 | + } | |
| 87 | + | |
| 88 | + cards.forEach((card) => { | |
| 89 | + const suffix = card.dataset.asset; | |
| 90 | + if (!suffix) return; | |
| 91 | + | |
| 92 | + const match = (release.assets ?? []).find((a) => a.name.endsWith(`-${suffix}`)); | |
| 93 | + if (match) { | |
| 94 | + card.href = match.browser_download_url; | |
| 95 | + } else { | |
| 96 | + card.href = RELEASES_URL; | |
| 97 | + } | |
| 98 | + }); | |
| 99 | + } catch { | |
| 100 | + if (versionLabel) { | |
| 101 | + versionLabel.textContent = "Could not load release info."; | |
| 102 | + } | |
| 103 | + cards.forEach((card) => { | |
| 104 | + card.href = RELEASES_URL; | |
| 105 | + }); | |
| 106 | + } | |
| 107 | + } | |
| 108 | + | |
| 109 | + init(); | |
| 110 | +</script> | |
| 111 | + | |
| 112 | +<style> | |
| 113 | + .main { | |
| 114 | + padding: 8vh 1.5rem 4rem; | |
| 115 | + } | |
| 116 | + | |
| 117 | + /* ── Heading ── */ | |
| 118 | + | |
| 119 | + .heading { | |
| 120 | + font-weight: 500; | |
| 121 | + font-size: clamp(1.75rem, 4vw, 2.75rem); | |
| 122 | + letter-spacing: -0.035em; | |
| 123 | + line-height: 1.15; | |
| 124 | + text-align: center; | |
| 125 | + margin-bottom: 0.5rem; | |
| 126 | + opacity: 0; | |
| 127 | + animation: fade-in 1s ease-out forwards; | |
| 128 | + } | |
| 129 | + | |
| 130 | + .subheading { | |
| 131 | + font-size: 0.9rem; | |
| 132 | + color: var(--fg-dim); | |
| 133 | + margin-bottom: 3.5rem; | |
| 134 | + opacity: 0; | |
| 135 | + animation: fade-in 1s ease-out 0.1s forwards; | |
| 136 | + display: flex; | |
| 137 | + align-items: center; | |
| 138 | + gap: 0.75rem; | |
| 139 | + } | |
| 140 | + | |
| 141 | + .changelog-link { | |
| 142 | + color: var(--fg-muted); | |
| 143 | + font-size: 0.8rem; | |
| 144 | + text-decoration: underline; | |
| 145 | + text-decoration-color: rgba(161, 161, 170, 0.4); | |
| 146 | + text-underline-offset: 3px; | |
| 147 | + transition: color 0.3s ease, text-decoration-color 0.3s ease; | |
| 148 | + } | |
| 149 | + | |
| 150 | + .changelog-link:hover { | |
| 151 | + color: var(--fg); | |
| 152 | + text-decoration-color: var(--fg); | |
| 153 | + } | |
| 154 | + | |
| 155 | + /* ── Platforms ── */ | |
| 156 | + | |
| 157 | + .platforms { | |
| 158 | + width: 100%; | |
| 159 | + max-width: 720px; | |
| 160 | + display: flex; | |
| 161 | + flex-direction: column; | |
| 162 | + gap: 2.5rem; | |
| 163 | + opacity: 0; | |
| 164 | + animation: fade-in 1s ease-out 0.2s forwards; | |
| 165 | + } | |
| 166 | + | |
| 167 | + .platform-section { | |
| 168 | + display: flex; | |
| 169 | + flex-direction: column; | |
| 170 | + gap: 0.75rem; | |
| 171 | + } | |
| 172 | + | |
| 173 | + .platform-header { | |
| 174 | + display: flex; | |
| 175 | + align-items: center; | |
| 176 | + gap: 0.6rem; | |
| 177 | + padding-bottom: 0.5rem; | |
| 178 | + border-bottom: 1px solid var(--border); | |
| 179 | + } | |
| 180 | + | |
| 181 | + .platform-icon { | |
| 182 | + width: 1.15em; | |
| 183 | + height: 1.15em; | |
| 184 | + color: var(--fg-muted); | |
| 185 | + flex-shrink: 0; | |
| 186 | + } | |
| 187 | + | |
| 188 | + .platform-name { | |
| 189 | + font-weight: 500; | |
| 190 | + font-size: 1.1rem; | |
| 191 | + letter-spacing: -0.01em; | |
| 192 | + } | |
| 193 | + | |
| 194 | + /* ── Download cards ── */ | |
| 195 | + | |
| 196 | + .download-cards { | |
| 197 | + display: grid; | |
| 198 | + grid-template-columns: repeat(2, 1fr); | |
| 199 | + gap: 0.5rem; | |
| 200 | + } | |
| 201 | + | |
| 202 | + .download-card { | |
| 203 | + display: flex; | |
| 204 | + flex-direction: column; | |
| 205 | + gap: 0.2rem; | |
| 206 | + padding: 0.85rem 1rem; | |
| 207 | + border-radius: 10px; | |
| 208 | + border: 1px solid var(--border); | |
| 209 | + background: rgba(255, 255, 255, 0.02); | |
| 210 | + transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease; | |
| 211 | + } | |
| 212 | + | |
| 213 | + .download-card:hover { | |
| 214 | + background: rgba(255, 255, 255, 0.06); | |
| 215 | + border-color: rgba(255, 255, 255, 0.15); | |
| 216 | + transform: translateY(-1px); | |
| 217 | + } | |
| 218 | + | |
| 219 | + .download-card:active { | |
| 220 | + transform: translateY(0); | |
| 221 | + } | |
| 222 | + | |
| 223 | + .card-arch { | |
| 224 | + font-weight: 600; | |
| 225 | + font-size: 0.95rem; | |
| 226 | + } | |
| 227 | + | |
| 228 | + .card-format { | |
| 229 | + font-size: 0.8rem; | |
| 230 | + color: var(--fg-dim); | |
| 231 | + } | |
| 232 | + | |
| 233 | + /* ── Releases link ── */ | |
| 234 | + | |
| 235 | + .releases-link { | |
| 236 | + margin-top: 3rem; | |
| 237 | + font-size: 0.825rem; | |
| 238 | + color: var(--fg-dim); | |
| 239 | + opacity: 0; | |
| 240 | + animation: fade-in 1s ease-out 0.35s forwards; | |
| 241 | + } | |
| 242 | + | |
| 243 | + .releases-link a { | |
| 244 | + color: var(--fg-muted); | |
| 245 | + text-decoration: underline; | |
| 246 | + text-decoration-color: rgba(161, 161, 170, 0.4); | |
| 247 | + text-underline-offset: 3px; | |
| 248 | + transition: color 0.3s ease, text-decoration-color 0.3s ease; | |
| 249 | + } | |
| 250 | + | |
| 251 | + .releases-link a:hover { | |
| 252 | + color: var(--fg); | |
| 253 | + text-decoration-color: var(--fg); | |
| 254 | + } | |
| 255 | + | |
| 256 | + /* ── Mobile ── */ | |
| 257 | + | |
| 258 | + @media (max-width: 640px) { | |
| 259 | + .main { | |
| 260 | + padding: 5vh 1.25rem 4rem; | |
| 261 | + } | |
| 262 | + | |
| 263 | + .platforms { | |
| 264 | + padding: 0 0.25rem; | |
| 265 | + } | |
| 266 | + | |
| 267 | + .download-cards { | |
| 268 | + grid-template-columns: 1fr; | |
| 269 | + } | |
| 270 | + } | |
| 271 | +</style> | |
| @@ -1,75 +1,30 @@ | ||
| 1 | 1 | --- |
| 2 | +import Layout from "../layouts/Layout.astro"; | |
| 2 | 3 | --- |
| 3 | 4 | |
| 4 | −<html lang="en"> | |
| 5 | − <head> | |
| 6 | − <meta charset="UTF-8" /> | |
| 7 | − <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 8 | − <meta name="description" content="T3 Code — The best way to code with AI." /> | |
| 9 | − <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| 10 | − <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| 11 | − <link | |
| 12 | − href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600&display=swap" | |
| 13 | − rel="stylesheet" | |
| 14 | − /> | |
| 15 | − <link rel="icon" href="/favicon.ico" sizes="48x48" /> | |
| 16 | − <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32" /> | |
| 17 | − <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16" /> | |
| 18 | − <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> | |
| 19 | − <title>T3 Code</title> | |
| 20 | − </head> | |
| 21 | − <body> | |
| 22 | − <div class="page"> | |
| 23 | − <nav class="nav"> | |
| 24 | − <a href="/" class="nav-brand"> | |
| 25 | − <img src="/icon.png" alt="T3" class="nav-icon" /> | |
| 26 | − </a> | |
| 27 | − <a | |
| 28 | − href="https://github.com/pingdotgg/t3code" | |
| 29 | − target="_blank" | |
| 30 | − rel="noopener noreferrer" | |
| 31 | − class="nav-github" | |
| 32 | − > | |
| 33 | − GitHub | |
| 34 | − <span class="nav-github-arrow" aria-hidden="true">↗</span> | |
| 35 | − </a> | |
| 36 | − </nav> | |
| 37 | − | |
| 38 | − <main class="main"> | |
| 39 | − <h1 class="tagline">T3 Code is the best way to code with AI.</h1> | |
| 40 | − | |
| 41 | − <a | |
| 42 | − id="download-btn" | |
| 43 | − href="https://github.com/pingdotgg/t3code/releases" | |
| 44 | − class="hero-button" | |
| 45 | − > | |
| 46 | − <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> | |
| 47 | − <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> | |
| 48 | − <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> | |
| 49 | − <span id="download-label">Download now</span> | |
| 50 | − </a> | |
| 51 | − | |
| 52 | − <div class="screenshot-wrap"> | |
| 53 | − <img src="/screenshot.jpeg" alt="T3 Code" class="screenshot" /> | |
| 54 | − </div> | |
| 55 | − | |
| 56 | − </main> | |
| 57 | − | |
| 58 | − <footer class="footer"> | |
| 59 | − <span class="footer-copy">© {new Date().getFullYear()} T3 Tools Inc</span> | |
| 60 | − <div class="footer-links"> | |
| 61 | − <a href="https://github.com/pingdotgg/t3code" target="_blank" rel="noopener noreferrer">GitHub</a> | |
| 62 | − <a href="https://discord.gg/jn4EGJjrvv" target="_blank" rel="noopener noreferrer">Discord</a> | |
| 63 | − </div> | |
| 64 | − </footer> | |
| 65 | − </div> | |
| 66 | − </body> | |
| 67 | −</html> | |
| 5 | +<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> | |
| 24 | +</Layout> | |
| 68 | 25 | |
| 69 | 26 | <script> |
| 70 | − const REPO = "pingdotgg/t3code"; | |
| 71 | − const RELEASES_URL = `https://github.com/${REPO}/releases`; | |
| 72 | − const API_URL = `https://api.github.com/repos/${REPO}/releases/latest`; | |
| 27 | + import { fetchLatestRelease, RELEASES_URL, type ReleaseAsset } from "../lib/releases"; | |
| 73 | 28 | |
| 74 | 29 | type Platform = { os: "mac" | "win" | "linux"; label: string; arch?: string }; |
| 75 | 30 | |
| @@ -87,10 +42,7 @@ · 11 unmodified lines | ||
| 87 | 42 | return null; |
| 88 | 43 | } |
| 89 | 44 | |
| 90 | − function pickAsset( | |
| 91 | − assets: Array<{ name: string; browser_download_url: string }>, | |
| 92 | − platform: Platform, | |
| 93 | − ): string | null { | |
| 45 | + function pickAsset(assets: ReleaseAsset[], platform: Platform): string | null { | |
| 94 | 46 | if (platform.os === "win") { |
| 95 | 47 | return ( |
| 96 | 48 | assets.find((a) => a.name.endsWith("-x64.exe")) |
| @@ -125,16 +77,8 @@ · 28 unmodified lines | ||
| 125 | 77 | label.textContent = platform.label; |
| 126 | 78 | |
| 127 | 79 | try { |
| 128 | − const cached = sessionStorage.getItem("t3code-latest-release"); | |
| 129 | − const data = cached | |
| 130 | − ? JSON.parse(cached) | |
| 131 | − : await fetch(API_URL).then((r) => r.json()); | |
| 132 | − | |
| 133 | − if (!cached && data?.assets) { | |
| 134 | − sessionStorage.setItem("t3code-latest-release", JSON.stringify(data)); | |
| 135 | − } | |
| 136 | − | |
| 137 | − const url = pickAsset(data.assets ?? [], platform); | |
| 80 | + const release = await fetchLatestRelease(); | |
| 81 | + const url = pickAsset(release.assets ?? [], platform); | |
| 138 | 82 | if (url) { |
| 139 | 83 | btn.href = url; |
| 140 | 84 | btn.removeAttribute("target"); |
| @@ -149,120 +93,7 @@ · 8 unmodified lines | ||
| 149 | 93 | </script> |
| 150 | 94 | |
| 151 | 95 | <style> |
| 152 | − :root { | |
| 153 | − --bg: #09090b; | |
| 154 | − --fg: #fafafa; | |
| 155 | − --fg-muted: #a1a1aa; | |
| 156 | − --fg-dim: #71717a; | |
| 157 | − --border: rgba(255, 255, 255, 0.08); | |
| 158 | − } | |
| 159 | − | |
| 160 | − * { | |
| 161 | − box-sizing: border-box; | |
| 162 | − margin: 0; | |
| 163 | − padding: 0; | |
| 164 | − } | |
| 165 | − | |
| 166 | − html { | |
| 167 | − color-scheme: dark; | |
| 168 | − } | |
| 169 | − | |
| 170 | − body { | |
| 171 | − background: var(--bg); | |
| 172 | − color: var(--fg); | |
| 173 | − font-family: "DM Sans", -apple-system, BlinkMacSystemFont, system-ui, sans-serif; | |
| 174 | − -webkit-font-smoothing: antialiased; | |
| 175 | − -moz-osx-font-smoothing: grayscale; | |
| 176 | − min-height: 100vh; | |
| 177 | − overflow-x: hidden; | |
| 178 | − } | |
| 179 | − | |
| 180 | − body::after { | |
| 181 | − content: ""; | |
| 182 | − position: fixed; | |
| 183 | − inset: 0; | |
| 184 | − pointer-events: none; | |
| 185 | − opacity: 0.035; | |
| 186 | − background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); | |
| 187 | − background-repeat: repeat; | |
| 188 | − background-size: 256px 256px; | |
| 189 | − z-index: 9999; | |
| 190 | − } | |
| 191 | − | |
| 192 | − a { | |
| 193 | − color: inherit; | |
| 194 | − text-decoration: none; | |
| 195 | − } | |
| 196 | − | |
| 197 | − img { | |
| 198 | − display: block; | |
| 199 | − max-width: 100%; | |
| 200 | − } | |
| 201 | − | |
| 202 | − /* ── Page ── */ | |
| 203 | − | |
| 204 | − .page { | |
| 205 | − min-height: 100vh; | |
| 206 | − display: flex; | |
| 207 | − flex-direction: column; | |
| 208 | − overflow-x: hidden; | |
| 209 | − } | |
| 210 | − | |
| 211 | − /* ── Navbar ── */ | |
| 212 | − | |
| 213 | − .nav { | |
| 214 | − display: flex; | |
| 215 | − align-items: center; | |
| 216 | − justify-content: space-between; | |
| 217 | − padding: 1.5rem 2.5rem; | |
| 218 | − opacity: 0.5; | |
| 219 | − transition: opacity 0.4s ease; | |
| 220 | − } | |
| 221 | − | |
| 222 | − .nav:hover { | |
| 223 | − opacity: 1; | |
| 224 | − } | |
| 225 | − | |
| 226 | − .nav-brand { | |
| 227 | − display: flex; | |
| 228 | − align-items: center; | |
| 229 | − } | |
| 230 | − | |
| 231 | − .nav-icon { | |
| 232 | − width: 28px; | |
| 233 | − height: 28px; | |
| 234 | − border-radius: 6px; | |
| 235 | − } | |
| 236 | − | |
| 237 | − .nav-github { | |
| 238 | − display: flex; | |
| 239 | − align-items: center; | |
| 240 | − gap: 0.35rem; | |
| 241 | − color: var(--fg-muted); | |
| 242 | − font-size: 0.875rem; | |
| 243 | − transition: color 0.3s ease; | |
| 244 | − } | |
| 245 | − | |
| 246 | − .nav-github:hover { | |
| 247 | − color: var(--fg); | |
| 248 | − } | |
| 249 | − | |
| 250 | − .nav-github-arrow { | |
| 251 | − display: inline-block; | |
| 252 | − transition: transform 0.3s ease; | |
| 253 | − } | |
| 254 | − | |
| 255 | − .nav-github:hover .nav-github-arrow { | |
| 256 | − transform: translateX(2px) translateY(-1px); | |
| 257 | − } | |
| 258 | − | |
| 259 | − /* ── Main content ── */ | |
| 260 | − | |
| 261 | 96 | .main { |
| 262 | − flex: 1; | |
| 263 | − display: flex; | |
| 264 | − flex-direction: column; | |
| 265 | − align-items: center; | |
| 266 | 97 | padding-top: 10vh; |
| 267 | 98 | } |
| 268 | 99 | |
| @@ -291,7 +122,7 @@ · 22 unmodified lines | ||
| 291 | 122 | border-radius: 999px; |
| 292 | 123 | font-weight: 600; |
| 293 | 124 | font-size: 0.9rem; |
| 294 | − margin-bottom: 5vh; | |
| 125 | + margin-bottom: 1.25rem; | |
| 295 | 126 | opacity: 0; |
| 296 | 127 | animation: fade-in 1s ease-out 0.15s forwards; |
| 297 | 128 | transition: transform 0.25s ease, box-shadow 0.25s ease; |
| @@ -325,6 +156,25 @@ · 27 unmodified lines | ||
| 325 | 156 | display: block; |
| 326 | 157 | } |
| 327 | 158 | |
| 159 | + /* ── Other platforms link ── */ | |
| 160 | + | |
| 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; | |
| 171 | + } | |
| 172 | + | |
| 173 | + .other-platforms:hover { | |
| 174 | + color: var(--fg-muted); | |
| 175 | + text-decoration-color: var(--fg-muted); | |
| 176 | + } | |
| 177 | + | |
| 328 | 178 | /* ── Screenshot ── */ |
| 329 | 179 | |
| 330 | 180 | .screenshot-wrap { |
| @@ -358,44 +208,6 @@ · 27 unmodified lines | ||
| 358 | 208 | pointer-events: none; |
| 359 | 209 | } |
| 360 | 210 | |
| 361 | − /* ── Footer ── */ | |
| 362 | − | |
| 363 | − .footer { | |
| 364 | − display: flex; | |
| 365 | − align-items: center; | |
| 366 | − justify-content: space-between; | |
| 367 | − padding: 1.5rem 2.5rem; | |
| 368 | − font-size: 0.8rem; | |
| 369 | − color: var(--fg-dim); | |
| 370 | − } | |
| 371 | − | |
| 372 | − .footer-links { | |
| 373 | − display: flex; | |
| 374 | − gap: 1.25rem; | |
| 375 | − } | |
| 376 | − | |
| 377 | − .footer-links a { | |
| 378 | − color: var(--fg-dim); | |
| 379 | − transition: color 0.3s ease; | |
| 380 | − } | |
| 381 | − | |
| 382 | − .footer-links a:hover { | |
| 383 | − color: var(--fg); | |
| 384 | − } | |
| 385 | − | |
| 386 | − /* ── Animations ── */ | |
| 387 | − | |
| 388 | − @keyframes fade-in { | |
| 389 | − from { | |
| 390 | − opacity: 0; | |
| 391 | − transform: translateY(8px); | |
| 392 | − } | |
| 393 | − to { | |
| 394 | − opacity: 1; | |
| 395 | − transform: translateY(0); | |
| 396 | − } | |
| 397 | − } | |
| 398 | − | |
| 399 | 211 | @keyframes screenshot-in { |
| 400 | 212 | from { |
| 401 | 213 | opacity: 0; |
| @@ -410,10 +222,6 @@ · 8 unmodified lines | ||
| 410 | 222 | /* ── Mobile ── */ |
| 411 | 223 | |
| 412 | 224 | @media (max-width: 640px) { |
| 413 | − .nav { | |
| 414 | − padding: 1.25rem 1.25rem; | |
| 415 | − } | |
| 416 | − | |
| 417 | 225 | .main { |
| 418 | 226 | padding-top: 7vh; |
| 419 | 227 | } |
| @@ -425,9 +233,5 @@ · 5 unmodified lines | ||
| 425 | 233 | .screenshot-wrap { |
| 426 | 234 | width: 95vw; |
| 427 | 235 | } |
| 428 | − | |
| 429 | − .footer { | |
| 430 | − padding: 1.25rem; | |
| 431 | − } | |
| 432 | 236 | } |
| 433 | 237 | </style> |