mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-12 00:42:03 +00:00
main
66 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
759ed3d4e2 |
feat(website): add community-workflows demo page (#11942)
*PR Created by the Glary-Bot Agent* --- Adds a new interactive demo page at `comfy.org/demos/community-workflows` for the [Explore and Use a Community Workflow from the Hub](https://app.arcade.software/flows/mqZh17oWDuWIyhK0xwEV/view) Arcade walkthrough. Built on top of the demo infrastructure merged in #11436. ## Changes - `apps/website/src/config/demos.ts` — register the new demo - `apps/website/src/i18n/translations.ts` — add en + zh-CN strings (title, description, transcript) - `apps/website/public/images/demos/community-workflows-og.png` — 1200×630 OG image so email/social previews render correctly - `apps/website/public/images/demos/community-workflows-thumb.webp` — 1280×720 WebP thumbnail - `apps/website/e2e/demos.spec.ts` — refactored to iterate `demos` from config so every demo (current + future) is exercised in both en and zh-CN, and the iframe `src` is asserted to contain the correct Arcade ID Adding a new demo only requires editing `demos.ts` + `translations.ts` going forward; the e2e refactor is a one-time generalization that gives future demos coverage automatically. ## Verification - `pnpm typecheck:website`: 0 errors, 0 warnings, 0 hints - Pre-commit hook ran `pnpm typecheck`, `oxfmt`, `oxlint`, `eslint` — all clean on staged files - `npx astro build`: 53 pages built; `/demos/community-workflows/` and `/zh-CN/demos/community-workflows/` generated and present in `sitemap-0.xml` - Page rendered in Playwright preview: hero (title, GETTING STARTED, BEGINNER, ~2 min), Arcade embed loads, transcript section present, "What's Next" links to `image-to-video` - zh-CN page shows localized title (探索并使用社区工作流), description, badges, and "What's Next" heading - OG meta tag references the new 1200×630 PNG ## Screenshots   ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11942-feat-website-add-community-workflows-demo-page-3576d73d36508139b647c774b1d39323) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
d901c63a0b |
feat: convert careers CategoryNav to scroll-spy locator (#12110)
*PR Created by the Glary-Bot Agent*
---
Converts the `CategoryNav` in the careers `RolesSection` from a
click-to-filter button into a scroll-spy section locator, matching the
pattern already used by `ContentSection.vue` (customer story details,
TOS, privacy policy).
## Changes
- **`apps/website/src/components/careers/RolesSection.vue`**
- Replaced category-based filtering with anchor navigation: clicking a
department in the sidebar smooth-scrolls (via existing Lenis/GSAP
`scrollTo` helper) to that department's section with a `-144px` header
offset.
- Removed the `ALL` button — every department is always rendered as its
own scroll target with `id="careers-dept-{key}"`.
- Added `useIntersectionObserver` (rootMargin `-20% 0px -60% 0px`) that
updates the active nav item as the user scrolls. An `isScrolling` guard
prevents the observer from fighting click-jumps mid-animation.
- Added a viewport-entry fade/slide-up animation on each department
section, gated by `motion-safe:` so users with `prefers-reduced-motion`
see content immediately. The reveal state is sticky (one-way) so
sections don't disappear once revealed.
- Active state is driven by raw department keys; both the nav model and
the observer's id-to-key mapping use a single consistent identifier.
- **`apps/website/e2e/careers.spec.ts`**
- Replaced the obsolete "ENGINEERING filter narrows the list" test with
one that validates locator behavior: clicking the department button
scrolls the section into the viewport, sets `aria-pressed="true"`, and
keeps the full role list rendered.
## Verification
- `pnpm --filter @comfyorg/website typecheck` — clean.
- `pnpm exec oxfmt` / `pnpm exec eslint` / `pnpm exec oxlint` — clean.
- Pre-commit lint-staged hooks (stylelint, oxfmt, oxlint, eslint,
typecheck) — passing.
- Manual smoke test via Playwright on `astro dev`: careers page renders
all departments stacked vertically, active department in the sidebar
highlights based on viewport position (DESIGN active on initial scroll),
nav items reflect each department instead of including an `ALL` button.
## Screenshots

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-12110-feat-convert-careers-CategoryNav-to-scroll-spy-locator-35b6d73d3650818a9226e5dcb1244756)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary <glary@bot.local>
|
||
|
|
5ca9f3e7e6 |
feat(website): remove left-edge fade-out from local hero illustration (#12137)
*PR Created by the Glary-Bot Agent* --- Removes the left-edge fade-out gradient overlay on the hexagonal hero illustration on the `/download` (local) page. The hex cluster now reads fully edge-to-edge instead of being blended into the page background on the left side. Tracked in [FE-650: Remove fade-out effect on local page hero illustration](https://linear.app/comfyorg/issue/FE-650/remove-fade-out-effect-on-local-page-hero-illustration). ## Change Drops the `<!-- Left-edge fade -->` `<rect>` and its `<defs><linearGradient id="localHeroFadeLeft">…</linearGradient></defs>` from `apps/website/src/components/product/local/HeroSection.vue`. Animation logic (panel expansion + hex ring rotation) is untouched. ## Verification - `pnpm nx typecheck website` — pass (0 errors) - `pnpm nx build website` — pass (51 pages built) - `pnpm exec eslint apps/website/src/components/product/local/HeroSection.vue` — clean - `pnpm format:check apps/website/src/components/product/local/HeroSection.vue` — clean - Manual: `pnpm dev` + visited `/download` at 390×844 (mobile), 1280×800, and 1440×900. Mobile screenshots clearly show the fade is gone; the leftmost hexagons are now fully visible. ## Screenshots Mobile (390×844), before — note the dark fade obscuring the left side of the hex cluster: ## Screenshots    ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12137-feat-website-remove-left-edge-fade-out-from-local-hero-illustration-35d6d73d365081cba690ed7d46a19882) by [Unito](https://www.unito.io) Co-authored-by: Glary Bot <bot@glary.dev> |
||
|
|
6d5fa743b3 |
fix: seamless SocialProofBar marquee loop (#12139)
*PR Created by the Glary-Bot Agent* --- ## Summary The partner-logo marquee on the homepage `SocialProofBar` glitched on every loop restart — a visible jump where the strip snapped back to the start. ## Root cause The previous implementation rendered all logos as siblings of a single flex container and animated the track from `translateX(0)` to `translateX(-50%)`. Because the `gap` utility inserts spacing between every adjacent pair of items (including the seam between the two duplicated halves), `-50%` of the total width does not equal the distance from one half-start to the next half-start. The mismatch (`gap / 2`) is exactly what the eye sees as a jump. ## Fix - Wrap each duplicated half in its own flex group. - Place the two groups as siblings of an outer `flex w-max gap-X` track with a gap that matches the inner gap. - Animate each group by `translateX(calc(-100% - var(--marquee-gap)))`, where `--marquee-gap` is set inline to the same value as the Tailwind gap class. - Scope the `animation` declaration to `@media (prefers-reduced-motion: no-preference)` so reduced-motion users get a stable, non-animated client list instead of the global "snap to 0.01ms" jump. At `t = end`, the second group sits at `x = 0` — exactly where the first group started — so the next animation cycle is visually indistinguishable from the previous frame. The duplicate carries `aria-hidden="true"` so screen readers don't read the client list twice. ## Verification - `pnpm typecheck`, `pnpm format`, `npx eslint` on changed files: clean. - Geometry verified at runtime on desktop (1440×900) and mobile (390×844): copy widths match, second copy lands at `x = 0` at animation end. - New Playwright regression tests (`apps/website/e2e/responsive.spec.ts`) pause the CSS animation, sample bounding rects at `t=0` and `t≈duration`, and assert the seam invariant — covering desktop forward, mobile forward, and mobile reverse marquees. All 5 SocialProofBar tests pass on both `desktop` and `mobile` projects. - Reduced-motion behavior verified in the browser: `animationName: none`, `transform: none`, tracks at their natural positions. Fixes FE-649 ## Screenshots     ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12139-fix-seamless-SocialProofBar-marquee-loop-35d6d73d36508141b6ccf0167016b8c8) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
d767a325a2 |
FE-604: fix(website): activate last section badge when scrolled to bottom (#12057)
*PR Created by the Glary-Bot Agent* --- ## Summary Fixes the bug where the last badge in `ContentSection`'s sticky sidebar nav stays unhighlighted when the user scrolls to the very bottom of the page on tall viewports (reported on a 14" MacBook M4 Pro at 3024×1964 / 2016×1310 logical, both Chrome and Safari). ## Root cause The scroll-spy uses an IntersectionObserver with `rootMargin: '-20% 0px -60% 0px'`, which makes only a 20%–40% horizontal band from the viewport top "active". When multiple intersecting entries are reported, the callback picks the one whose `boundingClientRect.top` is smallest (highest up on screen). On tall viewports, when the page is scrolled to the absolute bottom, the last *and* the second-to-last sections frequently both sit inside that 20%–40% band at the same time. The "smallest top" tiebreak then selects the second-to-last section, leaving the last badge inactive even though the user has reached the end of the page. ## Fix `apps/website/src/components/common/ContentSection.vue`: 1. Add `isAtBottom()` — true when the viewport bottom has reached the document bottom (within 4px to absorb sub-pixel rounding). 2. The IntersectionObserver callback bails out when `isAtBottom()` so it cannot overwrite the choice below. 3. A passive `scroll` listener (and a one-shot `onMounted` call) sets `activeSection` to the last section whenever the page is at the bottom — including when the component mounts already at the bottom (e.g. hash navigation to a trailing anchor, restored scroll position, or a page shorter than the viewport). 4. Both the scroll handler and the IO callback honor the existing `isScrolling` flag, so click-driven smooth scroll-to-section behavior is unchanged. ## Verification Reproduced the bug at viewport 2016×1310 (14" M4 Pro "More Space" mode) on `/privacy-policy`: - Before fix: at absolute bottom, IntersectionObserver picks `australian-privacy` (second-to-last) — bug confirmed via DOM inspection that showed multiple sections intersecting the active band, with the second-to-last winning the "smallest top" tiebreak. - After fix: - Scrolled to bottom → last badge `CONTACT` is active. - Scrolled to top → first badge `INTRO` is active. - Scrolled mid-page → correct mid-section is active. - Click on a badge → smooth scrolls and that badge becomes active. - Initial render at bottom (loaded `/privacy-policy#contact`, browser scrolls to the bottom on mount) → `CONTACT` active immediately. `pnpm typecheck` and `pnpm typecheck:website` pass; `pnpm lint` reports 0 errors; existing website unit tests pass. Note: The website app currently has no Vue component test setup (`vitest.config.ts` is configured for `node` env, no DOM). Adding component tests for this scroll-spy interaction would require setting up `happy-dom` and `@testing-library/vue` for the website app, which is out of scope for this bug fix. Fixes FE-604 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12057-FE-604-fix-website-activate-last-section-badge-when-scrolled-to-bottom-3596d73d365081faa243f4dd8e6ee54a) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
8c295e7c68 |
fix: remove transition delay from FeedbackSection progress bar (#12059)
*PR Created by the Glary-Bot Agent* --- ## Summary The horizontal progress bar in `FeedbackSection.vue` lagged behind the carousel scroll position because the bar's width was driven reactively by `useScroll`, but the `transition-all duration-200` utility animated each width change over 200ms. As scroll continuously emits new target widths, the bar visibly trailed the scroll position. Removing the transition makes the bar track scroll synchronously. ## Verification - Reproduced the lag locally on `/customers`. - Verified post-fix that `bar.style.width` updates in the same frame as `scrollLeft` changes (samples at scrollLeft 0 / 944 / 1600 → width 0% / 59% / 100%, with `transitionDuration: 0s`). - `pnpm exec eslint`, `pnpm exec oxfmt --check`, `pnpm nx typecheck website`, and `pnpm test:unit` all pass. ## Notes No regression test added — the customers section components have no existing unit/E2E coverage in this repo, and standing up a new test harness for a one-line CSS fix would be disproportionate. Worth following up on broader carousel coverage as a separate task. ## Screenshot After fix, scrolled to second slide — progress bar tracks scroll position synchronously. ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12059-fix-remove-transition-delay-from-FeedbackSection-progress-bar-3596d73d36508107bc80dc38ea7ab79e) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
fef2cab31e |
fix(website): prevent video glitch when c-projection.webp loads on /customers (#12060)
*PR Created by the Glary-Bot Agent* --- ## Summary Fix the video position glitch on `/customers` caused by `c-projection.webp` loading. ## Root cause In `HeroSection.vue` the hero `<img>` for `c-projection.webp` had no `width`/`height` attributes, so the browser reserved no space for it. When the image finished loading, the layout shifted ~192px, pushing the `VideoPlayer` below it. `useHeroAnimation` registers a GSAP `ScrollTrigger` parallax against the video in `onMounted` (before the image is loaded), so the cached scroll geometry then went stale and the video visibly glitched. ## Fix - Add explicit `width="1568"` / `height="1763"` to the `<img>` (the image's native size) so the browser reserves the correct aspect-ratio'd space upfront. - Add `h-auto` so the height attribute doesn't override the responsive layout. - Refresh `ScrollTrigger` on the image's `@load` (with `refresh(true)` so measurements happen after layout has settled) as a defensive measure for any sub-pixel adjustments. ## Test coverage Added `apps/website/e2e/customers.spec.ts` with a regression guard that: 1. Asserts the hero `<img>` declares numeric `width`/`height` attributes. 2. Asserts the unloaded image still reserves vertical space (>100px), which is the exact property that prevents the video from jumping when the image finishes loading. Verified the test fails when the `width`/`height` attributes are removed and passes with the fix applied. ## Verification - `pnpm typecheck` clean. - `pnpm test:unit` (website app) — 30/30 pass. - `pnpm test:e2e customers.spec.ts --project=desktop` — passes. - ESLint + oxfmt clean on changed files. - Manual Playwright verification confirmed the video bounding rect stays at `top=785, height=628` through the full image load lifecycle. Reverting the fix in DevTools and re-loading the image reproduces the original ~192px shift. ## Out of scope `apps/website/src/components/contact/FormSection.vue` uses the same `c-projection.webp` pattern (also without `width`/`height`). It runs `useHeroAnimation` with `parallax: false`, so the symptom is much smaller — leaving as a follow-up to keep this PR minimal. - Fixes [FE-607](https://linear.app/comfyorg/issue/FE-607/bug-video-on-customers-shifts-position-when-c-projectionwebp-finishes) ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12060-fix-website-prevent-video-glitch-when-c-projection-webp-loads-on-customers-3596d73d365081ebbcb8db25aaa5c451) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
2322a5a497 |
fix: use webm video for VFX use case right asset (#12040)
*PR Created by the Glary-Bot Agent* --- ## Summary Replaces `right1.webp` with `right1.webm` in the VFX panel of `UseCaseSection`. `BlobMedia` already auto-detects `.webm` URLs and mounts a `<video>` element (with the `.webp` as poster), so this single URL swap is the only change required — matching the pattern used by the other 4 use-case panels. ## Files changed - `apps/website/src/components/home/UseCaseSection.vue` — swap `right1.webp` → `right1.webm`. ## Verification - `pnpm exec nx run website:typecheck` — clean - `pnpm exec eslint` on changed file — clean - `pnpm exec oxfmt --check` — clean - pre-commit lint-staged hooks — passed ## Reviewer note (Oracle finding) VFX is the default active panel, so the homepage's initial right-rail asset moves from ~131 KB `.webp` to ~4.1 MB `.webm`. Behaviorally consistent with the other 4 panels (which already use `.webm`), but worth confirming whether `right1.webm` should be re-encoded smaller on the CDN before promoting this PR out of draft. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12040-fix-use-webm-video-for-VFX-use-case-right-asset-3596d73d365081829976f37b733840f1) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
81d9df61f2 |
fix(website): tighten GitHub ticker spacing on wide screens (#12021)
*PR Created by the Glary-Bot Agent* --- ## Summary The GitHub star ticker reads as detached from the GitHub octocat icon on wider viewports. The CSS gap is constant (`gap-2` = 8px), but the 28px icon next to a 20px badge plus the fixed gap make the pair look like two separate items at `lg+` widths instead of a single coupled unit. ## Change `apps/website/src/components/common/GitHubStarBadge.vue`: - Inner gap `gap-2` → `gap-1` (8px → 4px) so the badge and icon sit closer together. - Icon `size-7` → `size-6 shrink-0` (28px → 24px) so the icon height is closer to the badge height (20px) and the pair reads as one unit. The outer `gap-2` between CTA items in `SiteNav.vue` is intentionally unchanged — it is the correct spacing between unrelated CTA elements. ## Verification - `pnpm typecheck` — 0 errors (1 pre-existing hint in unrelated file). - `pnpm format:check` — clean. - `pnpm exec eslint apps/website/src/components/common/GitHubStarBadge.vue` — clean. - `pnpm test:unit` (apps/website) — 30/30 pass. - Pre-commit hook (oxfmt + oxlint + eslint + typecheck + typecheck:website) — passed. - `/review` (Oracle) — 0 critical, 0 warnings, 0 suggestions. - Manual visual verification at 1280px, 1920px, and 2560px viewports. - Tested longer star strings (`999.9K`, `1.2M`) — no wrapping. ## Before / After (2560px viewport) Before: badge and octocat appear visually detached. After: badge and octocat read as a single tightly-coupled unit. ## Screenshots      ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12021-fix-website-tighten-GitHub-ticker-spacing-on-wide-screens-3586d73d365081be8d66dfbb22b8dc2c) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> |
||
|
|
d3f802de10 |
feat(pricing): add concurrent API jobs feature to Creator and Pro tiers (#12000)
*PR Created by the Glary-Bot Agent* --- ## Summary Adds a new feature bullet to the Creator and Pro plans on the [cloud pricing page](https://comfy.org/cloud/pricing) to call out included API concurrency: - **Creator**: `3 concurrent API jobs` - **Pro**: `5 concurrent API jobs` Free and Standard tiers do not include API access, so they are not changed. This matches the language landing in the docs PR: [Comfy-Org/docs#965](https://github.com/Comfy-Org/docs/pull/965). ## Changes - `apps/website/src/components/pricing/PriceSection.vue`: added `feature2` to the Creator and Pro plan feature lists. - `apps/website/src/i18n/translations.ts`: added `pricing.plan.creator.feature2` and `pricing.plan.pro.feature2` for `en` and `zh-CN`. - Updated `pricing-tiers-{1-sm,2-md,3-lg,4-xl}` visual regression snapshots in `apps/website/e2e/visual-responsive.spec.ts-snapshots/` to match the new copy. ## Verification - `pnpm nx run @comfyorg/website:typecheck` — clean - ESLint and `oxfmt` clean on changed files (pre-commit lint-staged also passed) - `pnpm exec playwright test --project visual -g "pricing-tiers"` — 4/4 passing against the regenerated snapshots - Manually rendered `localhost:4321/cloud/pricing`; confirmed copy appears in both desktop and mobile layouts and that Free / Standard are unchanged. Screenshots below. ## Screenshots ### Desktop  ### Mobile — Creator  ### Mobile — Pro  ## Screenshots    ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12000-feat-pricing-add-concurrent-API-jobs-feature-to-Creator-and-Pro-tiers-3586d73d365081559acfc44eb5024c52) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: github-actions <github-actions@github.com> |
||
|
|
e46667b33f |
feat: replace spin logo video with Three.js instance in homepage HeroSection (#11964)
Replace the pre-rendered `.webm` video in the homepage hero section with an interactive Three.js 3D logo. ## Changes - Add `three` dependency to the website package and pnpm catalog - Add `useHeroLogo` composable that sets up the Three.js scene: - Extruded Comfy "C" logo with stencil-masked image sequence slideshow - Auto-rotation with drag interaction and cursor tilt - Graceful degradation if some textures fail to load - Update `HeroSection.vue` to use the composable instead of a `<video>` element - Upload 16 image sequence frames to `gs://comfy-org-videos/website/homepage/hero-logo-seq/` <img width="1000" height="648" alt="Kapture 2026-05-05 at 20 54 05" src="https://github.com/user-attachments/assets/7a7b1634-2da3-4aa2-871a-f64d4d337b39" /> @coderabbitai approve ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11964-feat-replace-spin-logo-video-with-Three-js-instance-in-homepage-HeroSection-3576d73d365081bbab0ed19dd121830c) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> |
||
|
|
fb32b9a5c5 |
fix(website): prevent HeroSection fade from bleeding into CloudBannerSection on /download (#11974)
*PR Created by the Glary-Bot Agent* --- ## Summary The left side of `CloudBannerSection` on `/download` showed an unintended fade-out: the bottom-left of the banner appeared darker than the rest of the bar. ## Root cause `product/local/HeroSection.vue` renders an SVG illustration whose container has `lg:z-1` and whose SVG element has `overflow-visible`. The SVG contains a left-edge fade `<rect x="300" y="150" width="250" height="900" fill="url(#localHeroFadeLeft)" />` that paints outside the SVG's `viewBox` (`400 200 550 800`) — including upward into the area occupied by the preceding `CloudBannerSection`. Because `CloudBannerSection` had `position: static` and `z-auto`, the positively-stacked illustration painted over the banner's bottom-left, producing the visible darkening. ## Fix Establish a stacking context on `CloudBannerSection` (`relative z-20`) so it always renders above the hero illustration's overflow on every page that includes the banner (download, api, cloud/enterprise, and zh-CN equivalents). This is a minimal, isolated change to the shared component — no logic or markup structure changes. ## Verification - Reproduced visually at `lg` breakpoint and confirmed the fade is gone after the fix. - Verified `/download`, `/api`, `/cloud/enterprise`, and `/zh-CN/download` render correctly. - `pnpm typecheck` and `pnpm typecheck:website` pass (run automatically by pre-commit hook). - `oxfmt`, `oxlint`, `eslint`, `stylelint` all pass. ### Before  ### After  ## Follow-up Consider adding a Playwright visual regression test for the banner/hero seam on `/download` to catch future stacking regressions (called out by review). ## Screenshots   ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11974-fix-website-prevent-HeroSection-fade-from-bleeding-into-CloudBannerSection-on-downloa-3576d73d3650813d8924fb54d5f78cee) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> |
||
|
|
6474faaa17 |
fix(website): prevent illustration cutoff in enterprise hero section (#11973)
*PR Created by the Glary-Bot Agent* --- ## Summary The illustration in the `HeroSection` of `/cloud/enterprise` was getting cut off at the top — the topmost ripple ring was clipped by the section's `overflow-y-clip`/`overflow-hidden`. **Root cause:** the SVG wrapper has `scale-150`, which makes the rendered illustration 50% larger than its layout box and overflows symmetrically (~25% above, ~25% below). The section only had `lg:pb-[min(8vw,10rem)]` — bottom padding — and on lg the wrapper had `lg:translate-y-[40px]` to nudge it down, but that wasn't enough room for the top to escape clipping. On mobile there was no padding at all, so the same issue occurred. **Fix:** add symmetric vertical padding (`pt-16` on mobile, `lg:pt-[min(8vw,10rem)]` mirroring the existing bottom value on lg) so the scaled illustration has room above and below. Removed the now-unnecessary `lg:translate-y-[40px]` since symmetric padding keeps the illustration vertically centered within the flex row. Verified at 375px (mobile), 1024px (lg), and 1440px (xl) viewports — all four ripple rings render fully without clipping at the top. ## Verification - `pnpm typecheck:website` ✅ - `pnpm exec oxfmt --check` on edited file ✅ - `pnpm exec oxlint` on edited file ✅ - `pnpm --filter @comfyorg/website build` ✅ - Pre-commit hooks (stylelint, oxfmt, oxlint, eslint, typecheck, typecheck:website) ✅ - Visual verification with Playwright at mobile / lg / xl ## Before vs After **Desktop (1440px) — before:** the topmost ripple ring is clipped at the top of the section. **Desktop (1440px) — after:** all four ripple rings are fully visible. **Mobile (375px) — before:** the top of the outermost ring is cut off by the section's top edge. **Mobile (375px) — after:** the full illustration (rings + blocks) is visible. ## Screenshots     ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11973-fix-website-prevent-illustration-cutoff-in-enterprise-hero-section-3576d73d3650813f9f04c3f93b9b42d6) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> |
||
|
|
eecbaa8f39 |
fix(website): change 'Blogs' to 'Blog' in Resources nav dropdown (#11970)
*PR Created by the Glary-Bot Agent* --- ## Summary Corrects the "Blogs" label to "Blog" (singular) in the website header's Resources dropdown menu, as requested in #website-and-docs Slack channel. ## Changes - `apps/website/src/i18n/translations.ts`: `nav.blogs` English value `Blogs` → `Blog` (zh-CN translation `博客` left unchanged since it was already correct) This also makes the header consistent with the footer, which already labeled the same link as "Blog". ## Verification - `pnpm typecheck` (astro check): 0 errors, 0 warnings, 0 hints (87 files) - `pnpm test:unit`: 30 tests passed across 4 files - `pnpm exec eslint apps/website/src/i18n/translations.ts`: clean - Manual verification via Playwright on `pnpm dev` — Resources dropdown now displays "Blog" - Code review (oracle): 0 issues found ## Screenshot Resources dropdown after the change: ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11970-fix-website-change-Blogs-to-Blog-in-Resources-nav-dropdown-3576d73d365081638245d235bec04230) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
a763c7132c |
feat(website): add "comfyui app" SEO keywords to product pages (#11834)
*PR Created by the Glary-Bot Agent* --- ## Summary Adds "comfyui app" / "comfyui web app" / "comfy ui application" keywords to the titles and meta descriptions of the home, download, and Comfy Cloud pages (and zh-CN equivalents) to recover organic traffic for those queries. ## Context Organic traffic for the query **"comfyui app"** dropped after `https://docs.comfy.org/interface/app-mode` started outranking the product/landing pages. The docs page about app-mode converts worse than the product pages, so we want Google to prefer comfy.org product pages for that query. The cleanest, lowest-risk lever is on-page SEO metadata. ## Changes - **What**: - `apps/website/src/pages/index.astro` → title `ComfyUI App — Professional Control of Visual AI` + product-focused description. - `apps/website/src/pages/download.astro` → title `Download the ComfyUI App — Run Visual AI Locally` + desktop-app description. - `apps/website/src/pages/cloud/index.astro` → title `Comfy Cloud — The ComfyUI Web App` + web-app description. - `apps/website/src/pages/zh-CN/{index,download,cloud/index}.astro` → localised Chinese titles and descriptions so the zh-CN product pages no longer fall back to the English `BaseLayout` default. - `apps/website/src/layouts/BaseLayout.astro` → unchanged net-net (touched then reverted to neutral copy after review feedback so non-product / non-localised pages keep their existing, generic fallback). - **Breaking**: none. Visual content, routing, and components are untouched — only `<title>` and `<meta>` tags change. ## Review Focus - The keyword copy reads naturally (no stuffing) and stays under typical SERP truncation limits (≤ ~165 chars). - zh-CN pages get Chinese descriptions — they intentionally don't repeat the English keywords, since "comfyui app" is an English-language query. - Pre-existing behaviour preserved: zh-CN pages **without** an explicit description still inherit the English `BaseLayout` default. Fixing that fallback for the whole zh-CN tree is out of scope for this PR — happy to follow up if desired. ## Verification - `pnpm typecheck` — 0 errors - `pnpm build` — 39 pages built clean - `pnpm test:unit` — 23/23 pass - `pnpm format:check apps/website/src` — clean - Manually verified rendered `<title>` and `<meta name="description">` via Playwright on `/`, `/download`, `/cloud`, and the zh-CN equivalents. ## Screenshots Home page rendered with the new title (visible in browser tab / SERP preview); visual content unchanged. ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11834-feat-website-add-comfyui-app-SEO-keywords-to-product-pages-3546d73d3650819da11bd665c2fcfb88) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
24fc11aa3e |
fix(website): remove placeholder author info for groove-jones customer story (#11937)
*PR Created by the Glary-Bot Agent* --- Removes the placeholder "GROOVE JONES CONTRIBUTORS" author card from the Groove Jones customer story (`/customers/groove-jones`). The card was rendering with `TBD` / `待补充` values for the contributor name and role. ## Change Deletes 3 i18n keys from `apps/website/src/i18n/translations.ts`: - `customers.detail.groove-jones.topic-10.block.2.label` - `customers.detail.groove-jones.topic-10.block.2.name` - `customers.detail.groove-jones.topic-10.block.2.role` Block types in `ContentSection.vue` are inferred from the presence of suffix keys (`.role` → `author` block) via `deriveSections` in `apps/website/src/config/contentSections.ts`. Removing the keys causes the author card to drop out of the rendered output entirely. The other two blocks in topic-10 (intro paragraph + Dale Carman blockquote) remain unchanged. ## Verification - `pnpm typecheck` — passes - `pnpm lint` — 0 errors (1 pre-existing warning, unrelated) - `pnpm format` — applied - `pnpm knip` — clean (1 pre-existing warning, unrelated) - Manual: ran `pnpm dev` for the website app, navigated to `/customers/groove-jones`, confirmed the conclusion section ends naturally — no `TBD` text, no orphan `CONTRIBUTORS` label, no broken card. Code review (Oracle): 0 critical / 0 warning / 0 suggestion. ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11937-fix-website-remove-placeholder-author-info-for-groove-jones-customer-story-3576d73d36508193b1a0c0c3cd887686) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
055486cac0 |
feat(website): add 4 team photos and remove infinite scroll loop (#11945)
## Summary Add 4 new team photos and remove the infinite scroll behavior from the careers page team photos carousel. ## Changes - **What**: - Add 4 new photos (team4–team7) to `TeamPhotosSection.vue` - Remove the infinite scroll loop (`loopedPhotos`, `onScroll` handler, `onMounted` scroll initializer) <img width="1000" height="308" alt="Kapture 2026-05-05 at 11 02 16" src="https://github.com/user-attachments/assets/f5f6737f-c6bf-4abf-8780-d72c895f4015" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11945-feat-website-add-4-team-photos-and-remove-infinite-scroll-loop-3576d73d365081cabebecbc06666b9d9) by [Unito](https://www.unito.io) Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
d1df5fadf8 |
fix(website): update payment-failed heading to "Unable to complete payment" (#11943)
*PR Created by the Glary-Bot Agent* --- ## Summary Reword the `payment.failed.title` copy on `comfy.org/payment/failed` from "Payment was not completed" to "Unable to complete payment" — a more active, distinguishing phrasing per design feedback. ## Changes - `apps/website/src/i18n/translations.ts` — update English (`Unable to complete payment`) and Chinese (`无法完成支付`) translations - `apps/website/e2e/payment.spec.ts` — update both English and zh-CN heading assertions to match ## Verification - `pnpm --filter website typecheck` — passes - `pnpm --filter website test:unit` — 30 tests passing - Pre-commit hooks (oxfmt, oxlint, eslint, typecheck, typecheck:website) — all pass - Manual visual verification with Playwright on `/payment/failed` and `/zh-CN/payment/failed` — both render the new heading correctly (screenshots attached) ## Screenshots   ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11943-fix-website-update-payment-failed-heading-to-Unable-to-complete-payment-3576d73d3650817e85e2e7a3891cc307) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
aef71852f0 |
feat: add demo pages with Arcade embeds at /demos/{slug} (#11436)
*PR Created by the Glary-Bot Agent*
---
## Summary
Adds a demo pages system to the website that embeds Arcade interactive
walkthroughs at `comfy.org/demos/{slug}`. These pages will be linked
from welcome/lifecycle emails via Customer.io.
- Adds `/demos/image-to-video` and `/demos/workflow-templates` as the
first two demos
- Follows the existing `customers/[slug].astro` pattern exactly
(config-driven `getStaticPaths()`)
- Full SEO: OG/Twitter cards, HowTo + LearningResource + BreadcrumbList
JSON-LD schemas
- GEO: AI crawler directives in robots.txt, crawlable transcript
alongside iframe
- A11y: iframe title, sr-only transcript, aria-expanded toggle, noscript
fallback
- Email optimization: 1200x630 OG images, SSG pre-rendered, preconnect
to Arcade CDN
- Full zh-CN localization
- Library index stub at /demos for future expansion
- Automatic sitemap inclusion
## Architecture
Adding a new demo = adding one object to `src/config/demos.ts`.
## Note
OG images are tiny placeholders — replace with real 1200x630 screenshots
before go-live.
## Screenshots


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11436-feat-add-demo-pages-with-Arcade-embeds-at-demos-slug-3486d73d365081abbd72e02bf497a43a)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
|
||
|
|
f70285dcb2 |
fix(website): point Install via GitHub buttons to install docs anchor (#11852)
*PR Created by the Glary-Bot Agent* --- ## Summary Updates the "Install via GitHub" CTA buttons on the `/download` page to deep-link to the install instructions section of the ComfyUI README (`#installing`) instead of the repo root, so users land directly on setup steps. ## Changes - `apps/website/src/config/routes.ts`: add `externalLinks.githubInstall = 'https://github.com/Comfy-Org/ComfyUI#installing'` (separate from `externalLinks.github`, which is still used by the navbar/footer/star badge for the generic repo link). - `apps/website/src/components/product/local/HeroSection.vue`: switch the secondary CTA next to "Download Local" from `externalLinks.github` to `externalLinks.githubInstall`. - `apps/website/src/components/product/local/EcoSystemSection.vue`: same swap on the ecosystem-section CTA. The platform-aware `Download Local` button (Windows/macOS installers via `useDownloadUrl`) and the generic GitHub social/repo links elsewhere on the site are unchanged. ## Verification - `pnpm --filter @comfyorg/website typecheck` — 0 errors - `pnpm --filter @comfyorg/website test:unit` — 23/23 passing - `pnpm exec eslint` on changed files — clean - `pnpm exec oxfmt --check` — clean - Manual via `pnpm dev` + Playwright DOM assertion on `/download`: - Hero "INSTALL FROM GITHUB" → `https://github.com/Comfy-Org/ComfyUI#installing` ✓ - EcoSystem "INSTALL FROM GITHUB" → `https://github.com/Comfy-Org/ComfyUI#installing` ✓ - Other "GitHub" links (nav, footer, star badge) → unchanged at `https://github.com/Comfy-Org/ComfyUI` ✓ Per request from #website-and-docs: the local download surfaces should at least link to the ComfyUI install instructions on GitHub. Companion change to comfy-org/website#227. ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11852-fix-website-point-Install-via-GitHub-buttons-to-install-docs-anchor-3546d73d365081fe8370cd675ae8f896) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
6762c08134 |
feat(website): add payment success and failed pages (#11855)
*PR Created by the Glary-Bot Agent* --- ## Summary Recreate the two payment status pages that were never migrated from Framer (they weren't in the sitemap, so were missed). The Stripe checkout flow in `comfy-api` redirects to `https://www.comfy.org/payment/{success,failed}` after a checkout session, so users currently hit a 404 on completion or cancel. ## Changes - **What**: New static Astro pages at `/payment/success`, `/payment/failed` and their `/zh-CN/` variants, sharing a `PaymentStatusSection.vue` component built from the existing `BrandButton` / `SectionLabel` primitives. Translation keys live in `src/i18n/translations.ts` for both locales. Pages are `noindex` and explicitly excluded from the generated sitemap. Adds a Playwright e2e spec covering both pages in both locales. - **Dependencies**: none ## Review Focus - **URL slug**: matches production Stripe config (`STRIPE_CANCEL_URL=…/payment/failed` in `comfy-api/run-service-{prod,staging}.yaml`), not `/payment/failure`. - **Primary CTA target**: links to `externalLinks.apiKeys` (`platform.comfy.org/profile/api-keys`) — the platform root is just a redirect, so this avoids a hop. - **Locale-aware secondary CTA**: derived from `getRoutes(locale)` so future i18n/route changes flow through the existing helper. - **Stale fallback** (out of scope): `comfy-api/gateways/stripe/stripe.go:159` has an unrelated stale fallback pointing at `/payments/` (plural) that's overridden by the env config in production. Worth fixing in a follow-up. ## Screenshots EN success / failed and zh-CN success / failed at desktop widths. Mobile viewport stacks the CTA buttons vertically (verified locally). ## Screenshots     ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11855-feat-website-add-payment-success-and-failed-pages-3556d73d3650819f8f45d8ecf27cb264) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
4033dde983 |
refactor(website): replace UseCaseSection scroll override with hover on desktop (#11696)
## Summary
Per product feedback, scroll-jacking the page to step through
'Industries that create with ComfyUI' categories feels bad on desktop.
This PR removes the desktop scroll override and switches to hover-driven
imagery on lg+, while preserving the existing pin/scrub interaction on
mobile/touch breakpoints.
## Changes
- **What**:
- Gate `usePinScrub` setup to `(max-width: 1023px)` so the pin/scrub
only runs on touch breakpoints; desktop never engages it.
- Wire `@mouseenter` and `@focus` on each category button to update the
active category on desktop. Click still works on both modes via the
existing `scrollToIndex` (which falls through to a direct ref set when
no ScrollTrigger instance is present).
- Pass the same `(max-width: 1023px)` to `useParallax` via its existing
`mediaQuery` option so parallax doesn't run against the no-longer-pinned
section on desktop.
- Apply the section's `lg:h-[calc(100vh+60px)]` unconditionally on lg+
since pin no longer drives it; mobile height is still managed
dynamically by `usePinScrub`'s `cacheLayout`.
- **Breaking**: None.
- **Dependencies**: None.
## Review Focus
- Mobile path inside `usePinScrub.onMounted` is byte-identical to main —
only the early-return condition gained one extra clause
(`!window.matchMedia('(max-width: 1023px)').matches`), which mobile
evaluates to `false` so it falls through to the existing setup.
- `onCategoryHover` early-returns when `isEnabled` is true, making it a
no-op on mobile (where pin is engaged), so a tap doesn't accidentally
fight the scrub.
- `@focus` is wired alongside `@mouseenter` so keyboard tab navigation
also previews the imagery.
- The previous Lenis-on-macOS workaround from this branch is reverted —
it was only needed because the scroll override existed.
## Screenshots (if applicable)
N/A — interaction change. Test on desktop (≥1024px) by hovering category
labels — imagery should swap with no scroll-jacking. Test on mobile
(<1024px) by scrolling the section; pin/scrub should engage as before.
---------
Co-authored-by: Marwan Ahmed <marwan@Marwans-MacBook-Pro.local>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
|
||
|
|
24b548aebc |
fix: route footer Support link to Zendesk help center (#11904)
*PR Created by the Glary-Bot Agent* --- ## Summary The "Support" link in the marketing site footer (Contact column) was reusing the Discord external link. Update it to point at the Zendesk help center at `https://support.comfy.org/hc/en-us`, as requested in the `#website-and-docs` Slack thread. ## Changes - `apps/website/src/config/routes.ts` — add `support` entry to `externalLinks` pointing at `https://support.comfy.org/hc/en-us`. - `apps/website/src/components/common/SiteFooter.vue` — use `externalLinks.support` for the Contact > Support entry instead of `externalLinks.discord`. ## Verification - `pnpm format` and `pnpm exec eslint` clean on both files. - `pnpm typecheck` passes. - Verified locally with `pnpm dev` (Astro on `localhost:4321`); the rendered footer Support link now resolves to `https://support.comfy.org/hc/en-us` (screenshot below). ## Notes Reviewer flagged that `/hc/en-us` forces English and bypasses Zendesk locale negotiation. The exact URL was explicitly requested by the user in the Slack thread, so it is preserved here. Switching to a locale-neutral `https://support.comfy.org/` can be done as a follow-up if desired. ## Screenshots  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11904-fix-route-footer-Support-link-to-Zendesk-help-center-3566d73d36508189abcff34ae766d3c4) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
560e53c68f |
fix: remove coming soon badge from parallel job execution (#11819)
*PR Created by the Glary-Bot Agent* --- Removes the "coming soon" badge from the Parallel Job Execution feature card on the cloud pricing page (`comfy.org/cloud/pricing`). ## Changes - `apps/website/src/components/pricing/WhatsIncludedSection.vue`: drop `isComingSoon: true` from feature11 so it renders with the standard check icon and no badge. The `isComingSoon` mechanism (clock icon + yellow badge) is preserved in the component for future use on other features. ## Note The FAQ copy elsewhere on the site (`cloud.faq.9.a`) still references "one active job at a time" and "parallel runs soon". That copy will be updated separately. ## Verification - `pnpm typecheck` (website): 0 errors - `pnpm lint`: clean (1 pre-existing warning unrelated to this change) - `pnpm format:check`: clean - `pnpm test:unit` (website): 20 passed - Visual check via Playwright on local dev server (see screenshot) ## Screenshots  ┆Issue is synchronized with this [Notion page](https://app.notion.com/p/PR-11819-fix-remove-coming-soon-badge-from-parallel-job-execution-3546d73d365081d19060f976095d03ac) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
1999b7fba0 |
fix: remove (beta) from cloud.faq.3.a (#11905)
*PR Created by the Glary-Bot Agent* --- ## Summary Remove `(beta)` from the `cloud.faq.3.a` translation entry in both English and Simplified Chinese (`zh-CN`), since Comfy Cloud is no longer in beta. ## Changes `apps/website/src/i18n/translations.ts`: - en: `Comfy Cloud (beta) has zero setup...` → `Comfy Cloud has zero setup...` - zh-CN: `Comfy Cloud(测试版)无需任何设置...` → `Comfy Cloud 无需任何设置...` ## Verification - Pre-commit hooks (oxfmt, oxlint, eslint, typecheck, typecheck:website) all passed - Code review (oracle): 0 issues, ready to merge - Manual verification via Playwright on `/cloud` and `/zh-CN/cloud` — FAQ item 3 renders updated copy in both locales (screenshots attached) ## Screenshots   ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11905-fix-remove-beta-from-cloud-faq-3-a-3566d73d36508150997bcf2c89826091) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
5523df1aea |
fix(website): unstretch See all case studies button (#11854)
*PR Created by the Glary-Bot Agent* --- ## Summary The "See all case studies" button on the homepage `CaseStudySpotlightSection` was rendering oddly stretched because it had `class="flex-1 text-center"` while being the sole child of a `flex-row` container — it expanded to fill the entire content column (~592px) instead of sizing to its label. This drops `flex-1`/`text-center` and adds `items-start` to the wrapper so the button sizes to its content and is left-aligned, matching the proportions of every other outline `BrandButton` on the site (Hero, UseCase, customer detail, etc.). ## Changes - `apps/website/src/components/home/CaseStudySpotlightSection.vue`: remove `flex-1 text-center` from the `BrandButton` and align the row's items to the start. `BrandButton` already centers its label internally via `inline-flex … justify-center`, so dropping `text-center` is a no-op visually. ## Before / After - Desktop before: button width = 592px (stretched across the column) - Desktop after: button width = 223px (natural) - Mobile: 1-column layout, now consistently left-aligned ## Review Focus Whether the fix should also live on the `BrandButton` component itself (e.g. a global `max-width`) instead of at the call site. I went with the instance-level fix because every other CTA in the website intentionally uses bare `BrandButton` and lets the content size it; only this one had `flex-1`. A blanket `max-width` would risk changing Hero/MobileMenu buttons that explicitly opt into `w-full lg:w-auto lg:min-w-60`. ## Screenshots    ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11854-fix-website-unstretch-See-all-case-studies-button-3556d73d365081abb3bbe9dbc51cbc07) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
65876c635d |
feat(website): add responsive media tooling for marketing assets (#11869)
*PR Created by the Glary-Bot Agent*
---
## Summary
Adds the building blocks for a responsive media system on
`apps/website`, motivated by the gallery video blurriness raised in
Slack. Three independent pieces:
1. **`<SiteVideo>` Vue component + URL helper** — emits a `<video>` with
multiple `<source>` tags, designed to pair with assets named
`${name}-${width}.${format}` on `media.comfy.org`.
2. **`scripts/process-videos.sh`** — local-developer `ffmpeg` helper
that produces VP9/WebM + H.264/MP4 variants and a poster JPG. Not wired
into CI; the team uploads to `media.comfy.org` out-of-band.
3. **Marketing image conventions** — shared `MARKETING_FORMATS` /
`MARKETING_WIDTHS` constants and a README documenting how to render
local marketing images via Astro's built-in `<Picture>` from
`astro:assets`.
This PR is **infrastructure only** — no existing pages are modified.
Adoption (e.g. converting `HeroSection`, gallery videos) is a follow-up.
The new files are added to knip's ignore list with the existing "pending
stacked PR" pattern.
## Why this shape
- **No custom `<Picture>` wrapper.** Astro 5 already ships a
`ResponsiveImage` component (name conflict), and Astro's
`LocalImageProps | RemoteImageProps` discriminated union does not
survive a thin wrapper without unsafe `as` casts. Shared constants give
the consistency benefit at lower cost.
- **No CI media-upload step.** The `Release: Website` workflow currently
only refreshes the Ashby snapshot; wiring GCS uploads into it would
require new secrets and team coordination beyond this PR's scope. The
script runs locally and outputs are uploaded to `media.comfy.org` the
same way as today.
- **Single resolution per `<video>`.** `<source media="...">` inside
`<video>` is unreliable across browsers (Safari ignores it). The script
generates multiple widths so callers can pick one per page; JS-based
selection can be layered on later if metrics demand it.
## What's verified
- `pnpm --filter @comfyorg/website test:unit` — 30 pass (7 new for
`buildVideoSources` / `videoKey`)
- `pnpm --filter @comfyorg/website typecheck` — clean
- `pnpm --filter @comfyorg/website build` — 41 pages built clean
- `pnpm knip` — exit 0
- `oxfmt --check` and `oxlint` clean on all changed files
- `bash -n` on `process-videos.sh` clean; usage and missing-deps paths
exercised manually
- Manual: home page and `/gallery` rendered via `astro dev` — both
unchanged with zero console errors (screenshots attached)
## Review feedback addressed
After Oracle review, three follow-up commits land:
- **`SiteVideo` reactivity** — `sources` is now `computed`; the
`<video>` is keyed on the joined source URLs so it remounts when the
source set changes (browsers don't reload on `<source>` mutation).
- **`SiteVideo` accessibility** — `aria-hidden="true"` only when truly
decorative (no `alt` and no `controls`).
- **Shell script robustness** — probes duration with `ffprobe` and falls
back to `t=0` for clips shorter than 1s; enables `nocaseglob` so
`CLIP.MP4` is picked up.
- **Docs** — clarifies when to use `<SiteVideo>` (lightweight
multi-source) vs `<VideoPlayer>` (captions, controls, scrubber).
## Out of scope (follow-ups)
- Converting existing pages (`HeroSection`, customer detail heros,
gallery) to use the new components. Most current images are CDN-hosted
and migrating them is a separate decision.
- Re-encoding the gallery videos at a higher source width to actually
fix the blurriness — that requires the team to run `process-videos.sh`
against the source clips and re-upload.
- Combining `<SiteVideo>`'s multi-source support with `<VideoPlayer>`'s
rich chrome.
## Screenshots


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11869-feat-website-add-responsive-media-tooling-for-marketing-assets-3556d73d3650818899c7f9ed3204c9a5)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
|
||
|
|
7abd9d12c8 |
chore(website): refresh Ashby roles snapshot (#11851)
Automated refresh of `apps/website/src/data/ashby-roles.snapshot.json` from the Ashby job board API. **Flow:** 1. `Release: Website` workflow ran (manual trigger). 2. This PR opens with the regenerated snapshot. 3. `CI: Vercel Website Preview` deploys a preview for review. 4. Merging to `main` triggers the production Vercel deploy. The snapshot fallback in `apps/website/src/utils/ashby.ts` remains intact: builds without `WEBSITE_ASHBY_API_KEY` continue to use the committed snapshot. Triggered by workflow run `25260868155`. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11851-chore-website-refresh-Ashby-roles-snapshot-3546d73d365081579f98f13f7b58e611) by [Unito](https://www.unito.io) Co-authored-by: christian-byrne <72887196+christian-byrne@users.noreply.github.com> |
||
|
|
dd9cb42fa1 |
feat: add Run your first workflow button to home hero (#11848)
## Summary Add an outline-style `BrandButton` to the right side of the home page hero section linking to the workflows page. ## Changes - **What**: - Added a `Run your first workflow` outline button below the subtitle in `apps/website/src/components/home/HeroSection.vue`, linking to `externalLinks.workflows`. Mirrors the button pattern from `product/local/HeroSection.vue`. - Added `hero.runFirstWorkflow` i18n entry (en + zh-CN) in `apps/website/src/i18n/translations.ts`. ## Review Focus - Confirmed alignment with design spec. <img width="1505" height="776" alt="image" src="https://github.com/user-attachments/assets/215e667d-1827-447b-99b8-eba8cb5ec7e3" /> <img width="335" height="700" alt="image" src="https://github.com/user-attachments/assets/aeac0876-74c3-4e12-a4b3-203f9e541bc2" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11848-feat-add-Run-your-first-workflow-button-to-home-hero-3546d73d365081358d54eddfda71111e) by [Unito](https://www.unito.io) Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
809fba7b36 |
feat: add Groove Jones customer story (#11849)
## Summary Add a new customer story for Groove Jones — Crocs x NFL FOOH holiday campaign for Dick's Sporting Goods, delivered with Comfy. ## Changes - **What**: - New entry in [`apps/website/src/config/customerStories.ts`](https://github.com/Comfy-Org/ComfyUI_frontend/blob/feat/groove-jones-customer-story/apps/website/src/config/customerStories.ts) registering slug `groove-jones` with cover image hosted on `media.comfy.org/website/customers/groove-jones/`. - Added `customers.story.groove-jones.{category,title,body}` and `customers.detail.groove-jones.topic-1` … `topic-10` translations (en + zh-CN) in [`apps/website/src/i18n/translations.ts`](https://github.com/Comfy-Org/ComfyUI_frontend/blob/feat/groove-jones-customer-story/apps/website/src/i18n/translations.ts). 10 sections matching design sidebar: INTRO, THE OUTPUT, THE PROBLEM, HOW COMFY SOLVED THE PROBLEM, BRAND-TRAINED LORAS, MULTI-MODEL ORCHESTRATION, THE PIPELINE, VERSION CONTROL, FINISHING IN NUKE, THE TAKEAWAY. - Includes 2 pull quotes (Doug Hogan, Dale Carman), 1 final blockquote + author card, and 3 inline images. - Routes `/customers/groove-jones` and `/zh-CN/customers/groove-jones` are auto-generated by `[slug].astro`. ## Review Focus - Contributors author card uses `TBD` placeholder names/roles — to be filled in. - No `readMoreHref` set yet (no public blog post URL). - All 4 images uploaded to `gs://comfy-org-videos/website/customers/groove-jones/` and served via `media.comfy.org`. <img width="1000" height="535" alt="Kapture 2026-05-02 at 23 17 04" src="https://github.com/user-attachments/assets/28654d24-0d49-4303-82ac-b6923cd6bc93" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11849-feat-add-Groove-Jones-customer-story-3546d73d36508128a64bd6809ad77447) by [Unito](https://www.unito.io) Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
3c7781190a |
feat(website): add llms.txt for GEO discovery by AI search agents (#11830)
## Summary Adds `/llms.txt` at the apex following the [llms.txt standard](https://llmstxt.org) — a curated, link-based markdown file that tells LLM-based search agents (ChatGPT search, Perplexity, Claude search, Google AI Overviews, etc.) what's most important on the site. It complements `robots.txt` (crawler permissions) and `sitemap-index.xml` (URL inventory) by giving AI agents a short, prose-friendly index they can ingest into a context window. ## What's in the file 28 links across 6 sections: - **Product** (6) — homepage, Local download, Cloud, Cloud pricing, API, Enterprise - **Workflows and Gallery** (2) — gallery + community workflows site - **Customers and Case Studies** (5) — customers index + 4 named studios (Series Entertainment, Moment Factory, Ubisoft Chord, Open Story Movement) - **Developers and Documentation** (4) — docs.comfy.org, ComfyUI repo, Comfy-Org GitHub org, registry.comfy.org - **Company** (6) — about, careers, contact, blog, privacy, terms - **Optional** (5) — `zh-CN` locale variant, long-form enterprise case studies, blog posts (de-prioritized per spec — agents can skip if context-limited) The intro paragraph names the four product surfaces (Local, Cloud, API, Enterprise), the named customers, and the use-case industries (VFX & animation, advertising, gaming, eCommerce/fashion) — so an agent that ingests only the prose still gets the elevator pitch. ## Verification - All 28 URLs verified live (`HTTP 200`) before commit. - File is plain markdown — no build step. Astro/Vercel will serve it from `apps/website/public/llms.txt` exactly as it serves `robots.txt` (which lives in the same directory and ships at `https://comfy.org/robots.txt`). - Will verify on the Vercel preview deploy after this PR opens that `curl -sI https://<preview>/llms.txt` returns `200` with a sensible `content-type`. (`robots.txt` currently serves as `text/plain; charset=utf-8` — `.txt` will likely do the same; that's fine for AI agents.) ## Decisions - **No `llms-full.txt` yet.** That variant inlines full prose of key pages and requires curating substantive content. Deferred to a follow-up — the marketing-site pages are mostly Vue-rendered hero/feature blocks rather than long-form prose, so a meaningful `llms-full.txt` would need either dedicated copy or a build step that flattens i18n strings + section text. Tracking separately. - **No comment line in `robots.txt`.** I considered adding a `# AI agents: see /llms.txt` comment above the `Sitemap:` directive, but decided against it: (a) the convention is to probe the well-known path `/llms.txt` directly, not to discover it via robots.txt; (b) `robots.txt` was just polished in #11823 with a deliberate compact design and adding a non-standard comment would muddy that; (c) zero implementations I checked actually parse robots.txt for llms.txt hints. Easy to add later if needed. ## Context Third of three follow-ups from the SEO/GEO sweep on 2026-05-02: 1. ~~Comfy-Router: add `X-Content-Type-Options: nosniff` to apex security headers~~ (separate PR on `Comfy-Org/comfy-router`) 2. ~~Cloudflare: enable "Always Use HTTPS"~~ (dashboard toggle, no PR) 3. **This PR** — add `llms.txt` for GEO discovery ## Testing - [x] All linked URLs return 200 - [x] File parses as valid markdown - [ ] Preview deploy serves `/llms.txt` (will verify once preview is up) ┆Issue is synchronized with this [Notion page](https://app.notion.com/p/PR-11830-feat-website-add-llms-txt-for-GEO-discovery-by-AI-search-agents-3546d73d365081a98c6bfc5301699f64) by [Unito](https://www.unito.io) |
||
|
|
167a1e6a0c |
fix(website): override X-Robots-Tag to index,follow on production deployment (#11831)
## P0 SEO fix — entire marketing site is currently `noindex` A deep-audit sweep on **2026-05-02** confirmed that every page on `comfy.org` (home, `/about`, `/pricing`, `/customers`, `/careers`, …) is being served with: ``` x-robots-tag: noindex ``` This hides the entire marketing site from Google and other search engines. ### Root cause `comfy.org` reaches the Astro marketing site via a Cloudflare Worker reverse proxy ([`comfy-router`](https://github.com/Comfy-Org/comfy-router)) that does: ```js fetch('https://website-frontend-comfyui.vercel.app/...') ``` Per Vercel's KB article [Avoiding duplicate-content with vercel.app URLs](https://vercel.com/kb/guide/avoiding-duplicate-content-with-vercel-app-urls): > By default, Vercel adds an `X-Robots-Tag: noindex` HTTP header to all deployments hosted on `vercel.app` URLs. […] This header tells search engines like Google not to index these deployment URLs. Because `website-frontend-comfyui.vercel.app` is **not** registered as a Production custom domain on the Vercel project, Vercel applies that header — and our Worker faithfully forwards it back to `comfy.org` clients (and Googlebot). ### Fix Vercel's documented workaround for proxied `*.vercel.app` setups is to override the header via `vercel.json` ([blog post by Dan Denney](https://www.dandenney.com/posts/front-end-dev/fixing-x-robots-nofollow-with-vercel/)): ```json "headers": [ { "source": "/(.*)", "has": [ { "type": "host", "value": "website-frontend-comfyui.vercel.app" } ], "headers": [ { "key": "X-Robots-Tag", "value": "index, follow" } ] } ] ``` ### Why the `has` host filter Critical scoping detail: without the `has` filter, the override would also apply to PR-preview deployments at `comfy-website-preview-pr-N.vercel.app`. We want previews to **stay** `noindex` to avoid duplicate-content competition with production. The filter pins the override to the production deployment hostname only. The hostname matches `WEBSITE_ORIGIN` in `comfy-router/src/index.js`: ```js const WEBSITE_ORIGIN = 'https://website-frontend-comfyui.vercel.app'; ``` ### Defense in depth A parallel PR on `comfy-router` (TBD) will also strip `X-Robots-Tag: noindex` at the Worker layer, so the public `comfy.org` response is correct even if a future Vercel project change re-introduces the upstream header. ### Verification (after merge + Vercel production deploy) ```bash # Production should no longer be noindex curl -sI https://comfy.org/ | grep -i x-robots-tag curl -sI https://comfy.org/about | grep -i x-robots-tag curl -sI https://comfy.org/pricing | grep -i x-robots-tag # Expect: empty output, OR "x-robots-tag: index, follow" # Direct Vercel production hostname curl -sI https://website-frontend-comfyui.vercel.app/ | grep -i x-robots-tag # Expect: "x-robots-tag: index, follow" # Preview deploys must stay noindex (proves the host filter works) curl -sI https://comfy-website-preview-pr-<N>.vercel.app/ | grep -i x-robots-tag # Expect: "x-robots-tag: noindex" ``` ### Pre-merge state (for the record) ``` $ curl -sI https://comfy.org/ | grep -iE 'x-robots-tag|x-served-by' x-served-by: vercel-website x-robots-tag: noindex ``` ### Scope Minimum delta — only `apps/website/vercel.json`. No other files touched. ┆Issue is synchronized with this [Notion page](https://app.notion.com/p/PR-11831-fix-website-override-X-Robots-Tag-to-index-follow-on-production-deployment-3546d73d365081489b62e6633d25dfe5) by [Unito](https://www.unito.io) --------- Co-authored-by: Christian Byrne <christian@comfy.org> Co-authored-by: GitHub Action <action@github.com> |
||
|
|
e831daae59 |
feat(website): point robots.txt at /sitemap-index.xml + AI crawler rules (#11823)
## Summary Once [comfy-router#22](https://github.com/Comfy-Org/comfy-router/pull/22) ships, `comfy.org/sitemap-index.xml` will return a unified index aggregating both the website (38 URLs) and workflow-templates sitemaps. This PR: 1. Reverts `Sitemap:` back to `/sitemap-index.xml` (was `/sitemap-0.xml` in #11802 as a workaround for the 404). 2. Adds explicit allow records for 21 search and AI/LLM crawlers (GPTBot, ChatGPT-User, OAI-SearchBot, Google-Extended, ClaudeBot, Claude-Web, anthropic-ai, PerplexityBot, Perplexity-User, Applebot-Extended, Bytespider, Amazonbot, CCBot, Meta-ExternalAgent, Meta-ExternalFetcher, Diffbot, etc.). 3. Adds `Disallow:` for `/_astro/`, `/_website/`, `/_vercel/` — Vercel build artifacts that aren't useful to crawl. ## Why granular UAs Stacked `User-agent:` records (per [RFC 9309 §2.2](https://datatracker.ietf.org/doc/html/rfc9309#section-2.2)) share one rule block. Listing each bot explicitly: - Signals intent to AI bots that look for their UA in robots.txt before crawling more aggressively. - Surfaces our crawl policy clearly to anyone inspecting the file. - Lets us add per-bot Disallows in future without restructuring. ## Merge order ⚠️ **Do NOT merge until comfy-router#22 is deployed to production.** Until then, `/sitemap-index.xml` returns 404 and this PR would re-break the issue PR #11802 patched. Verification: ```bash curl -sI https://comfy.org/sitemap-index.xml # expect: HTTP/2 200, x-served-by: worker-sitemap-index ``` Once that returns 200, this is safe to merge. ## Verification (after merge + deploy) ```bash # robots.txt is served and points at the unified index curl -s https://comfy.org/robots.txt | grep '^Sitemap:' # → Sitemap: https://comfy.org/sitemap-index.xml # Each AI crawler can fetch it for ua in 'GPTBot/1.0' 'ClaudeBot/1.0' 'PerplexityBot/1.0' 'Google-Extended' 'Applebot-Extended'; do curl -s -o /dev/null -w "$ua → %{http_code}\n" -A "$ua" https://comfy.org/robots.txt done # Sitemap is reachable from robots.txt SITEMAP=$(curl -s https://comfy.org/robots.txt | awk -F': ' '/^Sitemap:/ {print $2}') curl -s "$SITEMAP" | xmllint --noout - && echo "valid XML" ``` ## Linear / closes - Closes FE-437 (AI crawler rules) - Updates FE-432 — the robots.txt change in #11802 was a workaround that's no longer needed once #22 ships ┆Issue is synchronized with this [Notion page](https://app.notion.com/p/PR-11823-feat-website-point-robots-txt-at-sitemap-index-xml-AI-crawler-rules-3546d73d3650811dbceedd06c00db444) by [Unito](https://www.unito.io) |
||
|
|
4ed00cec08 |
update: robots.txt to point to /sitemap-0.xml (#11802)
## Summary <!-- One sentence describing what changed and why. --> robots.txt at [comfy.org](https://comfy.org/) references /sitemap-index.xml which returns 404. The actual working sitemap is at /sitemap-0.xml (200, 38 URLs). This blocks search engines from discovering the sitemap. ## Changes - **What**: <!-- Core functionality added/modified --> - Update robots.txt to point to /sitemap-0.xml, OR ## Review Focus <!-- Critical design decisions or edge cases that need attention --> <!-- If this PR fixes an issue, uncomment and update the line below --> <!-- Fixes #ISSUE_NUMBER --> ## Screenshots (if applicable) <!-- Add screenshots or video recording to help explain your changes --> ┆Issue is synchronized with this [Notion page](https://app.notion.com/p/PR-11802-update-robots-txt-to-point-to-sitemap-0-xml-3536d73d365081bb9545eb96dd1e8025) by [Unito](https://www.unito.io) |
||
|
|
ef98ba0e8f |
feat: add plum/ink color primitives and standardize design tokens (#11139)
*PR Created by the Glary-Bot Agent* --- ## Summary Adds new `plum` and `ink` color scales for Comfy Hub branding and standardizes existing tokens to align with current Figma design system. ### Changes **Phase 1 — New primitives** (`_palette.css`) - Added `plum-300/400/500/600` and `ink-100` through `ink-900` **Phase 2 — Token cleanup** (`style.css`) - Removed deprecated `slate-100/200/300` primitives (cool blue-grey, removed from Figma) - Removed duplicate `graphite-400` (identical hex to slate-100) - Dark mode: migrated 6 slate/graphite references to muted-foreground, smoke-700, smoke-800, charcoal-200 - Light mode: replaced 3 `ash-500` references with `smoke-800` per designer alignment ### Token migration detail | Dark mode token | Old value | New value | Rationale | |---|---|---|---| | `--node-component-header-icon` | slate-300 (#5b5e7d) | muted-foreground (smoke-800) | Figma `node/foreground-secondary` | | `--node-component-slot-text` | slate-200 (#9fa2bd) | smoke-700 (#a0a0a0) | Lighter neutral for text contrast | | `--node-component-surface-highlight` | slate-100 (#9c9eab) | smoke-800 (#8a8a8a) | Neutral grey highlight | | `--node-component-tooltip-border` | slate-300 (#5b5e7d) | charcoal-200 (#494a50) | Consistent with dark border tokens | | `--text-secondary` | slate-100 (#9c9eab) | smoke-700 (#a0a0a0) | Adequate contrast on dark surfaces | | `--widget-background-highlighted` | graphite-400 (#9c9eab) | smoke-800 (#8a8a8a) | Removed duplicate, neutral replacement | ### Visual note These changes shift some dark mode colors from cool blue-grey to neutral grey. This is intentional per the design team. The `--node-component-surface-highlight` and `--node-component-tooltip-border` tokens should be QA'd as the designer noted. ### Not included (Phase 3) Hub Dark overlay theme will ship separately once the Hub UI work is ready to validate against. ## Screenshots   ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11139-feat-add-plum-ink-color-primitives-and-standardize-design-tokens-33e6d73d365081418e13e0efe6161fb5) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
a934056246 |
feat(website): add PostHog analytics (#11735)
## Summary Adds PostHog page analytics to the marketing website (`apps/website/`). ## Changes - **What**: New `posthog.ts` script with `initPostHog`/`capturePageview`. Wired into `BaseLayout.astro` behind `import.meta.env.PROD` (mirroring the GTM gate). Pageviews are captured on every `astro:page-load` so ClientRouter view-transition navigations are tracked, not just hard reloads. - **Dependencies**: `posthog-js` (already in the workspace catalog at `^1.358.1`; previously used by the workbench telemetry provider). ## Review Focus - API host is set to `https://t.comfy.org` to match `src/platform/telemetry/providers/cloud/PostHogTelemetryProvider.ts` — confirm that proxy is OK to share with the website surface. - Project token is hard-coded inline. It is a public `phc_…` frontend token (designed to ship to clients); this matches the pattern used for `gtmId` in the same file. Happy to switch to a `PUBLIC_POSTHOG_KEY` env var if preferred. - `person_profiles: 'identified_only'` to avoid creating profiles for every anonymous visitor — flag if you want full anonymous tracking instead. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11735-feat-website-add-PostHog-analytics-3516d73d3650811189c6d64c3af4ded9) by [Unito](https://www.unito.io) |
||
|
|
17c18b0707 |
fix: embed HubSpot contact form (#11723)
## Summary Embed the HubSpot-hosted contact sales form on `/contact` and `/zh-CN/contact` so HubSpot owns submission handling, validation, anti-spam/security updates, tracking context, and form configuration. ## Changes - **What**: Replaces the custom local contact form stub with a HubSpot embed component using the HubSpot-hosted developer/raw HTML script and `hs-form-html` container. - **Localization**: Uses the existing English form ID by default and switches to the zh-CN form ID for `/zh-CN/contact`. - **Styling**: Applies HubSpot form CSS custom properties to match the Comfy contact page colors and `PP Formula` font more closely. - **Docs**: Updates the website README with the developer embed snippet and the zh-CN form ID. - **Dependencies**: None. ## Why Embedded Form - HubSpot docs say forms should be loaded with the HubSpot-hosted JavaScript file, and that security, anti-spam, accessibility, and performance improvements will not propagate if the embed runtime is copied or self-hosted: https://developers.hubspot.com/docs/cms/start-building/building-blocks/modules/forms - The direct form submission endpoint is documented under `v3 legacy`: https://developers.hubspot.com/docs/api-reference/legacy/marketing/forms/v3-legacy/submit-data-unauthenticated - HubSpot’s legacy API overview says numeric-versioned APIs are legacy and will be deprecated in a future release: https://developers.hubspot.com/docs/api-reference/legacy/overview ## Review Focus - Confirm the portal ID and form IDs are correct: - `en`: `94e05eab-1373-47f7-ab5e-d84f9e6aa262` - `zh-CN`: `6885750c-02ef-4aa2-ba0d-213be9cccf93` - Check visual fit on `/contact` and `/zh-CN/contact`, especially font, background, inputs, radio controls, and submit button. - Confirm the developer/raw HTML embed remains the preferred integration over a custom Forms API POST. ## Local Checks - `pnpm exec oxfmt --check apps/website/src/components/contact/HubspotFormEmbed.vue apps/website/README.md` - `pnpm exec eslint apps/website/src/components/contact/HubspotFormEmbed.vue` - `pnpm --filter @comfyorg/website typecheck` - `pnpm --filter @comfyorg/website test:unit` - `pnpm --filter @comfyorg/website build` - Commit hooks: stylelint, oxfmt, oxlint, eslint, `pnpm typecheck`, `pnpm typecheck:website` - Push hook: `pnpm knip --cache` Build completed with existing non-fatal environment warnings: Node `v25.8.1` vs requested `24.x`, unresolved website font paths deferred to runtime, `transformWithEsbuild` deprecation, and missing Ashby env falling back to the committed snapshot. Incredibly, during the taking of these screenshots, I discovered a bug in macos, where despite the snapshot/record bar not existing, from me esc'ing out, some of the tooltips persist. Closing and reopening the lid did not fix this. I didn't see the process in activity monitor. <img width="1512" height="862" alt="Screenshot 2026-04-29 at 7 09 55 PM" src="https://github.com/user-attachments/assets/92518795-6845-4b34-8da3-54048b440eb1" /> <img width="1512" height="862" alt="Screenshot 2026-04-29 at 7 13 18 PM" src="https://github.com/user-attachments/assets/f7609e58-898d-413c-975c-b02b70b84e73" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11723-fix-embed-HubSpot-contact-form-3506d73d365081528bfbe4b024c2a21f) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com> |
||
|
|
810381ab63 |
Stabilize website GitHub stars in visual snapshots (#11771)
## Summary Stabilize the website nav GitHub star count in visual-test builds so snapshot comparisons do not drift as the live GitHub count changes. ## Changes - **What**: Added `WEBSITE_GITHUB_STARS_OVERRIDE` for build-time star-count overrides and set it to `111000` in the website E2E and screenshot-update workflows. - **Dependencies**: None. ## Review Focus Confirm the deterministic build-time override is preferable to screenshot masking, since Playwright masks draw a colored rectangle whose geometry can also drift when masked content changes size. ## Screenshots (if applicable) Not included; this keeps visual-test input data stable rather than changing the UI. |
||
|
|
eb8f8b75b5 |
fix: correct zh-CN translations across landing, product, and pricing pages (#11655)
*PR Created by the Glary-Bot Agent* --- ## Summary Applies translation corrections to the Chinese (zh-CN) version of the website, requested in the `#project-new-website-brand-refresh` Slack thread by a native-speaker reviewer. ### Changes (in `apps/website/src/i18n/translations.ts` + `apps/website/src/pages/zh-CN/index.astro`) - **Landing — blog section badges**: `如何` → `了解`, `运作` → `运行方式` - **Landing — hero headline**: `专业控制` → `最强可控性` (also updates the zh-CN page `<title>`) - **Landing — hero subtitle**: `Comfy 是面向视觉专业人士的 AI 创作引擎,让您掌控每个模型、每个参数和每个输出。` → `Comfy 是面向专业视觉人士的 AI 创作引擎。您可以精确掌控每个模型、每个参数和每个输出。` - **Landing — showcase subtitle**: `从社区模板开始,或从零构建。` → `从工作流模板开始,或从零构建。` - **Landing — showcase feature1 title**: `节点式完全控制` → `节点带来的可控性` - **Landing — use case body**: `由 60,000+ 节点、数千个工作流 和一个比任何公司都更快构建的社区驱动。` → `60,000+ 节点,数千条工作流,一个比任何公司速度都更快的社区。` - **All `查看xx特性` CTAs** (local / cloud / API / enterprise product cards): `特性` → `属性` - **All `合作节点` pricing copy**: `合作节点` → `合作伙伴节点` (correct translation for "partner node") ### Verification - `pnpm typecheck` (astro check): 0 errors, 0 warnings, 0 hints - `pnpm build`: completes successfully; rebuilt zh-CN pages contain the new strings and no longer contain the old ones - Manual Playwright verification on `/zh-CN/` (hero, showcase badges, showcase feature card, use-case body, product cards) and `/zh-CN/cloud/pricing/` (`合作伙伴节点` appears 4×, `合作节点` appears 0×) ### Notes on review feedback A review pass flagged two of the swaps (`特性→属性` and `从社区模板→从工作流模板`) as potential style concerns. Both changes are kept as-is because they were specified verbatim by the native-speaker reviewer who requested this pass. ## Screenshots     ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11655-fix-correct-zh-CN-translations-across-landing-product-and-pricing-pages-34e6d73d3650816daddde4a90fb47a01) by [Unito](https://www.unito.io) Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> |
||
|
|
7a13340989 |
chore: add 301 redirects for old Framer case study URLs (#11654)
## Summary Add 301 redirects for old Framer case study URLs to new `/customers/` pages. ## Changes - Add `redirects` config to `apps/website/astro.config.ts` mapping two old Framer enterprise case study URLs to their new Astro customer pages ## Testing ### Automated - Website build succeeds with redirect pages generated - Lint, typecheck, and format checks pass ### E2E Verification Steps 1. Deploy to preview 2. Visit `/cloud/enterprise-case-studies/comfyui-at-architectural-scale-how-moment-factory-reimagined-3d-projection-mapping` — should 301 redirect to `/customers/moment-factory/` 3. Visit `/cloud/enterprise-case-studies/how-series-entertainment-rebuilt-game-and-video-production-with-comfyui` — should 301 redirect to `/customers/series-entertainment/` Fixes #11583 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11654-chore-add-301-redirects-for-old-Framer-case-study-URLs-34e6d73d36508187a386eed3e25cf1b2) by [Unito](https://www.unito.io) |
||
|
|
d0e9984a73 |
feat: update BYOKeySection images to enterprise node WebPs (#11614)
Update BYOKeySection card images from placeholder API logos to dedicated enterprise node WebP images hosted on media.comfy.org. ## Changes - Replace `logo-purple.webp` and `logo-yellow.webp` with `enterprise_node_1.webp` and `enterprise_node_2.webp` - New images are near-lossless WebP (~70% smaller than source PNGs) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11614-feat-update-BYOKeySection-images-to-enterprise-node-WebPs-34c6d73d365081239d92c649eb563b7e) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
725ed120e8 |
fix: disable parallax on mobile to prevent enterprise section overlap (#11609)
## Summary Disable parallax on mobile in the enterprise DataOwnershipSection to prevent images from overlapping the next section. ## Changes - **What**: Add `mediaQuery` option to `useParallax` composable, using GSAP's `matchMedia()` to create/revert animations responsively. DataOwnershipSection now only applies parallax at the `lg` (1024px+) breakpoint. ## Review Focus GSAP `matchMedia` automatically reverts animations (resetting transforms) when the query stops matching, so no manual cleanup is needed on resize. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11609-fix-disable-parallax-on-mobile-to-prevent-enterprise-section-overlap-34c6d73d365081a48d55e4cf880e3bab) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
453a0edd1e |
chore: refresh Ashby careers snapshot (#11611)
## Changes Refreshes the Ashby careers snapshot (`ashby-roles.snapshot.json`). The "Business" department has been renamed to "Operations" on Ashby's side. The same 3 roles (Senior Technical Recruiter, BizOps Strategist, Founding Customer Success Manager) now appear under "Operations". ## Testing - Snapshot was generated via `pnpm --filter @comfyorg/website ashby:refresh-snapshot` which validates the API response through Zod schemas before writing. - Lint-staged checks (typecheck, eslint, oxlint, oxfmt) passed on commit. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11611-chore-refresh-Ashby-careers-snapshot-34c6d73d3650813ea289c3c0371f882b) by [Unito](https://www.unito.io) Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
5a8ded7959 |
Website: pull careers page listing from ashby API (#11590)
Careers --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> |
||
|
|
bb23b9352c |
fix: update enterprise hero SVG to match updated design (#11608)
## Changes Update the enterprise hero SVG in `HeroSection.vue` to match the updated design export. ### Key changes - **viewBox**: `600 -50 1000 1100` → `0 0 1600 1046` with `clip-path` wrapper and background rects for proper clipping - **Block pieces**: stroke/stroke-width moved from parent `<g>` to each individual `<path>`, with duplicated paths for layered rendering - **Block cluster**: wrapped in `.block-cluster` group with its own CSS transform-origin - **Ripple delay classes**: renamed `ripple-delay-*` → `delay-*` - **Fade overlay**: added `pointer-events: none` to prevent blocking interactions Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
25f0b41f63 |
Remember what was forgotten (#11603)
## Summary Every page has a story to tell. ## Changes - **What**: Something was missing. Now it isn't. ## Review Focus Look closely at what was lost. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11603-Remember-what-was-forgotten-34c6d73d36508184b3cef39d0be4a3bd) by [Unito](https://www.unito.io) |
||
|
|
e7673fcca7 |
update: API page links to keys and docs (#11606)
## Summary Update API page CTA buttons to link directly to the API keys page and API docs instead of generic platform/cloud/docs links. ## Changes - **What**: Point "Get API Keys" buttons in HeroSection and StepsSection to `platform.comfy.org/profile/api-keys`; point "Read the Docs" button to `docsApi` route; add `apiKeys` entry to `externalLinks` config. ## Review Focus Straightforward link target updates — verify the new URLs are correct. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11606-update-API-page-links-to-keys-and-docs-34c6d73d365081268bb5dd55c33646c8) by [Unito](https://www.unito.io) |
||
|
|
7038cab926 |
update: replace placeholder images in API automation section (#11602)
## Changes - Replace placeholder images in API automation section with final assets - Feature 1: `desert.webp` → `precision-tools.webp` - Feature 3: `free.webp` → `infrastructure-nodes.webp` <img width="1000" height="552" alt="Kapture 2026-04-25 at 00 54 23" src="https://github.com/user-attachments/assets/dd503d2f-56c3-4346-adfa-27b3b92a04a8" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11602-update-replace-placeholder-images-in-API-automation-section-34c6d73d365081319ca4db9b60099835) by [Unito](https://www.unito.io) Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
1f888de0f6 |
update: content in Price page (#11600)
## Summary <!-- One sentence describing what changed and why. --> Update wrong content in Price page of new website ## Changes - **What**: <!-- Core functionality added/modified --> - update both English and Chinese content of translate key `pricing.included.feature2.description` ## Review Focus <!-- Critical design decisions or edge cases that need attention --> <!-- If this PR fixes an issue, uncomment and update the line below --> <!-- Fixes #ISSUE_NUMBER --> ## Screenshots (if applicable) <!-- Add screenshots or video recording to help explain your changes --> <img width="1046" height="147" alt="image" src="https://github.com/user-attachments/assets/0f2dc66c-d384-4fb4-85cb-2d9f68469dbc" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11600-update-content-in-Price-page-34c6d73d365081bb9ae1e09842c77249) by [Unito](https://www.unito.io) |
||
|
|
b7a8056ab0 |
update: local hero illustration stroke colors and fix overflow clipping (#11601)
## Changes - Update SVG stroke color from `#7E7C78` to `#4D3762` to match design spec - Reduce hex node stroke width from 6 to 3 - Fix illustration bottom edge being hard-clipped by removing `lg:overflow-y-clip` from section - Adjust container aspect ratio to match SVG viewBox proportions <img width="1000" height="1287" alt="Kapture 2026-04-25 at 00 41 16" src="https://github.com/user-attachments/assets/a3a14fba-74b3-4051-ac12-c175c4b3bd61" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11601-update-local-hero-illustration-stroke-colors-and-fix-overflow-clipping-34c6d73d3650811e9f0bdc1a3274800e) by [Unito](https://www.unito.io) Co-authored-by: Amp <amp@ampcode.com> |