refactor(frontend): unify Tailwind classes — replace hardcoded colors with semantic design tokens

- Replace all bg-blue-600/hover:bg-blue-700 → bg-primary/hover:bg-primary-hover
- Replace all bg-red-600/hover:bg-red-700 → bg-destructive/hover:bg-destructive-hover
- Replace all focus:ring-blue-500 → focus-visible:ring-primary-ring
- Replace all text-blue-600 → text-primary on interactive elements
- Replace all bg-blue-50 → bg-primary-light on UI surfaces
- Replace all bg-red-50 → bg-destructive-light on error surfaces
- Replace all border-blue-200/300 → border-primary-ring
- Replace all border-red-200 → border-destructive-light
- Replace peer-checked:bg-blue-600 → peer-checked:bg-primary (toggles)
- Replace focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 patterns
- Keep status badge patterns (bg-*-100 text-*-700) and hover:bg-blue-50 intact

82 files changed, ~400 changes. Build passes.
This commit is contained in:
2026-05-19 10:46:00 +03:00
parent afe6c7e281
commit 8039d09505
79 changed files with 331 additions and 331 deletions

View File

@@ -141,7 +141,7 @@
size="sm"
onclick={() => showCreate = !showCreate}
disabled={loading}
class="text-blue-600"
class="text-primary"
>
+ {$t.git.new_branch}
</Button>

View File

@@ -69,7 +69,7 @@
<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider">
{$t.git.history}
</h3>
<Button variant="ghost" size="sm" onclick={loadHistory} class="text-blue-600">
<Button variant="ghost" size="sm" onclick={loadHistory} class="text-primary">
{$t.git.refresh}
</Button>
</div>

View File

@@ -158,7 +158,7 @@
<button
onclick={handleGenerateMessage}
disabled={generatingMessage || loading}
class="text-xs text-blue-600 hover:text-blue-800 disabled:opacity-50 flex items-center"
class="text-xs text-primary hover:text-blue-800 disabled:opacity-50 flex items-center"
>
{#if generatingMessage}
<span class="animate-spin mr-1"></span> {$t.mapper?.generating}
@@ -169,7 +169,7 @@
</div>
<textarea
bind:value={message}
class="w-full border rounded p-2 h-32 focus:ring-2 focus:ring-blue-500 outline-none resize-none"
class="w-full border rounded p-2 h-32 focus-visible:ring-2 focus-visible:ring-primary-ring outline-none resize-none"
placeholder={$t.git?.describe_changes}
></textarea>
</div>
@@ -202,7 +202,7 @@
{/each}
{#each status.untracked_files as file}
<li
class="text-blue-600 flex items-center"
class="text-primary flex items-center"
title={$t.git?.untracked}
>
<span class="mr-2">?</span>
@@ -258,7 +258,7 @@
loading ||
(!status?.is_dirty &&
status?.staged_files?.length === 0)}
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50"
class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover disabled:opacity-50"
>
{committing ? $t.git?.committing : $t.git?.commit}
</button>

View File

@@ -112,7 +112,7 @@
>
<div class="p-0 flex flex-col">
<div
class="bg-blue-50 px-4 py-1 text-[10px] font-bold text-blue-600 uppercase border-b"
class="bg-primary-light px-4 py-1 text-[10px] font-bold text-primary uppercase border-b"
>
Your Changes (Mine)
</div>
@@ -124,8 +124,8 @@
class="w-full py-2 text-sm font-medium border-t transition-colors {resolutions[
conflict.file_path
] === 'mine'
? 'bg-blue-600 text-white'
: 'bg-gray-50 hover:bg-blue-50 text-blue-600'}"
? 'bg-primary text-white'
: 'bg-gray-50 hover:bg-blue-50 text-primary'}"
onclick={() =>
resolve(conflict.file_path, "mine")}
>
@@ -168,7 +168,7 @@
</button>
<button
onclick={handleSave}
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors shadow-sm"
class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover transition-colors shadow-sm"
>
Resolve & Continue
</button>

View File

