diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 5669267..43b7f43 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,4 +1,4 @@ -import { BrowserRouter, Routes, Route } from 'react-router-dom'; +import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom'; import { LanguageProvider } from './context/LanguageContext'; import { AuthProvider, useAuth } from "./auth/AuthProvider"; import ScrollToTop from './components/ScrollToTop'; @@ -15,21 +15,24 @@ import Me from "./pages/profile/Me"; import Settings from "./pages/profile/Settings"; import Products from "./pages/profile/Products"; import ProtectedRoute from "./auth/ProtectedRoute"; -import AccountLayout from "./pages/profile/AccountLayout"; +import DashboardLayout from "./pages/profile/DashboardLayout"; import VerifyEmail from "./pages/VerifyEmail"; import ResetPassword from "./pages/ResetPassword"; import UserProfile from "./pages/user/UserProfile"; import GitHubCallback from "./pages/GitHubCallback"; import Services from "./pages/services"; -function AppContent() { +function AppShell() { const { user } = useAuth(); + const location = useLocation(); + const showNavbar = !location.pathname.startsWith('/me'); + const showFooter = !location.pathname.startsWith('/me'); return ( - + <>
- + {showNavbar ? : null} } /> @@ -47,21 +50,34 @@ function AppContent() { path="/me" element={ - + } > } /> } /> } /> + } /> + } /> + } /> + } /> + } /> } /> } /> } /> -
+ {showFooter ?
: null}
+ + ); +} + +function AppContent() { + return ( + + ); } diff --git a/frontend/src/components/icons/svgs.jsx b/frontend/src/components/icons/svgs.jsx index 509f2b2..3ab56ea 100644 --- a/frontend/src/components/icons/svgs.jsx +++ b/frontend/src/components/icons/svgs.jsx @@ -6,6 +6,8 @@ import { RepoForkedIcon, StarIcon, TrophyIcon, + CreditCardIcon, + PackageIcon } from "@primer/octicons-react"; const ICON_SIZE = 16; @@ -62,6 +64,8 @@ export const SvgProfile = () => ; export const SvgProducts = () => ; export const SvgBadges = () => ; +export const SvgBilling = () => ; +export const SvgOrders = () => ; function ServiceSvg({ children, size = 24, ...props }) { return ( diff --git a/frontend/src/i18n/de.json b/frontend/src/i18n/de.json index 6a2062e..2bc438b 100644 --- a/frontend/src/i18n/de.json +++ b/frontend/src/i18n/de.json @@ -304,7 +304,6 @@ "account.me.avatar_error.no_file": "Bitte wähle eine Datei aus.", "account.me.avatar_error.upload_failed": "Avatar konnte nicht hochgeladen werden.", "account.me.bio_label": "Bio", - "account.me.bio_placeholder": "Erzähl kurz etwas über dich…", "account.me.location_label": "Standort", "account.me.save_profile": "Speichern", "account.me.saving_profile": "Speichern", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 2cb5dd9..e352b24 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -304,7 +304,6 @@ "account.me.avatar_error.no_file": "Please select a file.", "account.me.avatar_error.upload_failed": "Could not upload the avatar.", "account.me.bio_label": "Bio", - "account.me.bio_placeholder": "Tell people a little about yourself…", "account.me.location_label": "Location", "account.me.save_profile": "Save", "account.me.saving_profile": "Saving…", diff --git a/frontend/src/pages/profile/AccountLayout.jsx b/frontend/src/pages/profile/AccountLayout.jsx index cbed53e..d7c469c 100644 --- a/frontend/src/pages/profile/AccountLayout.jsx +++ b/frontend/src/pages/profile/AccountLayout.jsx @@ -1,18 +1,12 @@ -import { useState } from "react"; import { Outlet } from "react-router-dom"; -import Sidebar from "./Sidebar"; import "../../styles/Me.css"; export default function AccountLayout() { - const [open, setOpen] = useState(true); - return ( -
- setOpen(prev => !prev)} /> - -
+
+
-
+
); } diff --git a/frontend/src/pages/profile/DashboardLayout.jsx b/frontend/src/pages/profile/DashboardLayout.jsx new file mode 100644 index 0000000..e4e5d6a --- /dev/null +++ b/frontend/src/pages/profile/DashboardLayout.jsx @@ -0,0 +1,36 @@ +import { useEffect, useState } from "react"; +import { Outlet, useLocation } from "react-router-dom"; +import Sidebar from "./Sidebar"; +import "../../styles/Me.css"; + +export default function DashboardLayout() { + const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); + const location = useLocation(); + + useEffect(() => { + setMobileSidebarOpen(false); + }, [location.pathname]); + + return ( +
+ setMobileSidebarOpen(false)} /> + +
+ + +
+ +
+
+
+ ); +} diff --git a/frontend/src/pages/profile/Me.jsx b/frontend/src/pages/profile/Me.jsx index f7bb55e..51cc7ac 100644 --- a/frontend/src/pages/profile/Me.jsx +++ b/frontend/src/pages/profile/Me.jsx @@ -349,13 +349,15 @@ const Me = () => { if (!user) return
{t("account.loading")}
; return ( -
-
+
+
+

{t("account.me.profile_details")}

+
- {profileError ?

{profileError}

: null} - {profileSuccess ?

{profileSuccess}

: null} + {profileError ?

{profileError}

: null} + {profileSuccess ?

{profileSuccess}

: null} -
+
{
-
- {activeBadge ? (
setActiveBadge(null)}>
{
) : null} -
+ ); }; diff --git a/frontend/src/pages/profile/Products.jsx b/frontend/src/pages/profile/Products.jsx index 8b178c0..ed799b9 100644 --- a/frontend/src/pages/profile/Products.jsx +++ b/frontend/src/pages/profile/Products.jsx @@ -12,22 +12,22 @@ const Projects = () => { ]; return ( -
-
- -
- - {projects.map((p, i) => ( -
-

{p.name}

-

{p.desc}

-
- ))} - -
- -
-
+
+
+

{t("account.products.title")}

+

{t("account.products.title")}

+

{t("account.products.subtitle")}

+
+ +
+ {projects.map((p, i) => ( +
+

{p.name}

+

{p.desc}

+
+ ))} +
+
); }; diff --git a/frontend/src/pages/profile/Settings.jsx b/frontend/src/pages/profile/Settings.jsx index ea327c0..f7a8c10 100644 --- a/frontend/src/pages/profile/Settings.jsx +++ b/frontend/src/pages/profile/Settings.jsx @@ -510,11 +510,12 @@ const Settings = () => { if (loading || !user) return
{t("account.loading")}
; return ( -
-
-
-

{t("account.settings.title")}

-

{t("account.settings.subtitle")}

+
+
+

{t("account.settings.title")}

+
+ +
{error ?

{error}

: null} @@ -749,8 +750,7 @@ const Settings = () => {
) : null} -
-
+ ); }; diff --git a/frontend/src/pages/profile/Sidebar.jsx b/frontend/src/pages/profile/Sidebar.jsx index 8e5508a..8253f13 100644 --- a/frontend/src/pages/profile/Sidebar.jsx +++ b/frontend/src/pages/profile/Sidebar.jsx @@ -1,46 +1,92 @@ import React from "react"; import { useLocation, useNavigate } from "react-router-dom"; -import { SvgProfile, SvgSettings, SvgProducts } from "../../components/icons/svgs"; +import { + SvgProfile, + SvgSettings, + SvgProducts, + SvgBadges, + SvgBilling, + SvgOrders +} from "../../components/icons/svgs"; import { useLanguage } from "../../context/LanguageContext"; -import "../../styles/Me.css" +import { useAuth } from "../../auth/AuthProvider"; +import "../../styles/Me.css"; -const Sidebar = ({ open, toggle }) => { +const Sidebar = ({ open, onClose }) => { const navigate = useNavigate(); const location = useLocation(); const { t } = useLanguage(); + const { user, clearAuth } = useAuth(); const items = [ - { label: t("account.sidebar.profile"), path: "/me", icon: SvgProfile }, - { label: t("account.sidebar.products"), path: "/me/products", icon: SvgProducts }, - { label: t("account.sidebar.settings"), path: "/me/settings", icon: SvgSettings } + { label: "Mein Profil", path: "/me", icon: SvgProfile }, + { label: "Produkte", path: "/me/products", icon: SvgProducts }, + { label: "Billing", path: "/me/billing", icon: SvgBilling }, + { label: "Bestellungen", path: "/me/orders", icon: SvgOrders }, + { label: "Einstellungen", path: "/me/settings", icon: SvgSettings }, ]; + const logout = async () => { + clearAuth(); + navigate("/login"); + }; + return ( - + ); }; diff --git a/frontend/src/styles/Me.css b/frontend/src/styles/Me.css index 2f018b3..2aa7953 100644 --- a/frontend/src/styles/Me.css +++ b/frontend/src/styles/Me.css @@ -1,116 +1,288 @@ -.me-layout { +.dashboard-layout { + display: grid; + grid-template-columns: 280px minmax(0, 1fr); + min-height: 100dvh; + background: var(--bg); +} + +.dashboard-sidebar { + position: sticky; + top: 0; display: flex; - width: 100%; - min-height: calc(100vh - 58px); - margin-top: 58px; - background: var(--color-bg-deep); + flex-direction: column; + gap: 18px; + height: 100vh; + padding: 20px 16px; + border-right: 1px solid var(--border); + background: + linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02)), + rgba(8, 9, 12, 0.96); + backdrop-filter: blur(18px); +} + +.dashboard-sidebar-profile { + display: flex; + align-items: center; + gap: 12px; + padding: 14px; + border: 1px solid var(--border); + border-radius: 18px; + background: rgba(255,255,255,0.026); } -.me-sidebar { - margin-top: 0; - width: 296px; - min-height: calc(100vh - 58px); - border-right: 1px solid var(--color-border); - background: var(--color-bg-deep); +.dashboard-avatar-wrap { + width: 52px; + height: 52px; + flex-shrink: 0; + border-radius: 14px; overflow: hidden; - transition: width 0.25s ease; + border: 1px solid var(--accent-24); + background: rgba(255,255,255,0.03); + display: grid; + place-items: center; +} + +.dashboard-avatar, +.dashboard-avatar-letter { + width: 100%; + height: 100%; + object-fit: cover; } -.me-sidebar.closed { - width: 80px; +.dashboard-avatar-letter { + display: grid; + place-items: center; + color: var(--text-bright); + font-family: var(--font-display); + font-size: 20px; + font-weight: 700; } -.me-sidebar-inner { +.dashboard-sidebar-meta { + min-width: 0; display: flex; flex-direction: column; - padding: 18px 14px; - gap: 6px; + gap: 4px; } -.me-toggle { - cursor: default; - padding: 10px 12px; - border-radius: 6px; - border: 1px solid transparent; - color: var(--color-text-dim); - transition: 0.2s; +.dashboard-sidebar-meta strong { + color: var(--text); + font-size: 14px; } -.me-toggle:hover { - background: var(--color-bg-surface); - color: var(--color-text-soft); - border-color: var(--color-border); +.dashboard-sidebar-meta span { + color: var(--text-muted); + font-size: 12px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dashboard-nav { + display: flex; + flex-direction: column; + gap: 8px; } -.me-nav-item { +.dashboard-nav-item { display: flex; align-items: center; - gap: 10px; - padding: 10px 12px; - border-radius: 6px; + gap: 12px; + width: 100%; border: 1px solid transparent; - color: var(--color-text-dim); - cursor: default; - transition: background-color 0.2s ease, color 0.2s ease; + border-radius: 12px; + padding: 11px 12px; + background: transparent; + color: var(--text-muted); + font: inherit; + font-size: 14px; + font-weight: 600; + text-align: left; + cursor: pointer; + transition: transform 160ms var(--ease-out-strong), border-color 180ms var(--ease-out-strong), background 180ms var(--ease-out-strong), color 180ms var(--ease-out-strong); } -.me-nav-item svg { - width: 16px; - height: 16px; - opacity: 0.85; - transition: 0.2s; +.dashboard-nav-item:hover { + transform: translateX(1px); + color: var(--text); + border-color: var(--border); + background: rgba(255,255,255,0.03); +} + +.dashboard-nav-item.active { + color: var(--text); + background: rgba(76,122,245,0.12); + border-color: var(--accent-24); +} + +.dashboard-nav-icon { + width: 18px; + height: 18px; + display: inline-flex; + align-items: center; + justify-content: center; + color: inherit; } -.me-nav-item:hover { - background: var(--color-bg-surface); - color: var(--color-text-soft); - border-color: var(--color-border); +.dashboard-sidebar-footer { + margin-top: auto; } -.me-nav-item.active { - background: rgba(56, 139, 253, 0.14); - border-color: rgba(56, 139, 253, 0.35); - color: var(--color-text-bright); +.dashboard-logout { + border-color: var(--border); } -.me-content { - flex: 1; - max-width: 980px; - padding: 24px 36px; +.dashboard-content { + min-width: 0; +} + +.dashboard-mobile-toggle { + position: fixed; + top: 18px; + left: 18px; + z-index: 70; + display: none; + flex-direction: column; + gap: 4px; + width: 44px; + height: 44px; + border: 1px solid var(--border); + border-radius: 12px; + background: rgba(8, 9, 12, 0.92); + cursor: pointer; + padding: 10px; +} + +.dashboard-mobile-toggle span { + display: block; + width: 100%; + height: 2px; + border-radius: 99px; + background: var(--text); +} + +.dashboard-sidebar-backdrop { + display: none; +} + +.page-shell { + position: relative; + z-index: 1; + width: min(1180px, 100%); + margin: 0 auto; + padding: 36px 24px 56px; +} + +.account-page { + position: relative; + min-height: 100dvh; + background: var(--bg); +} + +.account-page::before { + content: ""; + position: fixed; + inset: 0; + pointer-events: none; + background: + linear-gradient(90deg, rgba(255,255,255,0.018) 1px, transparent 1px), + linear-gradient(0deg, rgba(255,255,255,0.012) 1px, transparent 1px); + background-size: 96px 96px, 96px 96px; + mask-image: linear-gradient(to bottom, rgba(0,0,0,0.45), rgba(0,0,0,0.16) 58%, transparent 100%); + opacity: 0.24; +} + +.account-panel { + border: 1px solid var(--border); + border-radius: 26px; + padding: 28px; + background: linear-gradient(180deg, rgba(255,255,255,0.038), rgba(255,255,255,0.02)); + box-shadow: 0 22px 70px rgba(0, 0, 0, 0.28); + backdrop-filter: blur(18px); +} + +.account-header { + margin-bottom: 22px; + padding-bottom: 18px; + border-bottom: 1px solid var(--border); +} + +.account-page-title { + margin: 0 0 10px; + color: var(--text); + font-family: var(--font-display); + font-size: clamp(30px, 4vw, 48px); + line-height: 1.1; + letter-spacing: -0.02em; +} + +.account-page-subtitle { + margin: 0; + max-width: 720px; + color: var(--text-muted); + font-size: 15px; + line-height: 1.75; +} + +.journey-kicker { + display: inline-flex; + align-items: center; + gap: 8px; + margin: 0 0 18px; + font-family: var(--font-mono); + font-size: 10.5px; + font-weight: 600; + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--accent-strong); +} + +.journey-kicker::before { + content: ""; + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--accent-strong); } .me-loading { - color: var(--color-text-soft); + color: var(--text-muted); padding: 24px; } .me-top-msg { - margin: 0 0 16px 0; + margin: 0 0 16px; } .me-header { - display: flex; + display: grid; + grid-template-columns: auto 1fr; + gap: 20px; align-items: center; - gap: 18px; - padding-bottom: 22px; - border-bottom: 1px solid var(--color-border); + padding: 10px 0 18px; } .avatar { - width: 92px; - height: 92px; - border-radius: 10px; - border: 1px solid var(--color-border); - background: var(--color-bg-surface); + width: 96px; + height: 96px; + border-radius: 18px; + border: 1px solid var(--border); + background: rgba(255,255,255,0.028); display: flex; align-items: center; justify-content: center; overflow: hidden; - transition: border-color 0.2s ease; + color: var(--text-bright); + font-family: var(--font-display); + font-size: 28px; + font-weight: 700; + transition: border-color 180ms var(--ease-out-strong), transform 180ms var(--ease-out-strong), box-shadow 180ms var(--ease-out-strong); } .avatar:hover { - border-color: var(--color-text-dim); + border-color: var(--accent-40); + box-shadow: var(--shadow-soft); + transform: translateY(-1px); } .avatar img { @@ -119,29 +291,26 @@ object-fit: cover; } -.avatar.avatar-editable { +.avatar-editable { position: relative; cursor: pointer; } -.avatar.avatar-editable:hover { - border-color: var(--color-accent-2); -} - .avatar-edit-label { position: absolute; inset: auto 0 0; - padding: 6px 8px; + padding: 8px 10px; font-size: 11px; + font-weight: 600; text-align: center; - color: var(--color-text-bright); - background: linear-gradient(180deg, rgba(1, 4, 9, 0), rgba(1, 4, 9, 0.88)); + color: var(--text-bright); + background: linear-gradient(180deg, transparent, rgba(0,0,0,0.86)); opacity: 0; - transition: opacity 0.2s ease; + transition: opacity 180ms var(--ease-out-strong); } -.avatar.avatar-editable:hover .avatar-edit-label, -.avatar.avatar-editable:focus-within .avatar-edit-label { +.avatar-editable:hover .avatar-edit-label, +.avatar-editable:focus-within .avatar-edit-label { opacity: 1; } @@ -149,1043 +318,616 @@ display: none; } -.me-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 16px; - margin-top: 22px; -} +.me-header-info { min-width: 0; } -.me-block { - background: var(--color-bg-surface); - border: 1px solid var(--color-border); - border-radius: 8px; - padding: 16px; - transition: border-color 0.2s ease; +.me-header-top { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + flex-wrap: wrap; } -.me-block:hover { - border-color: var(--color-text-dim); +.me-header-top h2 { + margin: 0; + color: var(--text); + font-family: var(--font-display); + font-size: clamp(24px, 3vw, 34px); + line-height: 1.1; } -.me-block h3 { - margin-top: 0; - font-size: 13px; - color: var(--color-text-dim); - letter-spacing: 0.3px; +.me-email { + margin: 6px 0 0; + color: var(--text-muted); + font-size: 14px; } -.badges { - display: flex; - flex-wrap: wrap; - gap: 8px; +.me-profile-link { + color: var(--accent-strong); + font-size: 13px; + font-weight: 600; } -.badges span { - padding: 5px 10px; - border-radius: 999px; - font-size: 12px; - color: #ffffff; +.me-profile-link:hover { + color: var(--text-bright); } -.achievement { - padding: 10px 12px; - border-radius: 6px; - background: var(--color-bg); - border: 1px solid var(--color-border); - margin-bottom: 8px; - cursor: default; - transition: border-color 0.2s ease, background-color 0.2s ease; +.me-section { + margin-top: 18px; + padding: 18px; + border: 1px solid var(--border); + border-radius: 18px; + background: rgba(255,255,255,0.024); } -.achievement:hover { - background: var(--color-bg-surface); - border-color: var(--color-text-dim); +.me-section-title { + margin: 0 0 12px; + color: var(--text); + font-family: var(--font-display); + font-size: 20px; + line-height: 1.2; } -.projects-grid { +.me-profile-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); - gap: 14px; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 18px; } -.project-card { - background: var(--color-bg-surface); - border: 1px solid var(--color-border); - border-radius: 8px; - padding: 16px; - transition: border-color 0.2s ease; +.me-field { + display: flex; + flex-direction: column; + gap: 10px; } -.project-card:hover { - border-color: var(--color-text-dim); +.me-field span:first-child { + color: var(--text-muted); + font-size: 13px; + font-weight: 600; } -.project-card h3 { - margin-top: 0; - color: var(--color-text-bright); +.me-field textarea, +.me-field select, +.me-settings input, +.settings-confirm-input { + width: 100%; + min-height: 46px; + padding: 12px 14px; + border: 1px solid var(--border); + border-radius: 14px; + background: rgba(255,255,255,0.02); + color: var(--text); + font: inherit; + transition: border-color 180ms var(--ease-out-strong), box-shadow 180ms var(--ease-out-strong), background 180ms var(--ease-out-strong), transform 180ms var(--ease-out-strong); } -.project-card p { - color: var(--color-text-dim); - margin-bottom: 0; +.me-field textarea { + min-height: 118px; + resize: vertical; } -.me-settings { - max-width: none; - margin-top: 0; - background: transparent; - border: none; - border-radius: 0; - box-shadow: none; - padding: 0; +.me-field textarea:focus, +.me-field select:focus, +.me-settings input:focus, +.settings-confirm-input:focus { + outline: none; + border-color: var(--accent-40); + box-shadow: 0 0 0 4px rgba(76,122,245,0.16); + background: rgba(255,255,255,0.03); } -.settings-layout { - background: var(--color-bg-deep); - min-height: calc(100vh - 100px); +.me-bio-counter { + align-self: flex-end; + font-size: 12px; + color: var(--text-dim); } -.settings-content { - max-width: 880px; - width: 100%; - margin: 0 auto; - padding: 24px 24px 40px; +.me-empty, +.settings-help { + margin: 0; + color: var(--text-muted); + line-height: 1.7; } -.settings-page-title { - margin: 0; - font-size: 32px; - line-height: 1.2; - letter-spacing: 0; - color: var(--color-text-bright); +.me-badges-loading { + display: inline-flex; + align-items: center; + gap: 10px; + color: var(--text-muted); } -.settings-page-subtitle { - margin: 10px 0 16px; - color: var(--color-text-dim); +.me-badges-spinner { + width: 16px; + height: 16px; + border-radius: 50%; + border: 2px solid rgba(255,255,255,0.18); + border-top-color: var(--accent); + animation: me-spin 0.95s linear infinite; } -.settings-error { - margin: 0 0 12px; - padding: 10px 12px; - border-radius: 6px; - background: rgba(248, 81, 73, 0.12); - border: 1px solid rgba(248, 81, 73, 0.4); - color: #ffb4ad; - font-size: 13px; +@keyframes me-spin { + to { transform: rotate(360deg); } } -.settings-username-error { - margin: -6px 0 10px; - font-size: 12px; - color: #f85149; +.me-badge-grid, +.projects-grid, +.badge-cards-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 16px; } -.settings-avatar-wrap { - display: flex; - align-items: center; - gap: 14px; - margin-bottom: 14px; - flex-wrap: wrap; +.me-badge-card, +.project-card, +.badge-card { + border: 1px solid var(--border); + border-radius: 18px; + background: rgba(255,255,255,0.026); + padding: 18px; + transition: border-color 180ms var(--ease-out-strong), transform 180ms var(--ease-out-strong), box-shadow 180ms var(--ease-out-strong), background 180ms var(--ease-out-strong); } -.settings-avatar-preview { - width: 72px; - height: 72px; - border-radius: 10px; - border: 1px solid var(--color-border); - object-fit: cover; - background: var(--color-bg-surface); - flex-shrink: 0; +.me-badge-card:hover, +.project-card:hover, +.badge-card:hover { + border-color: var(--accent-40); + box-shadow: var(--shadow-soft); + background: rgba(255,255,255,0.04); } -.settings-avatar-placeholder { - width: 72px; - height: 72px; - border-radius: 10px; - border: 1px solid var(--color-border); - background: var(--color-bg-surface); +.me-badge-card { + position: relative; display: flex; align-items: center; - justify-content: center; - font-size: 28px; - font-weight: 700; - color: var(--color-text-dim); - flex-shrink: 0; -} - -.settings-avatar-btn { - padding: 8px 14px; - border-radius: 6px; - border: 1px solid rgba(88, 166, 255, 0.85); - background: var(--color-bg-deep); - color: white; - font-size: 13px; + gap: 12px; + width: 100%; cursor: pointer; - transition: background 0.2s; -} - -.settings-content .settings-section .settings-avatar-btn:hover { - background: linear-gradient(180deg, var(--color-accent-2)f2, #58a7fff2); + text-align: left; + color: inherit; + overflow: hidden; } -.settings-content .settings-section { - border-top: 1px solid var(--color-border); - padding: 20px 0; +.me-badge-card::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: radial-gradient(circle at top left, var(--badge-glow, rgba(76,122,245,0.16)), transparent 48%); + opacity: 0.75; } -.settings-title { - margin: 0; - font-size: 20px; - color: var(--color-text-bright); +.me-badge-card[data-rarity="legendary"] { + border-color: rgba(245, 158, 11, 0.45); + box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.2); } -.settings-help { - margin: 8px 0 14px; - color: var(--color-text-dim); - font-size: 14px; +.me-badge-card[data-rarity="epic"] { + border-color: rgba(236, 72, 153, 0.42); + box-shadow: inset 0 0 0 1px rgba(236, 72, 153, 0.18); } -.me-settings input { - width: 100%; - padding: 11px; - margin-bottom: 10px; - background: #0a0f16; - border: 1px solid var(--color-border); - border-radius: 6px; - color: var(--color-text-bright); +.me-badge-card[data-rarity="rare"] { + border-color: rgba(139, 92, 246, 0.42); + box-shadow: inset 0 0 0 1px rgba(139, 92, 246, 0.18); } -.me-settings input:focus { - outline: none; - border-color: #1f6feb; - box-shadow: 0 0 0 3px rgba(31, 111, 235, 0.25); -} - -.me-settings button { - padding: 10px 12px; - border-radius: 6px; - border-width: 1px; - border-style: solid; - border-color: rgba(88, 166, 255, 0.85); - background: var(--color-bg-deep); - color: var(--color-text-bright); - cursor: pointer; - margin-bottom: 10px; - transition: background 0.2s, border-color 0.2s; +.me-badge-card[data-rarity="common"] { + border-color: rgba(16, 185, 129, 0.32); + box-shadow: inset 0 0 0 1px rgba(16, 185, 129, 0.14); } -.me-settings button:disabled { - opacity: 0.65; - cursor: default; +.me-badge-icon-wrap, +.badge-card-icon { + width: 46px; + height: 46px; + border-radius: 14px; + display: grid; + place-items: center; + flex-shrink: 0; + border: 1px solid var(--accent-24); + background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02)); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.06); } -.me-settings button:hover:not(:disabled) { - background: linear-gradient(180deg, var(--color-accent-2)f2, #58a7fff2); +.me-badge-icon-wrap img, +.badge-card-icon img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: inherit; } -.settings-save-btn { - width: auto; - min-width: 150px; - border-color: rgba(63, 185, 80, 0.95); - background: linear-gradient(180deg, #238636, #1a6b29); +.me-badge-body, +.badge-card-body { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 4px; } -.settings-save-btn:hover:not(:disabled) { - background: linear-gradient(180deg, #2ea043, #238636); +.me-badge-name, +.badge-card-name, +.project-card h3 { + color: var(--text); + font-family: var(--font-display); + font-size: 16px; + font-weight: 600; } -.settings-password-btn { - border-color: rgba(88, 166, 255, 0.95); - box-shadow: inset 0 0 0 1px rgba(88, 166, 255, 0.2); +.me-badge-rarity, +.badge-card-rarity { + display: inline-flex; + align-items: center; + width: fit-content; + border-radius: 999px; + padding: 3px 8px; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + background: rgba(255,255,255,0.05); + color: var(--text-muted); } -.settings-password-btn:hover:not(:disabled) { - background: linear-gradient(180deg, var(--color-accent-2)f2, #58a7fff2); +.me-badge-card[data-rarity="legendary"] .me-badge-rarity, +.badge-modal-hero[data-rarity="legendary"] + .badge-modal-body .badge-modal-name { + color: #f8c65a; } -.danger-zone { - border-top-color: rgba(248, 81, 73, 0.35) !important; +.me-badge-card[data-rarity="epic"] .me-badge-rarity, +.badge-modal-hero[data-rarity="epic"] + .badge-modal-body .badge-modal-name { + color: #ff78bf; } -.danger-btn { - width: auto; - min-width: 180px; - display: inline-flex; - justify-content: center; - margin-right: 10px; +.me-badge-card[data-rarity="rare"] .me-badge-rarity, +.badge-modal-hero[data-rarity="rare"] + .badge-modal-body .badge-modal-name { + color: #bda8ff; } -.danger-btn.delete-btn { - border-color: rgba(255, 94, 91, 0.98) !important; +.me-badge-card[data-rarity="common"] .me-badge-rarity, +.badge-modal-hero[data-rarity="common"] + .badge-modal-body .badge-modal-name { + color: #8df0a2; } -.danger-btn.delete-btn:hover:not(:disabled) { - background: linear-gradient(180deg, #da3633, #b62324) !important; +.me-badge-arrow { + color: var(--text-dim); + flex-shrink: 0; } -.danger-btn.logout-btn { - border-color: rgba(255, 94, 91, 0.98) !important; -} - -.danger-btn.logout-btn:hover:not(:disabled) { - background: linear-gradient(180deg, #f85149, #da3633) !important; -} - -.settings-modal-backdrop { - position: fixed; - inset: 0; - background: rgba(13, 17, 23, 0.62); - backdrop-filter: blur(3px); +.project-card { display: flex; - align-items: center; - justify-content: center; - padding: 20px; - z-index: 300; + flex-direction: column; + gap: 10px; } -.settings-modal { - width: 100%; - max-width: 460px; - background: var(--color-bg-surface); - border: 1px solid var(--color-border); - border-radius: 10px; - box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45); - overflow: hidden; +.project-card p { + margin: 0; + color: var(--text-muted); + line-height: 1.7; } -.settings-modal-header { +.me-save-row { display: flex; - justify-content: space-between; - align-items: center; - padding: 14px 16px; - border-bottom: 1px solid var(--color-border); -} - -.settings-modal h4 { - margin: 0; - font-size: 16px; - color: var(--color-text-bright); + justify-content: flex-start; + margin-top: 20px; } -.settings-modal-close { - width: 30px; - height: 30px; - border-radius: 6px; - border: 1px solid transparent; +.settings-save-btn, +.settings-password-btn, +.danger-btn, +.settings-modal-actions button, +.badge-modal-close-btn { + appearance: none; + border: 1px solid var(--border); + border-radius: 14px; + min-height: 44px; + padding: 11px 16px; background: transparent; - color: var(--color-text-dim); - font-size: 20px; - line-height: 1; -} - -.settings-modal-close:hover { - background: var(--color-border-subtle); - color: var(--color-text-soft); - border-color: var(--color-border); -} - -.settings-modal-body { - padding: 16px; -} - -.settings-modal p { - margin: 0 0 12px; - color: var(--color-text-dim); -} - -.settings-modal .settings-help { - margin-top: 0; - margin-bottom: 8px; -} - -.settings-confirm-input { - margin-bottom: 0; - font-family: "Fira Code", monospace; - letter-spacing: 0.6px; - text-transform: uppercase; - background: var(--color-bg); - border: 1px solid rgba(248, 81, 73, 0.45); -} - -.settings-confirm-input:focus { - outline: none; - border-color: #f85149; - box-shadow: 0 0 0 3px rgba(248, 81, 73, 0.2); -} - -.settings-modal-actions { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; - padding: 0 16px 16px; -} - -.settings-modal-actions button { - margin-bottom: 0; - min-height: 42px; + color: var(--text); + font: inherit; font-weight: 600; -} - -.settings-modal-cancel { - background: var(--color-border-subtle); - border: 1px solid var(--color-border); - color: var(--color-text-soft); -} - -.settings-modal-cancel:hover { - background: var(--color-border); -} - -.settings-modal-delete { - background: linear-gradient(180deg, #da3633, #b62324); - border: 1px solid rgba(240, 246, 252, 0.2); - box-shadow: 0 6px 18px rgba(218, 54, 51, 0.25); -} - -.settings-modal-delete:hover { - background: linear-gradient(180deg, #f85149, #da3633); -} - -@media (max-width: 900px) { - .me-layout { - flex-direction: column; - } - - .me-sidebar { - width: 100%; - min-height: auto; - border-right: none; - border-bottom: 1px solid var(--color-border); - } - - .me-sidebar.closed { - width: 100%; - } - - .me-content { - padding: 18px; - } - - .me-grid { - grid-template-columns: 1fr; - } - - .me-profile-grid { - grid-template-columns: 1fr; - } - - .settings-content { - padding: 22px 16px 28px; - } - - .settings-page-title { - font-size: 26px; - } - - .danger-btn { - width: 100%; - margin-right: 0; - margin-bottom: 10px; - } -} - -/* Badge Cards (Settings) */ -.badge-cards-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 10px; - margin-bottom: 16px; -} - -.badge-card { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 14px; - background: var(--color-bg); - border: 1px solid var(--color-border); - border-radius: 8px; cursor: pointer; - text-align: left; - transition: border-color 0.2s, background 0.2s; - width: 100%; -} - -.badge-card:hover { - background: var(--color-bg-surface); - border-color: var(--color-accent-2); -} - -.badge-card-icon { - width: 38px; - height: 38px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - font-weight: 700; - color: #fff; - flex-shrink: 0; -} - -.badge-card-body { - display: flex; - flex-direction: column; - gap: 3px; -} - -.badge-card-name { - font-size: 14px; - font-weight: 600; - color: var(--color-text-bright); -} - -.badge-card-rarity { - font-size: 11px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.4px; - padding: 2px 6px; - border-radius: 4px; - display: inline-block; -} - -.badge-card-rarity[data-rarity="legendary"] { background: rgba(245,158,11,0.15); color: #f59e0b; } -.badge-card-rarity[data-rarity="epic"] { background: rgba(236,72,153,0.15); color: #ec4899; } -.badge-card-rarity[data-rarity="rare"] { background: rgba(139,92,246,0.15); color: #8b5cf6; } -.badge-card-rarity[data-rarity="common"] { background: rgba(16,185,129,0.15); color: #10b981; } - -.badge-section-actions { - display: flex; - align-items: center; - gap: 16px; - flex-wrap: wrap; -} - -.settings-badge-sync-btn { - background: var(--color-bg-deep) !important; - border-color: rgba(88, 166, 255, 0.85) !important; - min-width: 160px; + transition: transform 160ms var(--ease-out-strong), border-color 180ms var(--ease-out-strong), background 180ms var(--ease-out-strong), box-shadow 180ms var(--ease-out-strong), color 180ms var(--ease-out-strong), opacity 180ms var(--ease-out-strong); } -.settings-badge-sync-btn:hover:not(:disabled) { - background: #0a0f16 !important; +.settings-save-btn:hover:not(:disabled), +.settings-password-btn:hover:not(:disabled), +.danger-btn:hover:not(:disabled), +.settings-modal-actions button:hover:not(:disabled), +.badge-modal-close-btn:hover:not(:disabled) { + transform: translateY(-1px); + border-color: var(--accent-40); + box-shadow: var(--shadow-soft); } -.badge-profile-link { - font-size: 14px; - color: var(--color-accent-2); - text-decoration: none; -} - -.badge-profile-link:hover { - text-decoration: underline; -} - -.badge-detail-modal { - overflow: hidden; -} - -.badge-detail-header { - height: 90px; - display: flex; - align-items: center; - justify-content: center; +.settings-save-btn, +.settings-password-btn { + background: linear-gradient(180deg, rgba(76,122,245,0.96), rgba(76,122,245,0.88)); + border-color: rgba(76,122,245,0.9); + color: #ffffff; + box-shadow: 0 10px 26px rgba(76, 122, 245, 0.22); } -.badge-detail-initial { - font-size: 40px; - font-weight: 800; - color: rgba(255, 255, 255, 0.9); +.settings-save-btn:hover:not(:disabled), +.settings-password-btn:hover:not(:disabled) { + background: linear-gradient(180deg, rgba(102,144,255,0.98), rgba(76,122,245,0.94)); + border-color: rgba(102,144,255,0.98); + box-shadow: 0 14px 30px rgba(76, 122, 245, 0.28); } -.badge-modal-profile-btn { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 8px 16px; - border-radius: 6px; - font-size: 14px; - font-weight: 600; - background: var(--color-bg-deep); - border: 1px solid rgba(88, 166, 255, 0.85); - color: var(--color-accent-2); - text-decoration: none; - transition: 0.2s; +.danger-btn.delete-btn, +.danger-btn.logout-btn, +.settings-modal-delete { + background: rgba(248,81,73,0.12); + border-color: rgba(248,81,73,0.5); + color: #ffb4ad; } -.badge-modal-profile-btn:hover { - background: #0a0f16; +.settings-save-btn:disabled, +.settings-password-btn:disabled, +.danger-btn:disabled, +.settings-modal-actions button:disabled, +.badge-modal-close-btn:disabled { + opacity: 0.62; + cursor: not-allowed; } +.settings-error, .settings-success { - margin: 0 0 12px; - padding: 10px 12px; - border-radius: 6px; - background: rgba(63, 185, 80, 0.1); - border: 1px solid rgba(63, 185, 80, 0.3); - color: #3fb950; + margin: 0 0 16px; + padding: 12px 14px; + border-radius: 14px; font-size: 13px; + line-height: 1.5; } -.me-email { - margin: 2px 0 0; - color: var(--color-text-dim); - font-size: 14px; -} - -.me-header-info { - flex: 1; - min-width: 0; -} - -.me-header-top { - display: flex; - align-items: center; - justify-content: space-between; - gap: 14px; - flex-wrap: wrap; -} - -.me-header-top h2 { - margin: 0; -} - -.me-divider { - margin-top: 18px; - border-top: 1px solid var(--color-border); -} - -.me-section { - margin-top: 18px; - padding-top: 0; - border-top: none; +.settings-error { + background: rgba(248,81,73,0.12); + border: 1px solid rgba(248,81,73,0.4); + color: #ffb4ad; } -.me-section-first { - margin-top: 20px; - padding-top: 0; - border-top: none; +.settings-success { + background: rgba(63,185,80,0.12); + border: 1px solid rgba(63,185,80,0.4); + color: #8df0a2; } -.me-section-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: 12px; - margin-bottom: 16px; - flex-wrap: wrap; +.settings-username-error { + margin: -6px 0 10px; + color: #ffb4ad; + font-size: 12px; } -.me-section-title { - margin: 0; - font-size: 16px; - font-weight: 600; - color: var(--color-text-bright); +.settings-section { + padding: 18px; + border: 1px solid var(--border); + border-radius: 18px; + background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.018)); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.03); } -.me-profile-grid { - display: grid; - grid-template-columns: 1fr; - gap: 14px; - margin: 14px 0; +.settings-title { + margin: 0 0 8px; + color: var(--text); + font-family: var(--font-display); + font-size: 20px; } -.me-field { +.settings-github-connected { display: flex; flex-direction: column; - gap: 6px; -} - -.me-field span { - font-size: 12px; - color: var(--color-text-dim); - font-weight: 600; - letter-spacing: 0.2px; -} - -.me-field textarea, -.me-field input, -.me-field select { - width: 100%; - padding: 10px 11px; - background: #0a0f16; - border: 1px solid var(--color-border); - border-radius: 6px; - color: var(--color-text-bright); - font: inherit; -} - -.me-field textarea { - resize: vertical; - min-height: 94px; -} - -.me-field textarea:focus, -.me-field input:focus, -.me-field select:focus { - outline: none; - border-color: #1f6feb; - box-shadow: 0 0 0 3px rgba(31, 111, 235, 0.22); -} - -.me-bio-counter { - align-self: flex-end; - font-size: 11px; - color: var(--color-text-dim); -} - -.me-field-static { - padding: 10px 11px; - border: 1px solid var(--color-border); - border-radius: 6px; - background: #0a0f16; -} - -.me-field-static p { - margin: 2px 0 0; - color: var(--color-text-soft); - font-size: 14px; -} - -.me-save-btn { - padding: 10px 14px; - min-width: 180px; - border-radius: 6px; - border: 1px solid rgba(63, 185, 80, 0.95); - background: var(--color-bg-deep); - color: var(--color-text-bright); - font-weight: 600; - cursor: pointer; - transition: background 0.2s, border-color 0.2s; -} - -.me-save-btn:hover:not(:disabled) { - background: linear-gradient(180deg, #2ea043, #238636); -} - -.me-save-btn:disabled { - opacity: 0.7; - cursor: default; -} - -.me-save-row { - margin-top: 18px; -} - -.me-save-row .me-save-btn { - margin-bottom: 0; + gap: 10px; } -.me-section-actions { - display: flex; +.settings-github-badge { + display: inline-flex; align-items: center; - gap: 12px; - flex-wrap: wrap; -} - -.me-profile-link { - font-size: 13px; - color: var(--color-accent-2); - text-decoration: none; -} - -.me-profile-link:hover { - text-decoration: underline; -} - -.me-sync-btn { - padding: 6px 14px; - border-radius: 6px; - border: 1px solid rgba(88, 166, 255, 0.7); - background: transparent; - color: var(--color-accent-2); - font-size: 13px; - cursor: pointer; - transition: background 0.2s, border-color 0.2s; -} - -.me-sync-btn:hover:not(:disabled) { - background: rgba(88, 166, 255, 0.08); - border-color: var(--color-accent-2); -} - -.me-sync-btn:disabled { - opacity: 0.5; - cursor: default; -} - -.me-sync-msg { - margin: 0 0 14px; - padding: 8px 12px; - border-radius: 6px; - background: rgba(63, 185, 80, 0.08); - border: 1px solid rgba(63, 185, 80, 0.25); - color: #3fb950; - font-size: 13px; -} - -.me-empty { - color: var(--color-text-dim); - font-size: 14px; - margin: 0; + width: fit-content; + gap: 8px; + padding: 6px 10px; + border-radius: 999px; + border: 1px solid var(--accent-24); + background: rgba(76,122,245,0.1); + color: var(--text-muted); + font-size: 12px; } -/* Badge Detail Modal (Me.jsx) */ +.settings-modal-backdrop, .badge-modal-backdrop { position: fixed; inset: 0; - background: rgba(13, 17, 23, 0.72); - backdrop-filter: blur(4px); - display: flex; - align-items: center; - justify-content: center; + z-index: 30; + display: grid; + place-items: center; padding: 20px; - z-index: 400; + background: rgba(7,9,13,0.72); } +.settings-modal, .badge-modal { - width: 100%; - max-width: 420px; - background: var(--color-bg-surface); - border: 1px solid var(--color-border); - border-radius: 12px; + width: min(460px, 100%); + border-radius: 22px; + border: 1px solid var(--border); + background: linear-gradient(180deg, rgba(15,17,21,0.99), rgba(9,11,15,0.98)); + box-shadow: 0 30px 80px rgba(0, 0, 0, 0.44); overflow: hidden; - box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6); -} - -.badge-modal-hero { - height: 110px; - display: flex; - align-items: center; - justify-content: center; } -.badge-modal-initial { - font-size: 48px; - font-weight: 800; - color: rgba(255, 255, 255, 0.9); - text-shadow: 0 2px 12px rgba(0, 0, 0, 0.3); +.settings-modal-header, +.settings-modal-body, +.settings-modal-actions, +.badge-modal-body, +.badge-modal-footer { + padding-left: 16px; + padding-right: 16px; } -.badge-modal-body { - padding: 18px 24px 6px; +.settings-modal-header { display: flex; - flex-direction: column; - gap: 8px; - text-align: center; align-items: center; + justify-content: space-between; + padding-top: 16px; + padding-bottom: 14px; + border-bottom: 1px solid var(--border); } +.settings-modal h4, .badge-modal-name { margin: 0; + color: var(--text); + font-family: var(--font-display); font-size: 20px; - font-weight: 700; - color: var(--badge-color, var(--color-text-bright)); - text-shadow: 0 0 24px var(--badge-glow, transparent); } -.badge-modal-desc { - margin: 0; - color: var(--color-text-dim); - font-size: 14px; - line-height: 1.6; - text-align: center; - max-width: 280px; +.settings-modal-close { + width: 36px; + height: 36px; + display: grid; + place-items: center; + border: 1px solid var(--border); + border-radius: 12px; + background: transparent; + color: var(--text-muted); + cursor: pointer; } -.badge-modal-date { - margin: 4px 0 0; - color: var(--color-text-muted); - font-size: 12px; - text-align: center; +.settings-modal-body, +.badge-modal-body { + padding-top: 16px; + padding-bottom: 16px; } -.badge-modal-footer { - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - padding: 14px 20px; - border-top: 1px solid var(--color-border); +.badge-modal-title-row { + margin-bottom: 8px; } -.badge-modal-close-btn { - padding: 7px 16px; - border-radius: 6px; - border: 1px solid var(--color-border); - background: var(--color-border-subtle); - color: var(--color-text-soft); - font-size: 14px; - cursor: pointer; - transition: background 0.2s, border-color 0.2s; +.settings-modal-body p, +.badge-modal-desc, +.badge-modal-date { + margin: 0 0 10px; + color: var(--text-muted); + line-height: 1.7; } -.badge-modal-close-btn:hover { - background: #2d333b; - border-color: var(--color-text-dim); +.settings-modal-actions { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + padding-bottom: 16px; } -.me-badges-loading { - display: flex; - align-items: center; - gap: 10px; - color: var(--color-text-dim); - font-size: 14px; - margin-bottom: 4px; +.badge-modal-hero { + position: relative; + min-height: 130px; + display: grid; + place-items: center; + background: + radial-gradient(circle at top, rgba(255,255,255,0.09), transparent 55%), + linear-gradient(135deg, rgba(76,122,245,0.18), rgba(255,255,255,0.02)); + border-bottom: 1px solid var(--border); } -.me-badges-spinner { - width: 18px; - height: 18px; - border: 2px solid var(--color-border); - border-top-color: var(--color-accent-2); - border-radius: 50%; - animation: me-spin 0.75s linear infinite; - flex-shrink: 0; +.badge-modal-icon-wrap { + width: 74px; + height: 74px; + display: grid; + place-items: center; + border-radius: 18px; + border: 1px solid var(--accent-24); + background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02)); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 12px 30px rgba(0,0,0,0.26); } -@keyframes me-spin { - to { transform: rotate(360deg); } +.badge-modal-glow { + position: absolute; + inset: 0; + pointer-events: none; } -.me-badge-grid { +.me-settings { display: grid; - grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); - gap: 10px; + gap: 14px; } -.me-badge-card { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 14px; - background: var(--color-bg); - border: 1px solid var(--color-border); - border-radius: 10px; - cursor: pointer; - text-align: left; - transition: border-color 0.2s, background 0.2s, box-shadow 0.2s; - width: 100%; - position: relative; +.me-settings .settings-section { + display: grid; + gap: 14px; } -.me-badge-card:hover { - background: #111820; - border-color: var(--badge-color, var(--color-accent-2)); - box-shadow: 0 0 16px var(--badge-glow, transparent); +.me-settings .settings-section > * { + margin: 0; } -.me-badge-icon-wrap { - width: 40px; - height: 40px; - border-radius: 50%; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} +@media (max-width: 900px) { + .dashboard-layout { + grid-template-columns: 1fr; + } -.me-badge-body { - display: flex; - flex-direction: column; - gap: 3px; - flex: 1; - min-width: 0; -} + .dashboard-sidebar { + position: fixed; + left: 0; + top: 0; + z-index: 60; + width: min(320px, 86vw); + transform: translateX(-104%); + transition: transform 200ms var(--ease-out-strong); + box-shadow: var(--shadow-card); + } -.me-badge-name { - font-size: 14px; - font-weight: 600; - color: var(--color-text-bright); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} + .dashboard-sidebar.open { + transform: translateX(0); + } -.me-badge-rarity { - font-size: 10px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.5px; - padding: 2px 7px; - border-radius: 4px; - display: inline-block; -} + .dashboard-sidebar-backdrop { + position: fixed; + inset: 0; + z-index: 50; + background: rgba(4, 5, 7, 0.7); + } -.me-badge-rarity[data-rarity="legendary"] { background: rgba(245,158,11,0.15); color: #f59e0b; border: 1px solid rgba(245,158,11,0.25); } -.me-badge-rarity[data-rarity="epic"] { background: rgba(236,72,153,0.15); color: #ec4899; border: 1px solid rgba(236,72,153,0.25); } -.me-badge-rarity[data-rarity="rare"] { background: rgba(139,92,246,0.15); color: #8b5cf6; border: 1px solid rgba(139,92,246,0.25); } -.me-badge-rarity[data-rarity="common"] { background: rgba(16,185,129,0.12); color: #10b981; border: 1px solid rgba(16,185,129,0.25); } + .dashboard-sidebar-backdrop.visible { + display: block; + } -.me-badge-arrow { - color: var(--color-border); - flex-shrink: 0; - transition: color 0.2s, transform 0.2s; -} + .dashboard-mobile-toggle { + display: flex; + } -.me-badge-card:hover .me-badge-arrow { - color: var(--badge-color, var(--color-accent-2)); - transform: translateX(2px); -} + .page-shell { + padding: 84px 16px 32px; + } -/* New Badge Modal (with SVG hero + glow) */ -.badge-modal-hero { - position: relative; - height: 180px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 14px; - overflow: hidden; -} + .account-panel { + padding: 20px; + border-radius: 18px; + } -.badge-modal-hero[data-rarity="legendary"] { background: linear-gradient(160deg, #1a1200 0%, var(--color-bg) 100%); } -.badge-modal-hero[data-rarity="epic"] { background: linear-gradient(160deg, #1a0010 0%, var(--color-bg) 100%); } -.badge-modal-hero[data-rarity="rare"] { background: linear-gradient(160deg, #100d1a 0%, var(--color-bg) 100%); } -.badge-modal-hero[data-rarity="common"] { background: linear-gradient(160deg, #001a10 0%, var(--color-bg) 100%); } + .me-header { + grid-template-columns: 1fr; + justify-items: start; + } -.badge-modal-icon-wrap { - width: 90px; - height: 90px; - border-radius: 50%; - overflow: hidden; - border: 2.5px solid var(--badge-color, rgba(255,255,255,0.15)); - display: flex; - align-items: center; - justify-content: center; - position: relative; - z-index: 1; - box-shadow: 0 0 28px var(--badge-glow, transparent), 0 0 0 6px color-mix(in srgb, var(--badge-color, #fff) 10%, transparent); -} + .me-profile-grid { + grid-template-columns: 1fr; + } -.badge-modal-icon-wrap img { - width: 100%; - height: 100%; - object-fit: cover; - display: block; + .settings-modal-actions { + grid-template-columns: 1fr; + } } -.badge-modal-icon-wrap svg { - width: 48px; - height: 48px; -} +@media (max-width: 640px) { + .page-shell { + padding-inline: 10px; + } -.badge-modal-glow { - position: absolute; - inset: -20px; - z-index: 0; - pointer-events: none; -} + .account-panel { + padding: 16px; + } -.badge-modal-title-row { - display: flex; - align-items: center; - gap: 10px; - flex-wrap: wrap; -} + .me-header-top { + align-items: flex-start; + } +} \ No newline at end of file diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index c8cb5f5..abdae94 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -79,6 +79,16 @@ main { flex: 1; width: 100%; } button, a { -webkit-tap-highlight-color: transparent; } +button { + font: inherit; +} + +input, +select, +textarea { + font: inherit; +} + :focus-visible { outline: 2px solid var(--border-focus); outline-offset: 3px; diff --git a/frontend/src/styles/services.css b/frontend/src/styles/services.css index 98dae1c..c14919d 100644 --- a/frontend/src/styles/services.css +++ b/frontend/src/styles/services.css @@ -3,11 +3,8 @@ position: relative; overflow: hidden; scroll-behavior: smooth; - background: - radial-gradient(circle at 80% 8%, rgba(110, 231, 242, 0.09), transparent 32%), - radial-gradient(circle at 8% 30%, rgba(143, 179, 255, 0.06), transparent 28%), - #05070c; - color: #f0f4ff; + background: var(--bg); + color: var(--text); } .services-page::before { @@ -15,10 +12,10 @@ position: fixed; inset: 0; pointer-events: none; - opacity: 0.22; + opacity: 0.16; background-image: - linear-gradient(rgba(122, 151, 185, 0.04) 1px, transparent 1px), - linear-gradient(90deg, rgba(122, 151, 185, 0.04) 1px, transparent 1px); + linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px), + linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px); background-size: 72px 72px; mask-image: linear-gradient(to bottom, black, transparent 75%); } @@ -45,7 +42,7 @@ position: relative; z-index: 1; padding: 132px 0 52px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); + border-bottom: 1px solid var(--border); } .services-hero__content { @@ -59,27 +56,42 @@ .services-section-heading > span, .services-final-cta__card > span { display: inline-flex; - color: #6ee7f2; - font-size: 0.72rem; - font-weight: 800; - letter-spacing: 0.18em; + align-items: center; + gap: 9px; + color: var(--accent-strong); + font-family: var(--font-mono); + font-size: 0.68rem; + font-weight: 600; + letter-spacing: 0.17em; text-transform: uppercase; } +.services-eyebrow::before, +.services-section-heading > span::before, +.services-final-cta__card > span::before { + content: ""; + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--accent-strong); + flex-shrink: 0; +} .services-hero h1 { max-width: 560px; - margin: 14px 0 16px; + margin: 16px 0 16px; + font-family: var(--font-display); + font-weight: 700; font-size: clamp(2.25rem, 4vw, 4rem); - line-height: 1.02; - letter-spacing: 0; + line-height: 1.05; + letter-spacing: -0.015em; } .services-hero__intro > p { max-width: 620px; margin: 0; - color: #7b86a0; + color: var(--text-muted); font-size: 0.98rem; - line-height: 1.7; + line-height: 1.72; } .services-button { @@ -88,32 +100,35 @@ align-items: center; justify-content: center; gap: 9px; - padding: 0 24px; + padding: 0 26px; border: 1px solid transparent; - border-radius: 999px; + border-radius: 8px; font-size: 0.88rem; - font-weight: 750; + font-weight: 600; text-decoration: none; transition: transform 160ms var(--ease-out-strong), border-color 180ms var(--ease-out-strong), - background 180ms var(--ease-out-strong), - box-shadow 180ms var(--ease-out-strong); + background 180ms var(--ease-out-strong); } .services-button:hover { transform: translateY(-1px); } .services-button:active { transform: scale(0.98); } .services-button--primary { - background: linear-gradient(135deg, #1e5fe7, #21aabd); - box-shadow: 0 12px 26px rgba(20, 85, 140, 0.24); - color: #fff; + background: var(--accent); + border-color: var(--accent); + color: #ffffff; +} +.services-button--primary:hover { + background: var(--accent-strong); + border-color: var(--accent-strong); } .services-button--secondary { - border-color: rgba(180, 190, 255, 0.14); - background: rgba(255, 255, 255, 0.035); - color: #aab4cf; + border-color: var(--border); + background: transparent; + color: var(--text-muted); } .services-jump-nav { @@ -124,9 +139,10 @@ } .services-hero__navigation > span { - color: #64708a; - font-size: 0.68rem; - font-weight: 800; + color: var(--text-dim); + font-family: var(--font-mono); + font-size: 0.66rem; + font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; } @@ -139,14 +155,14 @@ gap: 10px; overflow: hidden; padding: 14px 16px; - border: 1px solid rgba(122, 151, 185, 0.12); - border-radius: 10px; - background: rgba(8, 14, 24, 0.64); - color: #aab4cf; + border: 1px solid var(--border); + border-radius: 8px; + background: var(--surface); + color: var(--text-muted); font-size: 0.85rem; - font-weight: 650; + font-weight: 550; + text-decoration: none; transition: - transform 160ms var(--ease-out-strong), border-color 180ms var(--ease-out-strong), background 180ms var(--ease-out-strong), color 180ms var(--ease-out-strong); @@ -155,49 +171,33 @@ .services-jump-nav__item::before { content: ""; position: absolute; - left: 16px; - right: 16px; - bottom: 8px; - height: 2px; - border-radius: 999px; - background: linear-gradient(90deg, var(--service-color), rgba(var(--service-rgb), 0.28)); + left: 0; + top: 0; + bottom: 0; + width: 2px; + background: var(--accent); opacity: 0; - transform: scaleX(0.24); - transform-origin: left; - transition: - opacity 180ms var(--ease-out-strong), - transform 260ms var(--ease-out-strong); + transition: opacity 180ms var(--ease-out-strong); } .services-jump-nav__item:hover { - border-color: var(--service-color); - background: rgba(10, 18, 30, 0.82); - color: #fff; + border-color: var(--border-hover); + color: var(--text); } .services-jump-nav__item.is-active { - border-color: rgba(var(--service-rgb), 0.52); - background: - linear-gradient(135deg, rgba(var(--service-rgb), 0.13), rgba(10, 18, 30, 0.8) 58%), - rgba(8, 14, 24, 0.78); - color: #fff; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.055); + border-color: var(--accent-24); + background: var(--accent-06); + color: var(--text); } -.services-jump-nav__item.is-active::before, -.services-jump-nav__item:hover::before { +.services-jump-nav__item.is-active::before { opacity: 1; - transform: scaleX(1); } .services-jump-nav__item svg { - position: relative; flex: 0 0 auto; - color: var(--service-color); -} - -.services-jump-nav__item span { - position: relative; + color: var(--accent-strong); } .services-list { @@ -211,48 +211,38 @@ .services-section-heading h2, .services-final-cta h2 { margin: 14px 0 18px; + font-family: var(--font-display); + font-weight: 600; font-size: clamp(2rem, 4vw, 3.6rem); - line-height: 1.06; - letter-spacing: 0; + line-height: 1.08; + letter-spacing: -0.015em; } .services-section-heading p, .services-final-cta p { margin: 0; - color: #6f7b95; + color: var(--text-muted); font-size: 1rem; line-height: 1.75; } -.services-list__inner { display: grid; gap: 36px; } +.services-list__inner { display: grid; gap: 28px; } .service-detail { - --service-color: #6ee7f2; - --service-rgb: 136, 120, 255; display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(36px, 7vw, 96px); align-items: center; - min-height: 560px; + min-height: 540px; padding: clamp(32px, 5vw, 64px); scroll-margin-top: 120px; - border: 1px solid rgba(122, 151, 185, 0.14); + border: 1px solid var(--border); border-radius: 14px; - background: - linear-gradient(135deg, rgba(var(--service-rgb), 0.055), transparent 42%), - rgba(8, 14, 24, 0.6); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.045), - 0 24px 64px rgba(0, 0, 0, 0.22); + background: var(--surface); } .service-detail:nth-child(even) .service-detail__visual { order: 2; } -.services-tone--discord { --service-color: #7888f8; --service-rgb: 88, 101, 242; } -.services-tone--web { --service-color: #38b8f8; --service-rgb: 14, 165, 233; } -.services-tone--app { --service-color: #e878b8; --service-rgb: 236, 72, 153; } -.services-tone--individual { --service-color: #c078f8; --service-rgb: 168, 85, 247; } - .service-detail__visual, .service-detail__content { min-width: 0; @@ -265,9 +255,10 @@ position: absolute; top: -34px; right: 0; - color: rgba(var(--service-rgb), 0.14); + color: var(--border); + font-family: var(--font-display); font-size: clamp(4rem, 9vw, 7.5rem); - font-weight: 900; + font-weight: 700; line-height: 1; } @@ -279,12 +270,9 @@ justify-content: space-between; padding: 28px; overflow: hidden; - border: 1px solid rgba(var(--service-rgb), 0.2); + border: 1px solid var(--border); border-radius: 12px; - background: - radial-gradient(circle at 18% 18%, rgba(var(--service-rgb), 0.14), transparent 34%), - linear-gradient(145deg, rgba(var(--service-rgb), 0.07), rgba(3, 6, 12, 0.9)); - box-shadow: inset 0 1px rgba(255, 255, 255, 0.05), 0 22px 48px rgba(0, 0, 0, 0.28); + background: var(--bg-elevated); } .service-example-placeholder__heading { @@ -294,29 +282,31 @@ } .service-example-placeholder__heading span { - color: var(--service-color); + color: var(--accent-strong); + font-family: var(--font-mono); font-size: 0.64rem; - font-weight: 800; - letter-spacing: 0.13em; + font-weight: 600; + letter-spacing: 0.12em; text-transform: uppercase; } .service-example-placeholder__heading h4 { - margin: 3px 0 0; - color: #e5e9f5; + margin: 5px 0 0; + color: var(--text); + font-family: var(--font-display); + font-weight: 600; font-size: 1rem; } .service-detail__visual-icon { display: grid; - width: 54px; - height: 54px; + width: 52px; + height: 52px; place-items: center; - border: 1px solid rgba(var(--service-rgb), 0.3); - border-radius: 12px; - background: rgba(var(--service-rgb), 0.12); - color: var(--service-color); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); + border: 1px solid var(--accent-24); + border-radius: 10px; + background: var(--accent-10); + color: var(--accent-strong); } .service-example-placeholder__status { @@ -324,44 +314,53 @@ align-items: center; gap: 8px; margin-top: 18px; - color: #68748d; - font-size: 0.72rem; + color: var(--text-dim); + font-family: var(--font-mono); + font-size: 0.7rem; } .service-example-placeholder__status i { - width: 7px; - height: 7px; + width: 6px; + height: 6px; border-radius: 50%; - background: var(--service-color); - box-shadow: 0 0 12px rgba(var(--service-rgb), 0.7); + background: var(--accent-strong); } .service-detail__label { - color: var(--service-color); + color: var(--accent-strong); + font-family: var(--font-mono); font-size: 0.7rem; - font-weight: 800; - letter-spacing: 0.16em; + font-weight: 600; + letter-spacing: 0.14em; text-transform: uppercase; } .service-detail h3 { margin: 14px 0 18px; - font-size: clamp(2rem, 4vw, 3.25rem); - line-height: 1.05; - letter-spacing: 0; + font-family: var(--font-display); + font-weight: 600; + font-size: clamp(2rem, 4vw, 3.1rem); + line-height: 1.08; + letter-spacing: -0.015em; } .service-detail__description, -.service-detail__result { color: #75819a; line-height: 1.72; } +.service-detail__result { color: var(--text-muted); line-height: 1.72; } .service-detail__description { margin: 0 0 16px; font-size: 1rem; } -.service-detail__result { margin: 0 0 26px; padding-left: 14px; border-left: 2px solid var(--service-color); color: #aab4cf; } +.service-detail__result { + margin: 0 0 26px; + padding-left: 14px; + border-left: 2px solid var(--accent); + color: var(--text); +} .service-detail__subheading { margin: 0 0 12px; - color: #717d96; - font-size: 0.67rem; - font-weight: 800; - letter-spacing: 0.14em; + color: var(--text-dim); + font-family: var(--font-mono); + font-size: 0.65rem; + font-weight: 600; + letter-spacing: 0.13em; text-transform: uppercase; } @@ -369,23 +368,44 @@ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 18px; - margin: 0 0 28px; + margin: 0 0 30px; padding: 0; list-style: none; } -.service-detail__features li { display: flex; min-width: 0; align-items: flex-start; gap: 9px; color: #c5cce0; font-size: 0.88rem; line-height: 1.45; } -.service-detail__features svg { flex: 0 0 auto; margin-top: 2px; color: var(--service-color); } - -.service-detail__tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 28px; } -.service-detail__tags span { padding: 6px 11px; border: 1px solid rgba(var(--service-rgb), 0.17); border-radius: 999px; background: rgba(var(--service-rgb), 0.07); color: #8e99b2; font-size: 0.72rem; font-weight: 650; } +.service-detail__features li { + display: flex; + min-width: 0; + align-items: flex-start; + gap: 9px; + color: var(--text-muted); + font-size: 0.88rem; + line-height: 1.48; +} +.service-detail__features svg { flex: 0 0 auto; margin-top: 2px; color: var(--accent-strong); } -.service-detail__link { display: inline-flex; align-items: center; gap: 8px; color: var(--service-color); font-size: 0.88rem; font-weight: 750; transition: gap 160ms var(--ease-out-strong), color 160ms var(--ease-out-strong), transform 120ms var(--ease-out-strong); } -.service-detail__link:hover { gap: 12px; color: #fff; } +.service-detail__link { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--text); + font-size: 0.88rem; + font-weight: 600; + text-decoration: none; + transition: gap 160ms var(--ease-out-strong), color 160ms var(--ease-out-strong); +} +.service-detail__link:hover { gap: 12px; color: var(--accent-strong); } .service-detail__link:active { transform: scale(0.98); } .services-final-cta { position: relative; z-index: 1; padding: 110px 0; } -.services-final-cta__card { padding: clamp(42px, 7vw, 84px); border: 1px solid rgba(110, 231, 242, 0.16); border-radius: 14px; background: radial-gradient(circle at 50% 0, rgba(110, 231, 242, 0.12), transparent 55%), rgba(8, 14, 24, 0.68); text-align: center; } +.services-final-cta__card { + padding: clamp(42px, 7vw, 84px); + border: 1px solid var(--border); + border-radius: 14px; + background: var(--surface); + text-align: center; +} +.services-final-cta__card > span { justify-content: center; } .services-final-cta__card p { max-width: 580px; margin: 0 auto 32px; } @media (max-width: 980px) { @@ -403,8 +423,8 @@ .services-jump-nav { grid-template-columns: 1fr; } .services-list { padding: 76px 0; } .services-section-heading { margin-bottom: 40px; } - .service-detail { padding: 22px; border-radius: 20px; } + .service-detail { padding: 22px; border-radius: 14px; } .service-example-placeholder { min-height: 190px; padding: 20px; } .service-detail__features { grid-template-columns: 1fr; } .services-final-cta { padding: 76px 0; } -} +} \ No newline at end of file