Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/unreleased/console-kill-ai-slop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### English

- Tighten the console's visual noise: small text now uses one 12 px caption size, oversized card radii and the toast's heavy shadow are reduced, and account errors, update status, and the key "all providers" tag use neutral surfaces instead of tinted red, green, or yellow boxes.

### 中文

- 收敛控制台视觉噪音:小字统一为 12 px 一档,卡片过大圆角与通知的重阴影减小,账号错误、更新状态和密钥“全部供应商”标签改用中性底色,不再使用红/绿/黄整块着色。
2 changes: 1 addition & 1 deletion docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ HeroUI 3.2.4 的 `Tabs.Indicator` 会因 `SharedElementTransition` 崩溃,不
| 页内说明 | `mt-1 max-w-2xl text-sm leading-6 text-muted` |
| 区块标题 | `font-semibold tracking-[-0.015em]` |
| 正文 | `text-sm leading-6` |
| 元信息 / 标签 | `text-xs` 或 `text-[11px] text-muted` |
| 元信息 / 标签 | `text-caption text-muted`(12 px;`text-xs` 为同值别名,不再单独使用 11 px) |
| 侧栏分组 | `text-[10px] font-semibold tracking-[0.12em] uppercase text-muted` |
| 等宽 | `.mono`,`font-variant-numeric: tabular-nums` |

Expand Down
28 changes: 14 additions & 14 deletions frontend/src/components/AddAccountModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
<Modal.Header className="relative items-center justify-center px-12 pt-5 text-center">
<div className="min-w-0">
<Modal.Heading className="text-section font-semibold">{t('addAccountTitle')}</Modal.Heading>
<p ref={stepDesc} className="mt-1 text-xs font-normal leading-5 text-muted">
<p ref={stepDesc} className="mt-1 text-caption font-normal leading-5 text-muted">
{step === 'method' ? t('addAccountDesc') : (hint || t('addAccountDesc'))}
</p>
</div>
Expand All @@ -549,7 +549,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
{typesLoading ? (
<AccountTypeSkeleton ariaLabel={t('accountType')} />
) : !typesReady ? (
<p className="rounded-lg bg-surface-secondary/45 px-3.5 py-3 text-xs leading-5 text-muted">{t('accountTypeHint')}</p>
<p className="rounded-lg bg-surface-secondary/45 px-3.5 py-3 text-caption leading-5 text-muted">{t('accountTypeHint')}</p>
) : (
<OptionTiles
ariaLabel={t('accountType')}
Expand Down Expand Up @@ -588,7 +588,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
type="button"
onClick={() => setAdvancedOpen((open) => !open)}
aria-expanded={advancedOpen}
className="inline-flex items-center gap-1 text-xs font-medium text-muted transition-colors hover:text-foreground"
className="inline-flex items-center gap-1 text-caption font-medium text-muted transition-colors hover:text-foreground"
>
<CaretRight size={12} className={`transition-transform duration-200 ${advancedOpen ? 'rotate-90' : ''}`} />
{t('wizardAdvanced')}
Expand Down Expand Up @@ -640,7 +640,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
<div className="flex items-center justify-between gap-3">
<div className="min-w-0">
<div className="text-body font-medium text-muted">{t('dropSystemPrompt')}</div>
<p className="mt-0.5 text-xs leading-5 text-muted">{t('dropSystemPromptCreateHint')}</p>
<p className="mt-0.5 text-caption leading-5 text-muted">{t('dropSystemPromptCreateHint')}</p>
</div>
<CompactSwitch
isSelected={dropSystemPrompt}
Expand Down Expand Up @@ -683,7 +683,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
</>
) : null}
{message ? (
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-xs">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-caption">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
) : null}
<Button className="w-full" isPending={phase === 'busy'} onPress={() => void runZhipu()} isDisabled={isDone}>
{isDone ? <><CheckCircle size={15} />{t('wizardAccountReady')}</> : <><Key size={15} />{t('zhipuCreate')}</>}
Expand Down Expand Up @@ -712,7 +712,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
}))}
/>