@@ -177,7 +177,7 @@
<select
id="deployment-target-env"
bind:value={selectedEnv}
class="w-full border rounded p-2 focus:ring-2 focus:ring-blue-500 outline-none bg-white"
class="w-full border rounded p-2 focus-visible:ring-2 focus-visible:ring-primary-ring outline-none bg-white"
>
{#each deploymentCandidates as env}
<option value={env.id}
@@ -187,7 +187,7 @@
</select>
</div>
{#if isProdTarget}
<p class="mb-3 rounded border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-800">
<p class="mb-3 rounded border border-destructive-light bg-destructive-light px-3 py-2 text-xs text-red-800">
Внимание: выбрано PROD окружение. Потребуется подтверждение перед deploy.
</p>
{/if}
@@ -202,7 +202,7 @@
<button
onclick={handleDeploy}
disabled={deploying || !selectedEnv}
class={`px-4 py-2 text-white rounded disabled:opacity-50 flex items-center ${isProdTarget ? 'bg-red-600 hover:bg-red-700' : 'bg-green-600 hover:bg-green-700'}`}
class={`px-4 py-2 text-white rounded disabled:opacity-50 flex items-center ${isProdTarget ? 'bg-destructive hover:bg-destructive-hover' : 'bg-green-600 hover:bg-green-700'}`}
>
{#if deploying}
<svg

View File

@@ -110,7 +110,7 @@
onclick={onAbortMerge}
disabled={mergeAbortInProgress}
isLoading={mergeAbortInProgress}
class="border border-red-300 text-red-700 hover:bg-red-50"
class="border border-destructive-ring text-red-700 hover:bg-red-50"
>
{$t.git?.unfinished_merge?.abort_merge || 'Abort merge'}
</Button>

View File

@@ -38,7 +38,7 @@
<Button
variant="primary"
onclick={onDeploy}
class={`w-full ${currentEnvStage === 'PROD' ? 'bg-red-600 hover:bg-red-700 focus-visible:ring-red-500' : 'bg-green-600 hover:bg-green-700 focus-visible:ring-green-500'}`}
class={`w-full ${currentEnvStage === 'PROD' ? 'bg-destructive hover:bg-destructive-hover focus-visible:ring-red-500' : 'bg-green-600 hover:bg-green-700 focus-visible:ring-green-500'}`}
>
🚀 Deploy
</Button>

View File

@@ -44,7 +44,7 @@
onclick={onPromote}
disabled={promoting || !promoteFromBranch || !promoteToBranch || promoteFromBranch === promoteToBranch}
isLoading={promoting}
class={`w-full ${promoteMode === 'direct' ? 'bg-red-600 hover:bg-red-700 focus-visible:ring-red-500' : ''}`}
class={`w-full ${promoteMode === 'direct' ? 'bg-destructive hover:bg-destructive-hover focus-visible:ring-red-500' : ''}`}
>
{promoteMode === 'direct'
? `Прямой перенос ${promoteFromBranch} ${promoteToBranch} (unsafe)`
@@ -81,7 +81,7 @@
]}
/>
{#if promoteMode === 'direct'}
<div class="rounded-lg border border-red-300 bg-red-50 p-3 text-sm text-red-800">
<div class="rounded-lg border border-destructive-ring bg-destructive-light p-3 text-sm text-red-800">
<div class="font-semibold">Внимание: прямой перенос без MR</div>
<div class="mt-1">Это обходит процесс аппрува и записывается в audit лог.</div>
</div>

View File

@@ -42,7 +42,7 @@
<div class="mb-2 flex items-center justify-between">
<h3 class="text-sm font-semibold text-slate-700">Сообщение коммита</h3>
<button
class="inline-flex items-center text-xs text-blue-600 hover:text-blue-800 disabled:opacity-50"
class="inline-flex items-center text-xs text-primary hover:text-blue-800 disabled:opacity-50"
onclick={onGenerateMessage}
disabled={generatingMessage || workspaceLoading}
>
@@ -51,7 +51,7 @@
</div>
<textarea
bind:value={commitMessage}
class={`h-36 w-full resize-none rounded border p-2 outline-none focus:ring-2 focus:ring-blue-500 ${generatingMessage ? 'animate-pulse bg-slate-100' : ''}`}
class={`h-36 w-full resize-none rounded border p-2 outline-none focus-visible:ring-2 focus-visible:ring-primary-ring ${generatingMessage ? 'animate-pulse bg-slate-100' : ''}`}
placeholder="Опишите изменения..."
></textarea>
</div>