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 {