diff --git a/frontend/src/pages/sub/SubPage.css b/frontend/src/pages/sub/SubPage.css index 989974197..7c897e514 100644 --- a/frontend/src/pages/sub/SubPage.css +++ b/frontend/src/pages/sub/SubPage.css @@ -1,78 +1,18 @@ .subscription-page { - /* --sub-grad-* paints graphics, --sub-ink-* paints text: the cyan end darkens - so text clears 4.5:1. --sub-accent is ACCENT.primary in SubPage.tsx. */ - --sub-grad-from: #8b5cf6; - --sub-grad-to: #06b6d4; - --sub-ink-from: #6d28d9; - --sub-ink-to: #0e7490; - --sub-accent: #7c3aed; - --bg-page: linear-gradient(135deg, #e9e4ff 0%, #ddeefc 52%, #e2f7f2 100%); - --sub-card-bg: rgba(255, 255, 255, 0.72); - --sub-card-border: rgba(255, 255, 255, 0.7); - --sub-card-shadow: 0 1px 3px rgba(15, 23, 42, 0.05), 0 20px 56px rgba(124, 58, 237, 0.16); - --sub-card-sheen: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.75), - rgba(255, 255, 255, 0) 42%, - rgba(124, 58, 237, 0.22) 88% - ); - --sub-blob-1: rgba(139, 92, 246, 0.55); - --sub-blob-2: rgba(6, 182, 212, 0.45); - --sub-grid: rgba(124, 58, 237, 0.06); - --sub-hairline: linear-gradient(90deg, rgba(139, 92, 246, 0.4), rgba(6, 182, 212, 0.4)); - --sub-tile-bg: rgba(124, 58, 237, 0.05); - --sub-tile-border: rgba(124, 58, 237, 0.12); - --sub-row-bg: rgba(124, 58, 237, 0.045); - --sub-row-border: rgba(124, 58, 237, 0.11); - --sub-row-bg-hover: rgba(124, 58, 237, 0.09); - --sub-row-border-hover: rgba(124, 58, 237, 0.3); - --sub-row-glow: rgba(124, 58, 237, 0.28); - --sub-glass-bg: rgba(255, 255, 255, 0.6); - - position: relative; + --bg-page: #e6e8ec; + --bg-card: #ffffff; min-height: 100vh; background: var(--bg-page); } .subscription-page.is-dark { - --sub-grad-from: #a78bfa; - --sub-grad-to: #22d3ee; - --sub-ink-from: #c4b5fd; - --sub-ink-to: #67e8f9; - --sub-accent: #a78bfa; - --bg-page: radial-gradient(ellipse 120% 90% at 18% -10%, #1f1740 0%, #16171d 52%, #101116 100%); - --sub-card-bg: rgba(35, 37, 43, 0.62); - --sub-card-border: rgba(255, 255, 255, 0.08); - --sub-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 24px 64px rgba(109, 40, 217, 0.24); - --sub-card-sheen: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.16), - rgba(255, 255, 255, 0) 42%, - rgba(167, 139, 250, 0.4) 88% - ); - --sub-blob-1: rgba(139, 92, 246, 0.4); - --sub-blob-2: rgba(34, 211, 238, 0.26); - --sub-grid: rgba(255, 255, 255, 0.035); - --sub-hairline: linear-gradient(90deg, rgba(167, 139, 250, 0.45), rgba(34, 211, 238, 0.45)); - --sub-tile-bg: rgba(167, 139, 250, 0.07); - --sub-tile-border: rgba(167, 139, 250, 0.14); - --sub-row-bg: rgba(167, 139, 250, 0.06); - --sub-row-border: rgba(167, 139, 250, 0.12); - --sub-row-bg-hover: rgba(167, 139, 250, 0.12); - --sub-row-border-hover: rgba(167, 139, 250, 0.35); - --sub-row-glow: rgba(139, 92, 246, 0.45); - --sub-glass-bg: rgba(255, 255, 255, 0.06); + --bg-page: #1a1b1f; + --bg-card: #23252b; } .subscription-page.is-dark.is-ultra { - --bg-page: radial-gradient(ellipse 120% 90% at 18% -10%, #120a2b 0%, #050509 55%, #000 100%); - --sub-card-bg: rgba(16, 16, 19, 0.68); - --sub-card-border: rgba(255, 255, 255, 0.055); - --sub-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.6), 0 24px 64px rgba(88, 28, 135, 0.3); - --sub-blob-1: rgba(139, 92, 246, 0.22); - --sub-blob-2: rgba(34, 211, 238, 0.14); - --sub-grid: rgba(255, 255, 255, 0.022); - --sub-glass-bg: rgba(255, 255, 255, 0.04); + --bg-page: #000; + --bg-card: #101013; } .subscription-page .ant-layout, @@ -80,72 +20,6 @@ background: transparent; } -/* aurora backdrop */ -.sub-aurora { - position: fixed; - inset: 0; - z-index: 0; - overflow: hidden; - pointer-events: none; -} - -.sub-aurora-grid { - position: absolute; - inset: 0; - background-image: - linear-gradient(var(--sub-grid) 1px, transparent 1px), - linear-gradient(90deg, var(--sub-grid) 1px, transparent 1px); - background-size: 48px 48px; - background-position: center; - -webkit-mask-image: radial-gradient(ellipse at 50% 30%, black 20%, transparent 72%); - mask-image: radial-gradient(ellipse at 50% 30%, black 20%, transparent 72%); -} - -.sub-aurora::before, -.sub-aurora::after { - content: ''; - position: absolute; - width: 70vmax; - height: 70vmax; - max-width: 820px; - max-height: 820px; - border-radius: 50%; - filter: blur(80px); - will-change: transform; -} - -.sub-aurora::before { - top: -22vmax; - left: -16vmax; - background: radial-gradient(circle, var(--sub-blob-1) 0%, transparent 65%); - animation: sub-blob-a 28s ease-in-out infinite alternate; -} - -.sub-aurora::after { - bottom: -24vmax; - right: -18vmax; - background: radial-gradient(circle, var(--sub-blob-2) 0%, transparent 65%); - animation: sub-blob-b 34s ease-in-out infinite alternate; -} - -@keyframes sub-blob-a { - 0% { - transform: translate(0, 0) scale(1); - } - 100% { - transform: translate(16vw, 14vh) scale(1.18); - } -} - -@keyframes sub-blob-b { - 0% { - transform: translate(0, 0) scale(1); - } - 100% { - transform: translate(-14vw, -12vh) scale(1.15); - } -} - .sub-content { position: relative; z-index: 1; @@ -158,35 +32,24 @@ } .subscription-page .sub-card { - position: relative; - border-radius: 20px; - border: 1px solid var(--sub-card-border); - background: var(--sub-card-bg); - box-shadow: var(--sub-card-shadow); - -webkit-backdrop-filter: blur(24px) saturate(180%); - backdrop-filter: blur(24px) saturate(180%); + border-radius: 12px; + background: var(--bg-card); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); } -/* Hairline gradient rim: a padded sheen layer with its own middle masked out. */ -.subscription-page .sub-card::before { - content: ''; - position: absolute; - inset: 0; - z-index: 0; - border-radius: inherit; - padding: 1px; - background: var(--sub-card-sheen); - -webkit-mask: - linear-gradient(#000 0 0) content-box, - linear-gradient(#000 0 0); - -webkit-mask-composite: xor; - mask-composite: exclude; - pointer-events: none; +.subscription-page.is-dark .sub-card { + box-shadow: + 0 1px 2px rgba(0, 0, 0, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.03); +} + +.subscription-page.is-dark.is-ultra .sub-card { + box-shadow: + 0 1px 2px rgba(0, 0, 0, 0.6), + inset 0 1px 0 rgba(255, 255, 255, 0.025); } .sub-card > .ant-card-body { - position: relative; - z-index: 1; padding: 28px; } @@ -200,7 +63,7 @@ font-size: 13px; } -/* Gradient hairline shared by the header, the stats grid and the footer. */ +/* Divider shared by the header, the stats grid and the footer. */ .sub-header::after, .sub-stats::before, .sub-footer::before { @@ -208,8 +71,7 @@ position: absolute; inset-inline: 0; height: 1px; - background: var(--sub-hairline); - opacity: 0.7; + background: var(--ant-color-border-secondary); } /* header */ @@ -242,8 +104,7 @@ align-items: center; justify-content: center; border-radius: 13px; - background: linear-gradient(135deg, var(--sub-grad-from), var(--sub-grad-to)); - box-shadow: 0 8px 20px -8px var(--sub-row-glow); + background: var(--ant-color-primary); color: #fff; font-size: 20px; font-weight: 600; @@ -290,20 +151,6 @@ font-size: 18px; } -.subscription-page .toolbar-btn { - border-color: var(--sub-row-border); - background: var(--sub-glass-bg); - color: var(--sub-accent); - -webkit-backdrop-filter: blur(8px); - backdrop-filter: blur(8px); -} - -.subscription-page .toolbar-btn:hover { - border-color: var(--sub-row-border-hover); - background: var(--sub-row-bg-hover); - color: var(--sub-accent); -} - .sub-announce { margin-bottom: 24px; } @@ -352,11 +199,7 @@ font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; - background: linear-gradient(135deg, var(--sub-ink-from), var(--sub-ink-to)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - color: var(--sub-ink-from); + color: var(--ant-color-text); } .sub-big-unit { @@ -365,8 +208,6 @@ } .sub-hero.is-alert .sub-big-num { - background: none; - -webkit-text-fill-color: var(--ant-color-error); color: var(--ant-color-error); } @@ -386,8 +227,8 @@ .sub-stat { padding: 10px 12px; border-radius: 12px; - border: 1px solid var(--sub-tile-border); - background: var(--sub-tile-bg); + border: 1px solid var(--ant-color-border-secondary); + background: var(--ant-color-fill-quaternary); } .sub-stat-value { @@ -408,20 +249,14 @@ margin-top: 28px; } -.sub-tabs.ant-tabs .ant-tabs-ink-bar { - height: 3px; - border-radius: 2px; - background: linear-gradient(90deg, var(--sub-grad-from), var(--sub-grad-to)); -} - .sub-tab-count { margin-inline-start: 6px; padding: 0 7px; border-radius: 10px; font-size: 12px; - background: var(--sub-tile-bg); - border: 1px solid var(--sub-tile-border); - color: var(--sub-accent); + background: var(--ant-color-fill-quaternary); + border: 1px solid var(--ant-color-border-secondary); + color: var(--ant-color-primary); } .sub-rows { @@ -437,20 +272,16 @@ min-width: 0; padding: 10px 12px; border-radius: 12px; - background: var(--sub-row-bg); - border: 1px solid var(--sub-row-border); + background: var(--ant-color-fill-quaternary); + border: 1px solid var(--ant-color-border-secondary); transition: background 160ms ease, - border-color 160ms ease, - box-shadow 160ms ease, - transform 160ms ease; + border-color 160ms ease; } .sub-row:hover { - background: var(--sub-row-bg-hover); - border-color: var(--sub-row-border-hover); - box-shadow: 0 8px 20px -14px var(--sub-row-glow); - transform: translateY(-1px); + background: var(--ant-color-primary-bg); + border-color: var(--ant-color-primary-border); } .sub-row-tag { @@ -481,7 +312,7 @@ } a.sub-row-title:hover { - color: var(--sub-accent); + color: var(--ant-color-primary); } .sub-row-url { @@ -554,8 +385,8 @@ a.sub-row-title:hover { margin-top: 8px; padding: 16px; border-radius: 14px; - border: 1px dashed var(--sub-row-border-hover); - background: var(--sub-row-bg); + border: 1px dashed var(--ant-color-primary-border); + background: var(--ant-color-fill-quaternary); } .sub-qr-code { @@ -596,9 +427,9 @@ a.sub-row-title:hover { align-items: center; justify-content: center; border-radius: 9px; - border: 1px solid var(--sub-tile-border); - background: linear-gradient(135deg, var(--sub-row-bg-hover), var(--sub-tile-bg)); - color: var(--sub-accent); + border: 1px solid var(--ant-color-border-secondary); + background: var(--ant-color-primary-bg); + color: var(--ant-color-primary); font-weight: 600; } @@ -620,7 +451,7 @@ a.sub-row-title:hover { flex-shrink: 0; border-radius: 9px; object-fit: cover; - box-shadow: 0 0 0 1px var(--sub-tile-border); + box-shadow: 0 0 0 1px var(--ant-color-border-secondary); } .sub-app-name { @@ -664,17 +495,6 @@ a.sub-row-title:hover { gap: 6px; } -@media (prefers-reduced-motion: reduce) { - .sub-aurora::before, - .sub-aurora::after { - animation: none; - } - - .sub-row:hover { - transform: none; - } -} - @media (max-width: 576px) { .sub-content { padding: 16px 8px; @@ -684,15 +504,6 @@ a.sub-row-title:hover { padding: 16px; } - /* One static blob: two animated 70vmax blurs drop frames on low-end phones. */ - .sub-aurora::before { - animation: none; - } - - .sub-aurora::after { - display: none; - } - .sub-hero { grid-template-columns: minmax(0, 1fr); gap: 20px; diff --git a/frontend/src/pages/sub/SubPage.tsx b/frontend/src/pages/sub/SubPage.tsx index 82acec7be..725d3571f 100644 --- a/frontend/src/pages/sub/SubPage.tsx +++ b/frontend/src/pages/sub/SubPage.tsx @@ -60,23 +60,6 @@ const apps = buildSubApps({ subUrl, sId, subTitle }); const initialPlatform = detectPlatform(navigator.userAgent); const RTL_LANGUAGES = new Set(['fa-IR', 'ar-EG']); -// The sub page runs its own violet accent, so every antd control on it picks the -// hue up instead of the panel blue useTheme pins. Mirrored in SubPage.css. -const ACCENT = { - light: { - primary: '#7c3aed', - hover: '#8b5cf6', - active: '#6d28d9', - rail: 'rgba(124, 58, 237, 0.16)', - }, - dark: { - primary: '#a78bfa', - hover: '#c4b5fd', - active: '#8b5cf6', - rail: 'rgba(167, 139, 250, 0.18)', - }, -}; - export default function SubPage() { const { t } = useTranslation(); const { isDark, isUltra, antdThemeConfig } = useTheme(); @@ -150,36 +133,10 @@ export default function SubPage() { .filter(Boolean) .join(' '); - const themeConfig = useMemo(() => { - const accent = isDark ? ACCENT.dark : ACCENT.light; - const primary = { - colorPrimary: accent.primary, - colorPrimaryHover: accent.hover, - colorPrimaryActive: accent.active, - }; - return { - ...antdThemeConfig, - token: { - ...antdThemeConfig.token, - ...primary, - colorLink: accent.primary, - colorInfo: accent.primary, - }, - components: { - ...antdThemeConfig.components, - Button: { ...antdThemeConfig.components?.Button, ...primary }, - Progress: { ...antdThemeConfig.components?.Progress, remainingColor: accent.rail }, - }, - }; - }, [antdThemeConfig, isDark]); - return ( - + {messageContextHolder} -