From 6bd5775412cd6c578e152c8a49c08d0a86bddf6f Mon Sep 17 00:00:00 2001 From: Rhys Sullivan <39114868+RhysSullivan@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:35:41 -0700 Subject: [PATCH 1/4] Marketing: faster testimonial drift, Hermes logo (#2018) * marketing: faster testimonial drift Co-Authored-By: Claude Fable 5.1 * marketing: hermes agent mark in the agent reveal Co-Authored-By: Claude Fable 5.1 --------- Co-authored-by: Claude Fable 5.1 --- apps/marketing/src/assets/logos/hermes.svg | 1 + apps/marketing/src/components/variants/doc-body.astro | 2 +- apps/marketing/src/styles/variants/testimonials.css | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 apps/marketing/src/assets/logos/hermes.svg diff --git a/apps/marketing/src/assets/logos/hermes.svg b/apps/marketing/src/assets/logos/hermes.svg new file mode 100644 index 000000000..7d92a0cb8 --- /dev/null +++ b/apps/marketing/src/assets/logos/hermes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/marketing/src/components/variants/doc-body.astro b/apps/marketing/src/components/variants/doc-body.astro index abcdd0c44..214bc79c3 100644 --- a/apps/marketing/src/components/variants/doc-body.astro +++ b/apps/marketing/src/components/variants/doc-body.astro @@ -24,7 +24,7 @@ const logo = (name: string): string => { return hit[1]; }; const toolLogos = ["github", "linear", "sentry", "stripe", "notion", "slack", "jira", "gmail"]; -const agentLogos = ["claude", "codex", "cursor", "chatgpt", "gemini", "copilot", "windsurf", "opencode", "zed", "grok"]; +const agentLogos = ["claude", "codex", "cursor", "chatgpt", "gemini", "hermes", "copilot", "windsurf", "opencode", "zed", "grok"]; // The three marks on the copy button; the full list would crowd it. const agentLogosShort = ["claude", "codex", "cursor"]; const X_URL = "https://x.com/RhysSullivan"; diff --git a/apps/marketing/src/styles/variants/testimonials.css b/apps/marketing/src/styles/variants/testimonials.css index 85ec95cbd..39b23c86f 100644 --- a/apps/marketing/src/styles/variants/testimonials.css +++ b/apps/marketing/src/styles/variants/testimonials.css @@ -13,13 +13,13 @@ display: flex; gap: 12px; overflow: hidden; - --testi-duration: 260s; + --testi-duration: 180s; } .testi__row[data-row="1"] { - --testi-duration: 300s; + --testi-duration: 210s; } .testi__row[data-row="2"] { - --testi-duration: 280s; + --testi-duration: 195s; } .testi__track { display: flex; From 37f91a2ded3e44a4eeab844dfb23c567aaf39451 Mon Sep 17 00:00:00 2001 From: Rhys Sullivan <39114868+RhysSullivan@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:44:54 -0700 Subject: [PATCH 2/4] marketing: blog on the rail layout; one shared shell for home, pricing, and blog (#2019) Co-authored-by: Claude Fable 5.1 --- .../src/layouts/BlogPostLayout.astro | 180 +++--------------- apps/marketing/src/layouts/RailLayout.astro | 49 +++++ apps/marketing/src/pages/blog/index.astro | 153 +++------------ apps/marketing/src/pages/index.astro | 57 +----- apps/marketing/src/pages/pricing.astro | 143 ++++++-------- apps/marketing/src/styles/variants/doc.css | 66 +++++++ 6 files changed, 233 insertions(+), 415 deletions(-) create mode 100644 apps/marketing/src/layouts/RailLayout.astro diff --git a/apps/marketing/src/layouts/BlogPostLayout.astro b/apps/marketing/src/layouts/BlogPostLayout.astro index 6a244d6ff..11b5f8e9a 100644 --- a/apps/marketing/src/layouts/BlogPostLayout.astro +++ b/apps/marketing/src/layouts/BlogPostLayout.astro @@ -1,5 +1,5 @@ --- -import Layout from "./Layout.astro"; +import RailLayout from "./RailLayout.astro"; interface Props { title: string; @@ -11,17 +11,9 @@ interface Props { authorAvatar: string; } -const { - title, - description, - date, - author, - authorHandle, - authorRole, - authorAvatar, -} = Astro.props; +const { title, description, date, author, authorHandle, authorRole, authorAvatar } = + Astro.props; -const GH = "https://github.com/UsefulSoftwareCo/executor"; const authorX = `https://x.com/${authorHandle}`; const formattedDate = date.toLocaleDateString("en-US", { @@ -36,147 +28,29 @@ const formattedDate = date.toLocaleDateString("en-US", { const isoDate = date.toISOString(); --- - -
- {/* Graph-paper pattern + fade behind the header, matching the homepage */} -
+ +
+
+ ← Writing +

{title}

+

{description}

+ + + + {author} + {authorRole} · + + +
+ +
+
-
-
- -
- {/* ─── NAV ─── */} - - - {/* ─── HEADER ─── */} -
-
- ← Blog -

- {title} -

-

- {description} -

-
- - {author} - -
- {author} -
- {authorRole} · -
-
-
-
-
- {/* ─── ARTICLE ─── */} -
-
- -
-
- - {/* ─── BOTTOM CTA ─── */} -
-
-

- Connect any agent to everything. -

- -
-
- - {/* ─── FOOTER ─── */} - -
-
-
+
+

+ More writing · Back to Executor +

+
+ + diff --git a/apps/marketing/src/layouts/RailLayout.astro b/apps/marketing/src/layouts/RailLayout.astro new file mode 100644 index 000000000..71a32b1e6 --- /dev/null +++ b/apps/marketing/src/layouts/RailLayout.astro @@ -0,0 +1,49 @@ +--- +// The site shell: sticky rail on the left, one centred frame, footer at the +// bottom of the body column. The homepage, pricing, and blog all use it. +// Prerendered pages resolve the star count once at build time. +import Layout from "./Layout.astro"; +import RailB from "../components/variants/rail-b.astro"; +import { getStars, formatStars } from "../lib/github"; +import "../styles/variants/doc.css"; + +interface Props { + title: string; + description: string; + current?: "home" | "pricing" | "blog"; +} +const { title, description, current = "home" } = Astro.props; + +const GH = "https://github.com/UsefulSoftwareCo/executor"; +const stars = await getStars(); +--- + + +
+
+
+ +
+
+ + + +
+
+
+
diff --git a/apps/marketing/src/pages/blog/index.astro b/apps/marketing/src/pages/blog/index.astro index 1549b9e79..a81839b87 100644 --- a/apps/marketing/src/pages/blog/index.astro +++ b/apps/marketing/src/pages/blog/index.astro @@ -1,10 +1,8 @@ --- export const prerender = true; -import Layout from "../../layouts/Layout.astro"; +import RailLayout from "../../layouts/RailLayout.astro"; import { getCollection } from "astro:content"; -const GH = "https://github.com/UsefulSoftwareCo/executor"; - const posts = (await getCollection("blog", ({ data }) => !data.draft)).sort( (a, b) => b.data.date.getTime() - a.data.date.getTime(), ); @@ -20,126 +18,29 @@ const fmt = (date: Date) => }); --- - -
-
-
-
-
- -
- {/* ─── NAV ─── */} - - - {/* ─── HEADER ─── */} -
-
-

