From 5875a52b4795bfedb65a3b3b4d837663aebaf290 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 25 Jun 2025 21:18:20 -0400 Subject: [PATCH] refactor: standardize z-index values with CSS variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create _z-index.scss with systematic z-index constants - Replace 60+ hardcoded z-index values across 19 components - Establish consistent layering hierarchy: - Base layers (1-3) - Interactive elements (10-200) - Overlays and modals (1000-1100) - Top-level elements (1200-10000) This improves maintainability and prevents z-index conflicts. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- prd/PRD-codebase-cleanup-refactoring.md | 6 +-- src/assets/styles/_z-index.scss | 39 +++++++++++++++++++ src/assets/styles/imports.scss | 1 + src/lib/components/AvatarHeadphones.svelte | 2 +- src/lib/components/Header.svelte | 2 +- src/lib/components/Lightbox.svelte | 8 ++-- src/lib/components/NavDropdown.svelte | 2 +- src/lib/components/NowPlaying.svelte | 2 +- src/lib/components/PhotoItem.svelte | 14 +++---- src/lib/components/SegmentedController.svelte | 4 +- src/lib/components/Slideshow.svelte | 8 ++-- src/lib/components/StreamStatus.svelte | 2 +- .../components/ThreeColumnPhotoGrid.svelte | 2 +- src/lib/components/admin/AdminNavBar.svelte | 2 +- .../admin/DeleteConfirmationModal.svelte | 2 +- src/lib/components/admin/DropdownMenu.svelte | 2 +- .../admin/DropdownMenuContainer.svelte | 2 +- .../admin/InlineComposerModal.svelte | 2 +- src/lib/components/admin/Modal.svelte | 4 +- src/lib/components/admin/PostDropdown.svelte | 2 +- .../components/admin/UnifiedMediaModal.svelte | 4 +- 21 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 src/assets/styles/_z-index.scss diff --git a/prd/PRD-codebase-cleanup-refactoring.md b/prd/PRD-codebase-cleanup-refactoring.md index ec0bf10..4adf955 100644 --- a/prd/PRD-codebase-cleanup-refactoring.md +++ b/prd/PRD-codebase-cleanup-refactoring.md @@ -74,9 +74,9 @@ Focus on low-risk, high-impact changes that don't require architectural modifica ### Phase 2: CSS Variable Standardization (Week 2) Create a consistent design system by extracting hardcoded values. -- [ ] **Create z-index system** - - [ ] Create `src/assets/styles/_z-index.scss` with constants - - [ ] Replace 60+ hardcoded z-index values +- [x] **Create z-index system** + - [x] Create `src/assets/styles/_z-index.scss` with constants + - [x] Replace 60+ hardcoded z-index values - [ ] **Extract color variables** - [ ] Add missing color variables for frequently used colors diff --git a/src/assets/styles/_z-index.scss b/src/assets/styles/_z-index.scss new file mode 100644 index 0000000..312ea91 --- /dev/null +++ b/src/assets/styles/_z-index.scss @@ -0,0 +1,39 @@ +/* Z-Index System + * -------------------------------------------------------------------------- + * A systematic approach to z-index values to maintain consistent layering + * throughout the application. + * -------------------------------------------------------------------------- */ + +// Base layers +$z-index-base: 1; +$z-index-above: 2; +$z-index-hover: 3; + +// Interactive elements +$z-index-dropdown: 10; +$z-index-sticky: 100; +$z-index-fixed: 200; + +// Overlays and modals +$z-index-overlay: 1000; +$z-index-modal-backdrop: 1000; +$z-index-modal: 1050; +$z-index-modal-content: 1100; + +// Top-level elements +$z-index-popover: 1200; +$z-index-tooltip: 1400; +$z-index-notification: 10000; + +// Component-specific z-indexes +$z-index-header: 100; +$z-index-navigation: 150; +$z-index-sidebar: 200; +$z-index-media-modal: 1050; +$z-index-lightbox: 1100; +$z-index-toast: 10000; + +// Admin-specific z-indexes +$z-index-admin-nav: 100; +$z-index-admin-sidebar: 200; +$z-index-admin-modal: 1050; \ No newline at end of file diff --git a/src/assets/styles/imports.scss b/src/assets/styles/imports.scss index 509590f..9c15ecf 100644 --- a/src/assets/styles/imports.scss +++ b/src/assets/styles/imports.scss @@ -2,5 +2,6 @@ // It should NOT contain any actual CSS rules to avoid duplication @import './variables.scss'; +@import './z-index.scss'; @import './fonts.scss'; @import './themes.scss'; diff --git a/src/lib/components/AvatarHeadphones.svelte b/src/lib/components/AvatarHeadphones.svelte index a137a3a..5c34de6 100644 --- a/src/lib/components/AvatarHeadphones.svelte +++ b/src/lib/components/AvatarHeadphones.svelte @@ -80,7 +80,7 @@ left: 65%; top: 30.6%; pointer-events: none; - z-index: 10; + z-index: $z-index-dropdown; svg { width: 100%; diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index e7c64f9..0cd330b 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -53,7 +53,7 @@ .site-header { position: sticky; top: 0; - z-index: 100; + z-index: $z-index-header; display: flex; justify-content: center; // Smooth padding transition based on scroll diff --git a/src/lib/components/Lightbox.svelte b/src/lib/components/Lightbox.svelte index 3564561..b61f55f 100644 --- a/src/lib/components/Lightbox.svelte +++ b/src/lib/components/Lightbox.svelte @@ -131,7 +131,7 @@ position: fixed; inset: 0; background: rgba(0, 0, 0, 0.9); - z-index: 1400; + z-index: $z-index-lightbox; display: flex; align-items: center; justify-content: center; @@ -208,7 +208,7 @@ inset: 0; border-radius: $unit-2x; border: 2px solid transparent; - z-index: 2; + z-index: $z-index-above; pointer-events: none; transition: border-color 0.2s ease; } @@ -219,7 +219,7 @@ inset: 2px; border-radius: calc($unit-2x - 2px); border: 2px solid transparent; - z-index: 3; + z-index: $z-index-hover; pointer-events: none; transition: border-color 0.2s ease; } @@ -246,7 +246,7 @@ height: 100%; object-fit: cover; position: relative; - z-index: 1; + z-index: $z-index-base; user-select: none; -webkit-user-drag: none; } diff --git a/src/lib/components/NavDropdown.svelte b/src/lib/components/NavDropdown.svelte index c28c526..9ebf800 100644 --- a/src/lib/components/NavDropdown.svelte +++ b/src/lib/components/NavDropdown.svelte @@ -232,7 +232,7 @@ border-radius: $unit-2x; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: $unit; - z-index: 1000; + z-index: $z-index-overlay; animation: dropdownOpen 0.2s ease; } diff --git a/src/lib/components/NowPlaying.svelte b/src/lib/components/NowPlaying.svelte index dd57ee9..000a309 100644 --- a/src/lib/components/NowPlaying.svelte +++ b/src/lib/components/NowPlaying.svelte @@ -54,7 +54,7 @@ border-radius: $unit * 2; font-size: $font-size-small; backdrop-filter: blur(10px); - z-index: 10; + z-index: $z-index-dropdown; animation: fadeIn 0.3s ease-out; width: fit-content; } diff --git a/src/lib/components/PhotoItem.svelte b/src/lib/components/PhotoItem.svelte index 70b0607..28ff6d8 100644 --- a/src/lib/components/PhotoItem.svelte +++ b/src/lib/components/PhotoItem.svelte @@ -119,7 +119,7 @@ opacity: 0; transition: opacity 0.4s ease; position: relative; - z-index: 2; + z-index: $z-index-above; &.loaded { opacity: 1; @@ -142,7 +142,7 @@ right: -6px; height: 100%; background: rgba(0, 0, 0, 0.1); - z-index: 1; + z-index: $z-index-base; transform: rotate(2deg); } @@ -153,13 +153,13 @@ right: -3px; height: 100%; background: rgba(0, 0, 0, 0.2); - z-index: 2; + z-index: $z-index-above; transform: rotate(-1deg); } &.stack-front { position: relative; - z-index: 3; + z-index: $z-index-hover; img { width: 100%; @@ -169,7 +169,7 @@ opacity: 0; transition: opacity 0.4s ease; position: relative; - z-index: 2; + z-index: $z-index-above; &.loaded { opacity: 1; @@ -186,7 +186,7 @@ background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent); color: white; padding: $unit-2x; - z-index: 4; + z-index: calc($z-index-hover + 1); border-radius: 0 0 $corner-radius $corner-radius; } @@ -229,7 +229,7 @@ border-radius: $corner-radius; opacity: 1; transition: opacity 0.4s ease; - z-index: 1; + z-index: $z-index-base; overflow: hidden; &.loaded { diff --git a/src/lib/components/SegmentedController.svelte b/src/lib/components/SegmentedController.svelte index d93c478..5080f39 100644 --- a/src/lib/components/SegmentedController.svelte +++ b/src/lib/components/SegmentedController.svelte @@ -147,7 +147,7 @@ height: calc(100% - #{$unit * 2}); border-radius: 100px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - z-index: 1; + z-index: $z-index-base; } .nav-item { @@ -160,7 +160,7 @@ font-size: 1rem; font-weight: 400; position: relative; - z-index: 2; + z-index: $z-index-above; transition: color 0.2s ease, background-color 0.2s ease; diff --git a/src/lib/components/Slideshow.svelte b/src/lib/components/Slideshow.svelte index db0ae58..92ba3f2 100644 --- a/src/lib/components/Slideshow.svelte +++ b/src/lib/components/Slideshow.svelte @@ -248,7 +248,7 @@ inset: 0; border-radius: $image-corner-radius; border: 4px solid transparent; - z-index: 2; + z-index: $z-index-above; pointer-events: none; transition: border-color 0.2s ease; } @@ -259,7 +259,7 @@ inset: 4px; border-radius: calc($image-corner-radius - 4px); border: 4px solid transparent; - z-index: 3; + z-index: $z-index-hover; pointer-events: none; transition: border-color 0.2s ease; } @@ -320,7 +320,7 @@ font-size: 1.2rem; font-weight: 600; border-radius: $image-corner-radius; - z-index: 2; + z-index: $z-index-above; } &:hover { @@ -347,7 +347,7 @@ height: 100%; object-fit: cover; position: relative; - z-index: 1; + z-index: $z-index-base; } } diff --git a/src/lib/components/StreamStatus.svelte b/src/lib/components/StreamStatus.svelte index 3f9ca8e..c1c4b4a 100644 --- a/src/lib/components/StreamStatus.svelte +++ b/src/lib/components/StreamStatus.svelte @@ -30,7 +30,7 @@ color: white; border-radius: $unit * 2; font-size: $font-size-small; - z-index: 1000; + z-index: $z-index-overlay; animation: fadeIn 0.3s ease-out; &.connected { diff --git a/src/lib/components/ThreeColumnPhotoGrid.svelte b/src/lib/components/ThreeColumnPhotoGrid.svelte index 216d8b5..1f804fb 100644 --- a/src/lib/components/ThreeColumnPhotoGrid.svelte +++ b/src/lib/components/ThreeColumnPhotoGrid.svelte @@ -195,7 +195,7 @@ background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent); color: white; padding: $unit-2x; - z-index: 1; + z-index: $z-index-base; } .album-info { diff --git a/src/lib/components/admin/AdminNavBar.svelte b/src/lib/components/admin/AdminNavBar.svelte index 9dab8f2..1508d78 100644 --- a/src/lib/components/admin/AdminNavBar.svelte +++ b/src/lib/components/admin/AdminNavBar.svelte @@ -84,7 +84,7 @@ .admin-nav-bar { position: sticky; top: 0; - z-index: 100; + z-index: $z-index-admin-nav; width: 100%; background: $bg-color; border-bottom: 1px solid transparent; diff --git a/src/lib/components/admin/DeleteConfirmationModal.svelte b/src/lib/components/admin/DeleteConfirmationModal.svelte index 5e7d0d4..12fa9d9 100644 --- a/src/lib/components/admin/DeleteConfirmationModal.svelte +++ b/src/lib/components/admin/DeleteConfirmationModal.svelte @@ -64,7 +64,7 @@ display: flex; align-items: center; justify-content: center; - z-index: 1050; + z-index: $z-index-modal; } .modal { diff --git a/src/lib/components/admin/DropdownMenu.svelte b/src/lib/components/admin/DropdownMenu.svelte index 59ba38f..4d1db25 100644 --- a/src/lib/components/admin/DropdownMenu.svelte +++ b/src/lib/components/admin/DropdownMenu.svelte @@ -217,7 +217,7 @@ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); overflow: hidden; min-width: 180px; - z-index: 1050; + z-index: $z-index-modal; max-height: 400px; overflow-y: auto; } diff --git a/src/lib/components/admin/DropdownMenuContainer.svelte b/src/lib/components/admin/DropdownMenuContainer.svelte index ff63d57..8dbd2d1 100644 --- a/src/lib/components/admin/DropdownMenuContainer.svelte +++ b/src/lib/components/admin/DropdownMenuContainer.svelte @@ -23,6 +23,6 @@ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); overflow: hidden; min-width: 180px; - z-index: 1050; + z-index: $z-index-modal; } diff --git a/src/lib/components/admin/InlineComposerModal.svelte b/src/lib/components/admin/InlineComposerModal.svelte index 0657d80..2488254 100644 --- a/src/lib/components/admin/InlineComposerModal.svelte +++ b/src/lib/components/admin/InlineComposerModal.svelte @@ -744,7 +744,7 @@ position: absolute !important; top: $unit-2x; right: $unit-2x; - z-index: 10; + z-index: $z-index-dropdown; background-color: rgba(255, 255, 255, 0.9) !important; backdrop-filter: blur(8px); border: 1px solid $grey-80 !important; diff --git a/src/lib/components/admin/Modal.svelte b/src/lib/components/admin/Modal.svelte index 7bc8dd0..c85cb87 100644 --- a/src/lib/components/admin/Modal.svelte +++ b/src/lib/components/admin/Modal.svelte @@ -123,7 +123,7 @@ display: flex; justify-content: center; align-items: center; - z-index: 1400; + z-index: $z-index-modal-backdrop; padding: $unit-2x; } @@ -169,7 +169,7 @@ position: absolute !important; top: $unit-2x; right: $unit-2x; - z-index: 1; + z-index: $z-index-base; } .modal-content { diff --git a/src/lib/components/admin/PostDropdown.svelte b/src/lib/components/admin/PostDropdown.svelte index 1f1f31b..a3348f5 100644 --- a/src/lib/components/admin/PostDropdown.svelte +++ b/src/lib/components/admin/PostDropdown.svelte @@ -146,7 +146,7 @@ border-radius: $unit-2x; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); min-width: 140px; - z-index: 1050; + z-index: $z-index-modal; overflow: hidden; margin: 0; padding: 0; diff --git a/src/lib/components/admin/UnifiedMediaModal.svelte b/src/lib/components/admin/UnifiedMediaModal.svelte index fadd52c..7ff5ef1 100644 --- a/src/lib/components/admin/UnifiedMediaModal.svelte +++ b/src/lib/components/admin/UnifiedMediaModal.svelte @@ -569,7 +569,7 @@ gap: $unit; top: 0; background: white; - z-index: 10; + z-index: $z-index-dropdown; padding: $unit-3x $unit-3x 0 $unit-3x; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); @@ -791,7 +791,7 @@ padding: $unit-3x $unit-4x $unit-4x; border-top: 1px solid $grey-85; background: white; - z-index: 10; + z-index: $z-index-dropdown; box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05); }