feat(marketing): redesign the T3 Code website - #5457
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| desktopSections.forEach((section) => section.toggleAttribute("hidden", isDev)); | ||
| mobileSection?.toggleAttribute("hidden", isDev); |
There was a problem hiding this comment.
🟠 High pages/download.astro:239
Selecting the Dev desktop channel hides the Mobile section, so the iOS App Store and Google Play download links disappear until the user switches back to Latest or Nightly. The mobile store links are independent of desktop release assets, so they should remain visible in all channels. Consider removing the mobileSection toggle from applyStage.
desktopSections.forEach((section) => section.toggleAttribute("hidden", isDev));
- mobileSection?.toggleAttribute("hidden", isDev);🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/marketing/src/pages/download.astro around lines 239-240:
Selecting the Dev desktop channel hides the Mobile section, so the iOS App Store and Google Play download links disappear until the user switches back to Latest or Nightly. The mobile store links are independent of desktop release assets, so they should remain visible in all channels. Consider removing the `mobileSection` toggle from `applyStage`.
ApprovabilityVerdict: Needs human review 6 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |
d4ceccf to
97f757e
Compare
| display: block; | ||
| } | ||
|
|
||
| .v2-hero-provider-line { |
There was a problem hiding this comment.
🟠 High pages/v2.astro:405
The hero heading is clipped on narrow phone viewports. The .v2-hero-provider-line forces white-space: nowrap while keeping the rotator at a fixed 4.15em width, and .v2-hero has overflow: hidden, so on a 320px screen the combined width of "Bring your" plus the rotator exceeds the available 248px and the rotating provider text is cut off. Consider allowing the line to wrap or shrinking the rotator width under the mobile breakpoint.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/marketing/src/pages/v2.astro around line 405:
The hero heading is clipped on narrow phone viewports. The `.v2-hero-provider-line` forces `white-space: nowrap` while keeping the rotator at a fixed `4.15em` width, and `.v2-hero` has `overflow: hidden`, so on a 320px screen the combined width of "Bring your" plus the rotator exceeds the available 248px and the rotating provider text is cut off. Consider allowing the line to wrap or shrinking the rotator width under the mobile breakpoint.
01b20ba to
0aecacb
Compare
0aecacb to
3b3333d
Compare
| [WS_METHODS.projectsWriteFile]: () => unsupported("projectsWriteFile"), | ||
| [WS_METHODS.shellOpenInEditor]: () => unsupported("shellOpenInEditor"), | ||
| [WS_METHODS.filesystemBrowse]: () => unsupported("filesystemBrowse"), | ||
| [WS_METHODS.assetsCreateUrl]: (input) => |
There was a problem hiding this comment.
🟡 Medium demo/server.ts:1106
demoAssetsExpireAt is computed once at module load as Date.now() + 24h, so every assetsCreateUrl call returns the same absolute timestamp. After the demo tab has been open for 24 hours, newly requested attachment/favicon URLs are reported as already expired, and consumers cannot refresh to a valid result. Compute the expiry relative to each request instead.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/demo/server.ts around line 1106:
`demoAssetsExpireAt` is computed once at module load as `Date.now() + 24h`, so every `assetsCreateUrl` call returns the same absolute timestamp. After the demo tab has been open for 24 hours, newly requested attachment/favicon URLs are reported as already expired, and consumers cannot refresh to a valid result. Compute the expiry relative to each request instead.
| return data; | ||
| } | ||
|
|
||
| export async function fetchNightlyRelease(): Promise<Release> { |
There was a problem hiding this comment.
🟡 Medium lib/releases.ts:154
fetchNightlyRelease stops paginating as soon as a page contains any nightly release, so it can return a stale nightly even when a newer one exists on a later page. GitHub's releases list is ordered by creation time, not by the date/run encoded in the nightly tag, so selectNightlyRelease only sees candidates from the first page that has one and never compares them against newer tags on subsequent pages. Accumulate all releases across pages and run selectNightlyRelease on the full list (or establish a safe ordering cutoff) before stopping.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/marketing/src/lib/releases.ts around line 154:
`fetchNightlyRelease` stops paginating as soon as a page contains *any* nightly release, so it can return a stale nightly even when a newer one exists on a later page. GitHub's releases list is ordered by creation time, not by the date/run encoded in the nightly tag, so `selectNightlyRelease` only sees candidates from the first page that has one and never compares them against newer tags on subsequent pages. Accumulate all releases across pages and run `selectNightlyRelease` on the full list (or establish a safe ordering cutoff) before stopping.
| instanceId={activeEntry.instanceId} | ||
| models={activeEntry.models} | ||
| model={model} | ||
| prompt="" |
There was a problem hiding this comment.
🟠 High demo/modelPicker.tsx:75
Selecting the Ultrathink effort option in the demo's TraitsPicker silently does nothing — the prompt is never updated. TraitsMenuContent handles Ultrathink by calling onPromptChange and returning without touching modelOptions, so when that callback is a no-op the selection is discarded and the demo state stays unchanged. Wire onPromptChange to actual state (e.g. a prompt/setPrompt pair) so prompt-backed traits take effect.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/demo/modelPicker.tsx around line 75:
Selecting the Ultrathink effort option in the demo's `TraitsPicker` silently does nothing — the prompt is never updated. `TraitsMenuContent` handles Ultrathink by calling `onPromptChange` and returning without touching `modelOptions`, so when that callback is a no-op the selection is discarded and the demo state stays unchanged. Wire `onPromptChange` to actual state (e.g. a `prompt`/`setPrompt` pair) so prompt-backed traits take effect.
| completedMinutesAgo: 20, | ||
| }, | ||
| sessionStatus: "ready", | ||
| }), |
There was a problem hiding this comment.
Connect demo missing VCS fixture
Low Severity
thread-connect sets worktreePath to ~/code/t3code-worktrees/remote-command-center, but demoVcsStatusByCwd has no entry for that path. The demo VCS store then falls back to an empty snapshot on main with no remote, so the Connect iframe’s git header disagrees with the thread’s feat/remote-command-center branch. Other worktree showcase threads include matching VCS fixtures.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ef916e4. Configure here.
| function seedOpenSourceTerminalState(): void { | ||
| const params = new URLSearchParams(window.location.search); | ||
| if (params.get("showcase") !== "open-source") return; | ||
|
|
||
| const persisted = readLocalStorage(TERMINAL_UI_STATE_STORAGE_KEY); |
There was a problem hiding this comment.
🟡 Medium demo/seed.ts:350
seedOpenSourceTerminalState overwrites the persisted terminal entry for OPEN_SOURCE_TERMINAL_THREAD_KEY on every load when ?showcase=open-source is present, so a returning visitor's terminal preferences (resized height, closed state, terminal groups, active terminal) are reset to the hard-coded open layout. Unlike seedRightPanelState and seedDiffPanelSelection, this function lacks an early return when existing state is present, so it always re-seeds. Consider skipping the write when persisted is non-null (or when the thread key already has an entry) to preserve visitor customizations.
function seedOpenSourceTerminalState(): void {
const params = new URLSearchParams(window.location.search);
if (params.get("showcase") !== "open-source") return;
const persisted = readLocalStorage(TERMINAL_UI_STATE_STORAGE_KEY);
+ if (persisted !== null) return;
+
let existingState: Record<string, unknown> = {};🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/demo/seed.ts around lines 350-354:
`seedOpenSourceTerminalState` overwrites the persisted terminal entry for `OPEN_SOURCE_TERMINAL_THREAD_KEY` on every load when `?showcase=open-source` is present, so a returning visitor's terminal preferences (resized height, closed state, terminal groups, active terminal) are reset to the hard-coded open layout. Unlike `seedRightPanelState` and `seedDiffPanelSelection`, this function lacks an early return when existing state is present, so it always re-seeds. Consider skipping the write when `persisted` is non-null (or when the thread key already has an entry) to preserve visitor customizations.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 31a16fb. Configure here.
| .download-faq-item[open] { | ||
| border-color: rgba(255, 255, 255, 0.16); | ||
| background: var(--download-surface-hover); | ||
| } |
There was a problem hiding this comment.
FAQ cards miss surface styles
Medium Severity
The new FAQ section sits outside .download-page, but FAQ items still use --download-surface, --download-surface-hover, and --download-surface-border, which are only defined on that ancestor. Those var() references go invalid, so FAQ cards lose their intended background and border (and channel-stage surface overrides never apply).
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 31a16fb. Configure here.
|
Note 🤖 GPT-5.6 Sol responding on behalf of Theo We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together. This branch duplicates the marketing redesign in #4909. That PR is the active implementation and includes the fuller appearance assets and release work. If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed. |


The current marketing site does not clearly show how T3 Code works across desktop, web, and mobile, and its download flow does not distinguish release channels well.
This redesign gives the site a product-led story with a real interactive app demo, dedicated desktop and mobile download paths, and a cleaner Latest/Nightly/Dev flow. The embedded demo preserves visitor state, the download data handles long release histories, and the large footer wordmark stays visually neutral across channels.
Visual reference:
Verification:
vp test run apps/web/src/demo/fixtures.test.ts apps/web/src/demo/server.test.ts apps/marketing/src/lib/releases.test.ts(22 tests)vp run --filter @t3tools/web typecheckvp run --filter @t3tools/marketing typecheckGenerated with GPT-5.6 in T3 Code through the Codex harness.
Note
Medium Risk
Large user-facing marketing and download behavior change; the new workflow can push commits to the default branch when showcase screenshots differ, which needs correct secrets and branch gating but is not core app security.
Overview
Replaces the marketing homepage with a new v2 experience (rotating provider hero, product showcase driven by
showcase-spec.json, embedded sidebar demo, mobile store CTAs) whileindex.astronow only renders that page.Overhauls shared chrome and download:
Layout.astrogains canonical/OG tags, a Latest / Nightly / Dev channel persisted inlocalStorage(favicon + accent theming), and a new nav/footer;/downloadadds a full-viewport channel hero, nightly/latest release resolution, a dev “build from source” path, and an FAQ. Release helpers now pick the newest nightly tag, resolve platform assets without guessing macOS arch, and cache GitHub responses with TTL (plus unit tests).Build-time marketing assets:
prepare:assetsbuilds the web sidebar demo and runscapture-demo-screenshots.mjs(Playwright) to generatedemo-states/,og-image.png, and related crops; Astro dev middleware sets cache headers for demo/mobile static paths.Automation:
mobile-showcase-screenshots.ymladdspublish_marketing_preview—after successful iOS+Android dark runs on the default branch, it copies screenshots intoapps/marketing/public/mobile-states/, writessource.jsonmetadata, and commits to default via the release GitHub App when pixels change.Smaller touches: legal pages support a simplified layout; README links App Store/Google Play; new store logos and mobile preview PNGs are checked in.
Reviewed by Cursor Bugbot for commit 31a16fb. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Redesign the T3 Code marketing website with multi-channel download support and in-browser demo
GOOGLE_PLAY_STORE_URLandMARKETING_STATS.users(now 160,000) in site.ts.Macroscope summarized 31a16fb.