<p className="mt-2 min-h-5 text-xs leading-5 text-muted">{tabLead}</p>
<p className="mt-2 min-h-5 text-caption leading-5 text-muted">{tabLead}</p>

<div className="mt-3 flex flex-col gap-4">
{tab === 'browser' ? (
Expand All @@ -731,11 +731,11 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
) : null}
{authUrl ? (
<div className="rounded-lg bg-surface-secondary px-3 py-2.5">
<div className="flex items-center gap-2 text-xs">
<div className="flex items-center gap-2 text-caption">
<StatusIcon phase={phase} busy={busy} tab={tab} forTab="browser" />
<span className="text-muted">{message || t('loginOpenMsg')}</span>
</div>
<code className="mono mt-2 block break-all text-xs leading-5 text-foreground">{authUrl}</code>
<code className="mono mt-2 block break-all text-caption leading-5 text-foreground">{authUrl}</code>
<div className="mt-2 flex flex-wrap gap-2">
<Button size="sm" variant="secondary" onPress={() => window.open(authUrl, '_blank', 'noopener,noreferrer')}>
<ArrowSquareOut size={14} />{t('openAuthUrl')}
Expand All @@ -758,13 +758,13 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
</div>
) : null}
{message && !authUrl ? (
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-xs">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-caption">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
) : null}
{showCallbackPaste ? (
<div className="space-y-2">
<p className="text-caption leading-4 text-muted">{t('wizardCallbackLead')}</p>
<TextArea
className="h-28 w-full resize-none font-mono text-xs leading-5"
className="h-28 w-full resize-none font-mono text-caption leading-5"
value={callbackUrl}
onChange={(event) => setCallbackUrl(event.target.value)}
placeholder={t('wizardCallbackPh')}
Expand All @@ -786,7 +786,7 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
<Input type="password" value={pat} onChange={(event) => setPat(event.target.value)} placeholder={t('wizardPatPh')} aria-label={t('wizardPatPh')} disabled={busy} />
</FormRow>
{message ? (
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-xs">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-caption">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
) : null}
<Button className="w-full" isPending={tabPending('pat')} onPress={() => void runPat()}>
{isDone ? <><CheckCircle size={15} />{t('patDone')}</> : <><Key size={15} />{t('wizardCreateAndLogin')}</>}
Expand All @@ -795,13 +795,13 @@ export function AddAccountModal({ isOpen, onClose, onAdded }: Props) {
) : (
<>
<div className="flex items-center justify-between gap-3">
<span className="text-xs font-medium text-muted">JSON</span>
<span className="text-caption font-medium text-muted">JSON</span>
<Button size="sm" variant="secondary" onPress={onPickFile} isDisabled={busy}><FileCode size={13} />{t('wizardChooseFile')}</Button>
<input ref={fileInput} type="file" accept="application/json,.json" className="hidden" onChange={onFileChange} />
</div>
<TextArea className="min-h-32 font-mono text-xs" value={json} onChange={(event) => setJson(event.target.value)} placeholder={t('wizardImportPh')} aria-label={t('tabImport')} disabled={busy} />
<TextArea className="min-h-32 font-mono text-caption" value={json} onChange={(event) => setJson(event.target.value)} placeholder={t('wizardImportPh')} aria-label={t('tabImport')} disabled={busy} />
{message ? (
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-xs">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
<p className="flex items-center gap-2 rounded-lg bg-surface-secondary px-3 py-2 text-caption">{isDone ? <CheckCircle size={14} className="shrink-0 text-success" /> : null}<span className={isDone ? 'font-medium text-foreground' : 'text-muted'}>{message}</span></p>
) : null}
<Button className="w-full" isPending={tabPending('import')} onPress={() => void runImport()}>
{isDone ? <><CheckCircle size={15} />{t('accountImported')}</> : <><FileCode size={15} />{t('importCredential')}</>}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/EndpointList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function EndpointList({ access }: EndpointListProps) {
<h3 className="font-semibold">{t('endpoints')}</h3>
<Chip size="sm" variant="soft">{t('endpointCount', { count: endpoints.length - 1 })}</Chip>
</div>
<p className="mt-1 text-xs leading-5 text-muted">{t('routesHint')}</p>
<p className="mt-1 text-caption leading-5 text-muted">{t('routesHint')}</p>
</div>
</div>
<div className="grid gap-2.5 p-3 sm:grid-cols-2 sm:p-4 lg:grid-cols-3">
Expand All @@ -48,7 +48,7 @@ export function EndpointList({ access }: EndpointListProps) {
</div>
<Chip size="sm" variant="soft">{item.method}</Chip>
</div>
<p className="mt-2 min-h-0 text-xs leading-5 text-muted">{item.hint}</p>
<p className="mt-2 min-h-0 text-caption leading-5 text-muted">{item.hint}</p>
<div className="mt-2 flex items-center justify-between gap-2 pt-2">
<span className="text-caption font-medium text-muted">{item.method === 'BASE' ? t('endpointBaseLabel') : t('endpointAuthLabel')}</span>
<div className="flex gap-1">
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/ModelDetailsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function ModelDetailsModal({ model, t, onClose }: Props) {
</Modal.Header>
<Modal.Body className="space-y-4 px-5 pb-5">
<section>
<div className="text-xs font-medium text-muted">{t('contextWindowCol')}</div>
<div className="text-caption font-medium text-muted">{t('contextWindowCol')}</div>
<div className="mt-1 text-body">{formatTokens(windowDev)}{windowMax && windowMax !== windowDev ? ` → ${formatTokens(windowMax)}` : ''}</div>
{model.supports_max_mode ? <p className="mt-1 text-caption leading-5 text-muted">{provider === 'qoder' ? t('qoderMaxModeHint') : t('maxModeHint')}</p> : null}
{!model.supports_max_mode && windowMax && windowMax !== windowDev ? <p className="mt-1 text-caption leading-5 text-muted">{t('workbuddyContextHint')}</p> : null}
Expand All @@ -66,7 +66,7 @@ export function ModelDetailsModal({ model, t, onClose }: Props) {
: (model.max_output_tokens ? <div className="text-caption text-muted">{t('maxOutputTokens')}: {formatTokens(model.max_output_tokens)}</div> : null)}
</section>
<section>
<div className="text-xs font-medium text-muted">{t('reasoningLevels')}</div>
<div className="text-caption font-medium text-muted">{t('reasoningLevels')}</div>
{options.length ? (
<>
<p className="mt-1 text-caption leading-5 text-muted">{t('reasoningHint')}</p>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/VersionHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function VersionHistory({
return (
<div className="mt-5">
<div className="mb-2">
<p className="text-xs font-medium text-foreground">{t('versionHistory')}</p>
<p className="text-caption font-medium text-foreground">{t('versionHistory')}</p>
</div>
<Accordion className="rounded-lg bg-surface-secondary" hideSeparator defaultExpandedKeys={defaultExpanded ? [defaultExpanded] : []}>
{releases.map((release) => {
Expand All @@ -58,7 +58,7 @@ export function VersionHistory({
<span className="mono text-body font-semibold">{tag}</span>
{isCurrent ? <Chip size="sm" variant="soft" color="success">{t('versionCurrentBadge')}</Chip> : null}
{isLatest ? <Chip size="sm" variant="soft" color="warning">{t('versionLatestBadge')}</Chip> : null}
{published ? <span className="truncate text-xs text-muted">{published}</span> : null}
{published ? <span className="truncate text-caption text-muted">{published}</span> : null}
</span>
<Accordion.Indicator />
</Accordion.Trigger>
Expand Down
18 changes: 9 additions & 9 deletions frontend/src/components/account/AccountCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export function AccountCard({
<div className="space-y-1.5">
<div className="font-medium">{t('partialCooling')}</div>
{modelCooldowns.map(([model, until]) => (
<div key={model} className="flex items-center justify-between gap-4 text-xs">
<div key={model} className="flex items-center justify-between gap-4 text-caption">
<span>{model}</span>
<span className="mono text-foreground/65">{cooldownLabel(until)}</span>
</div>
Expand All @@ -233,7 +233,7 @@ export function AccountCard({
<div className="space-y-1.5">
<div className="font-medium">{t('partialCooling')}</div>
{modelCooldowns.map(([model, until]) => (
<div key={model} className="flex items-center justify-between gap-4 text-xs">
<div key={model} className="flex items-center justify-between gap-4 text-caption">
<span>{model}</span>
<span className="mono text-foreground/65">{cooldownLabel(until)}</span>
</div>
Expand Down Expand Up @@ -265,8 +265,8 @@ export function AccountCard({
{lastError ? (
<Tooltip>
<Tooltip.Trigger>
<div className="flex w-full cursor-help gap-2 rounded-2xl border border-danger/25 bg-danger/5 p-2 text-left text-xs leading-5 text-danger">
<WarningCircle size={14} className="mt-0.5 shrink-0" />
<div className="flex w-full cursor-help gap-2 rounded-lg bg-surface-secondary p-2 text-left text-caption leading-5 text-foreground">
<WarningCircle size={14} className="mt-0.5 shrink-0 text-danger" />
<div className="min-w-0 flex-1">
{errorKind ? <div className="mono mb-0.5 truncate text-caption opacity-75">{errorKind}</div> : null}
<p className="break-words line-clamp-3">{lastError}</p>
Expand All @@ -286,8 +286,8 @@ export function AccountCard({
{authPanelOpen && account.enabled ? (
<section ref={authRef} className="grid gap-3 bg-surface-secondary/55 px-3 py-3">
<div>
<div className="text-xs font-medium text-muted">{t('oauthDeviceFlow')}</div>
<p className="mt-1.5 text-xs leading-5 text-muted">{account.provider === 'codex' ? t('wizardCodexBrowserLead') : t('qoderLoginHint')}</p>
<div className="text-caption font-medium text-muted">{t('oauthDeviceFlow')}</div>
<p className="mt-1.5 text-caption leading-5 text-muted">{account.provider === 'codex' ? t('wizardCodexBrowserLead') : t('qoderLoginHint')}</p>
<div className="mt-2.5 flex flex-wrap gap-2">
{account.provider === 'codex' ? (
<>
Expand All @@ -302,7 +302,7 @@ export function AccountCard({
<div className="mt-3 space-y-2">
<p className="text-caption leading-4 text-muted">{t('wizardCallbackLead')}</p>
<TextArea
className="h-24 w-full resize-none font-mono text-xs leading-5"
className="h-24 w-full resize-none font-mono text-caption leading-5"
value={callbackUrl || ''}
onChange={(event) => onCallbackChange(event.target.value)}
placeholder={t('wizardCallbackPh')}
Expand All @@ -315,7 +315,7 @@ export function AccountCard({
) : null}
</div>
<div>
<div className="text-xs font-medium text-muted">{t('patFallback')}</div>
<div className="text-caption font-medium text-muted">{t('patFallback')}</div>
<div className="mt-2.5 flex flex-col gap-2 sm:flex-row">
<TextField className="flex-1" type="password" value={pat} onChange={onPatChange}>
<Label className="sr-only">{t('pat')}</Label>
Expand All @@ -325,7 +325,7 @@ export function AccountCard({
</div>
</div>
{authUrl || note ? (
<div className="text-xs">
<div className="text-caption">
{authUrl ? (
<div>
<div className="mb-1 text-caption font-medium text-muted">{t('authUrl')}</div>
Expand Down
Loading
Loading