From 7c566b57523c3c33b37c475f1c7ae1ed12c92f7f Mon Sep 17 00:00:00 2001 From: mahdiarghyani Date: Mon, 15 Dec 2025 13:15:12 +0330 Subject: [PATCH 1/2] feat: update theme color usage and enhance button styles across components --- app/assets/css/main.css | 219 +++++++++++++++------ app/components/common/FooterCopyright.vue | 4 +- app/components/portfolio/Hero.vue | 29 ++- docs/THEME-COLOR-GUIDE.md | 226 ++++++++++++++++++++++ 4 files changed, 409 insertions(+), 69 deletions(-) create mode 100644 docs/THEME-COLOR-GUIDE.md diff --git a/app/assets/css/main.css b/app/assets/css/main.css index 28965b3..54f2c1f 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -21,18 +21,6 @@ @theme { --font-sans: 'Geist', 'DM Sans', '-apple-system', 'ui-sans-serif', 'system-ui', 'sans-serif'; --font-display: 'Space Grotesk', 'Geist', 'ui-sans-serif', 'sans-serif'; - - --color-primary-50: oklch(0.98 0.01 280); - --color-primary-100: oklch(0.95 0.03 280); - --color-primary-200: oklch(0.89 0.08 280); - --color-primary-300: oklch(0.80 0.15 280); - --color-primary-400: oklch(0.70 0.22 280); - --color-primary-500: oklch(0.60 0.25 280); - --color-primary-600: oklch(0.50 0.22 280); - --color-primary-700: oklch(0.42 0.18 280); - --color-primary-800: oklch(0.34 0.14 280); - --color-primary-900: oklch(0.28 0.10 280); - --color-primary-950: oklch(0.18 0.06 280); } @layer base { @@ -213,7 +201,7 @@ h2, h3 { @apply font-display tracking-tight font-bold; - background: linear-gradient(135deg, currentColor 0%, color-mix(in oklch, currentColor, violet 30%) 100%); + background: linear-gradient(135deg, currentColor 0%, color-mix(in oklch, currentColor, var(--ui-color-primary-500) 30%) 100%); -webkit-background-clip: text; background-clip: text; } @@ -234,8 +222,31 @@ } @layer utilities { + /** + * THEME COLOR USAGE GUIDE + * + * Always use Nuxt UI CSS variables for primary colors: + * - var(--ui-color-primary-500) for main primary color + * - var(--ui-color-primary-400) for lighter shade + * - var(--ui-color-primary-600) for darker shade + * + * Or use semantic Tailwind classes: + * - text-primary, bg-primary, border-primary + * + * Never use hardcoded colors like: + * - purple-500, violet-600, #a855f7 + * + * For gradients, use CSS variables: + * background: linear-gradient(to right, + * var(--ui-color-primary-600), + * var(--ui-color-primary-500) + * ); + * + * See docs/THEME-COLOR-GUIDE.md for detailed documentation. + */ + .primary-text { - @apply text-violet-600 dark:text-violet-400; + @apply text-primary; } .section-spacing { @@ -255,7 +266,7 @@ } .decorated { - @apply underline underline-offset-8 decoration-violet-500 dark:decoration-violet-400 decoration-2; + @apply underline underline-offset-8 decoration-primary decoration-2; } /* Soft text color helpers */ @@ -263,13 +274,70 @@ @apply text-zinc-600 dark:text-zinc-300; } - /* Gradient text effect */ .gradient-text { - @apply bg-gradient-to-r from-violet-600 via-purple-600 to-fuchsia-600 dark:from-violet-400 dark:via-purple-400 dark:to-fuchsia-400 bg-clip-text text-transparent; + background: linear-gradient( + to right, + var(--ui-color-primary-600), + var(--ui-color-primary-500), + var(--ui-color-primary-400) + ); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } + + .dark .gradient-text { + background: linear-gradient( + to right, + var(--ui-color-primary-400), + var(--ui-color-primary-300), + var(--ui-color-primary-200) + ); + -webkit-background-clip: text; + background-clip: text; } .chip-base { - @apply inline-flex items-center gap-1.5 rounded-2xl px-3 py-1.5 text-xs font-semibold ring-1 ring-violet-200/70 bg-gradient-to-br from-white/90 to-violet-50/60 text-violet-700 shadow-lg shadow-violet-500/10 backdrop-blur-md dark:from-violet-950/40 dark:to-violet-900/20 dark:text-violet-200 dark:ring-violet-800/50 dark:shadow-violet-500/5 transition-all hover:scale-105 hover:shadow-xl hover:shadow-violet-500/20; + @apply inline-flex items-center gap-1.5 rounded-2xl px-3 py-1.5 text-xs font-semibold ring-2 transition-all hover:scale-105 hover:shadow-xl backdrop-blur-md; + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-400) 60%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, white 75%, transparent), + color-mix(in oklch, var(--ui-color-primary-100) 80%, transparent) + ); + color: var(--ui-color-primary-700); + box-shadow: + 0 10px 15px -3px color-mix(in oklch, var(--ui-color-primary-500) 15%, transparent), + 0 4px 6px -2px color-mix(in oklch, var(--ui-color-primary-500) 10%, transparent); + border: 1px solid color-mix(in oklch, var(--ui-color-primary-300) 40%, transparent); + } + + .chip-base:hover { + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-500) 70%, transparent); + box-shadow: + 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 25%, transparent), + 0 8px 10px -6px color-mix(in oklch, var(--ui-color-primary-500) 20%, transparent); + } + + .dark .chip-base { + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-600) 50%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, var(--ui-color-primary-950) 60%, transparent), + color-mix(in oklch, var(--ui-color-primary-900) 40%, transparent) + ); + color: var(--ui-color-primary-200); + box-shadow: + 0 10px 15px -3px color-mix(in oklch, var(--ui-color-primary-500) 10%, transparent), + 0 4px 6px -2px color-mix(in oklch, var(--ui-color-primary-500) 8%, transparent); + border: 1px solid color-mix(in oklch, var(--ui-color-primary-700) 40%, transparent); + } + + .dark .chip-base:hover { + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-500) 60%, transparent); + box-shadow: + 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 15%, transparent), + 0 8px 10px -6px color-mix(in oklch, var(--ui-color-primary-500) 12%, transparent); } /* Hide scrollbars for overflow containers */ @@ -292,9 +360,13 @@ padding-bottom: env(safe-area-inset-bottom); } - /* Modern glassmorphic card */ .glass-card { - @apply rounded-3xl bg-white/80 dark:bg-zinc-900/50 backdrop-blur-xl shadow-xl shadow-violet-500/5 dark:shadow-violet-500/10 border border-white/20 dark:border-zinc-800/50 transition-all duration-300; + @apply rounded-3xl bg-white/80 dark:bg-zinc-900/50 backdrop-blur-xl border border-white/20 dark:border-zinc-800/50 transition-all duration-300; + box-shadow: 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 5%, transparent); + } + + .dark .glass-card { + box-shadow: 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 10%, transparent); } .glass-card:hover { @@ -358,68 +430,97 @@ box-shadow: 0 10px 15px -3px color-mix(in srgb, var(--ui-color-primary-500) 5%, transparent); } - /* Modern button with gradient */ .btn-modern { - @apply inline-flex items-center justify-center px-6 py-3 rounded-2xl font-semibold text-white bg-gradient-to-r from-violet-600 to-purple-600 hover:from-violet-700 hover:to-purple-700 shadow-lg shadow-violet-500/30 hover:shadow-xl hover:shadow-violet-500/40 transition-all duration-300 hover:scale-105; + @apply inline-flex items-center justify-center px-6 py-3 rounded-2xl font-semibold text-white transition-all duration-300 hover:scale-105; + background: linear-gradient(to right, var(--ui-color-primary-600), var(--ui-color-primary-500)); + box-shadow: 0 10px 15px -3px color-mix(in oklch, var(--ui-color-primary-500) 30%, transparent); + } + + .btn-modern:hover { + background: linear-gradient(to right, var(--ui-color-primary-700), var(--ui-color-primary-600)); + box-shadow: 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 40%, transparent); } } @layer utilities { - /* Minimal outlined button: persistent subtle border and light background; hover handled separately */ .btn-outline-minimal { - @apply border border-violet-200/60 dark:border-violet-800/50 bg-gradient-to-br from-white/60 to-violet-50/30 dark:from-white/5 dark:to-violet-950/20 backdrop-blur-sm transition-all duration-300 hover:shadow-lg hover:shadow-violet-500/10; + @apply backdrop-blur-sm transition-all duration-300 hover:shadow-lg; + border: 1px solid color-mix(in oklch, var(--ui-color-primary-200) 60%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, white 60%, transparent), + color-mix(in oklch, var(--ui-color-primary-50) 30%, transparent) + ); + } + + .btn-outline-minimal:hover { + box-shadow: 0 10px 15px -3px color-mix(in oklch, var(--ui-color-primary-500) 10%, transparent); + } + + .dark .btn-outline-minimal { + border-color: color-mix(in oklch, var(--ui-color-primary-800) 50%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, white 5%, transparent), + color-mix(in oklch, var(--ui-color-primary-950) 20%, transparent) + ); } } @layer utilities { - /* Chip-style icon button inspired by SkillGrid: subtle ring, soft bg, minimal hover */ .chip-button { - @apply inline-flex items-center justify-center h-12 w-12 rounded-2xl ring-1 backdrop-blur-md transition-all duration-300 ease-out hover:scale-110; - - /* Dynamic theme colors using CSS variables */ - ring-color: color-mix(in srgb, var(--ui-color-primary-200) 70%, transparent); - background: linear-gradient(to bottom right, - color-mix(in srgb, white 90%, transparent), - color-mix(in srgb, var(--ui-color-primary-50) 50%, transparent) + @apply inline-flex items-center justify-center h-12 w-12 rounded-2xl ring-2 backdrop-blur-md transition-all duration-300 ease-out hover:scale-110; + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-400) 55%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, white 70%, transparent), + color-mix(in oklch, var(--ui-color-primary-100) 75%, transparent) ); color: var(--ui-color-primary-700); box-shadow: - 0 10px 15px -3px color-mix(in srgb, var(--ui-color-primary-500) 10%, transparent), - 0 4px 6px -4px color-mix(in srgb, var(--ui-color-primary-500) 10%, transparent); + 0 10px 15px -3px color-mix(in oklch, var(--ui-color-primary-500) 15%, transparent), + 0 4px 6px -2px color-mix(in oklch, var(--ui-color-primary-500) 10%, transparent); + border: 1px solid color-mix(in oklch, var(--ui-color-primary-300) 35%, transparent); } - + .chip-button:hover { - background: linear-gradient(to bottom right, - color-mix(in srgb, var(--ui-color-primary-50) 100%, transparent), - color-mix(in srgb, var(--ui-color-primary-100) 100%, transparent) + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-500) 70%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, var(--ui-color-primary-50) 90%, transparent), + color-mix(in oklch, var(--ui-color-primary-100) 95%, transparent) ); box-shadow: - 0 20px 25px -5px color-mix(in srgb, var(--ui-color-primary-500) 20%, transparent), - 0 8px 10px -6px color-mix(in srgb, var(--ui-color-primary-500) 20%, transparent); + 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 25%, transparent), + 0 8px 10px -6px color-mix(in oklch, var(--ui-color-primary-500) 20%, transparent); } - + .dark .chip-button { - ring-color: color-mix(in srgb, var(--ui-color-primary-800) 50%, transparent); - background: linear-gradient(to bottom right, - color-mix(in srgb, white 10%, transparent), - color-mix(in srgb, var(--ui-color-primary-950) 30%, transparent) + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-600) 45%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, white 15%, transparent), + color-mix(in oklch, var(--ui-color-primary-950) 50%, transparent) ); color: var(--ui-color-primary-200); box-shadow: - 0 10px 15px -3px color-mix(in srgb, var(--ui-color-primary-500) 5%, transparent), - 0 4px 6px -4px color-mix(in srgb, var(--ui-color-primary-500) 5%, transparent); + 0 10px 15px -3px color-mix(in oklch, var(--ui-color-primary-500) 10%, transparent), + 0 4px 6px -2px color-mix(in oklch, var(--ui-color-primary-500) 8%, transparent); + border: 1px solid color-mix(in oklch, var(--ui-color-primary-700) 35%, transparent); } - + .dark .chip-button:hover { - background: linear-gradient(to bottom right, - color-mix(in srgb, white 15%, transparent), - color-mix(in srgb, var(--ui-color-primary-900) 40%, transparent) + --tw-ring-color: color-mix(in oklch, var(--ui-color-primary-500) 60%, transparent); + background: linear-gradient( + to bottom right, + color-mix(in oklch, white 20%, transparent), + color-mix(in oklch, var(--ui-color-primary-900) 60%, transparent) ); box-shadow: - 0 20px 25px -5px color-mix(in srgb, var(--ui-color-primary-500) 10%, transparent), - 0 8px 10px -6px color-mix(in srgb, var(--ui-color-primary-500) 10%, transparent); + 0 20px 25px -5px color-mix(in oklch, var(--ui-color-primary-500) 15%, transparent), + 0 8px 10px -6px color-mix(in oklch, var(--ui-color-primary-500) 12%, transparent); } /* GitHub Activity Contribution Graph - Dynamic Primary Color */ @@ -526,13 +627,11 @@ width: 100%; z-index: 1000; pointer-events: none; - /* Use primary color gradient; adapt in dark mode */ - background-image: linear-gradient(to right, - rgb(99 102 241 / 0.9), - /* indigo-500 */ - rgb(139 92 246 / 0.9) - /* violet-500 */ - ); + background-image: linear-gradient( + to right, + color-mix(in oklch, var(--ui-color-primary-500) 90%, transparent), + color-mix(in oklch, var(--ui-color-primary-600) 90%, transparent) + ); transform-origin: left center; animation: locale-progress-grow 600ms ease-out forwards; } diff --git a/app/components/common/FooterCopyright.vue b/app/components/common/FooterCopyright.vue index 3186403..d2443aa 100644 --- a/app/components/common/FooterCopyright.vue +++ b/app/components/common/FooterCopyright.vue @@ -9,9 +9,9 @@ class="h-12 w-12" loading="lazy" /> -

© {{ currentYear }}, AliArghyani - +

© {{ currentYear }}, MahdiArghyani - All rights reserved.

- GitHub diff --git a/app/components/portfolio/Hero.vue b/app/components/portfolio/Hero.vue index 87c7274..b7d705a 100644 --- a/app/components/portfolio/Hero.vue +++ b/app/components/portfolio/Hero.vue @@ -31,10 +31,9 @@