- Blog -

-

- Latest news and updates from Executor -

-
-
- - {/* ─── POST LIST ─── */} -
-
- { - posts.length === 0 ? ( -

No posts yet. Check back soon.

- ) : ( - - ) - } -
-
- - {/* ─── FOOTER ─── */} - -
-
-
+ + + diff --git a/apps/marketing/src/pages/index.astro b/apps/marketing/src/pages/index.astro index 6000f5db4..22b6cbe2e 100644 --- a/apps/marketing/src/pages/index.astro +++ b/apps/marketing/src/pages/index.astro @@ -1,10 +1,8 @@ --- -import Layout from "../layouts/Layout.astro"; +import RailLayout from "../layouts/RailLayout.astro"; // Imported so Vite emits it as a hashed build asset (served from /_astro/...); // the deploy pipeline does not pick up newly added /public files. -import { getStars, formatStars } from "../lib/github"; import { setupPrompt } from "../content/site-copy"; -import RailB from "../components/variants/rail-b.astro"; import DocBody from "../components/variants/doc-body.astro"; const GH = "https://github.com/UsefulSoftwareCo/executor"; @@ -12,57 +10,16 @@ const GH = "https://github.com/UsefulSoftwareCo/executor"; // /api/* is app-owned (apps/cloud/src/app-paths.ts), so this hits the WorkOS // login flow directly. Returning users land here; new users use Get started. const SIGN_IN = "/api/auth/login"; -const stars = await getStars(); --- - -
- {/* Graph-paper hero texture: grayscale (ink-masked), faded into the surface - at the bottom. Part of the registry-grade language, not a colored effect. */} -
-
-
-
+ + + -
-
-
- - - - {/* ─── FOOTER ─── */} - -
-
-
-