style(sub): match the subscription page to the panel theme

The sub page ran its own violet/cyan palette, an animated aurora
backdrop, a grid overlay and a glass card, so it looked unrelated to
every other panel page. It now uses the panel shell background and card
colors for light, dark and ultra-dark, the panel's antd theme (blue
primary) unmodified, and antd tokens for dividers, tiles and rows.
This commit is contained in:
MHSanaei
2026-10-12 01:08:24 +02:00
parent c5e1e54c75
commit fd6c5925ce
2 changed files with 41 additions and 273 deletions
+40 -229
View File
@@ -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;
+1 -44
View File
@@ -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 (
<ConfigProvider theme={themeConfig} direction={direction}>
<ConfigProvider theme={antdThemeConfig} direction={direction}>
{messageContextHolder}
<Layout className={pageClass} dir={direction}>
<div className="sub-aurora" aria-hidden="true">
<span className="sub-aurora-grid" />
</div>
<Layout.Content className="sub-content">
<Card className="sub-card">
<SubHeader