diff --git a/bun.lock b/bun.lock index 60bacb7..fad3302 100644 --- a/bun.lock +++ b/bun.lock @@ -24,9 +24,13 @@ "name": "panel", "version": "0.1.0", "dependencies": { + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.564.0", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-router-dom": "^7.6.1", + "tailwind-merge": "^3.4.0", + "tailwindcss-animate": "^1.0.7", }, "devDependencies": { "@tailwindcss/vite": "^4.1.10", @@ -34,7 +38,6 @@ "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^4.6.0", "autoprefixer": "^10.4.21", - "daisyui": "^5.0.43", "postcss": "^8.5.6", "tailwindcss": "^4.1.10", "typescript": "^5.9.3", @@ -309,14 +312,14 @@ "caniuse-lite": ["caniuse-lite@1.0.30001769", "", {}, "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg=="], + "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - "daisyui": ["daisyui@5.5.18", "", {}, "sha512-VVzjpOitMGB6DWIBeRSapbjdOevFqyzpk9u5Um6a4tyId3JFrU5pbtF0vgjXDth76mJZbueN/j9Ok03SPrh/og=="], - "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], @@ -393,6 +396,8 @@ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + "lucide-react": ["lucide-react@0.564.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-JJ8GVTQqFwuliifD48U6+h7DXEHdkhJ/E87kksGByII3qHxtPciVb8T8woQONHBQgHVOl7rSMrrip3SeVNy7Fg=="], + "magic-bytes.js": ["magic-bytes.js@1.12.1", "", {}, "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -421,10 +426,6 @@ "react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="], - "react-router": ["react-router@7.13.0", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw=="], - - "react-router-dom": ["react-router-dom@7.13.0", "", { "dependencies": { "react-router": "7.13.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g=="], - "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="], @@ -433,16 +434,18 @@ "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], - "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + "tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="], + "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="], + "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="], + "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], diff --git a/docs/aurora-admin-design-guidelines.md b/docs/aurora-admin-design-guidelines.md new file mode 100644 index 0000000..01a23b0 --- /dev/null +++ b/docs/aurora-admin-design-guidelines.md @@ -0,0 +1,769 @@ +# Aurora Admin Panel - Design Guidelines + +## Design Philosophy + +The Aurora Admin Panel embodies the intersection of celestial mystique and institutional precision. It is a command center for academy administration—powerful, sophisticated, and unmistakably authoritative. Every interface element should communicate control, clarity, and prestige. + +**Core Principles:** +- **Authority over Friendliness**: This is an administrative tool, not a consumer app +- **Data Clarity**: Information density balanced with elegant presentation +- **Celestial Aesthetic**: Subtle cosmic theming that doesn't compromise functionality +- **Institutional Grade**: Professional, trustworthy, built to manage complex systems + +--- + +## Visual Foundation + +### Color System + +**Background Hierarchy** +``` +Level 0 (Base) #0A0A0F Eclipse Void - Deepest background +Level 1 (Container) #151520 Midnight Canvas - Cards, panels, modals +Level 2 (Surface) #1E1B4B Nebula Surface - Elevated elements +Level 3 (Raised) #2D2A5F Stellar Overlay - Hover states, dropdowns +``` + +**Text Hierarchy** +``` +Primary Text #F9FAFB Starlight White - Headings, key data +Secondary Text #E5E7EB Stardust Silver - Body text, labels +Tertiary Text #9CA3AF Cosmic Gray - Helper text, timestamps +Disabled Text #6B7280 Void Gray - Inactive elements +``` + +**Brand Accents** +``` +Primary (Action) #8B5CF6 Aurora Purple - Primary buttons, links, active states +Secondary (Info) #3B82F6 Nebula Blue - Informational elements +Success #10B981 Emerald - Confirmations, positive indicators +Warning #F59E0B Amber - Cautions, alerts +Danger #DC2626 Crimson - Errors, destructive actions +Gold (Prestige) #FCD34D Celestial Gold - Premium features, highlights +``` + +**Constellation Tier Colors** (for data visualization) +``` +Constellation A #FCD34D Celestial Gold +Constellation B #8B5CF6 Aurora Purple +Constellation C #3B82F6 Nebula Blue +Constellation D #6B7280 Slate Gray +``` + +**Semantic Colors** +``` +Currency (AU) #FCD34D Gold - Astral Units indicators +Currency (CU) #8B5CF6 Purple - Constellation Units indicators +XP/Progress #3B82F6 Blue - Experience and progression +Activity #10B981 Green - Active users, live events +``` + +### Typography + +**Font Stack** + +Primary (UI Text): +```css +font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; +``` +- Clean, highly legible, modern +- Excellent at small sizes for data-dense interfaces +- Professional without being sterile + +Display (Headings): +```css +font-family: 'Space Grotesk', 'Inter', sans-serif; +``` +- Geometric, slightly futuristic +- Use for page titles, section headers +- Reinforces celestial/institutional theme + +Monospace (Data): +```css +font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; +``` +- For numerical data, timestamps, IDs +- Improves scanability of tabular data +- Technical credibility + +**Type Scale** +``` +Display Large 48px / 3rem font-weight: 700 (Dashboard headers) +Display 36px / 2.25rem font-weight: 700 (Page titles) +Heading 1 30px / 1.875rem font-weight: 600 (Section titles) +Heading 2 24px / 1.5rem font-weight: 600 (Card headers) +Heading 3 20px / 1.25rem font-weight: 600 (Subsections) +Body Large 16px / 1rem font-weight: 400 (Emphasized body) +Body 14px / 0.875rem font-weight: 400 (Default text) +Body Small 13px / 0.8125rem font-weight: 400 (Secondary info) +Caption 12px / 0.75rem font-weight: 400 (Labels, hints) +Overline 11px / 0.6875rem font-weight: 600 (Uppercase labels) +``` + +**Font Weight Usage** +- **700 (Bold)**: Display text, critical metrics +- **600 (Semibold)**: Headings, emphasized data +- **500 (Medium)**: Buttons, active tabs, selected items +- **400 (Regular)**: Body text, form inputs +- **Never use weights below 400** - maintain readability + +### Spacing & Layout + +**Base Unit**: 4px + +**Spacing Scale** +``` +xs 4px 0.25rem Tight spacing, icon gaps +sm 8px 0.5rem Form element spacing +md 16px 1rem Default component spacing +lg 24px 1.5rem Section spacing +xl 32px 2rem Major section breaks +2xl 48px 3rem Page section dividers +3xl 64px 4rem Major layout divisions +``` + +**Container Widths** +``` +Full Bleed 100% Full viewport width +Wide 1600px Wide dashboards, data tables +Standard 1280px Default content width +Narrow 960px Forms, focused content +Reading 720px Long-form text (documentation) +``` + +**Grid System** +- 12-column grid for flexible layouts +- 24px gutters between columns +- Responsive breakpoints: 640px, 768px, 1024px, 1280px, 1536px + +### Borders & Dividers + +**Border Widths** +``` +Hairline 0.5px Subtle dividers +Thin 1px Default borders +Medium 2px Emphasized borders, focus states +Thick 4px Accent bars, category indicators +``` + +**Border Colors** +``` +Default #2D2A5F 15% opacity - Standard dividers +Subtle #2D2A5F 8% opacity - Very light separation +Emphasized #8B5CF6 30% opacity - Highlighted borders +Interactive #8B5CF6 60% opacity - Hover/focus states +``` + +**Border Radius** +``` +None 0px Data tables, strict layouts +sm 4px Buttons, badges, pills +md 8px Cards, inputs, panels +lg 12px Large cards, modals +xl 16px Feature cards, images +2xl 24px Hero elements +full 9999px Circular elements, avatars +``` + +--- + +## UI Patterns + +### Cards & Containers + +**Standard Card** +``` +Background: #151520 (Midnight Canvas) +Border: 1px solid rgba(139, 92, 246, 0.15) +Border Radius: 8px +Padding: 24px +Shadow: 0 4px 16px rgba(0, 0, 0, 0.4) +``` + +**Elevated Card** (hover/focus) +``` +Background: #1E1B4B (Nebula Surface) +Border: 1px solid rgba(139, 92, 246, 0.3) +Shadow: 0 8px 24px rgba(0, 0, 0, 0.6) +Transform: translateY(-2px) +Transition: all 200ms ease +``` + +**Stat Card** (metrics, KPIs) +``` +Background: Linear gradient from #151520 to #1E1B4B +Border: 1px solid rgba(139, 92, 246, 0.2) +Accent Border: 4px left border in tier/category color +Icon: Celestial icon in accent color +Typography: Large number (Display), small label (Overline) +``` + +### Data Tables + +**Table Structure** +``` +Header Background: #1E1B4B +Header Text: #E5E7EB, 11px uppercase, 600 weight +Row Background: Alternating #0A0A0F / #151520 +Row Hover: #2D2A5F with 40% opacity +Border: 1px solid rgba(139, 92, 246, 0.1) between rows +Cell Padding: 12px 16px +``` + +**Column Styling** +- Left-align text columns +- Right-align numerical columns +- Monospace font for numbers, IDs, timestamps +- Icon + text combinations for status indicators + +**Interactive Elements** +- Sortable headers with subtle arrow icons +- Hover state on entire row +- Click/select highlight with Aurora Purple tint +- Pagination in Nebula Blue + +### Forms & Inputs + +**Input Fields** +``` +Background: #1E1B4B +Border: 1px solid rgba(139, 92, 246, 0.2) +Border Radius: 6px +Padding: 10px 14px +Font Size: 14px +Text Color: #F9FAFB + +Focus State: + Border: 2px solid #8B5CF6 + Glow: 0 0 0 3px rgba(139, 92, 246, 0.2) + +Error State: + Border: 1px solid #DC2626 + Text: #DC2626 helper text below + +Disabled State: + Background: #0A0A0F + Text: #6B7280 + Cursor: not-allowed +``` + +**Labels** +``` +Font Size: 12px +Font Weight: 600 +Text Color: #E5E7EB +Margin Bottom: 6px +``` + +**Select Dropdowns** +``` +Same base styling as inputs +Dropdown Icon: Chevron in #9CA3AF +Menu Background: #2D2A5F +Menu Border: 1px solid rgba(139, 92, 246, 0.3) +Option Hover: #3B82F6 background +Selected: #8B5CF6 with checkmark icon +``` + +**Checkboxes & Radio Buttons** +``` +Size: 18px × 18px +Border: 2px solid rgba(139, 92, 246, 0.4) +Border Radius: 4px (checkbox) / 50% (radio) +Checked: #8B5CF6 background with white checkmark +Hover: Glow effect rgba(139, 92, 246, 0.2) +``` + +### Buttons + +**Primary Button** +``` +Background: #8B5CF6 (Aurora Purple) +Text: #FFFFFF +Padding: 10px 20px +Border Radius: 6px +Font Weight: 500 +Shadow: 0 2px 8px rgba(139, 92, 246, 0.3) + +Hover: + Background: #7C3AED (lighter purple) + Shadow: 0 4px 12px rgba(139, 92, 246, 0.4) + +Active: + Background: #6D28D9 (darker purple) + Transform: scale(0.98) +``` + +**Secondary Button** +``` +Background: transparent +Border: 1px solid rgba(139, 92, 246, 0.5) +Text: #8B5CF6 +Padding: 10px 20px + +Hover: + Background: rgba(139, 92, 246, 0.1) + Border: 1px solid #8B5CF6 +``` + +**Destructive Button** +``` +Background: #DC2626 +Text: #FFFFFF +(Same structure as Primary) +``` + +**Ghost Button** +``` +Background: transparent +Text: #E5E7EB +Padding: 8px 16px + +Hover: + Background: rgba(139, 92, 246, 0.1) + Text: #8B5CF6 +``` + +**Button Sizes** +``` +Small 8px 12px 12px text +Medium 10px 20px 14px text (default) +Large 12px 24px 16px text +``` + +### Navigation + +**Sidebar Navigation** +``` +Background: #0A0A0F with subtle gradient +Width: 260px (expanded) / 64px (collapsed) +Border Right: 1px solid rgba(139, 92, 246, 0.15) + +Nav Item: + Padding: 12px 16px + Border Radius: 6px + Font Size: 14px + Font Weight: 500 + Icon Size: 20px + Gap: 12px between icon and text + +Active State: + Background: rgba(139, 92, 246, 0.15) + Border Left: 4px solid #8B5CF6 + Text: #8B5CF6 + Icon: #8B5CF6 + +Hover State: + Background: rgba(139, 92, 246, 0.08) + Text: #F9FAFB +``` + +**Top Bar / Header** +``` +Background: #0A0A0F with backdrop blur +Height: 64px +Border Bottom: 1px solid rgba(139, 92, 246, 0.15) +Position: Sticky +Z-index: 100 + +Contains: + - Logo / Academy name + - Global search + - Quick actions + - User profile dropdown + - Notification bell +``` + +**Breadcrumbs** +``` +Font Size: 13px +Text Color: #9CA3AF +Separator: "/" or "›" in #6B7280 +Current Page: #F9FAFB, 600 weight +Links: #9CA3AF, hover to #8B5CF6 +``` + +### Modals & Overlays + +**Modal Structure** +``` +Backdrop: rgba(0, 0, 0, 0.8) with backdrop blur +Modal Container: #151520 +Border: 1px solid rgba(139, 92, 246, 0.2) +Border Radius: 12px +Shadow: 0 24px 48px rgba(0, 0, 0, 0.9) +Max Width: 600px (standard) / 900px (wide) +Padding: 32px + +Header: + Border Bottom: 1px solid rgba(139, 92, 246, 0.15) + Padding: 0 0 20px 0 + Font Size: 24px + Font Weight: 600 + +Footer: + Border Top: 1px solid rgba(139, 92, 246, 0.15) + Padding: 20px 0 0 0 + Buttons: Right-aligned, 12px gap +``` + +**Toast Notifications** +``` +Position: Top-right, 24px margin +Background: #2D2A5F +Border: 1px solid (color based on type) +Border Radius: 8px +Padding: 16px 20px +Max Width: 400px +Shadow: 0 8px 24px rgba(0, 0, 0, 0.6) + +Success: #10B981 border, green icon +Warning: #F59E0B border, amber icon +Error: #DC2626 border, red icon +Info: #3B82F6 border, blue icon + +Animation: Slide in from right, fade out +Duration: 4 seconds (dismissible) +``` + +### Data Visualization + +**Charts & Graphs** +``` +Background: #151520 or transparent +Grid Lines: rgba(139, 92, 246, 0.1) +Axis Labels: #9CA3AF, 12px +Data Points: Constellation tier colors or semantic colors +Tooltips: #2D2A5F background, white text +Legend: Horizontal, 12px, icons + labels +``` + +**Progress Bars** +``` +Track: #1E1B4B +Fill: Linear gradient with tier/category color +Height: 8px (thin) / 12px (medium) / 16px (thick) +Border Radius: 9999px +Label: Above or inline, monospace numbers +``` + +**Badges & Pills** +``` +Background: Semantic color with 15% opacity +Text: Semantic color (full saturation) +Border: 1px solid semantic color with 30% opacity +Padding: 4px 10px +Border Radius: 9999px +Font Size: 12px +Font Weight: 500 + +Status Examples: + Active: Green + Pending: Amber + Inactive: Gray + Error: Red + Premium: Gold +``` + +### Icons + +**Icon System** +- Use consistent icon family (e.g., Lucide, Heroicons, Phosphor) +- Line-style icons, not filled (except for active states) +- Stroke width: 1.5px-2px +- Sizes: 16px (small), 20px (default), 24px (large), 32px (extra large) + +**Icon Colors** +- Default: #9CA3AF (Cosmic Gray) +- Active/Selected: #8B5CF6 (Aurora Purple) +- Success: #10B981 +- Warning: #F59E0B +- Error: #DC2626 + +**Celestial Icon Themes** +- Stars, constellations, orbits for branding +- Minimalist, geometric line art +- Avoid overly detailed or realistic astronomy images + +--- + +## Animation & Motion + +### Principles +- **Purposeful**: Animations guide attention and provide feedback +- **Subtle**: No distracting or excessive motion +- **Fast**: Snappy interactions (150-300ms) +- **Professional**: Ease curves that feel polished + +### Timing Functions +``` +ease-out Default for most interactions +ease-in-out Modal/panel transitions +ease-in Exit animations +spring Micro-interactions (subtle bounce) +``` + +### Standard Durations +``` +Instant 0ms State changes +Fast 150ms Button hover, color changes +Standard 200ms Card hover, dropdown open +Moderate 300ms Modal open, page transitions +Slow 500ms Large panel animations +``` + +### Common Animations + +**Hover Effects** +```css +transition: all 200ms ease-out; +transform: translateY(-2px); +box-shadow: [enhanced shadow]; +``` + +**Focus States** +```css +transition: border 150ms ease-out, box-shadow 150ms ease-out; +border-color: #8B5CF6; +box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2); +``` + +**Loading States** +``` +Skeleton: Shimmer effect from left to right +Spinner: Rotating celestial icon or ring +Progress: Smooth bar fill with easing +``` + +**Page Transitions** +``` +Fade in: Opacity 0 → 1 over 200ms +Slide up: TranslateY(20px) → 0 over 300ms +Blur fade: Blur + opacity for backdrop +``` + +--- + +## Responsive Behavior + +### Breakpoints +``` +Mobile < 640px +Tablet 640px - 1024px +Desktop > 1024px +Wide Desktop > 1536px +``` + +### Mobile Adaptations +- Sidebar collapses to hamburger menu +- Cards stack vertically +- Tables become horizontally scrollable or convert to card view +- Reduce padding and spacing by 25-50% +- Larger touch targets (minimum 44px) +- Bottom navigation for primary actions + +### Tablet Optimizations +- Hybrid layouts (sidebar can be toggled) +- Adaptive grid (4 columns → 2 columns) +- Touch-friendly sizing maintained +- Utilize available space efficiently + +--- + +## Accessibility + +### Color Contrast +- Maintain WCAG AA standards minimum (4.5:1 for normal text) +- Critical actions and text meet AAA standards (7:1) +- Never rely on color alone for information + +### Focus Indicators +- Always visible focus states +- 2px Aurora Purple outline with 3px glow +- Logical tab order follows visual hierarchy + +### Screen Readers +- Semantic HTML structure +- ARIA labels for icon-only buttons +- Status messages announced appropriately +- Table headers properly associated + +### Keyboard Navigation +- All interactive elements accessible via keyboard +- Modal traps focus within itself +- Escape key closes overlays +- Arrow keys for navigation where appropriate + +--- + +## Dark Mode Philosophy + +**Aurora Admin is dark-first by design.** The interface assumes a dark environment and doesn't offer a light mode toggle. This decision is intentional: + +- **Focus**: Dark reduces eye strain during extended admin sessions +- **Data Emphasis**: Light text on dark makes numbers/data more prominent +- **Celestial Theme**: Dark backgrounds reinforce the cosmic aesthetic +- **Professional**: Dark UIs feel more serious and technical + +If light mode is ever required, avoid pure white—use off-white (#F9FAFB) backgrounds with careful contrast management. + +--- + +## Theming & Customization + +### Constellation Tier Theming +When displaying constellation-specific data: +- Use tier colors for accents, not backgrounds +- Apply colors to borders, icons, badges +- Maintain readability—don't overwhelm with color + +### Admin Privilege Levels +Different admin roles can have subtle UI indicators: +- Super Admin: Gold accents +- Moderator: Purple accents +- Viewer: Blue accents + +These are subtle hints, not dominant visual themes. + +--- + +## Component Library Standards + +### Consistency +- Reuse components extensively +- Maintain consistent spacing, sizing, behavior +- Document component variants clearly +- Avoid one-off custom elements + +### Composability +- Build complex UIs from simple components +- Components should work together seamlessly +- Predictable prop APIs +- Flexible but not overly configurable + +### Performance +- Lazy load heavy components +- Virtualize long lists +- Optimize re-renders +- Compress and cache assets + +--- + +## Code Style (UI Framework Agnostic) + +### Class Naming +Use clear, semantic names: +``` +.card-stat Not .cs or .c1 +.button-primary Not .btn-p or .bp +.table-header Not .th or .t-h +``` + +### Component Organization +``` +/components + /ui Base components (buttons, inputs) + /layout Layout components (sidebar, header) + /data Data components (tables, charts) + /feedback Toasts, modals, alerts + /forms Form-specific components +``` + +### Style Organization +- Variables/tokens for all design values +- No magic numbers in components +- DRY—reuse common styles +- Mobile-first responsive approach + +--- + +## Best Practices + +### Do's ✓ +- Use established patterns from these guidelines +- Maintain consistent spacing throughout +- Prioritize data clarity and scannability +- Test with real data, not lorem ipsum +- Consider loading and empty states +- Provide clear feedback for all actions +- Use progressive disclosure for complex features + +### Don'ts ✗ +- Don't use bright, saturated colors outside defined palette +- Don't create custom components when standard ones exist +- Don't sacrifice accessibility for aesthetics +- Don't use decorative animations that distract +- Don't hide critical actions in nested menus +- Don't use tiny fonts (below 12px) for functional text +- Don't ignore error states and edge cases + +--- + +## Quality Checklist + +Before considering any UI complete: + +**Visual** +- [ ] Colors match defined palette exactly +- [ ] Spacing uses the 4px grid system +- [ ] Typography follows scale and hierarchy +- [ ] Borders and shadows are consistent +- [ ] Icons are properly sized and aligned + +**Interaction** +- [ ] Hover states are defined for all interactive elements +- [ ] Focus states are visible and clear +- [ ] Loading states prevent user confusion +- [ ] Success/error feedback is immediate +- [ ] Animations are smooth and purposeful + +**Responsive** +- [ ] Layout adapts to mobile, tablet, desktop +- [ ] Touch targets are minimum 44px on mobile +- [ ] Text remains readable at all sizes +- [ ] No horizontal scrolling (except intentional) + +**Accessibility** +- [ ] Keyboard navigation works completely +- [ ] Focus indicators are always visible +- [ ] Color contrast meets WCAG AA minimum +- [ ] ARIA labels present where needed +- [ ] Screen reader tested for critical flows + +**Data** +- [ ] Empty states are handled gracefully +- [ ] Error states provide actionable guidance +- [ ] Large datasets perform well +- [ ] Loading states prevent layout shift + +--- + +## Reference Assets + +### Suggested Icon Library +- **Lucide Icons**: Clean, consistent, extensive +- **Heroicons**: Tailwind-friendly, well-designed +- **Phosphor Icons**: Flexible weights and styles + +### Font Resources +- **Inter**: [Google Fonts](https://fonts.google.com/specimen/Inter) +- **Space Grotesk**: [Google Fonts](https://fonts.google.com/specimen/Space+Grotesk) +- **JetBrains Mono**: [JetBrains](https://www.jetbrains.com/lp/mono/) + +### Design Tools +- Use component libraries: shadcn/ui, Headless UI, Radix +- Tailwind CSS for utility-first styling +- CSS variables for theming +- Design tokens for consistency + +--- + +## Conclusion + +The Aurora Admin Panel is a sophisticated tool that demands respect through its design. Every pixel serves a purpose—whether to inform, to guide, or to reinforce the prestige of the academy it administers. + +**Design with authority. Build with precision. Maintain the standard.** + +--- + +*These design guidelines are living documentation. As Aurora evolves, so too should these standards. Propose updates through the standard development workflow.* diff --git a/panel/package.json b/panel/package.json index d27b825..f0e38c0 100644 --- a/panel/package.json +++ b/panel/package.json @@ -9,19 +9,22 @@ "preview": "vite preview" }, "dependencies": { + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.564.0", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-router-dom": "^7.6.1" + "tailwind-merge": "^3.4.0", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { + "@tailwindcss/vite": "^4.1.10", "@types/react": "^19.1.6", "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^4.6.0", "autoprefixer": "^10.4.21", - "daisyui": "^5.0.43", "postcss": "^8.5.6", "tailwindcss": "^4.1.10", - "@tailwindcss/vite": "^4.1.10", "typescript": "^5.9.3", "vite": "^6.3.5" } diff --git a/panel/src/App.tsx b/panel/src/App.tsx index deea84c..376fa7c 100644 --- a/panel/src/App.tsx +++ b/panel/src/App.tsx @@ -1,53 +1,82 @@ -import { Routes, Route } from "react-router-dom"; +import { useState } from "react"; import { useAuth } from "./lib/useAuth"; -import Layout from "./components/Layout"; +import { Loader2 } from "lucide-react"; +import Layout, { type Page } from "./components/Layout"; import Dashboard from "./pages/Dashboard"; -import Items from "./pages/Items"; -import Quests from "./pages/Quests"; -import Classes from "./pages/Classes"; -import Users from "./pages/Users"; -import Settings from "./pages/Settings"; -import Lootdrops from "./pages/Lootdrops"; +import PlaceholderPage from "./pages/PlaceholderPage"; + +const placeholders: Record = { + users: { + title: "Users", + description: "Search, view, and manage user accounts, balances, XP, levels, and inventories.", + }, + items: { + title: "Items", + description: "Create, edit, and manage game items with icons, rarities, and pricing.", + }, + classes: { + title: "Classes", + description: "Manage academy classes, assign Discord roles, and track class balances.", + }, + quests: { + title: "Quests", + description: "Configure quests with trigger events, targets, and XP/balance rewards.", + }, + lootdrops: { + title: "Lootdrops", + description: "View active lootdrops, spawn new drops, and manage lootdrop history.", + }, + moderation: { + title: "Moderation", + description: "Review moderation cases — warnings, timeouts, kicks, bans — and manage appeals.", + }, + transactions: { + title: "Transactions", + description: "Browse the economy transaction log with filtering by user, type, and date.", + }, + settings: { + title: "Settings", + description: "Configure bot settings for economy, leveling, commands, and guild preferences.", + }, +}; export default function App() { const { loading, user, logout } = useAuth(); + const [page, setPage] = useState("dashboard"); if (loading) { return ( -
- +
+
); } if (!user) { return ( -
-
-

Aurora Admin Panel

-

Sign in with Discord to continue.

- - - - + ); } return ( - - }> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - + + {page === "dashboard" ? ( + + ) : ( + + )} + ); } diff --git a/panel/src/components/DataTable.tsx b/panel/src/components/DataTable.tsx deleted file mode 100644 index 912f983..0000000 --- a/panel/src/components/DataTable.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import type { ReactNode } from "react"; - -export interface Column { - key: string; - header: string; - render?: (row: T) => ReactNode; - className?: string; -} - -interface DataTableProps { - columns: Column[]; - data: T[]; - keyField: string; - loading?: boolean; - onRowClick?: (row: T) => void; - emptyMessage?: string; -} - -export default function DataTable>({ - columns, - data, - keyField, - loading, - onRowClick, - emptyMessage = "No data found", -}: DataTableProps) { - if (loading) { - return ( -
- -
- ); - } - - return ( -
- - - - {columns.map((col) => ( - - ))} - - - - {data.length === 0 ? ( - - - - ) : ( - data.map((row) => ( - onRowClick?.(row)} - > - {columns.map((col) => ( - - ))} - - )) - )} - -
- {col.header} -
- {emptyMessage} -
- {col.render ? col.render(row) : String(row[col.key] ?? "")} -
-
- ); -} diff --git a/panel/src/components/Layout.tsx b/panel/src/components/Layout.tsx index 2ed095e..2aeeae0 100644 --- a/panel/src/components/Layout.tsx +++ b/panel/src/components/Layout.tsx @@ -1,91 +1,139 @@ -import { NavLink, Outlet } from "react-router-dom"; +import { + LayoutDashboard, + Users, + Package, + Shield, + Scroll, + Gift, + ArrowLeftRight, + GraduationCap, + Settings, + LogOut, + ChevronLeft, + ChevronRight, +} from "lucide-react"; +import { useState } from "react"; +import { cn } from "../lib/utils"; import type { AuthUser } from "../lib/useAuth"; -const NAV_ITEMS = [ - { to: "/", label: "Dashboard", icon: "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1" }, - { to: "/items", label: "Items", icon: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }, - { to: "/quests", label: "Quests", icon: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }, - { to: "/classes", label: "Classes", icon: "M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" }, - { to: "/users", label: "Users", icon: "M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" }, - { to: "/settings", label: "Settings", icon: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z M15 12a3 3 0 11-6 0 3 3 0 016 0z" }, - { to: "/lootdrops", label: "Lootdrops", icon: "M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" }, -]; +export type Page = + | "dashboard" + | "users" + | "items" + | "classes" + | "quests" + | "lootdrops" + | "moderation" + | "transactions" + | "settings"; -function avatarUrl(user: AuthUser): string { - if (user.avatar) { - return `https://cdn.discordapp.com/avatars/${user.discordId}/${user.avatar}.png?size=64`; - } - const index = (BigInt(user.discordId) >> 22n) % 6n; - return `https://cdn.discordapp.com/embed/avatars/${index}.png`; -} +const navItems: { page: Page; label: string; icon: React.ComponentType<{ className?: string }> }[] = [ + { page: "dashboard", label: "Dashboard", icon: LayoutDashboard }, + { page: "users", label: "Users", icon: Users }, + { page: "items", label: "Items", icon: Package }, + { page: "classes", label: "Classes", icon: GraduationCap }, + { page: "quests", label: "Quests", icon: Scroll }, + { page: "lootdrops", label: "Lootdrops", icon: Gift }, + { page: "moderation", label: "Moderation", icon: Shield }, + { page: "transactions", label: "Transactions", icon: ArrowLeftRight }, + { page: "settings", label: "Settings", icon: Settings }, +]; export default function Layout({ user, - onLogout, + logout, + currentPage, + onNavigate, + children, }: { user: AuthUser; - onLogout: () => void; + logout: () => Promise; + currentPage: Page; + onNavigate: (page: Page) => void; + children: React.ReactNode; }) { + const [collapsed, setCollapsed] = useState(false); + + const avatarUrl = user.avatar + ? `https://cdn.discordapp.com/avatars/${user.discordId}/${user.avatar}.png?size=64` + : null; + return ( -
+
{/* Sidebar */} -