Compare commits

...

3 Commits

Author SHA1 Message Date
huang47
d4b1ced906 ci: make Codecov patch coverage informational 2026-07-17 13:27:56 -07:00
Maanil Verma
d791351a1c feat(subscription): unify credit gold across indicators and subscribe buttons (#13763)
## Summary

Credit indicators and subscribe CTAs now share one gold, so the credit
balance, the amounts in pricing and checkout, and the buttons that
upgrade or top up all read as a single system. The subscribe buttons
also drop the old purple gradient for a solid gold that is actually
legible.

## Changes

**What**

- Recolor the credit accent to a single gold value and point every
credit surface at that one token, replacing the scattered amber and gold
used before.
- Repaint the subscribe buttons: they were a multi layer purple gradient
with faint white text (nearly unreadable), and are now a solid gold fill
with dark text. Hover dims slightly instead of shifting the gradient.
- Rename the button `subscribe` variant (it used to be called
`gradient`, which stopped being accurate once it became a flat fill) and
delete the now unused gradient token so there is no dead styling left
behind.
- Swap the credit cost glyphs across pricing tables, subscription
success and preview screens, the free tier quota, the partner node
popover, and both user popovers so they match the recolored token rather
than raw amber.
- Built on top of #13712 

**Breaking**

None. The subscribe buttons keep the same public API (the shared
`SubscribeButton` still exposes a `buttonVariant` prop, now typed
`'default' | 'subscribe'`), and no behavior, routing, or telemetry
changes.

## Testing

This is a token and styling change with no logic, so the meaningful
verification is visual plus the standard gates, not new unit tests (a
test asserting a hex value would just be a change detector).

<img width="507" height="557" alt="image"
src="https://github.com/user-attachments/assets/fed73d12-e3cc-46a6-aae2-db37f24d9bbb"
/>
2026-07-18 00:37:26 +05:30
Mobeen Abdullah
922be31b74 feat(website): rename Comfy Hub to Comfy Workflows in user-facing copy (#13718)
## Summary

Marketing-site half of the **Comfy Hub → Comfy Workflows** rename
([GTM-271](https://linear.app/comfyorg/issue/GTM-271/comfy-workflows-rename-site-docs-copylogo-sweep));
the hub-side sweep is Comfy-Org/workflow_templates#1015. Silent copy
change, links keep pointing at comfy.org/workflows.

## Changes

- **What**: renames the six user-facing "Comfy Hub" mentions to "Comfy
Workflows": the Community nav item, the homepage/models showcase card
title, the models-page "COMFY HUB" eyebrow, the "Browse Comfy Hub" link
(en + zh-CN), and the two supported-models sentences (body copy + FAQ
JSON-LD text).
- Internal identifiers unchanged per the rename PRD non-goals (the
`nav.comfyHub` i18n key stays).

## Review Focus

- The supported-models copy also feeds the FAQPage JSON-LD;
`validate:jsonld` passes on all 503 pages.
- zh-CN strings keep the brand in Latin script ("Comfy Workflows"),
matching how "Comfy Hub" was handled.

## Verification

- typecheck 0 errors · unit 199/199 · oxfmt clean · build 500 pages ·
validate:jsonld 503 pages · built HTML contains zero remaining "Comfy
Hub".

## Screenshots (if applicable)

Attached below (Community nav dropdown, models-page showcase section).
2026-07-17 18:19:41 +00:00
20 changed files with 42 additions and 56 deletions

View File

@@ -83,8 +83,8 @@ const translations = {
'如果您是 ComfyUI 新手,可以从 App 模式开始——这是工作流的简化视图。您随时可以切换回节点图视图以深入了解。'
},
'showcase.feature3.title': {
en: 'Community Workflows on Comfy Hub',
'zh-CN': 'Comfy Hub 上的社区工作流'
en: 'Community Workflows on Comfy Workflows',
'zh-CN': 'Comfy Workflows 上的社区工作流'
},
'showcase.feature3.description': {
en: 'Browse and remix thousands of community-shared workflows. Start from a proven template and customize it to your needs.',
@@ -2272,7 +2272,7 @@ const translations = {
en: 'Comfy Enterprise',
'zh-CN': 'Comfy 企业版'
},
'nav.comfyHub': { en: 'Comfy Hub', 'zh-CN': 'Comfy Hub' },
'nav.comfyHub': { en: 'Comfy Workflows', 'zh-CN': 'Comfy Workflows' },
'nav.gallery': { en: 'Gallery', 'zh-CN': '画廊' },
'nav.learning': { en: 'Learning', 'zh-CN': '学习' },
'nav.blogs': { en: 'Blog', 'zh-CN': '博客' },
@@ -4302,8 +4302,8 @@ const translations = {
'zh-CN': '{count} 个工作流'
},
'models.list.contact.label': {
en: 'COMFY HUB',
'zh-CN': 'COMFY HUB'
en: 'COMFY WORKFLOWS',
'zh-CN': 'COMFY WORKFLOWS'
},
'models.showcase.label': { en: 'AI MODELS', 'zh-CN': 'AI 模型' },
'models.showcase.heading': {
@@ -4339,9 +4339,9 @@ const translations = {
'zh-CN': 'Wan 2.2\n文字转视频'
},
'models.list.contact.heading': {
en: 'Pick a model and explore what the community has built. <a href="https://comfy.org/workflows" target="_blank" rel="noopener noreferrer" class="text-primary-comfy-yellow underline">Browse Comfy Hub</a> for the newest workflows.',
en: 'Pick a model and explore what the community has built. <a href="https://comfy.org/workflows" target="_blank" rel="noopener noreferrer" class="text-primary-comfy-yellow underline">Browse Comfy Workflows</a> for the newest workflows.',
'zh-CN':
'选择一个模型,浏览社区的创作成果。<a href="https://comfy.org/workflows" target="_blank" rel="noopener noreferrer" class="text-primary-comfy-yellow underline">访问 Comfy Hub</a> 查看最新工作流。'
'选择一个模型,浏览社区的创作成果。<a href="https://comfy.org/workflows" target="_blank" rel="noopener noreferrer" class="text-primary-comfy-yellow underline">访问 Comfy Workflows</a> 查看最新工作流。'
},
// Payment status pages

View File

@@ -44,7 +44,7 @@ const dirDescriptions: Record<string, string> = {
}
const dirDesc = dirDescriptions[model.directory] ?? 'an AI model'
const whatIsDescription = `${displayName} is ${dirDesc}. You can run it locally in ComfyUI with full control over every parameter, or access it through Comfy Cloud. ComfyUI's node-based workflow editor lets you connect ${displayName} with ControlNets, LoRAs, upscalers, and custom nodes to build any pipeline you need. There are ${model.workflowCount} community workflow templates using ${displayName} on Comfy Hub, ready to load and customize.`
const whatIsDescription = `${displayName} is ${dirDesc}. You can run it locally in ComfyUI with full control over every parameter, or access it through Comfy Cloud. ComfyUI's node-based workflow editor lets you connect ${displayName} with ControlNets, LoRAs, upscalers, and custom nodes to build any pipeline you need. There are ${model.workflowCount} community workflow templates using ${displayName} on Comfy Workflows, ready to load and customize.`
const pageTitle = `${displayName} in ComfyUI`
const pageDescription = `Run ${displayName} in ComfyUI with full parameter control. ${model.workflowCount} community workflow templates, step-by-step tutorials, and free local inference.`
@@ -87,7 +87,7 @@ const faqPage: JsonLdNode = {
name: `How many ComfyUI workflows use ${displayName}?`,
acceptedAnswer: {
'@type': 'Answer',
text: `There are ${model.workflowCount} community workflow templates that use ${displayName} on Comfy Hub. Each template is ready to run in ComfyUI and can be customized to suit your project.`,
text: `There are ${model.workflowCount} community workflow templates that use ${displayName} on Comfy Workflows. Each template is ready to run in ComfyUI and can be customized to suit your project.`,
},
},
{

View File

@@ -1,3 +1,9 @@
coverage:
status:
patch:
default:
informational: true
comment:
layout: 'header, diff, flags, files'
behavior: default

View File

@@ -49,7 +49,7 @@
--color-gold-500: #fdab34;
--color-gold-600: #fd9903;
--color-credit: #fabc25;
--color-credit: #ddbd31;
--color-coral-500: #f75951;
--color-coral-600: #e04e48;
@@ -140,26 +140,6 @@
--button-surface: var(--color-white);
--button-surface-contrast: var(--color-black);
--subscription-button-gradient:
linear-gradient(
315deg,
rgb(105 230 255 / 0.15) 0%,
rgb(99 73 233 / 0.5) 100%
),
radial-gradient(
70.71% 70.71% at 50% 50%,
rgb(62 99 222 / 0.15) 0.01%,
rgb(66 0 123 / 0.5) 100%
),
linear-gradient(
92deg,
#d000ff 0.38%,
#b009fe 37.07%,
#3e1ffc 65.17%,
#009dff 103.86%
),
linear-gradient(var(--color-button-surface, #2d2e32));
/* Code styling colors for help menu*/
--code-text-color: rgb(0 122 255 / 1);
--code-bg-color: rgb(96 165 250 / 0.2);

View File

@@ -31,7 +31,7 @@
<!-- Credits Section -->
<div v-if="isActiveSubscription" class="flex items-center gap-2 px-4 py-2">
<i class="icon-[lucide--component] text-sm text-amber-400" />
<i class="icon-[lucide--component] text-sm text-credit" />
<Skeleton v-if="isLoading" width="4rem" height="1.25rem" class="w-full" />
<span v-else class="text-base font-semibold text-base-foreground">{{
formattedBalance
@@ -48,7 +48,7 @@
</Button>
<Button
v-if="isCloud && isFreeTier"
variant="gradient"
variant="subscribe"
size="sm"
data-testid="upgrade-to-add-credits-button"
@click="handleUpgradeToAddCredits"
@@ -72,7 +72,7 @@
:fluid="false"
:label="$t('subscription.subscribeToComfyCloud')"
size="sm"
button-variant="gradient"
button-variant="subscribe"
@subscribed="handleSubscribed"
/>
</div>

View File

@@ -2,7 +2,7 @@
<Button
v-if="isCloud && isFreeTier"
class="mr-2 shrink-0 whitespace-nowrap"
variant="gradient"
variant="subscribe"
size="sm"
data-testid="topbar-subscribe-button"
@click="handleClick"

View File

@@ -24,8 +24,8 @@ export const buttonVariants = cva({
base: 'bg-base-background text-base-foreground hover:bg-secondary-background-hover',
tertiary:
'bg-tertiary-background text-base-foreground hover:bg-tertiary-background-hover',
gradient:
'border-transparent bg-(image:--subscription-button-gradient) text-white hover:opacity-90'
subscribe:
'border-transparent bg-credit text-charcoal-800 hover:opacity-80'
},
size: {
sm: 'h-6 rounded-sm px-2 py-1 text-xs',
@@ -58,7 +58,7 @@ const variants = [
'base',
'tertiary',
'overlay-white',
'gradient'
'subscribe'
] as const satisfies Array<ButtonVariants['variant']>
const sizes = [
'sm',

View File

@@ -147,7 +147,7 @@
<div v-if="showActionButton" class="flex flex-col gap-3">
<Button
v-if="isFreeTier"
variant="gradient"
variant="subscribe"
size="lg"
class="w-full font-normal"
@click="handleUpgradeToAddCredits"

View File

@@ -43,7 +43,7 @@ const label = computed(() =>
v-if="hasInvalidNodes"
class="flex w-full items-center justify-center gap-2"
>
<i class="icon-[comfy--credits] bg-amber-400" />
<i class="icon-[comfy--credits] bg-credit" />
{{ t('actionbar.freeTierPartner') }}
</div>
<div v-else class="flex w-full items-center justify-between">

View File

@@ -123,7 +123,7 @@
</span>
<div class="flex flex-row items-center gap-1">
<i
class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400"
class="icon-[comfy--credits] size-4 shrink-0 bg-credit"
aria-hidden="true"
/>
<span

View File

@@ -2,7 +2,7 @@
<Button
:size
:disabled="disabled"
:variant="buttonVariant === 'gradient' ? 'gradient' : 'primary'"
:variant="buttonVariant === 'subscribe' ? 'subscribe' : 'primary'"
:class="cn('font-bold', fluid && 'w-full')"
@click="handleSubscribe"
>
@@ -28,7 +28,7 @@ const {
} = defineProps<{
label?: string
size?: 'sm' | 'lg'
buttonVariant?: 'default' | 'gradient'
buttonVariant?: 'default' | 'subscribe'
fluid?: boolean
disabled?: boolean
}>()

View File

@@ -5,7 +5,7 @@
showDelay: 600
}"
class="subscribe-to-run-button h-8 gap-1.5 rounded-lg px-4 whitespace-nowrap"
variant="gradient"
variant="subscribe"
size="unset"
data-testid="subscribe-to-run-button"
@click="handleSubscribeToRun"

View File

@@ -59,7 +59,7 @@
<!-- Credits Section -->
<div class="flex items-center gap-2 px-4 py-2">
<i class="icon-[lucide--component] text-sm text-amber-400" />
<i class="icon-[lucide--component] text-sm text-credit" />
<Skeleton
v-if="isLoadingBalance"
width="4rem"
@@ -82,7 +82,7 @@
<!-- Upgrade to add credits (free tier) -->
<Button
v-if="isActiveSubscription && permissions.canTopUp && isFreeTier"
variant="gradient"
variant="subscribe"
size="sm"
data-testid="upgrade-to-add-credits-button"
@click="handleUpgradeToAddCredits"
@@ -110,7 +110,7 @@
: $t('workspaceSwitcher.subscribe')
"
size="sm"
button-variant="gradient"
button-variant="subscribe"
/>
<Button
v-if="

View File

@@ -129,7 +129,7 @@
{{ t('subscription.monthlyCreditsPerMemberLabel') }}
</span>
<div class="flex flex-row items-center gap-1">
<i class="icon-[lucide--component] text-sm text-amber-400" />
<i class="icon-[lucide--component] text-sm text-credit" />
<span
class="font-inter text-sm/normal font-bold text-base-foreground"
>

View File

@@ -38,7 +38,7 @@
{{ $t(creditsRefillLabelKey) }}
</span>
<div class="flex items-center gap-1">
<i class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400" />
<i class="icon-[comfy--credits] size-4 shrink-0 bg-credit" />
<span class="font-bold text-base-foreground">
{{ refillCredits }}
</span>

View File

@@ -28,7 +28,7 @@
</span>
</div>
<div class="flex items-center gap-1 text-sm text-muted-foreground">
<i class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400" />
<i class="icon-[comfy--credits] size-4 shrink-0 bg-credit" />
<span>{{ displayCredits }} {{ $t('subscription.perMonth') }}</span>
</div>
</div>

View File

@@ -66,7 +66,7 @@
<div class="flex items-center justify-between">
<span class="text-base-foreground">{{ refillLabel }}</span>
<div class="flex items-center gap-1">
<i class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400" />
<i class="icon-[comfy--credits] size-4 shrink-0 bg-credit" />
<span class="font-bold text-base-foreground">{{
refillCredits
}}</span>
@@ -89,7 +89,7 @@
{{ $t('subscription.preview.creditsRefillMonthlyTo') }}
</span>
<div class="flex items-center gap-1">
<i class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400" />
<i class="icon-[comfy--credits] size-4 shrink-0 bg-credit" />
<span class="font-bold text-base-foreground">{{
monthlyRefillCredits
}}</span>

View File

@@ -166,7 +166,7 @@
<div class="mt-auto flex flex-col gap-1">
<div class="flex flex-row items-center gap-2">
<i
class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400"
class="icon-[comfy--credits] size-4 shrink-0 bg-credit"
aria-hidden="true"
/>
<span
@@ -244,7 +244,7 @@
<div class="flex flex-col gap-1">
<div class="flex flex-row items-center gap-2">
<i
class="icon-[comfy--credits] size-4 shrink-0 bg-amber-400"
class="icon-[comfy--credits] size-4 shrink-0 bg-credit"
aria-hidden="true"
/>
<span

View File

@@ -7,7 +7,7 @@ defineProps<{ title: string; price: string }>()
<span
class="mt-2 flex h-5 max-w-max items-center rounded-full bg-component-node-widget-background p-2 py-3"
>
<i class="mr-1 icon-[lucide--component] h-4 bg-amber-400" />
<i class="mr-1 icon-[lucide--component] h-4 bg-credit" />
{{ price }}
</span>
</div>

View File

@@ -20,7 +20,7 @@ const { t } = useI18n()
<Popover v-if="mobile && creditsBadges.length" side="top">
<template #button>
<Button class="mr-2 size-10">
<i class="icon-[comfy--credits] bg-amber-400" />
<i class="icon-[comfy--credits] bg-credit" />
</Button>
</template>
<section
@@ -51,7 +51,7 @@ const { t } = useI18n()
<div class="mb-1 w-full border-b border-border-subtle" />
<CollapsibleTrigger as-child>
<Button variant="textonly" class="w-full text-sm">
<i class="icon-[comfy--credits] size-4 bg-amber-400" />
<i class="icon-[comfy--credits] size-4 bg-credit" />
{{ t('linearMode.hasCreditCost') }}
<i v-if="open" class="ml-auto icon-[lucide--chevron-up]" />
<i v-else class="ml-auto icon-[lucide--chevron-down]" />