Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
99b83bf
feat(t3x): seed the fork homepage from apps/marketing
radroid Aug 10, 2026
2a60537
feat(t3x): strip upstream-only social proof, store links, and legal p…
radroid Aug 10, 2026
caa3fa5
feat(t3x): rebrand the homepage copy, chrome, and fork graph
radroid Aug 10, 2026
7e9f598
feat(t3x): serve downloads from the fork's update-relay manifest and …
radroid Aug 10, 2026
0fd3a95
feat(t3x): deploy the homepage as a Cloudflare assets-only Worker
radroid Aug 10, 2026
96bbab5
ci(t3x): auto-deploy the homepage to Cloudflare on push to main
radroid Aug 10, 2026
4961da1
docs(t3x): record the fork homepage on the seam ledger and sync runbook
radroid Aug 10, 2026
dd45537
ci(t3x): pin the deploy wrangler exactly, not to a floating major
radroid Aug 10, 2026
10b5604
docs(t3x): capture homepage screenshots and a scroll-through for review
radroid Aug 10, 2026
86b86d7
docs(coil): design for repositioning the homepage as Coil
radroid Aug 10, 2026
7197fa5
feat(coil): reposition the homepage as Coil, a personal fork
radroid Aug 10, 2026
220de98
docs(coil): recapture the homepage evidence against coil.curlycloud.dev
radroid Aug 10, 2026
acc3476
fix(coil): stop the hero marks colliding with mobile content, equalis…
radroid Aug 10, 2026
32063b9
docs(coil): recapture mobile evidence after the collision fix
radroid Aug 10, 2026
afc2f2a
fix(coil): bring the hero marks back on mobile as an in-flow row
radroid Aug 10, 2026
927109f
docs(coil): recapture the hero evidence with all five marks restored
radroid Aug 10, 2026
b482dc4
docs(coil): fix the stale deploy-workflow pointer, note the secret is…
radroid Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/coil-deploy-home.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
# Deploys the fork's homepage (apps/coil-home) to the `coil-home` Cloudflare Worker.
#
# Requires the repo secret CLOUDFLARE_API_TOKEN (Account → Workers Scripts → Edit) and the repo
# variable CLOUDFLARE_ACCOUNT_ID; both are set. If either is ever removed this job fails at the
# deploy step, and `pnpm run deploy` from apps/coil-home is the manual fallback.
#
# The daily sync force-pushes `main`, and on an undiffable force push GitHub runs `paths`-filtered
# workflows anyway. That is harmless: `wrangler deploy` is idempotent.
name: "coil: deploy homepage"

on:
push:
branches:
- main
paths:
- "apps/coil-home/**"
- ".github/workflows/coil-deploy-home.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: coil-home-deploy
cancel-in-progress: false

jobs:
deploy:
name: Build and deploy coil-home
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
args:
- --filter=@t3tools/coil-home...

- name: Build
run: vp run --filter @t3tools/coil-home build

# wrangler is fetched on demand rather than depended on — it drags ~500 lines into
# pnpm-lock.yaml, which SEAMS.md records as the fork's second-worst rebase-conflict surface.
#
# The version is pinned EXACTLY, not to `@4`. This step is the only place in the repo that
# runs an on-demand package while holding CLOUDFLARE_API_TOKEN, and a floating major would
# let any future 4.x release — or a compromised transitive dep of one — execute with that
# token, with no lockfile or integrity check standing in the way. Pinning keeps the
# zero-lockfile-rows property that motivated `pnpm dlx` in the first place and makes each
# wrangler upgrade an explicit, reviewable commit. Keep in step with
# apps/coil-home/package.json's `deploy` script.
- name: Deploy to Cloudflare
working-directory: apps/coil-home
run: pnpm dlx wrangler@4.120.1 deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

- name: Verify live site
run: |
code=$(curl -s -o /dev/null -w "%{http_code}" https://coil.curlycloud.dev/)
test "$code" = "200" || { echo "site returned $code"; exit 1; }
8 changes: 8 additions & 0 deletions apps/coil-home/astro.config.mjs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "astro/config";

export default defineConfig({
site: "https://coil.curlycloud.dev",
server: {
port: Number(process.env.PORT ?? 4173),
},
});
21 changes: 21 additions & 0 deletions apps/coil-home/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@t3tools/coil-home",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"typecheck": "astro check",
"//deploy": "wrangler is run via `pnpm dlx`, not depended on — it drags ~500 lines into pnpm-lock.yaml, the fork's second-worst rebase-conflict surface, and is only needed at deploy time. The version is pinned exactly because CI runs this while holding CLOUDFLARE_API_TOKEN and `pnpm dlx` has no lockfile to pin it for us; keep it in step with .github/workflows/coil-deploy-home.yml.",
"deploy": "pnpm dlx wrangler@4.120.1 deploy"
},
"dependencies": {
"astro": "^7.0.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.7",
"typescript": "catalog:"
}
}
Binary file addedapps/coil-home/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/apple-touch-icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-16x16.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon-32x32.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/claude-ai-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/cursor_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/coil-home/public/harnesses/grok-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/openai_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/public/harnesses/opencode-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/icon.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addedapps/coil-home/public/updated-screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/coil-home/src/env.d.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/// <reference types="astro/client" />
Loading
Loading