1---
2import RetroIcon from "../components/RetroIcon.astro";
3import RetroBox from "../components/RetroBox.astro";
4import { GITHUB_REPOSITORY_URL, MARKETING_STATS } from "../lib/site";
5import "../styles/retro.css";
6
7const agents = [
8 {
9 name: "Claude Code",
10 slug: "claude-code",
11 caption: "Now with manners.",
12 artwork: "Cream and orange software box with a bow-tied desktop computer and a gold PLEASE sticker.",
13 },
14 {
15 name: "Codex",
16 slug: "codex",
17 caption: "Some assembly automated.",
18 artwork: "Silver and green software box with a robot hand stacking glowing code blocks.",
19 },
20 {
21 name: "Cursor",
22 slug: "cursor",
23 caption: "Point. Click. Question everything.",
24 artwork: "Black and chrome software box with an enormous silver arrow and lightning bolts.",
25 },
26 {
27 name: "Grok",
28 slug: "grok",
29 caption: "Adult supervision sold separately.",
30 artwork: "Black and red software box with a spacecraft and an UH OH sticker.",
31 },
32 {
33 name: "OpenCode",
34 slug: "opencode",
35 caption: "Please copy this floppy.",
36 artwork: "Purple shareware box with floppy disks spilling from an open carton.",
37 },
38 {
39 name: "Antigravity",
40 slug: "antigravity",
41 caption: "System requirement: no gravity.",
42 artwork: "Blue and violet software box with a floating chrome triangle and metallic spheres.",
43 },
44];
45const userDigits = MARKETING_STATS.users.replaceAll(",", "").padStart(7, "0").split("");
46---
47
48<!doctype html>
49<html lang="en">
50 <head>
51 <meta charset="UTF-8" />
52 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
53 <meta name="description" content="Introducing T3 Code. All your coding agents in one happy little window. Free, open source, and available without six CD-ROMs." />
54 <meta name="theme-color" content="#000000" />
55 <link rel="icon" href="/favicon.ico" sizes="48x48" />
56 <title>T3 Code '95 | The future is now. Like, right now.</title>
57 </head>
58 <body>
59 <a class="skip-link retro-button" href="#main-content">Skip to the sales pitch</a>
60
61 <nav class="desktop-icons" aria-label="Desktop shortcuts">
62 <a href="/" class="desktop-icon"><RetroIcon name="computer" /><span>My Computer</span></a>
63 <a href="/download" class="desktop-icon"><RetroIcon name="disk" /><span>Install T3 Code</span></a>
64 <a href={GITHUB_REPOSITORY_URL} class="desktop-icon"><RetroIcon name="globe" /><span>Network<br />Neighborhood</span></a>
65 <button type="button" class="desktop-icon" data-dialog="recycle"><RetroIcon name="bin" /><span>Bad Ideas</span></button>
66 </nav>
67
68 <div class="desktop">
69 <div class="browser-window raised" id="sales-window">
70 <header class="window-title" id="window-title" tabindex="0" aria-label="Move browser window. Drag or use arrow keys. Double-click to maximize.">
71 <span class="window-name"><RetroIcon name="globe" size={18} /><span>T3 Code '95 - Internet Explorer</span></span>
72 <div class="window-controls">
73 <button class="retro-button window-control" type="button" id="minimize" aria-label="Minimize window"><span aria-hidden="true">_</span></button>
74 <button class="retro-button window-control" type="button" id="maximize" aria-label="Maximize window" aria-pressed="false"><span class="maximize-icon" aria-hidden="true"></span></button>
75 <button class="retro-button window-control" type="button" data-dialog="close" aria-label="Close window"><span aria-hidden="true">×</span></button>
76 </div>
77 </header>
78
79 <nav class="browser-menu" aria-label="Page navigation">
80 <a href="#nightly"><u>N</u>ightly</a>
81 <a href="#features"><u>F</u>eatures</a>
82 <a href="#agents"><u>A</u>gents</a>
83 <a href="#order"><u>O</u>rder now</a>
84 <a href={GITHUB_REPOSITORY_URL}><u>S</u>ource</a>
85 <button type="button" data-dialog="help"><u>H</u>elp</button>
86 </nav>
87
88 <div class="address-bar">
89 <span>Address</span>
90 <div class="address-field sunken"><RetroIcon name="globe" size={16} /><span>https://t3.codes/95</span></div>
91 <a class="retro-button address-go" href="/">Go <span aria-hidden="true">↗</span></a>
92 </div>
93
94 <main id="main-content" tabindex="0">
95 <section class="hero" aria-labelledby="hero-title">
96 <div class="hero-copy">
97 <h1 id="hero-title">All your agents.<br />One happy<br /><span>little window.</span></h1>
98 <p class="hero-explanation">Your coding agents in one free, open-source app.<br />You bring the subscriptions. We bring the buttons.</p>
99 <div class="platform-line"><span>AVAILABLE FOR</span><strong>Windows</strong><b>·</b><strong>macOS</strong><b>·</b><strong>Linux</strong></div>
100 </div>
101
102 <div class="edition-packages" aria-label="Choose Stable or Nightly">
103 <a class="hero-package" href="/download" aria-label="Download T3 Code stable">
104 <RetroBox image="t3-code-lime" alt="T3 Code in a lime and teal software box." sizes="(max-width: 620px) 38vw, 170px" eager />
105 <span class="retro-button edition-download">Get Stable <span aria-hidden="true">↗</span></span>
106 </a>
107 <a class="hero-package nightly-package" id="nightly" href="/download?channel=nightly" aria-label="Download T3 Code Nightly preview builds">
108 <RetroBox image="t3-code-nightly-clouds" alt="T3 Code Nightly in a navy box with violet clouds." sizes="(max-width: 620px) 38vw, 170px" eager />
109 <span class="retro-button edition-download">Get Nightly <span aria-hidden="true">↗</span></span>
110 </a>
111 </div>
112 </section>
113
114 <section class="agents-section" id="agents" aria-labelledby="agents-title">
115 <div class="section-heading"><h2 id="agents-title">Bring your favorite agents.</h2></div>
116 <div class="agent-list">
117 {agents.map((agent, index) => (
118 <figure class="agent">
119 <img
120 class="agent-box"
121 src={`/95/providers/${agent.slug}-640.webp`}
122 srcset={[320, 640, 960].map((width) => `/95/providers/${agent.slug}-${width}.webp ${width}w`).join(", ")}
123 sizes="auto, (max-width: 620px) 43vw, (max-width: 1100px) 27vw, 280px"
124 alt={agent.artwork}
125 width="640"
126 height="800"
127 loading={index < 3 ? "eager" : "lazy"}
128 decoding="async"
129 />
130 <figcaption>
131 <h3>{agent.name}</h3>
132 <p>{agent.caption}</p>
133 </figcaption>
134 </figure>
135 ))}
136 </div>
137 <p class="agents-note">Use the providers and subscriptions you already have. Provider charges still apply.</p>
138 <p class="agents-note">Parody packaging. No actual boxes for sale.</p>
139 </section>
140
141 <section class="features-section" id="features" aria-labelledby="features-title">
142 <div class="section-heading"><h2 id="features-title">Inside every copy.</h2></div>
143 <div class="feature-grid">
144 <article class="feature-window raised">
145 <div class="feature-titlebar"><span>01_multitasking.exe</span><span aria-hidden="true">■</span></div>
146 <div class="feature-body"><RetroIcon name="computer" size={38} /><h3>More agents.<br />Less window aerobics.</h3><p>Run agents side by side. Keep your threads, terminals, and diffs together. Reclaim your Alt-Tab finger.</p></div>
147 </article>
148 <article class="feature-window raised">
149 <div class="feature-titlebar"><span>02_remote_access.exe</span><span aria-hidden="true">■</span></div>
150 <div class="feature-body"><RetroIcon name="globe" size={38} /><h3>Your computer.<br />Now over there.</h3><p>Connect from the web, desktop, or mobile. Your agents keep working on your machine. You may approach the couch.</p></div>
151 </article>
152 <article class="feature-window raised">
153 <div class="feature-titlebar"><span>03_source_code.txt</span><span aria-hidden="true">■</span></div>
154 <div class="feature-body"><RetroIcon name="folder" size={38} /><h3>We left the<br />source code in.</h3><p>Read it. Change it. Fork the whole thing. It's MIT licensed, because your tools should actually be yours.</p><a class="feature-tag" href={GITHUB_REPOSITORY_URL}>View source <span aria-hidden="true">↗</span></a></div>
155 </article>
156 <article class="feature-window raised">
157 <div class="feature-titlebar"><span>04_terminal.exe</span><span aria-hidden="true">■</span></div>
158 <div class="feature-body"><RetroIcon name="computer" size={38} /><h3>A terminal.<br />Right where you work.</h3><p>Run commands alongside your agents. Keep the output with the project.</p></div>
159 </article>
160 <article class="feature-window raised">
161 <div class="feature-titlebar"><span>05_changes.diff</span><span aria-hidden="true">■</span></div>
162 <div class="feature-body"><RetroIcon name="folder" size={38} /><h3>See what<br />actually changed.</h3><p>Inspect file diffs and review the work before you ship it.</p></div>
163 </article>
164 <article class="feature-window raised">
165 <div class="feature-titlebar"><span>06_checkpoint.bak</span><span aria-hidden="true">■</span></div>
166 <div class="feature-body"><RetroIcon name="disk" size={38} /><h3>A way<br />back.</h3><p>Use turn checkpoints to inspect changes and restore earlier work.</p></div>
167 </article>
168 </div>
169 </section>
170
171 <section class="order-section" id="order" aria-labelledby="order-title">
172 <div class="order-pitch"><h2 id="order-title">For just <span>0 easy payments</span><br />of absolutely nothing.</h2><p>Get the app. Keep your subscriptions.</p><a class="retro-button primary-cta" href="/download"><RetroIcon name="disk" size={25} /><span>GET T3 CODE. IT'S FREE.</span><span aria-hidden="true">→</span></a><p class="offer-note">T3 Code is free. Your AI provider may charge for use.</p></div>
173 <div class="run-window raised"><div class="window-title"><span>Run</span><RetroIcon name="computer" size={18} /></div><div class="run-body"><p>Too cool for an installer?</p><label for="run-command">Type this in your terminal.</label><div class="command-row"><input id="run-command" class="sunken" value="npx t3" readonly spellcheck="false" aria-label="Terminal command" /><button type="button" class="retro-button" id="copy-command">Copy</button></div><p class="command-feedback" id="command-feedback" role="status">Node.js required. Modem optional.</p><div class="run-divider"></div><b>System requirements</b><ul><li>A modern computer</li><li>A supported coding agent</li><li>A dream, ideally a small one</li></ul><p class="requirements-note">Does not actually run on Windows 95.</p></div></div>
174 </section>
175
176 <section class="faq-section" aria-labelledby="faq-title">
177 <h2 id="faq-title">Questions</h2>
178 <details><summary>Wait. Is this a real product?</summary><p>Yes. T3 Code is a real, free, open-source app used by {MARKETING_STATS.users} developers. The packaging is a joke. The app is not. <a href="/">Visit the regular website.</a></p></details>
179 <details><summary>Does this replace my Claude or Codex subscription?</summary><p>No. T3 Code connects to the coding agents you already use. Keep your provider accounts and subscriptions. T3 Code gives you one app to work with them.</p></details>
180 <details><summary>Will it run on Windows 95?</summary><p>Absolutely not. We brought back the look, not the driver problems. <a href="/download">Get a build for a current version of Windows, macOS, or Linux.</a></p></details>
181 <details><summary>Where do I mail my check?</summary><p>Please do not mail us a check for zero dollars. Just download the app. The entire accounts department is a download button.</p></details>
182 </section>
183
184 <footer class="site-footer">
185 <div class="visitor-counter"><div class="counter-digits" aria-label={`${MARKETING_STATS.users} users`}>{userDigits.map((digit) => <span aria-hidden="true">{digit}</span>)}</div><span>developers use T3 Code.</span></div>
186 <p>© {new Date().getFullYear()} T3 Tools Inc.</p>
187 <nav aria-label="Footer"><a href="/">Back to the present</a><a href={GITHUB_REPOSITORY_URL}>GitHub</a><a href="/privacy-policy">Privacy</a><a href="/terms-of-service">Terms</a></nav>
188 </footer>
189 </main>
190
191 <div class="browser-status"><span class="sunken">Done.</span><span class="sunken"><RetroIcon name="globe" size={14} /> Internet</span><span class="resize-grip" aria-hidden="true"></span></div>
192 </div>
193
194 <div class="minimized-message" id="minimized-message" hidden><RetroIcon name="computer" size={64} /><h1>The future is minimized.</h1><p>Your productivity is one click away.</p><button type="button" class="retro-button" data-restore>Restore T3 Code '95</button></div>
195 </div>
196
197 <div class="taskbar raised">
198 <details class="start-menu" id="start-menu"><summary class="retro-button start-button"><span class="start-mark" aria-hidden="true"><i></i><i></i><i></i><i></i></span>Start</summary><nav class="start-panel raised" aria-label="Start menu"><div class="start-brand">T3 CODE <b>95</b></div><div><a href="/download"><RetroIcon name="disk" size={24} />Install T3 Code</a><button type="button" data-restore><RetroIcon name="computer" size={24} />Restore the future</button><a href={GITHUB_REPOSITORY_URL}><RetroIcon name="folder" size={24} />Explore source code</a><a href="/"><RetroIcon name="globe" size={24} />Return to the present</a></div></nav></details>
199 <span class="taskbar-divider" aria-hidden="true"></span>
200 <button class="task-button sunken" type="button" data-restore><RetroIcon name="globe" size={20} /><span>T3 Code '95</span></button>
201 <div class="taskbar-clock sunken"><span aria-hidden="true">◷</span><span>4:04 PM</span></div>
202 </div>
203
204 <dialog class="retro-dialog raised" id="sales-dialog" aria-labelledby="dialog-title" aria-describedby="dialog-message"><div class="window-title"><span id="dialog-title">T3 Code '95</span><button type="button" class="retro-button window-control" data-dismiss aria-label="Close dialog">×</button></div><div class="dialog-content"><RetroIcon name="computer" size={42} /><p id="dialog-message"></p></div><div class="dialog-actions"><button class="retro-button" type="button" data-dismiss autofocus>OK, fine.</button><a class="retro-button" href="/download">Get T3 Code</a></div></dialog>
205
206 <script>
207 const salesWindow = document.querySelector<HTMLElement>("#sales-window");
208 const minimizedMessage = document.querySelector<HTMLElement>("#minimized-message");
209 const minimizeButton = document.querySelector<HTMLButtonElement>("#minimize");
210 const maximizeButton = document.querySelector<HTMLButtonElement>("#maximize");
211 const startMenu = document.querySelector<HTMLDetailsElement>("#start-menu");
212 const taskButton = document.querySelector<HTMLButtonElement>(".task-button");
213 const titleBar = document.querySelector<HTMLElement>("#window-title");
214 const taskbar = document.querySelector<HTMLElement>(".taskbar");
215 let windowX = 0;
216 let windowY = 0;
217
218 // Keep the entire window above the taskbar, including after a viewport resize.
219 function moveWindow(x: number, y: number) {
220 if (!salesWindow || document.body.classList.contains("maximized")) return;
221 const rect = salesWindow.getBoundingClientRect();
222 const originX = rect.left - windowX;
223 const originY = rect.top - windowY;
224 const bottom = taskbar?.getBoundingClientRect().top ?? window.innerHeight;
225 windowX = Math.max(-originX, Math.min(x, window.innerWidth - rect.width - originX));
226 windowY = Math.max(-originY, Math.min(y, bottom - rect.height - originY));
227 salesWindow.style.setProperty("--window-x", `${windowX}px`);
228 salesWindow.style.setProperty("--window-y", `${windowY}px`);
229 }
230
231 function toggleMaximize() {
232 if (!maximizeButton) return;
233 const maximized = document.body.classList.toggle("maximized");
234 maximizeButton.setAttribute("aria-pressed", String(maximized));
235 maximizeButton.setAttribute("aria-label", maximized ? "Restore window size" : "Maximize window");
236 if (!maximized) moveWindow(windowX, windowY);
237 }
238
239 if (titleBar && salesWindow) {
240 let drag: { pointerId: number; startX: number; startY: number; x: number; y: number } | undefined;
241
242 titleBar.addEventListener("pointerdown", (event) => {
243 if (!event.isPrimary || event.button !== 0 || document.body.classList.contains("maximized")) return;
244 if (event.target instanceof Element && event.target.closest("button")) return;
245 drag = { pointerId: event.pointerId, startX: event.clientX, startY: event.clientY, x: windowX, y: windowY };
246 titleBar.focus({ preventScroll: true });
247 titleBar.setPointerCapture(event.pointerId);
248 titleBar.classList.add("dragging");
249 });
250 titleBar.addEventListener("pointermove", (event) => {
251 if (!drag || event.pointerId !== drag.pointerId) return;
252 moveWindow(drag.x + event.clientX - drag.startX, drag.y + event.clientY - drag.startY);
253 });
254 const stopDrag = () => {
255 drag = undefined;
256 titleBar.classList.remove("dragging");
257 };
258 titleBar.addEventListener("pointerup", stopDrag);
259 titleBar.addEventListener("pointercancel", stopDrag);
260 titleBar.addEventListener("lostpointercapture", stopDrag);
261 titleBar.addEventListener("dblclick", (event) => {
262 if (event.target instanceof Element && event.target.closest("button")) return;
263 toggleMaximize();
264 });
265 titleBar.addEventListener("keydown", (event) => {
266 if (event.target !== titleBar || event.altKey || event.ctrlKey || event.metaKey) return;
267 const step = event.shiftKey ? 1 : 10;
268 switch (event.key) {
269 case "ArrowLeft": moveWindow(windowX - step, windowY); break;
270 case "ArrowRight": moveWindow(windowX + step, windowY); break;
271 case "ArrowUp": moveWindow(windowX, windowY - step); break;
272 case "ArrowDown": moveWindow(windowX, windowY + step); break;
273 default: return;
274 }
275 event.preventDefault();
276 });
277 }
278
279 window.addEventListener("resize", () => {
280 if (!salesWindow?.hidden) moveWindow(windowX, windowY);
281 });
282
283 minimizeButton?.addEventListener("click", () => {
284 if (!salesWindow || !minimizedMessage) return;
285 salesWindow.hidden = true;
286 minimizedMessage.hidden = false;
287 taskButton?.focus();
288 });
289
290 document.querySelectorAll<HTMLButtonElement>("[data-restore]").forEach((button) => {
291 button.addEventListener("click", () => {
292 if (!salesWindow || !minimizedMessage) return;
293 salesWindow.hidden = false;
294 minimizedMessage.hidden = true;
295 if (startMenu) startMenu.open = false;
296 moveWindow(windowX, windowY);
297 minimizeButton?.focus({ preventScroll: true });
298 });
299 });
300
301 maximizeButton?.addEventListener("click", toggleMaximize);
302
303 const messages = {
304 recycle: { title: "Recycle Bin", message: "Contents: 47 abandoned side projects, 12 startup ideas, and one very ambitious TODO comment. T3 Code cannot fix your commitment issues. But it can help you ship." },
305 close: { title: "Close the future?", message: "You are about to return to a world with too many terminal windows. Are you sure? Our sales department would prefer that you download T3 Code." },
306 help: { title: "Windows Help", message: "It looks like you're trying to ship software. Have you tried putting all your coding agents in one app? Click Get T3 Code. No paperclip will follow you home." },
307 };
308 const dialog = document.querySelector<HTMLDialogElement>("#sales-dialog");
309 const dialogTitle = document.querySelector<HTMLElement>("#dialog-title");
310 const dialogMessage = document.querySelector<HTMLElement>("#dialog-message");
311
312 document.querySelectorAll<HTMLButtonElement>("[data-dialog]").forEach((button) => {
313 button.addEventListener("click", () => {
314 const kind = button.dataset.dialog;
315 if (!dialog || !dialogTitle || !dialogMessage) return;
316 if (kind !== "recycle" && kind !== "close" && kind !== "help") return;
317 dialogTitle.textContent = messages[kind].title;
318 dialogMessage.textContent = messages[kind].message;
319 dialog.showModal();
320 });
321 });
322 document.querySelectorAll<HTMLButtonElement>("[data-dismiss]").forEach((button) => {
323 button.addEventListener("click", () => dialog?.close());
324 });
325
326 document.addEventListener("keydown", (event) => {
327 if (event.key === "Escape" && startMenu?.open) {
328 startMenu.open = false;
329 startMenu.querySelector("summary")?.focus();
330 }
331 });
332 document.addEventListener("click", (event) => {
333 if (startMenu?.open && event.target instanceof Node && !startMenu.contains(event.target)) {
334 startMenu.open = false;
335 }
336 });
337
338 const copyButton = document.querySelector<HTMLButtonElement>("#copy-command");
339 const command = document.querySelector<HTMLInputElement>("#run-command");
340 const feedback = document.querySelector<HTMLElement>("#command-feedback");
341 copyButton?.addEventListener("click", async () => {
342 if (!command || !feedback) return;
343 try {
344 await navigator.clipboard.writeText(command.value);
345 feedback.textContent = "Copied! Paste it in your terminal. Welcome to the future.";
346 } catch {
347 command.focus();
348 command.select();
349 feedback.textContent = "Select and copy the command, then paste it in your terminal.";
350 }
351 });
352 </script>
353 </body>
354</html>