From 4b36e2c85241e5e4db230766dfe35d985963eadd Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 19 Jan 2026 22:14:04 +0000
Subject: [PATCH] Polish UI: Beautiful header, burger menu, logo, dialogs, and
dropdowns inspired by GitHub Spark
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
---
src/app/PageLayout.tsx | 30 +-
.../layout/navigation/Navigation.tsx | 11 +-
src/styles/components/_dialogs.scss | 332 ++++++++++++++++++
src/styles/components/_header.scss | 219 ++++++++++++
src/styles/components/_index.scss | 2 +
src/styles/utilities/_utilities.scss | 34 +-
6 files changed, 569 insertions(+), 59 deletions(-)
create mode 100644 src/styles/components/_dialogs.scss
create mode 100644 src/styles/components/_header.scss
diff --git a/src/app/PageLayout.tsx b/src/app/PageLayout.tsx
index e929b3e..5c69154 100644
--- a/src/app/PageLayout.tsx
+++ b/src/app/PageLayout.tsx
@@ -13,27 +13,7 @@ export function PageLayout({ children }: { children: ReactNode }) {
return (
-
+
@@ -50,13 +30,13 @@ export function PageLayout({ children }: { children: ReactNode }) {
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.4 }}
- className="flex items-center gap-3"
+ className="logo-container"
>
-
-
+
+
-
+
CodeSnippet
diff --git a/src/components/layout/navigation/Navigation.tsx b/src/components/layout/navigation/Navigation.tsx
index 92c1493..9d14f26 100644
--- a/src/components/layout/navigation/Navigation.tsx
+++ b/src/components/layout/navigation/Navigation.tsx
@@ -1,16 +1,15 @@
import { List } from '@phosphor-icons/react'
-import { Button } from '@/components/ui/button'
import { useNavigation } from './useNavigation'
export function Navigation() {
const { menuOpen, setMenuOpen } = useNavigation()
return (
-
+
+
)
}
diff --git a/src/styles/components/_dialogs.scss b/src/styles/components/_dialogs.scss
new file mode 100644
index 0000000..9c3282f
--- /dev/null
+++ b/src/styles/components/_dialogs.scss
@@ -0,0 +1,332 @@
+@use '../abstracts' as *;
+
+// Dialog/Modal styling - beautiful and polished
+[data-slot="dialog-overlay"],
+.dialog-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 50;
+ background-color: rgba(0, 0, 0, 0.6);
+ backdrop-filter: blur(8px);
+ animation: fadeIn 0.2s ease-out;
+}
+
+[data-slot="dialog"],
+.dialog-content {
+ position: fixed;
+ left: 50%;
+ top: 50%;
+ z-index: 50;
+ transform: translate(-50%, -50%);
+ width: 90%;
+ max-width: 32rem;
+ max-height: 85vh;
+ overflow-y: auto;
+ background: linear-gradient(135deg, rgba($card, 0.95) 0%, rgba($card, 0.98) 100%);
+ border: 1px solid rgba($border, 0.5);
+ border-radius: $radius-xl;
+ box-shadow:
+ 0 20px 40px rgba(0, 0, 0, 0.3),
+ 0 10px 20px rgba(0, 0, 0, 0.2),
+ 0 0 0 1px rgba($accent, 0.1);
+ animation: dialogSlideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &:focus {
+ outline: none;
+ }
+}
+
+// Dropdown menu styling - sleek and modern
+[data-slot="dropdown-menu-content"],
+.dropdown-content {
+ z-index: 50;
+ min-width: 12rem;
+ overflow: hidden;
+ border-radius: $radius-lg;
+ border: 1px solid rgba($border, 0.5);
+ background: rgba($popover, 0.95);
+ backdrop-filter: blur(12px) saturate(150%);
+ box-shadow:
+ 0 10px 25px rgba(0, 0, 0, 0.2),
+ 0 4px 10px rgba(0, 0, 0, 0.15),
+ 0 0 0 1px rgba($accent, 0.05);
+ padding: 0.375rem;
+ animation: dropdownSlideIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &:focus {
+ outline: none;
+ }
+}
+
+[data-slot="dropdown-menu-item"],
+.dropdown-item {
+ position: relative;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 0.75rem;
+ font-size: 0.875rem;
+ color: $foreground;
+ border-radius: $radius-sm;
+ cursor: pointer;
+ transition: all 0.15s ease;
+ user-select: none;
+ outline: none;
+
+ &:hover {
+ background-color: rgba($accent, 0.12);
+ color: $accent;
+ transform: translateX(2px);
+ }
+
+ &:focus {
+ background-color: rgba($accent, 0.15);
+ color: $accent;
+ }
+
+ &[data-disabled] {
+ pointer-events: none;
+ opacity: 0.5;
+ }
+}
+
+// Popover styling - refined and elegant
+[data-slot="popover-content"],
+.popover-content {
+ z-index: 50;
+ width: auto;
+ border-radius: $radius-lg;
+ border: 1px solid rgba($border, 0.5);
+ background: rgba($popover, 0.95);
+ backdrop-filter: blur(12px) saturate(150%);
+ padding: 1rem;
+ box-shadow:
+ 0 10px 25px rgba(0, 0, 0, 0.2),
+ 0 4px 10px rgba(0, 0, 0, 0.15);
+ animation: popoverSlideIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &:focus {
+ outline: none;
+ }
+}
+
+// Select dropdown styling - beautiful custom select
+[data-slot="select-trigger"],
+.select-trigger {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ padding: 0.5rem 0.75rem;
+ font-size: 0.875rem;
+ border-radius: $radius-md;
+ border: 1px solid rgba($border, 0.5);
+ background: rgba($input, 0.5);
+ color: $foreground;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: rgba($input, 0.7);
+ border-color: rgba($accent, 0.5);
+ }
+
+ &:focus {
+ outline: none;
+ border-color: $ring;
+ box-shadow: 0 0 0 3px rgba($ring, 0.1);
+ }
+
+ &[data-disabled] {
+ pointer-events: none;
+ opacity: 0.5;
+ }
+}
+
+[data-slot="select-content"],
+.select-content {
+ z-index: 50;
+ min-width: 8rem;
+ overflow: hidden;
+ border-radius: $radius-lg;
+ border: 1px solid rgba($border, 0.5);
+ background: rgba($popover, 0.95);
+ backdrop-filter: blur(12px) saturate(150%);
+ box-shadow:
+ 0 10px 25px rgba(0, 0, 0, 0.2),
+ 0 4px 10px rgba(0, 0, 0, 0.15);
+ padding: 0.375rem;
+ animation: selectSlideIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+[data-slot="select-item"],
+.select-item {
+ position: relative;
+ display: flex;
+ align-items: center;
+ padding: 0.5rem 0.75rem 0.5rem 2rem;
+ font-size: 0.875rem;
+ color: $foreground;
+ border-radius: $radius-sm;
+ cursor: pointer;
+ transition: all 0.15s ease;
+ outline: none;
+ user-select: none;
+
+ &:hover {
+ background-color: rgba($accent, 0.12);
+ color: $accent;
+ }
+
+ &:focus {
+ background-color: rgba($accent, 0.15);
+ color: $accent;
+ }
+
+ &[data-state="checked"] {
+ background-color: rgba($accent, 0.1);
+ color: $accent;
+ font-weight: 500;
+
+ &::before {
+ content: '✓';
+ position: absolute;
+ left: 0.5rem;
+ font-size: 0.875rem;
+ }
+ }
+
+ &[data-disabled] {
+ pointer-events: none;
+ opacity: 0.5;
+ }
+}
+
+// Alert Dialog styling - attention-grabbing
+[data-slot="alert-dialog-content"],
+.alert-dialog-content {
+ position: fixed;
+ left: 50%;
+ top: 50%;
+ z-index: 50;
+ transform: translate(-50%, -50%);
+ width: 90%;
+ max-width: 28rem;
+ background: linear-gradient(135deg, rgba($card, 0.95) 0%, rgba($card, 0.98) 100%);
+ border: 1px solid rgba($destructive, 0.3);
+ border-radius: $radius-xl;
+ box-shadow:
+ 0 20px 40px rgba($destructive, 0.2),
+ 0 10px 20px rgba(0, 0, 0, 0.2);
+ padding: 1.5rem;
+ animation: alertSlideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &:focus {
+ outline: none;
+ }
+}
+
+// Animations
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes dialogSlideIn {
+ from {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.96);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+}
+
+@keyframes dropdownSlideIn {
+ from {
+ opacity: 0;
+ transform: translateY(-8px) scale(0.96);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+}
+
+@keyframes popoverSlideIn {
+ from {
+ opacity: 0;
+ transform: scale(0.96);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+@keyframes selectSlideIn {
+ from {
+ opacity: 0;
+ transform: translateY(-4px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes alertSlideIn {
+ from {
+ opacity: 0;
+ transform: translate(-50%, -45%) scale(0.9);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+}
+
+// Namespace selector specific styling
+.namespace-select {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 1rem;
+ font-size: 0.875rem;
+ font-weight: 500;
+ border-radius: $radius-lg;
+ border: 1px solid rgba($border, 0.5);
+ background: rgba($secondary, 0.5);
+ color: $foreground;
+ cursor: pointer;
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+
+ svg {
+ width: 1rem;
+ height: 1rem;
+ color: $muted-foreground;
+ transition: color 0.2s ease;
+ }
+
+ &:hover {
+ background: rgba($secondary, 0.7);
+ border-color: rgba($accent, 0.4);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba($accent, 0.1);
+
+ svg {
+ color: $accent;
+ }
+ }
+
+ &:focus {
+ outline: none;
+ border-color: $ring;
+ box-shadow: 0 0 0 3px rgba($ring, 0.1);
+ }
+}
diff --git a/src/styles/components/_header.scss b/src/styles/components/_header.scss
new file mode 100644
index 0000000..5785f35
--- /dev/null
+++ b/src/styles/components/_header.scss
@@ -0,0 +1,219 @@
+@use '../abstracts' as *;
+
+// Header and navigation specific styles - GitHub Spark inspired
+header {
+ border-bottom: 1px solid rgba($border, 0.5);
+ background-color: rgba($background, 0.8);
+ backdrop-filter: blur(16px) saturate(180%);
+ position: sticky;
+ top: 0;
+ z-index: 20;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+
+ .container {
+ padding: 1rem 1.5rem;
+ }
+}
+
+// Burger menu / navigation button styling - refined and polished
+.nav-burger-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.25rem;
+ height: 2.25rem;
+ padding: 0.375rem;
+ border-radius: $radius-md;
+ background-color: rgba($secondary, 0.5);
+ border: 1px solid rgba($border, 0.5);
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ cursor: pointer;
+ position: relative;
+
+ svg {
+ width: 1.25rem;
+ height: 1.25rem;
+ color: $foreground;
+ transition: all 0.2s ease;
+ }
+
+ &::before {
+ content: '';
+ position: absolute;
+ inset: -2px;
+ border-radius: $radius-md;
+ padding: 2px;
+ background: linear-gradient(135deg, $accent 0%, transparent 100%);
+ -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
+ -webkit-mask-composite: xor;
+ mask-composite: exclude;
+ opacity: 0;
+ transition: opacity 0.2s ease;
+ }
+
+ &:hover {
+ background-color: rgba($accent, 0.15);
+ border-color: rgba($accent, 0.4);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba($accent, 0.15);
+
+ &::before {
+ opacity: 1;
+ }
+
+ svg {
+ color: $accent;
+ transform: scale(1.05);
+ }
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+
+ &:focus-visible {
+ outline: 2px solid $ring;
+ outline-offset: 2px;
+ }
+}
+
+// Logo styling improvements - elegant and refined
+.logo-container {
+ display: flex;
+ align-items: center;
+ gap: 0.875rem;
+}
+
+.logo-icon-box {
+ width: 2.25rem;
+ height: 2.25rem;
+ border-radius: $radius-lg;
+ background: linear-gradient(135deg, $primary 0%, hsl(195, 100%, 60%) 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow:
+ 0 2px 8px rgba($primary, 0.25),
+ 0 1px 2px rgba(0, 0, 0, 0.1),
+ inset 0 1px 1px rgba(255, 255, 255, 0.1);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ position: relative;
+ overflow: hidden;
+
+ &::before {
+ content: '';
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: linear-gradient(
+ 45deg,
+ transparent,
+ rgba(255, 255, 255, 0.1),
+ transparent
+ );
+ transform: rotate(45deg);
+ transition: all 0.5s ease;
+ }
+
+ svg {
+ width: 1.25rem;
+ height: 1.25rem;
+ color: $primary-foreground;
+ position: relative;
+ z-index: 1;
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
+ }
+
+ &:hover {
+ transform: translateY(-2px) scale(1.05);
+ box-shadow:
+ 0 6px 20px rgba($primary, 0.35),
+ 0 2px 4px rgba(0, 0, 0, 0.15),
+ inset 0 1px 1px rgba(255, 255, 255, 0.15);
+
+ &::before {
+ left: 100%;
+ }
+ }
+}
+
+.logo-text {
+ font-size: 1.375rem;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ background: linear-gradient(135deg, $primary 0%, $accent 50%, $primary 100%);
+ background-size: 200% auto;
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ animation: gradient-shift 4s ease infinite;
+ position: relative;
+ text-shadow: 0 0 30px rgba($accent, 0.3);
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: linear-gradient(90deg, transparent, $accent, transparent);
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ }
+
+ &:hover::after {
+ opacity: 0.6;
+ }
+}
+
+@keyframes gradient-shift {
+ 0%, 100% {
+ background-position: 0% center;
+ }
+ 50% {
+ background-position: 200% center;
+ }
+}
+
+// Grid pattern adjustment - ultra subtle like GitHub Spark
+.grid-pattern {
+ position: fixed;
+ inset: 0;
+ opacity: 0.015; // Very subtle
+ pointer-events: none;
+ background-image:
+ repeating-linear-gradient(
+ 0deg,
+ transparent,
+ transparent 48px,
+ rgba($accent, 0.15) 48px,
+ rgba($accent, 0.15) 49px
+ ),
+ repeating-linear-gradient(
+ 90deg,
+ transparent,
+ transparent 48px,
+ rgba($accent, 0.15) 48px,
+ rgba($accent, 0.15) 49px
+ );
+ background-size: 48px 48px;
+}
+
+// Header animations
+@keyframes fadeInDown {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+header {
+ animation: fadeInDown 0.4s ease-out;
+}
diff --git a/src/styles/components/_index.scss b/src/styles/components/_index.scss
index ab8dd3c..8a8b0cd 100644
--- a/src/styles/components/_index.scss
+++ b/src/styles/components/_index.scss
@@ -4,3 +4,5 @@
@forward './cards';
@forward './forms';
@forward './typography';
+@forward './header';
+@forward './dialogs';
diff --git a/src/styles/utilities/_utilities.scss b/src/styles/utilities/_utilities.scss
index 399b605..4acecf9 100644
--- a/src/styles/utilities/_utilities.scss
+++ b/src/styles/utilities/_utilities.scss
@@ -260,47 +260,25 @@ $space-values: (2, 3, 4, 6, 8);
text-underline-offset: 4px !important;
}
-// Gap variations (additional to the ones from spacing loop)
-.gap-1 { gap: 0.25rem !important; }
+// Gap variations - only adding those NOT in spacing map
.gap-1\.5 { gap: 0.375rem !important; }
-.gap-2 { gap: 0.5rem !important; }
-.gap-3 { gap: 0.75rem !important; }
-.gap-4 { gap: 1rem !important; }
-.gap-6 { gap: 1.5rem !important; }
-.gap-8 { gap: 2rem !important; }
-.gap-12 { gap: 3rem !important; }
// Rounded variations (additional)
.rounded-xs { border-radius: 0.125rem !important; }
.rounded-full { border-radius: 9999px !important; }
-// Padding variations (additional single values not in spacing map)
-.px-1 { padding-left: 0.25rem !important; padding-right: 0.25rem !important; }
-.px-2 { padding-left: 0.5rem !important; padding-right: 0.5rem !important; }
-.px-3 { padding-left: 0.75rem !important; padding-right: 0.75rem !important; }
-.px-4 { padding-left: 1rem !important; padding-right: 1rem !important; }
-.px-6 { padding-left: 1.5rem !important; padding-right: 1.5rem !important; }
-
+// Padding variations - only py-0 and py-20 which are not in the spacing map
.py-0 { padding-top: 0 !important; padding-bottom: 0 !important; }
-.py-1 { padding-top: 0.25rem !important; padding-bottom: 0.25rem !important; }
-.py-2 { padding-top: 0.5rem !important; padding-bottom: 0.5rem !important; }
-.py-4 { padding-top: 1rem !important; padding-bottom: 1rem !important; }
-.py-6 { padding-top: 1.5rem !important; padding-bottom: 1.5rem !important; }
-.py-8 { padding-top: 2rem !important; padding-bottom: 2rem !important; }
.py-20 { padding-top: 5rem !important; padding-bottom: 5rem !important; }
-// Space between variations (additional)
-.space-x-2 > * + * { margin-left: 0.5rem !important; }
-.space-x-3 > * + * { margin-left: 0.75rem !important; }
+// Space between variations - only adding those NOT in the loop
.space-y-0 > * + * { margin-top: 0 !important; }
.space-y-1 > * + * { margin-top: 0.25rem !important; }
.space-y-16 > * + * { margin-top: 4rem !important; }
-// SVG sizing helper - using attribute selector instead of complex class name
-svg {
- &[class*="h-5"] { height: 1.25rem; }
- &[class*="w-5"] { width: 1.25rem; }
-}
+// SVG sizing - explicit class matches for h-5 and w-5
+svg.h-5 { height: 1.25rem !important; }
+svg.w-5 { width: 1.25rem !important; }
// Button-specific utilities using nesting
button {