From def987d8e93e6a2769465ffb67e5ff3acd736f41 Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Mon, 29 Dec 2025 01:12:59 +1030 Subject: [PATCH] feat: enhance accent color support across the application - Introduced new accent colors (green, orange, teal, purple, rose) in the accent store. - Updated CSS variables for accent colors in app.css. - Refactored components to utilize accent colors for buttons, inputs, dropdowns, and tags. - Improved accessibility and visual consistency by replacing hardcoded colors with accent variables. - Adjusted styles in various components including modals, tables, and forms to reflect the new accent color scheme. --- src/app.css | 28 ++++++++++ src/lib/client/stores/accent.ts | 55 ++++++++++++++++++- src/lib/client/ui/button/Button.svelte | 35 ++++++++++++ .../ui/dropdown/CustomGroupManager.svelte | 6 +- .../client/ui/dropdown/DropdownItem.svelte | 2 +- src/lib/client/ui/form/FormInput.svelte | 4 +- src/lib/client/ui/form/NumberInput.svelte | 2 +- src/lib/client/ui/form/TagInput.svelte | 4 +- src/lib/client/ui/modal/Modal.svelte | 2 +- .../client/ui/modal/SaveTargetModal.svelte | 4 +- src/lib/client/ui/navigation/tabs/Tabs.svelte | 2 +- src/lib/client/ui/state/EmptyState.svelte | 2 +- .../client/ui/table/ExpandableTable.svelte | 4 +- src/routes/+layout.svelte | 2 +- .../components/DelayProfileForm.svelte | 12 ++-- .../[databaseId]/views/CardView.svelte | 2 +- .../[databaseId]/views/TableView.svelte | 2 +- .../[databaseId]/[id]/languages/+page.svelte | 4 +- .../[databaseId]/[id]/qualities/+page.svelte | 8 +-- .../[databaseId]/[id]/scoring/+page.svelte | 4 +- .../[databaseId]/views/CardView.svelte | 4 +- .../[databaseId]/views/TableView.svelte | 4 +- src/routes/settings/about/+page.svelte | 6 +- .../settings/about/components/InfoRow.svelte | 2 +- 24 files changed, 157 insertions(+), 43 deletions(-) create mode 100644 src/lib/client/ui/button/Button.svelte diff --git a/src/app.css b/src/app.css index b24e55d..8eb4676 100644 --- a/src/app.css +++ b/src/app.css @@ -7,6 +7,19 @@ @theme { --font-sans: 'DM Sans', ui-sans-serif, system-ui, sans-serif; --font-mono: 'Geist Mono', ui-monospace, monospace; + + /* Accent colors using CSS variables set by accent store */ + --color-accent-50: var(--accent-50); + --color-accent-100: var(--accent-100); + --color-accent-200: var(--accent-200); + --color-accent-300: var(--accent-300); + --color-accent-400: var(--accent-400); + --color-accent-500: var(--accent-500); + --color-accent-600: var(--accent-600); + --color-accent-700: var(--accent-700); + --color-accent-800: var(--accent-800); + --color-accent-900: var(--accent-900); + --color-accent-950: var(--accent-950); } @layer base { @@ -14,6 +27,21 @@ font-family: 'DM Sans', ui-sans-serif, system-ui, sans-serif; } + /* Default accent colors (blue) - overridden by JS */ + :root { + --accent-50: #eff6ff; + --accent-100: #dbeafe; + --accent-200: #bfdbfe; + --accent-300: #93c5fd; + --accent-400: #60a5fa; + --accent-500: #3b82f6; + --accent-600: #2563eb; + --accent-700: #1d4ed8; + --accent-800: #1e40af; + --accent-900: #1e3a8a; + --accent-950: #172554; + } + html { @apply bg-neutral-50 dark:bg-neutral-900; } diff --git a/src/lib/client/stores/accent.ts b/src/lib/client/stores/accent.ts index e48574f..d77fcf4 100644 --- a/src/lib/client/stores/accent.ts +++ b/src/lib/client/stores/accent.ts @@ -5,13 +5,62 @@ import { writable } from 'svelte/store'; import { browser } from '$app/environment'; -export type AccentColor = 'blue' | 'yellow'; +export type AccentColor = 'blue' | 'yellow' | 'green' | 'orange' | 'teal' | 'purple' | 'rose'; + +// Color palettes for each accent (matching Tailwind shades) +const colorPalettes: Record = { + blue: { + 50: '#eff6ff', 100: '#dbeafe', 200: '#bfdbfe', 300: '#93c5fd', 400: '#60a5fa', + 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8', 800: '#1e40af', 900: '#1e3a8a', 950: '#172554' + }, + yellow: { + 50: '#fefce8', 100: '#fef9c3', 200: '#fef08a', 300: '#fde047', 400: '#facc15', + 500: '#eab308', 600: '#ca8a04', 700: '#a16207', 800: '#854d0e', 900: '#713f12', 950: '#422006' + }, + green: { + 50: '#f0fdf4', 100: '#dcfce7', 200: '#bbf7d0', 300: '#86efac', 400: '#4ade80', + 500: '#22c55e', 600: '#16a34a', 700: '#15803d', 800: '#166534', 900: '#14532d', 950: '#052e16' + }, + orange: { + 50: '#fff7ed', 100: '#ffedd5', 200: '#fed7aa', 300: '#fdba74', 400: '#fb923c', + 500: '#f97316', 600: '#ea580c', 700: '#c2410c', 800: '#9a3412', 900: '#7c2d12', 950: '#431407' + }, + teal: { + 50: '#f0fdfa', 100: '#ccfbf1', 200: '#99f6e4', 300: '#5eead4', 400: '#2dd4bf', + 500: '#14b8a6', 600: '#0d9488', 700: '#0f766e', 800: '#115e59', 900: '#134e4a', 950: '#042f2e' + }, + purple: { + 50: '#faf5ff', 100: '#f3e8ff', 200: '#e9d5ff', 300: '#d8b4fe', 400: '#c084fc', + 500: '#a855f7', 600: '#9333ea', 700: '#7e22ce', 800: '#6b21a8', 900: '#581c87', 950: '#3b0764' + }, + rose: { + 50: '#fff1f2', 100: '#ffe4e6', 200: '#fecdd3', 300: '#fda4af', 400: '#fb7185', + 500: '#f43f5e', 600: '#e11d48', 700: '#be123c', 800: '#9f1239', 900: '#881337', 950: '#4c0519' + } +}; export const accentColors: { value: AccentColor; label: string; color: string }[] = [ { value: 'blue', label: 'Blue', color: '#2563eb' }, - { value: 'yellow', label: 'Yellow', color: '#eab308' } + { value: 'yellow', label: 'Yellow', color: '#eab308' }, + { value: 'green', label: 'Green', color: '#16a34a' }, + { value: 'orange', label: 'Orange', color: '#ea580c' }, + { value: 'teal', label: 'Teal', color: '#0d9488' }, + { value: 'purple', label: 'Purple', color: '#9333ea' }, + { value: 'rose', label: 'Rose', color: '#e11d48' } ]; +function applyAccentColors(accent: AccentColor) { + if (!browser) return; + const palette = colorPalettes[accent]; + const root = document.documentElement; + Object.entries(palette).forEach(([shade, color]) => { + root.style.setProperty(`--accent-${shade}`, color); + }); +} + function createAccentStore() { let initialAccent: AccentColor = 'blue'; if (browser) { @@ -19,12 +68,14 @@ function createAccentStore() { if (stored && accentColors.some((c) => c.value === stored)) { initialAccent = stored; } + applyAccentColors(initialAccent); } const { subscribe, set } = writable(initialAccent); function setAccent(accent: AccentColor) { set(accent); + applyAccentColors(accent); if (browser) { localStorage.setItem('accent', accent); } diff --git a/src/lib/client/ui/button/Button.svelte b/src/lib/client/ui/button/Button.svelte new file mode 100644 index 0000000..458522d --- /dev/null +++ b/src/lib/client/ui/button/Button.svelte @@ -0,0 +1,35 @@ + + + diff --git a/src/lib/client/ui/dropdown/CustomGroupManager.svelte b/src/lib/client/ui/dropdown/CustomGroupManager.svelte index bb23db4..a0cf046 100644 --- a/src/lib/client/ui/dropdown/CustomGroupManager.svelte +++ b/src/lib/client/ui/dropdown/CustomGroupManager.svelte @@ -34,17 +34,17 @@ type="text" bind:value={newGroupName} placeholder="Group name" - class="block w-full rounded border border-neutral-300 bg-white px-2 py-1.5 text-xs text-neutral-900 placeholder-neutral-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50 dark:placeholder-neutral-500" + class="block w-full rounded border border-neutral-300 bg-white px-2 py-1.5 text-xs text-neutral-900 placeholder-neutral-400 focus:border-accent-500 focus:ring-1 focus:ring-accent-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50 dark:placeholder-neutral-500" /> diff --git a/src/lib/client/ui/form/FormInput.svelte b/src/lib/client/ui/form/FormInput.svelte index 068b230..9d24c97 100644 --- a/src/lib/client/ui/form/FormInput.svelte +++ b/src/lib/client/ui/form/FormInput.svelte @@ -22,14 +22,14 @@ bind:value {placeholder} rows="6" - class="block w-full rounded-lg border border-neutral-300 bg-white px-3 py-2 text-neutral-900 placeholder-neutral-400 transition-colors focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50 dark:placeholder-neutral-500" + class="block w-full rounded-lg border border-neutral-300 bg-white px-3 py-2 text-neutral-900 placeholder-neutral-400 transition-colors focus:border-accent-500 focus:outline-none focus:ring-1 focus:ring-accent-500 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50 dark:placeholder-neutral-500" > {:else} {/if} diff --git a/src/lib/client/ui/form/NumberInput.svelte b/src/lib/client/ui/form/NumberInput.svelte index 32a4410..0fa4a22 100644 --- a/src/lib/client/ui/form/NumberInput.svelte +++ b/src/lib/client/ui/form/NumberInput.svelte @@ -58,7 +58,7 @@ {step} {required} {disabled} - class="block w-full [appearance:textfield] rounded-lg border border-neutral-300 bg-white px-3 py-2 pr-10 text-neutral-900 placeholder-neutral-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none disabled:bg-neutral-100 disabled:text-neutral-500 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50 dark:placeholder-neutral-500 dark:disabled:bg-neutral-900 dark:disabled:text-neutral-600 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none {fontClass}" + class="block w-full [appearance:textfield] rounded-lg border border-neutral-300 bg-white px-3 py-2 pr-10 text-neutral-900 placeholder-neutral-400 focus:border-accent-500 focus:ring-1 focus:ring-accent-500 focus:outline-none disabled:bg-neutral-100 disabled:text-neutral-500 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50 dark:placeholder-neutral-500 dark:disabled:bg-neutral-900 dark:disabled:text-neutral-600 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none {fontClass}" /> diff --git a/src/lib/client/ui/form/TagInput.svelte b/src/lib/client/ui/form/TagInput.svelte index 801c210..2ddfcd5 100644 --- a/src/lib/client/ui/form/TagInput.svelte +++ b/src/lib/client/ui/form/TagInput.svelte @@ -34,13 +34,13 @@ > {#each tags as tag, index (tag)}
{tag}