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
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ function InlineCommentComposerCard({ selectedElement }: InlineCommentComposerCar
<div className="min-w-0">
<div className="inline-flex items-center gap-2 text-[var(--text-xs)] font-medium text-[var(--color-text-primary)]">
<MessageSquareText className="h-4 w-4 text-[var(--color-accent)]" />
{t('inlineComment.title')} <code className="text-[var(--text-xs)]">{selectedElement.tag}</code>
{t('inlineComment.title')}{' '}
<code className="text-[var(--text-xs)]">{selectedElement.tag}</code>
</div>
<p
className="mt-1 truncate text-[var(--text-xs)] text-[var(--color-text-muted)]"
Expand Down
31 changes: 17 additions & 14 deletions apps/desktop/src/renderer/src/onboarding/ChooseModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ export function ChooseModel({
const canFinish = trimmedPrimary.length > 0 && trimmedFast.length > 0 && !saving;

return (
<div className="flex flex-col gap-5">
<div className="flex flex-col gap-2">
<h2 className="text-[20px] font-semibold text-[var(--color-text-primary)] tracking-[-0.01em] leading-[1.2]">
<div className="flex flex-col gap-[var(--space-5)]">
<div className="flex flex-col gap-[var(--space-2)]">
<h2 className="text-[var(--text-lg)] font-semibold text-[var(--color-text-primary)] tracking-[var(--tracking-heading)] leading-[var(--leading-heading)]">
{t('onboarding.choose.title')}
</h2>
<p className="text-[14px] text-[var(--color-text-secondary)] leading-[1.55]">
<p className="text-[var(--text-base)] text-[var(--color-text-secondary)] leading-[var(--leading-body)]">
{t('onboarding.choose.description')}
</p>
</div>
Expand Down Expand Up @@ -80,22 +80,22 @@ export function ChooseModel({
/>

{baseUrl !== null ? (
<p className="text-[12px] text-[var(--color-text-muted)] leading-[1.5]">
<p className="text-[var(--text-xs)] text-[var(--color-text-muted)] leading-[var(--leading-ui)]">
{t('onboarding.choose.customBaseUrl', { url: baseUrl })}
</p>
) : null}

<p className="text-[12px] text-[var(--color-text-muted)] leading-[1.5]">
<p className="text-[var(--text-xs)] text-[var(--color-text-muted)] leading-[var(--leading-ui)]">
{useFreeTierDefaults
? t('onboarding.choose.costNoteFree')
: t('onboarding.choose.costNote')}
</p>

{errorMessage !== null ? (
<p className="text-[13px] text-[var(--color-error)]">{errorMessage}</p>
<p className="text-[var(--text-sm)] text-[var(--color-error)]">{errorMessage}</p>
) : null}

<div className="flex justify-between gap-2 pt-2">
<div className="flex justify-between gap-[var(--space-2)] pt-[var(--space-2)]">
<Tooltip label={saving ? t('disabledReason.savingInProgress') : undefined} side="top">
<Button type="button" variant="ghost" onClick={onBack} disabled={saving}>
{t('onboarding.choose.back')}
Expand Down Expand Up @@ -138,10 +138,10 @@ function ModelPicker({ label, hint, value, options, onChange }: ModelPickerProps
const datalistId = useId();

return (
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-[var(--space-2)]">
<label
htmlFor={inputId}
className="text-[10px] uppercase tracking-[0.08em] text-[var(--color-text-muted)] font-medium"
className="text-[var(--text-2xs)] uppercase tracking-[var(--tracking-label)] text-[var(--color-text-muted)] font-medium"
style={{ fontFamily: 'var(--font-mono)' }}
>
{label}
Expand All @@ -156,15 +156,15 @@ function ModelPicker({ label, hint, value, options, onChange }: ModelPickerProps
placeholder={options[0]}
spellCheck={false}
style={{ fontFamily: 'var(--font-mono)' }}
className="w-full h-[40px] px-3 rounded-[var(--radius-md)] bg-[var(--color-surface)] border border-[var(--color-border)] text-[13px] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-muted)] focus:outline-none focus:border-[var(--color-accent)] focus:shadow-[0_0_0_3px_var(--color-focus-ring)] transition-[box-shadow,border-color] duration-150 ease-[cubic-bezier(0.16,1,0.3,1)]"
className="w-full h-[var(--size-control-md)] px-[var(--space-3)] rounded-[var(--radius-md)] bg-[var(--color-surface)] border border-[var(--color-border)] text-[var(--text-sm)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-muted)] focus:outline-none focus:border-[var(--color-accent)] focus:shadow-[0_0_0_3px_var(--color-focus-ring)] transition-[box-shadow,border-color] duration-[var(--duration-fast)] ease-[var(--ease-out)]"
/>
<datalist id={datalistId}>
{options.map((opt) => (
<option key={opt} value={opt} />
))}
</datalist>

<div className="flex flex-wrap gap-2">
<div className="flex flex-wrap gap-[var(--space-2)]">
{options.map((opt) => {
const selected = value.trim() === opt;

Expand All @@ -173,7 +173,8 @@ function ModelPicker({ label, hint, value, options, onChange }: ModelPickerProps
key={opt}
type="button"
onClick={() => onChange(opt)}
className={`px-2.5 h-[28px] rounded-full border text-[11px] transition-colors ${
aria-pressed={selected}
className={`px-[var(--space-2_5)] h-[var(--size-control-sm)] rounded-full border text-[var(--text-xs)] transition-colors ${
selected
? 'border-[var(--color-accent)] bg-[var(--color-accent-soft)] text-[var(--color-accent)]'
: 'border-[var(--color-border)] text-[var(--color-text-secondary)] hover:border-[var(--color-border-strong)] hover:text-[var(--color-text-primary)]'
Expand All @@ -186,7 +187,9 @@ function ModelPicker({ label, hint, value, options, onChange }: ModelPickerProps
})}
</div>

<span className="text-[12px] text-[var(--color-text-muted)] leading-[1.4]">{hint}</span>
<span className="text-[var(--text-xs)] text-[var(--color-text-muted)] leading-[var(--leading-ui)]">
{hint}
</span>
</div>
);
}
Expand Down
28 changes: 14 additions & 14 deletions apps/desktop/src/renderer/src/onboarding/Welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ export function Welcome({ onPickKey, onPickFreeTier, ollamaDetected }: WelcomePr
const t = useT();

return (
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-2">
<h1 className="text-[24px] font-semibold text-[var(--color-text-primary)] tracking-[-0.01em] leading-[1.2]">
<div className="flex flex-col gap-[var(--space-6)]">
<div className="flex flex-col gap-[var(--space-2)]">
<h1 className="text-[var(--text-xl)] font-semibold text-[var(--color-text-primary)] tracking-[var(--tracking-heading)] leading-[var(--leading-heading)]">
{t('onboarding.welcome.title')}
</h1>
<p className="text-[14px] text-[var(--color-text-secondary)] leading-[1.55]">
<p className="text-[var(--text-base)] text-[var(--color-text-secondary)] leading-[var(--leading-body)]">
{t('onboarding.welcome.subtitle')}
</p>
</div>

<div className="flex flex-col gap-3">
<div className="flex flex-col gap-[var(--space-3)]">
<PathButton
icon={<Rocket className="w-[18px] h-[18px]" />}
title={t('onboarding.welcome.tryFree')}
Expand All @@ -48,14 +48,14 @@ export function Welcome({ onPickKey, onPickFreeTier, ollamaDetected }: WelcomePr
) : null}
</div>

<div className="pt-4 border-t border-[var(--color-border-subtle)] flex flex-col gap-2">
<div className="pt-[var(--space-4)] border-t border-[var(--color-border-subtle)] flex flex-col gap-[var(--space-2)]">
<span
className="text-[10px] uppercase tracking-[0.08em] text-[var(--color-text-muted)] font-medium"
className="text-[var(--text-2xs)] uppercase tracking-[var(--tracking-label)] text-[var(--color-text-muted)] font-medium"
style={{ fontFamily: 'var(--font-mono)' }}
>
{t('onboarding.welcome.whereToGetKey')}
</span>
<div className="flex flex-wrap gap-x-4 gap-y-1">
<div className="flex flex-wrap gap-x-[var(--space-4)] gap-y-[var(--space-1)]">
{(
Object.values(PROVIDER_SHORTLIST) as Array<
(typeof PROVIDER_SHORTLIST)[SupportedOnboardingProvider]
Expand All @@ -66,7 +66,7 @@ export function Welcome({ onPickKey, onPickFreeTier, ollamaDetected }: WelcomePr
href={p.keyHelpUrl}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-[12px] text-[var(--color-text-secondary)] hover:text-[var(--color-accent)] transition-colors duration-150"
className="inline-flex items-center gap-[var(--space-1)] text-[var(--text-xs)] text-[var(--color-text-secondary)] hover:text-[var(--color-accent)] transition-colors duration-[var(--duration-fast)]"
>
{p.label}
<ExternalLink className="w-[11px] h-[11px]" />
Expand All @@ -92,20 +92,20 @@ function PathButton({ icon, title, subtitle, onClick, disabled }: PathButtonProp
type="button"
onClick={onClick}
disabled={disabled}
className="group relative flex items-start gap-4 w-full text-left p-4 rounded-[var(--radius-lg)] bg-[var(--color-surface)] border border-[var(--color-border)] shadow-[var(--shadow-soft)] transition-[transform,box-shadow,border-color,background-color] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] hover:-translate-y-[1px] hover:border-[var(--color-border-strong)] hover:shadow-[var(--shadow-card)] disabled:opacity-50 disabled:pointer-events-none"
className="group relative flex items-start gap-[var(--space-4)] w-full text-left p-[var(--space-4)] rounded-[var(--radius-lg)] bg-[var(--color-surface)] border border-[var(--color-border)] shadow-[var(--shadow-soft)] motion-safe:transition-[transform,box-shadow,border-color,background-color] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] motion-safe:hover:-translate-y-[1px] hover:border-[var(--color-border-strong)] hover:shadow-[var(--shadow-card)] active:translate-y-0 active:shadow-[var(--shadow-soft)] disabled:opacity-50 disabled:pointer-events-none"
>
<span className="shrink-0 mt-[2px] inline-flex items-center justify-center w-[34px] h-[34px] rounded-[var(--radius-md)] bg-[var(--color-accent-soft)] text-[var(--color-accent)]">
{icon}
</span>
<span className="flex flex-col gap-[2px] flex-1 min-w-0">
<span className="text-[14px] font-semibold text-[var(--color-text-primary)] tracking-[-0.005em]">
<span className="flex flex-col gap-[var(--space-0_5)] flex-1 min-w-0">
<span className="text-[var(--text-base)] font-semibold text-[var(--color-text-primary)] tracking-[-0.005em]">
{title}
</span>
<span className="text-[12px] text-[var(--color-text-secondary)] leading-[1.5]">
<span className="text-[var(--text-xs)] text-[var(--color-text-secondary)] leading-[var(--leading-ui)]">
{subtitle}
</span>
</span>
<ArrowRight className="w-[14px] h-[14px] mt-[10px] shrink-0 text-[var(--color-text-muted)] opacity-0 -translate-x-[4px] transition-[opacity,transform] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:opacity-100 group-hover:translate-x-0 group-hover:text-[var(--color-accent)]" />
<ArrowRight className="w-[14px] h-[14px] mt-[10px] shrink-0 text-[var(--color-text-muted)] opacity-0 -translate-x-[4px] motion-safe:transition-[opacity,transform] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:opacity-100 group-hover:translate-x-0 group-hover:text-[var(--color-accent)]" />
</button>
);
}
8 changes: 5 additions & 3 deletions apps/desktop/src/renderer/src/onboarding/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ export function Onboarding() {

function Stepper({ current, total }: { current: number; total: number }) {
return (
<div className="flex items-center gap-2">
<div className="flex items-center gap-[var(--space-2)]">
<span className="sr-only">{`Step ${current} of ${total}`}</span>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded English text in an accessibility label bypasses the language toggle. Please localize this string through useT() so screen readers follow the selected locale.

const t = useT();

<span className="sr-only">
  {t('onboarding.stepper.progress', { current, total })}
</span>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded English text in an accessibility label bypasses the language toggle. Please localize this via so screen readers follow the selected locale.

<span
className="text-[11px] text-[var(--color-text-muted)] tracking-[0.05em]"
className="text-[var(--text-2xs)] text-[var(--color-text-muted)] tracking-[var(--tracking-label)]"
style={{ fontFamily: 'var(--font-mono)' }}
aria-hidden="true"
>
{current.toString().padStart(2, '0')} / {total.toString().padStart(2, '0')}
</span>
Expand All @@ -119,7 +121,7 @@ function Stepper({ current, total }: { current: number; total: number }) {
<span
// biome-ignore lint/suspicious/noArrayIndexKey: stepper dots are positional
key={i}
className={`h-[3px] rounded-full transition-[width,background-color] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] ${
className={`h-[3px] rounded-full motion-safe:transition-[width,background-color] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] ${
i < current
? 'w-[14px] bg-[var(--color-accent)]'
: 'w-[6px] bg-[var(--color-border-strong)]'
Expand Down
Loading