From cf7598b33784b6e41eb7338900e0acc22fb7d884 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Thu, 13 Aug 2026 11:05:00 +0800 Subject: [PATCH] refactor(frontend): remove generic AI-slop styling --- frontend/src/app/globals.css | 1138 +++-------------- frontend/src/app/membership/page.tsx | 19 +- frontend/src/app/page.tsx | 56 +- .../src/app/reports/[reportId]/not-found.tsx | 2 +- frontend/src/components/admin/admin-app.tsx | 62 +- .../admin/administrators-resource.tsx | 2 +- .../components/admin/audit-logs-resource.tsx | 4 +- .../admin/billing-operations-resources.tsx | 8 +- .../admin/credit-transactions-resource.tsx | 4 +- .../admin/feature-flags-management.tsx | 4 +- .../src/components/admin/mfa-security.tsx | 37 +- .../src/components/admin/model-management.tsx | 11 +- .../components/admin/package-management.tsx | 4 +- .../components/admin/payment-management.tsx | 2 +- .../components/admin/product-management.tsx | 7 +- .../src/components/admin/roles-resource.tsx | 6 +- .../src/components/admin/users-resource.tsx | 6 +- frontend/src/components/email-otp-login.tsx | 1 - .../personal-report-center.tsx | 25 +- .../personal-report-document-view.tsx | 33 +- .../personal-report/personal-report-page.tsx | 8 +- frontend/tests/admin-contracts.test.ts | 6 +- frontend/tests/membership-page.test.ts | 42 +- frontend/tests/personal-report-view.test.ts | 4 +- 24 files changed, 377 insertions(+), 1114 deletions(-) diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 81889881..aaac8d08 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -138,7 +138,7 @@ button:disabled { cursor: default; opacity: .45; } [data-sonner-toast] [data-title] { font-size: var(--type-body-sm); font-weight: 600; } [data-sonner-toast] [data-description] { color: var(--color-ink-secondary) !important; font-size: var(--type-caption); line-height: 1.5; } .birth-time-transition-fields { min-width: 0; display: grid; gap: 14px; margin: 0; padding: 0; border: 0; } -.birth-time-assessment-overlay { position: absolute; z-index: 2; inset: 0; display: grid; place-items: center; padding: var(--space-6); border-radius: inherit; background: color-mix(in srgb, var(--color-canvas-soft) 94%, transparent); backdrop-filter: blur(2px); } +.birth-time-assessment-overlay { position: absolute; z-index: 2; inset: 0; display: grid; place-items: center; padding: var(--space-6); border-radius: inherit; background: var(--color-canvas-soft); } .birth-time-assessment-progress { width: min(360px, 100%); display: grid; justify-items: center; gap: var(--space-2); color: var(--color-ink-secondary); text-align: center; } .birth-time-assessment-progress strong { margin-top: var(--space-2); color: var(--color-ink); font-family: var(--font-display); font-size: var(--type-title-md); font-weight: 400; } .birth-time-assessment-progress > span { font-size: var(--type-body-sm); line-height: 1.55; text-wrap: pretty; word-break: auto-phrase; } @@ -423,7 +423,7 @@ button:disabled { cursor: default; opacity: .45; } .birth-time-detail-grid { display: grid; grid-template-columns: minmax(0, 180px) minmax(0, 1fr); align-items: end; gap: var(--space-3); } .birth-time-detail-grid > label { min-width: 0; } .birth-time-detail-note { padding-bottom: 12px; } -.birth-time-legacy-note { padding: var(--space-3); border-left: 2px solid var(--color-warning); background: var(--color-canvas-muted); } +.birth-time-legacy-note { padding: var(--space-3) 0; border-top: 1px solid var(--color-border); background: transparent; } .birth-time-rectification { width: 100%; min-width: 0; max-width: 680px; display: grid; box-sizing: border-box; gap: var(--space-5); } .birth-time-assessment-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); } .birth-time-assessment-heading > div { display: grid; gap: var(--space-1); } @@ -434,7 +434,7 @@ button:disabled { cursor: default; opacity: .45; } .birth-time-range-summary > div { display: grid; gap: var(--space-1); padding: var(--space-3) var(--space-4); background: var(--color-canvas); } .birth-time-range-summary dt { color: var(--color-ink-tertiary); font-size: var(--type-overline); } .birth-time-range-summary dd { margin: 0; color: var(--color-ink); font-size: var(--type-body-sm); font-variant-numeric: tabular-nums; } -.birth-time-assistant-intent, .birth-time-assessment-unavailable { margin: 0; padding: var(--space-4); border-left: 2px solid var(--color-action); background: var(--color-action-soft); color: var(--color-ink); font-size: var(--type-body-sm); line-height: 1.6; word-break: keep-all; overflow-wrap: break-word; } +.birth-time-assistant-intent, .birth-time-assessment-unavailable { margin: 0; padding: var(--space-3) 0; border-top: 1px solid var(--color-border); background: transparent; color: var(--color-ink); font-size: var(--type-body-sm); line-height: 1.6; word-break: keep-all; overflow-wrap: break-word; } .birth-time-question-list { display: grid; gap: var(--space-4); } .birth-time-question-progress { display: flex; justify-content: space-between; color: var(--color-ink-secondary); font-size: var(--type-caption); } .birth-time-question { display: grid; gap: var(--space-3); margin: 0; padding: var(--space-4) 0 0; border: 0; border-top: 1px solid var(--color-border); } @@ -462,7 +462,7 @@ button:disabled { cursor: default; opacity: .45; } .birth-time-candidate-grid > div { display: grid; gap: var(--space-1); padding: var(--space-3); background: var(--color-canvas-soft); } .birth-time-candidate-grid dt { color: var(--color-ink-tertiary); font-size: var(--type-overline); } .birth-time-candidate-grid dd { margin: 0; color: var(--color-ink); font-size: var(--type-body-sm); font-variant-numeric: tabular-nums; } -.birth-time-confirmation-panel { display: grid; gap: var(--space-3); padding: var(--space-4); border-left: 2px solid var(--color-action); background: var(--color-action-soft); } +.birth-time-confirmation-panel { display: grid; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); background: var(--color-canvas); } .birth-time-confirmation-panel > b { color: var(--color-ink); font-size: var(--type-body-sm); } .birth-time-confirmation-panel > p { margin: 0; color: var(--color-ink-secondary); font-size: var(--type-caption); line-height: 1.6; word-break: keep-all; overflow-wrap: break-word; } .birth-time-next-step { box-sizing: border-box; width: 100%; display: grid; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-action-soft); } @@ -486,9 +486,9 @@ button:disabled { cursor: default; opacity: .45; } .birth-time-draft-domain dt { color: var(--color-ink-tertiary); font-size: var(--type-overline); } .birth-time-draft-domain dd { margin: 0; color: var(--color-ink); font-size: var(--type-body-sm); } .birth-time-draft-fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); } -.birth-time-scoring-status { padding: var(--space-4); border-left: 2px solid var(--color-action); background: var(--color-action-soft); } +.birth-time-scoring-status { padding: var(--space-4); border: 1px solid var(--color-border); background: var(--color-canvas); } .birth-time-scoring-status > b { font-size: var(--type-body-sm); } -.birth-time-success-note { padding: var(--space-4); border-left: 2px solid var(--color-success); background: var(--color-success-muted); color: var(--color-success); } +.birth-time-success-note { padding: var(--space-3) 0; border-top: 1px solid var(--color-border); background: transparent; color: var(--color-success); } .birth-time-candidate-terminal { justify-items: start; } .birth-time-candidate-result, .birth-time-candidate-result > *, .birth-time-confirmation-panel > * { min-width: 0; max-width: 100%; } .rectification-session-surface { width: min(720px, 100%); min-width: 0; margin: 0 auto; } @@ -551,7 +551,12 @@ button:disabled { cursor: default; opacity: .45; } .product-entrypoints { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr); gap: var(--space-3); } .product-entrypoints small { color: var(--color-ink-secondary); line-height: 1.45; font-size: var(--type-caption); } .daily-starlanguage-card, .birth-rectification-card { min-height: 132px; display: grid; gap: var(--space-3); padding: var(--space-5); border: 1px solid color-mix(in srgb, var(--color-action) 16%, var(--color-border)); border-radius: var(--radius-lg); background: var(--color-canvas); } -.product-entrypoint-card { position: relative; transition: border-color 120ms ease-out, background-color 120ms ease-out, transform 120ms ease-out; } +.product-entrypoint-card { + position: relative; + overflow: hidden; + transition: background-color 180ms ease-out; +} + .product-entrypoint-hitarea { position: absolute; z-index: 2; inset: 0; width: 100%; min-height: 0; padding: 0; border: 0; border-radius: inherit; background: transparent; cursor: pointer; } .product-entrypoint-card > :not(.product-entrypoint-hitarea) { position: relative; z-index: 1; pointer-events: none; } .product-entrypoint-card:has(.product-entrypoint-hitarea:not(:disabled):active) { border-color: color-mix(in srgb, var(--color-action) 44%, var(--color-border)); background: var(--color-action-soft); transform: translateY(0); } @@ -561,8 +566,6 @@ button:disabled { cursor: default; opacity: .45; } } .product-entrypoint-card:has(.product-entrypoint-hitarea:disabled) { opacity: 1; } .product-entrypoint-hitarea:disabled { cursor: not-allowed; } -.daily-starlanguage-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); } -.daily-starlanguage-heading > span { color: var(--color-action); font-size: var(--type-overline); font-weight: 600; letter-spacing: 1.5px; } .daily-starlanguage-card dl, .birth-rectification-card dl { display: grid; gap: var(--space-2); margin: 0; } .daily-starlanguage-card dl > div, .birth-rectification-card dl > div { display: grid; gap: 4px; } .daily-starlanguage-card dt, .birth-rectification-card dt { color: var(--color-ink-secondary); font-size: var(--type-caption); } @@ -812,8 +815,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .auth-story-brand, .auth-brand { display: flex; align-items: center; gap: var(--space-3); font-family: var(--font-display); font-size: var(--type-title-lg); } .auth-story-brand strong, .auth-brand strong { font-weight: 400; } .auth-story h2 { max-width: 500px; margin: var(--space-4) 0 var(--space-5); font-family: var(--font-display); font-size: var(--type-display-lg); font-weight: 400; letter-spacing: -1px; line-height: 1.15; text-wrap: balance; } -.auth-story > div > p:not(.auth-kicker) { max-width: 480px; margin: 0; color: var(--color-ink-secondary); font-size: var(--type-body-md); line-height: 1.65; text-wrap: pretty; } -.auth-kicker { margin: 0; color: var(--color-action); font-size: var(--type-overline); font-weight: 500; letter-spacing: 1.5px; text-transform: uppercase; } +.auth-story > div > p { max-width: 480px; margin: 0; color: var(--color-ink-secondary); font-size: var(--type-body-md); line-height: 1.65; text-wrap: pretty; } .auth-footnote { margin: 0; color: var(--color-ink-tertiary); font-size: var(--type-caption); } .auth-panel { width: 100%; min-width: 0; display: flex; flex-direction: column; justify-content: center; padding: var(--space-12); border: 0; border-radius: 0; background: var(--color-canvas); } .auth-brand { align-items: center; gap: 10px; font-size: 17px; display: none; margin-bottom: var(--space-10); } @@ -902,7 +904,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .auth-shell { min-height: 100dvh; grid-template-columns: 1fr; grid-template-rows: auto 1fr; border-radius: 0; box-shadow: none; } .auth-story { min-height: 248px; padding: var(--space-8) var(--space-6); } .auth-story h2 { max-width: 560px; margin: var(--space-3) 0 0; font-size: var(--type-display-sm); } - .auth-story > div > p:not(.auth-kicker), .auth-footnote { display: none; } + .auth-story > div > p, .auth-footnote { display: none; } .auth-panel { padding: var(--space-8) var(--space-6); } .auth-panel h1 { font-size: var(--type-display-md); } .admin-header { padding: 0 var(--space-4); } @@ -967,133 +969,51 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled } .starter-hero { - position: relative; - min-height: 220px; - overflow: hidden; - display: grid; - grid-template-columns: minmax(0, 1fr) 250px; - align-items: center; - gap: var(--space-8); + min-height: 0; + display: block; padding: var(--space-10); - border: 1px solid color-mix(in srgb, var(--color-action) 14%, var(--color-border)); - border-radius: var(--radius-xl); - background: radial-gradient(circle at 82% 36%, rgba(133, 67, 47, .12), transparent 33%), linear-gradient(135deg, #fbfaf7 0%, #f5f1eb 100%); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + background: var(--color-canvas-soft); } -.starter-hero::after { - position: absolute; - inset: 0; - opacity: .2; - pointer-events: none; - background-image: radial-gradient(rgba(29, 29, 31, .24) .45px, transparent .45px); - background-size: 6px 6px; - content: ""; - mask-image: linear-gradient(to right, transparent 8%, #000 72%); -} - -.starter-hero-copy { - position: relative; - z-index: 1; - max-width: 720px; -} +.starter-hero-copy { max-width: 720px; } .starter-greeting { margin: 0 0 var(--space-3); color: var(--color-action); font-size: var(--type-body-sm); font-weight: 600; - letter-spacing: .02em; } .starter-hero h1 { - max-width: 980px; + max-width: 760px; margin: 0; color: var(--color-ink); - font-family: var(--font-display); - font-size: clamp(42px, 5.4vw, 68px); - font-weight: 400; - letter-spacing: -.055em; - line-height: .98; + font-family: var(--font-body); + font-size: clamp(34px, 5vw, 52px); + font-weight: 680; + letter-spacing: -.04em; + line-height: 1.08; text-wrap: balance; } .starter-hero-note { max-width: 590px; - margin: var(--space-5) 0 0; + margin: var(--space-4) 0 0; color: var(--color-ink-secondary); font-size: var(--type-body-sm); - line-height: 1.7; + line-height: 1.65; text-wrap: pretty; } -.starter-celestial-visual { - position: relative; - z-index: 1; - width: 232px; - height: 178px; - justify-self: end; -} - -.starter-orbit { - position: absolute; - border: 1px solid color-mix(in srgb, var(--color-action) 34%, transparent); - border-radius: 50%; -} - -.starter-orbit-outer { - inset: 8px 10px; - transform: rotate(-12deg); -} - -.starter-orbit-inner { - inset: 38px 50px; - border-color: color-mix(in srgb, var(--color-ink-tertiary) 42%, transparent); - transform: rotate(20deg); -} - -.starter-orbit-dot { - position: absolute; - width: 9px; - height: 9px; - border-radius: 50%; - background: var(--color-action); - box-shadow: 0 0 0 5px color-mix(in srgb, var(--color-action-soft) 72%, transparent); -} - -.starter-orbit-dot-primary { - top: 26px; - right: 37px; -} - -.starter-orbit-dot-secondary { - bottom: 31px; - left: 31px; - width: 6px; - height: 6px; - background: var(--color-ink-tertiary); - box-shadow: none; -} - -.starter-celestial-mark { - position: absolute; - top: 50%; - left: 50%; - width: 54px; - height: 54px; - border: 1px solid color-mix(in srgb, var(--color-action) 18%, var(--color-border)); - border-radius: 50%; - background: color-mix(in srgb, var(--color-canvas) 88%, transparent) url("/jyotish-logo.png") center / 32px 32px no-repeat; - box-shadow: 0 14px 36px -24px rgba(29, 29, 31, .48); - transform: translate(-50%, -50%); -} - .product-entrypoints { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; overflow: hidden; border: 1px solid var(--color-border); - border-radius: var(--radius-xl); + border-radius: var(--radius-lg); background: var(--color-canvas); } @@ -1193,23 +1113,15 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled max-width: 520px; } -.product-entrypoint-kicker { - display: block; - margin-bottom: var(--space-4); - color: var(--color-action); - font-size: var(--type-overline); - font-weight: 600; - letter-spacing: .12em; -} .product-entrypoint-copy h2 { margin: 0; color: var(--color-ink); - font-family: var(--font-display); - font-size: clamp(26px, 2.6vw, 34px); - font-weight: 400; - letter-spacing: -.035em; - line-height: 1.05; + font-family: var(--font-body); + font-size: clamp(24px, 2.4vw, 31px); + font-weight: 650; + letter-spacing: -.03em; + line-height: 1.12; } .product-entrypoint-copy p { @@ -1388,11 +1300,6 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled padding: var(--space-8); } - .starter-celestial-visual { - width: 180px; - height: 150px; - } - .product-entrypoints { grid-template-columns: 1fr; } @@ -1442,15 +1349,6 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled font-size: clamp(38px, 11vw, 54px); } - .starter-celestial-visual { - position: absolute; - top: var(--space-4); - right: calc(var(--space-8) * -1); - width: 180px; - height: 150px; - opacity: .34; - } - .product-entrypoints { grid-template-columns: 1fr; } @@ -1662,7 +1560,6 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .onboarding-card.birth-time-transition-card { max-width: 760px; padding: clamp(20px, 3vw, 32px); border-color: color-mix(in srgb, var(--color-action) 18%, var(--color-border)); border-radius: var(--radius-xl); background: var(--color-canvas); box-shadow: var(--shadow-elevated); } .onboarding-card-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-6); padding-bottom: var(--space-2); } .onboarding-card-heading-copy { display: grid; gap: 5px; } -.onboarding-card-kicker { color: var(--color-action); font-size: var(--type-overline); font-weight: 700; letter-spacing: .08em; } .onboarding-card-heading b { font-size: clamp(22px, 2.6vw, 30px); letter-spacing: -.03em; } .onboarding-card-heading small { max-width: 260px; color: var(--color-ink-secondary); line-height: 1.55; font-size: var(--type-caption); text-wrap: pretty; } .birth-time-intake { gap: var(--space-6); } @@ -1670,9 +1567,9 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .birth-time-source-fieldset legend { margin-bottom: 5px; color: var(--color-ink); font-size: var(--type-title-sm); font-weight: 700; } .birth-time-source-intro { margin: 0 0 var(--space-3); color: var(--color-ink-secondary); font-size: var(--type-caption); line-height: 1.55; } .birth-time-source-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); } -.birth-time-source-option { min-height: 118px; grid-template-columns: 20px minmax(0, 1fr); align-items: start; gap: var(--space-3); padding: 18px; border-color: var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas-soft); transition: border-color 160ms ease-out, background-color 160ms ease-out, box-shadow 160ms ease-out, transform 160ms var(--ease-out); } -.birth-time-source-option:hover { transform: translateY(-2px); box-shadow: 0 8px 20px -18px var(--color-ink); } -.birth-time-source-option.is-selected { border-color: var(--color-action); background: var(--color-action-soft); box-shadow: inset 0 0 0 1px var(--color-action), 0 10px 22px -20px var(--color-action); } +.birth-time-source-option { min-height: 118px; grid-template-columns: 20px minmax(0, 1fr); align-items: start; gap: var(--space-3); padding: 18px; border-color: var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas-soft); transition: border-color 160ms ease-out, background-color 160ms ease-out; } +.birth-time-source-option:hover { border-color: color-mix(in srgb, var(--color-action) 44%, var(--color-border)); } +.birth-time-source-option.is-selected { border-color: var(--color-action); background: var(--color-action-soft); box-shadow: inset 0 0 0 1px var(--color-action); } .birth-time-source-option input { appearance: none; position: relative; width: 16px; min-width: 16px; height: 16px; min-height: 16px; margin: 3px 0 0; border: 1.5px solid var(--color-border-strong); border-radius: 50%; background: var(--color-canvas); } .birth-time-source-option input:checked { border-color: var(--color-action); background: var(--color-action); box-shadow: inset 0 0 0 4px var(--color-action-soft); } .birth-time-source-option > span { gap: 7px; } @@ -1712,7 +1609,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled } .birth-time-period-details .birth-time-skip-button { grid-column: 1 / -1; justify-self: start; min-height: 40px; padding-inline: 13px; border-color: transparent; background: transparent; color: var(--color-action); font-size: var(--type-caption); } .birth-time-period-details .birth-time-skip-button:hover { background: color-mix(in srgb, var(--color-action-soft) 72%, transparent); } -.birth-time-detail-note[role="status"] { display: grid; gap: var(--space-3); padding: var(--space-4); border: 1px solid color-mix(in srgb, var(--color-action) 25%, var(--color-border)); border-left: 3px solid var(--color-action); border-radius: var(--radius-lg); background: var(--color-action-soft); } +.birth-time-detail-note[role="status"] { display: grid; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas-soft); } .birth-time-detail-note[role="status"] p { margin: 0; } .onboarding-card-actions { align-items: center; justify-content: space-between; gap: var(--space-4); padding-top: var(--space-2); } .onboarding-card-action-hint { color: var(--color-ink-secondary); font-size: var(--type-caption); line-height: 1.4; } @@ -1766,9 +1663,8 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled margin: 8px 0 16px; padding: 18px; border: 1px solid var(--color-border); - border-radius: var(--radius-xl); - background: linear-gradient(180deg, var(--color-canvas-muted) 0%, var(--color-canvas) 100%); - box-shadow: var(--shadow-soft); + border-radius: var(--radius-lg); + background: var(--color-canvas-soft); } .rectification-candidates-heading { display: grid; gap: 5px; } .rectification-candidates-heading strong { font-size: var(--type-title-sm); font-family: var(--font-display); font-weight: 600; letter-spacing: -.2px; } @@ -1798,8 +1694,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled } .rectification-candidate:hover:not(:disabled) { border-color: color-mix(in srgb, var(--color-action) 45%, var(--color-border)); - transform: translateY(-1px); - box-shadow: var(--shadow-soft); + background: var(--color-canvas-soft); } .rectification-candidate:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; } .rectification-candidate:disabled { cursor: default; opacity: 1; } @@ -1836,58 +1731,46 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .payment-qr-badge { position: absolute; top: 50%; left: 50%; display: grid; width: 44px; height: 44px; padding: 4px; transform: translate(-50%, -50%); border: 4px solid #fff; border-radius: 12px; background: #fff; box-shadow: 0 2px 10px rgb(0 0 0 / 18%); } .payment-qr-badge svg { display: block; width: 100%; height: 100%; } -/* Global report centre — editorial index, independent from chat sessions. */ +/* Global report centre — quiet archive, independent from chat sessions. */ .report-center-shell { width: 100%; min-height: 100dvh; overflow-x: hidden; padding: 0 clamp(20px, 5vw, 72px) 72px; background: var(--color-canvas-soft); color: var(--color-ink); } -.report-center-topbar { max-width: 1180px; min-height: 68px; display: flex; align-items: center; justify-content: space-between; gap: 20px; margin: 0 auto; border-bottom: 1px solid var(--color-border); color: var(--color-ink-tertiary); font-size: 12px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; } -.report-center-back { min-height: 44px; display: inline-flex; align-items: center; gap: 7px; color: var(--color-ink-secondary); font-size: 14px; font-weight: 500; letter-spacing: 0; text-decoration: none; text-transform: none; } +.report-center-topbar { max-width: 1080px; min-height: 64px; display: flex; align-items: center; justify-content: space-between; gap: 20px; margin: 0 auto; border-bottom: 1px solid var(--color-border); color: var(--color-ink-tertiary); font-size: 12px; } +.report-center-back { min-height: 44px; display: inline-flex; align-items: center; gap: 7px; color: var(--color-ink-secondary); font-size: 14px; font-weight: 500; text-decoration: none; } .report-center-back:hover { color: var(--color-action); } .report-center-back svg, .report-center-section-heading button svg { width: 16px; height: 16px; } -.report-center-hero { max-width: 1180px; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 48px; margin: 0 auto; padding: clamp(56px, 9vw, 104px) 0 52px; } -.report-center-hero > div { max-width: 760px; } -.report-center-kicker { margin: 0 0 12px; color: var(--color-action); font-size: 11px; font-weight: 700; letter-spacing: .14em; } -.report-center-hero h1 { margin: 0; font-size: clamp(48px, 8vw, 88px); font-weight: 720; letter-spacing: -.065em; line-height: .98; } -.report-center-hero > div > p:last-child { max-width: 680px; margin: 24px 0 0; color: var(--color-ink-secondary); font-size: 16px; line-height: 1.75; text-wrap: pretty; } -.report-center-hero > button { min-height: 46px; padding-inline: 18px; border-color: var(--color-action); background: var(--color-action); color: var(--color-on-dark); } -.report-center-summary { max-width: 1180px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0 auto 64px; border-top: 1px solid var(--color-border-strong); border-bottom: 1px solid var(--color-border); } -.report-center-summary > div { min-width: 0; display: grid; gap: 6px; padding: 22px 0; } -.report-center-summary > div + div { padding-left: 28px; border-left: 1px solid var(--color-border); } -.report-center-summary strong { font-size: 22px; font-weight: 680; } -.report-center-summary span { color: var(--color-ink-tertiary); font-size: 12px; } -.report-center-section { max-width: 1180px; margin: 0 auto; } -.report-center-section-heading { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 20px; } -.report-center-section-heading h2 { margin: 0; font-size: 26px; letter-spacing: -.03em; } -.report-center-section-heading button { min-height: 40px; display: inline-flex; align-items: center; gap: 7px; padding: 0 10px; border: 0; background: transparent; color: var(--color-ink-secondary); cursor: pointer; } +.report-center-hero { max-width: 1080px; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 40px; margin: 0 auto; padding: 52px 0 44px; } +.report-center-hero > div { max-width: 720px; } +.report-center-hero h1 { margin: 0; font-family: var(--font-body); font-size: clamp(34px, 5vw, 48px); font-weight: 680; letter-spacing: -.035em; line-height: 1.08; } +.report-center-hero > div > p:not(.report-center-meta) { max-width: 660px; margin: 18px 0 0; color: var(--color-ink-secondary); font-size: 15px; line-height: 1.7; text-wrap: pretty; } +.report-center-meta { margin: 16px 0 0; color: var(--color-ink-tertiary); font-size: 12px; line-height: 1.55; } +.report-center-hero > button { min-height: 44px; padding-inline: 16px; border-color: var(--color-action); background: var(--color-action); color: var(--color-on-dark); } +.report-center-section { max-width: 1080px; margin: 0 auto; } +.report-center-section-heading { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 14px; } +.report-center-section-heading h2 { margin: 0; font-family: var(--font-body); font-size: 20px; font-weight: 650; letter-spacing: -.015em; } +.report-center-section-heading button { min-height: 40px; display: inline-flex; align-items: center; gap: 7px; padding: 0 8px; border: 0; background: transparent; color: var(--color-ink-secondary); cursor: pointer; } .report-center-section-heading button:hover { color: var(--color-action); } .report-center-list { border-top: 1px solid var(--color-border-strong); } -.report-center-card { min-height: 150px; display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; align-items: center; gap: 24px; padding: 26px 0; border-bottom: 1px solid var(--color-border); } -.report-center-card-index { align-self: start; padding-top: 4px; color: var(--color-ink-tertiary); font-size: 12px; font-variant-numeric: tabular-nums; } +.report-center-card { min-height: 126px; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 24px; padding: 22px 0; border-bottom: 1px solid var(--color-border); } .report-center-card-body { min-width: 0; } -.report-center-status { width: fit-content; display: inline-flex; align-items: center; gap: 6px; margin-bottom: 10px; color: var(--color-ink-secondary); font-size: 12px; font-weight: 650; } +.report-center-status { width: fit-content; display: inline-flex; align-items: center; gap: 6px; margin-bottom: 8px; color: var(--color-ink-secondary); font-size: 12px; font-weight: 650; } .report-center-status.is-ready { color: var(--color-success); } .report-center-status.is-generating { color: var(--color-action); } .report-center-status.is-failed, .report-center-failure { color: var(--color-danger); } -.report-center-card h3 { margin: 0; font-size: 20px; letter-spacing: -.02em; } -.report-center-card p { margin: 7px 0; color: var(--color-ink-secondary); font-size: 14px; line-height: 1.55; } +.report-center-card h3 { margin: 0; font-family: var(--font-body); font-size: 18px; font-weight: 650; letter-spacing: -.01em; } +.report-center-card p { margin: 6px 0; color: var(--color-ink-secondary); font-size: 14px; line-height: 1.55; } .report-center-card small { color: var(--color-ink-tertiary); font-size: 12px; } -.report-center-failure { max-width: 180px; font-family: ui-monospace, monospace; font-size: 11px; overflow-wrap: anywhere; } -.report-center-empty { min-height: 260px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; border-top: 1px solid var(--color-border-strong); border-bottom: 1px solid var(--color-border); color: var(--color-ink-tertiary); text-align: center; } -.report-center-empty h3 { margin: 8px 0 0; color: var(--color-ink); font-size: 18px; } +.report-center-failure { max-width: 220px; font-family: var(--font-mono); font-size: 11px; overflow-wrap: anywhere; } +.report-center-empty { min-height: 220px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; border-top: 1px solid var(--color-border-strong); border-bottom: 1px solid var(--color-border); color: var(--color-ink-tertiary); text-align: center; } +.report-center-empty h3 { margin: 8px 0 0; color: var(--color-ink); font-family: var(--font-body); font-size: 17px; font-weight: 650; } .report-center-empty p { max-width: 460px; margin: 0; font-size: 14px; line-height: 1.6; } -.report-center-alert { padding: 12px 14px; border: 1px solid color-mix(in srgb, var(--color-danger) 36%, var(--color-border)); background: var(--color-danger-muted); color: var(--color-danger); } +.report-center-alert { padding: 12px 0; border-top: 1px solid color-mix(in srgb, var(--color-danger) 48%, var(--color-border)); border-bottom: 1px solid color-mix(in srgb, var(--color-danger) 32%, var(--color-border)); background: transparent; color: var(--color-danger); } .report-center-message { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; text-align: center; } .report-center-message h1, .report-center-message p { margin: 0; } @media (max-width: 720px) { - .report-center-topbar > span { display: none; } - .report-center-hero { grid-template-columns: 1fr; align-items: start; gap: 28px; padding-block: 48px 38px; } + .report-center-hero { grid-template-columns: 1fr; align-items: start; gap: 24px; padding-block: 40px 34px; } .report-center-hero > button { width: 100%; } - .report-center-summary { grid-template-columns: 1fr; margin-bottom: 48px; } - .report-center-summary > div { grid-template-columns: minmax(0, 1fr) auto; align-items: center; padding: 15px 0; } - .report-center-summary > div + div { padding-left: 0; border-top: 1px solid var(--color-border); border-left: 0; } - .report-center-summary span { grid-column: 1; grid-row: 1; } - .report-center-summary strong { grid-column: 2; grid-row: 1; font-size: 17px; } - .report-center-card { grid-template-columns: 32px minmax(0, 1fr); gap: 12px; } - .report-center-card > a, .report-center-card > button, .report-center-failure { grid-column: 2; justify-self: start; } + .report-center-card { grid-template-columns: 1fr; gap: 14px; } + .report-center-card > a, .report-center-card > button, .report-center-failure { justify-self: start; } .report-center-section-heading { align-items: center; } } @@ -1910,7 +1793,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled background: var(--report-paper); } .personal-report-reader-body { width: 100%; padding: 0 24px 64px; } -.personal-report-actions { position: sticky; top: 0; z-index: 20; border-bottom: 1px solid color-mix(in srgb, var(--report-rule) 78%, transparent); background: color-mix(in srgb, var(--report-paper) 94%, transparent); backdrop-filter: blur(16px); } +.personal-report-actions { position: sticky; top: 0; z-index: 20; border-bottom: 1px solid var(--report-rule); background: var(--report-paper); } .personal-report-actions > div { width: min(1040px, 100%); min-height: 54px; display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 0 auto; padding: 8px 24px; } .personal-report-back { min-height: 38px; display: inline-flex; align-items: center; gap: 6px; color: var(--color-ink-secondary); font-size: 14px; text-decoration: none; } .personal-report-back:hover { color: var(--color-ink); } @@ -1921,7 +1804,6 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .personal-report-document { width: min(1040px, 100%); margin: 0 auto; padding: 54px 52px 38px; color: var(--color-ink); font-family: var(--font-body); font-size: 15px; line-height: 1.78; } .personal-report-section { margin: 0 0 58px; } .personal-report-cover-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 34%); gap: 72px; align-items: end; } -.personal-report-eyebrow { margin: 0 0 14px; color: var(--report-accent); font-size: 13px; font-weight: 650; letter-spacing: .08em; } .personal-report-cover h1 { margin: 0; font-family: var(--font-body); font-size: clamp(44px, 6vw, 66px); font-weight: 700; letter-spacing: -.055em; line-height: 1.05; } .personal-report-deck { max-width: 620px; margin: 18px 0 0; color: var(--color-ink-secondary); font-size: 16px; line-height: 1.65; text-wrap: pretty; } .personal-report-metadata { display: grid; gap: 9px; margin: 0; } @@ -1940,11 +1822,10 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .personal-report-narrative p { margin: 0 0 14px; color: var(--color-ink-strong); font-size: 15px; line-height: 1.88; text-wrap: pretty; } .personal-report-narrative p:last-child { margin-bottom: 0; } .personal-report-summary { max-width: 920px; } -.personal-report-callout { margin: 26px 0 0; padding: 14px 18px; border-left: 4px solid var(--report-accent); background: color-mix(in srgb, var(--report-accent) 5%, transparent); color: var(--color-ink-strong); } +.personal-report-callout { margin: 26px 0 0; padding: 14px 0 0; border-top: 1px solid var(--report-rule); background: transparent; color: var(--color-ink-strong); } .personal-report-callout strong { color: var(--report-accent); } -.personal-report-priorities { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 30px; margin: 22px 0 0; padding: 0; list-style: none; } -.personal-report-priorities li { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 9px; padding: 10px 0; border-top: 1px solid color-mix(in srgb, var(--report-rule) 72%, transparent); color: var(--color-ink-secondary); font-size: 14px; } -.personal-report-priorities span { color: var(--report-accent); font-size: 11px; font-weight: 700; letter-spacing: .08em; } +.personal-report-priorities { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 30px; margin: 22px 0 0; padding-left: 20px; } +.personal-report-priorities li { padding: 10px 0 10px 4px; border-top: 1px solid color-mix(in srgb, var(--report-rule) 72%, transparent); color: var(--color-ink-secondary); font-size: 14px; } .personal-report-lead-chart { padding-top: 2px; } .personal-report-lead-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(300px, .9fr); gap: 40px; align-items: start; } @@ -1966,21 +1847,20 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .personal-report-chart-card { min-width: 0; padding-top: 16px; border-top: 2px solid var(--color-ink); } .personal-report-chart-card > header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; } .personal-report-chart-card h3 { margin: 0; font-size: 18px; } -.personal-report-claim-badge { display: inline-flex; flex: 0 0 auto; align-items: center; padding: 2px 7px; border: 1px solid var(--report-rule); border-radius: 999px; color: var(--color-ink-secondary); background: transparent; font-size: 10px; font-weight: 650; line-height: 1.5; } -.personal-report-claim-badge.is-success { border-color: color-mix(in srgb, var(--color-success) 45%, transparent); color: var(--color-success); } -.personal-report-claim-badge.is-warning { border-color: color-mix(in srgb, var(--color-warning) 45%, transparent); color: #866018; } -.personal-report-claim-badge.is-danger { border-color: color-mix(in srgb, var(--color-danger) 42%, transparent); color: var(--color-danger); } +.personal-report-claim-status { flex: 0 0 auto; color: var(--color-ink-secondary); font-size: 11px; font-weight: 650; line-height: 1.5; } +.personal-report-claim-status.is-success { color: var(--color-success); } +.personal-report-claim-status.is-warning { color: #866018; } +.personal-report-claim-status.is-danger { color: var(--color-danger); } .personal-report-table-wrap { max-width: 100%; overflow-x: auto; } .personal-report-planet-table { margin-top: 18px; font-size: 12px; } .personal-report-planet-table th, .personal-report-planet-table td { padding-inline: 5px; } .personal-report-themes { border-top: 1px solid var(--report-rule); padding-top: 34px; } .personal-report-theme { padding: 28px 0 32px; border-top: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); } -.personal-report-theme > header { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 10px; align-items: start; margin-bottom: 16px; } -.personal-report-theme > header > span { padding-top: 5px; color: var(--report-accent); font-size: 11px; font-weight: 700; letter-spacing: .08em; } +.personal-report-theme > header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; } .personal-report-theme h3 { margin: 0; font-family: var(--font-body); font-size: 21px; line-height: 1.45; } -.personal-report-theme .personal-report-narrative { padding-left: 44px; } -.personal-report-theme-details { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px; margin: 22px 0 0 44px; padding: 17px 0; border-top: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); } +.personal-report-theme .personal-report-narrative { padding-left: 0; } +.personal-report-theme-details { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px; margin: 22px 0 0; padding: 17px 0; border-top: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); } .personal-report-theme-details h4 { margin: 0 0 7px; color: var(--color-ink); font-size: 13px; } .personal-report-theme-details ul { margin: 0; padding-left: 18px; color: var(--color-ink-secondary); font-size: 13px; line-height: 1.7; } .personal-report-theme-details li + li { margin-top: 4px; } @@ -2031,9 +1911,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled .personal-report-facts dd { font-size: 17px; } .personal-report-priorities { grid-template-columns: 1fr; } .personal-report-lead-grid, .personal-report-chart-grid, .personal-report-chart-grid.is-single { grid-template-columns: 1fr; gap: 34px; } - .personal-report-theme > header { grid-template-columns: 28px minmax(0, 1fr); } - .personal-report-theme > header .personal-report-claim-badge { grid-column: 2; justify-self: start; } - .personal-report-theme .personal-report-narrative, .personal-report-theme-details, .personal-report-evidence-links { margin-left: 0; padding-left: 0; } + .personal-report-theme .personal-report-narrative, .personal-report-theme-details, .personal-report-evidence-links { margin-left: 0; padding-left: 0; } .personal-report-theme-details { grid-template-columns: 1fr; gap: 18px; } .personal-report-footer { display: grid; } .personal-report-footer span:last-child { text-align: left; } @@ -2073,743 +1951,114 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled /* ---- Membership page ---- */ -.membership-page { - height: 100dvh; - min-height: 100dvh; - overflow-y: auto; - background: var(--color-canvas); -} - -.membership-shell { - width: min(1160px, 100%); - margin: 0 auto; - padding: var(--space-6) var(--space-5) var(--space-16); - display: grid; - gap: var(--space-6); -} - -.membership-loading { - padding: var(--space-16) var(--space-5); - color: var(--color-ink-secondary); - text-align: center; -} - -.membership-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--space-4); -} - -.membership-header-left { - display: flex; - align-items: center; - gap: var(--space-3); - min-width: 0; -} - -.membership-back { - min-height: 44px; - display: inline-flex; - align-items: center; - gap: var(--space-1); - padding: 0 12px; - border: 1px solid var(--color-border); - border-radius: var(--radius-md); - background: var(--color-canvas); - color: var(--color-ink); - cursor: pointer; - font-size: 14px; - text-decoration: none; -} - -.membership-back svg { - width: 16px; - height: 16px; -} - -.membership-title { - margin: 0; - color: var(--color-ink); - font-family: var(--font-display); - font-size: var(--type-display-sm); - font-weight: 400; - letter-spacing: -.03em; -} - -.membership-header-actions { - display: flex; - align-items: center; - gap: var(--space-2); -} - -.membership-orders-entry, -.membership-redeem-entry { - min-height: 44px; - display: inline-flex; - align-items: center; - gap: var(--space-2); - padding: 0 14px; - border: 1px solid color-mix(in srgb, var(--color-action) 34%, transparent); - border-radius: var(--radius-md); - background: var(--color-action-soft); - color: var(--color-action-hover); - cursor: pointer; - font-size: 14px; - font-weight: 500; -} - -.membership-orders-entry { - border-color: var(--color-border); - background: var(--color-canvas); - color: var(--color-ink-secondary); - text-decoration: none; -} - -.membership-redeem-entry svg { - width: 16px; - height: 16px; -} - -.membership-hero { - position: relative; - min-height: 260px; - overflow: hidden; - display: grid; - grid-template-columns: minmax(0, 1fr) 240px; - align-items: center; - gap: var(--space-8); - padding: var(--space-10); - border: 1px solid color-mix(in srgb, var(--color-action) 14%, var(--color-border)); - border-radius: var(--radius-xl); - background: radial-gradient(circle at 84% 32%, rgba(133, 67, 47, .12), transparent 34%), linear-gradient(135deg, var(--color-canvas) 0%, var(--color-canvas-soft) 100%); -} - -.membership-hero::after { - position: absolute; - inset: 0; - opacity: .2; - pointer-events: none; - background-image: radial-gradient(rgba(29, 29, 31, .24) .45px, transparent .45px); - background-size: 6px 6px; - content: ""; - mask-image: linear-gradient(to right, transparent 8%, #000 72%); -} - -.membership-hero-copy { - position: relative; - z-index: 1; - max-width: 720px; -} - -.membership-greeting { - margin: 0 0 var(--space-3); - color: var(--color-action); - font-size: var(--type-body-sm); - font-weight: 600; - letter-spacing: .02em; -} - -.membership-hero h2 { - max-width: 640px; - margin: 0; - color: var(--color-ink); - font-family: var(--font-display); - font-size: clamp(32px, 4vw, 48px); - font-weight: 400; - letter-spacing: -.045em; - line-height: 1.05; - text-wrap: balance; -} - -.membership-summary { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: var(--space-4); - margin-top: var(--space-6); -} - -.membership-summary-card { - display: grid; - gap: var(--space-1); - padding: var(--space-4); - border: 1px solid color-mix(in srgb, var(--color-action) 18%, var(--color-border)); - border-radius: var(--radius-lg); - background: color-mix(in srgb, var(--color-canvas) 86%, transparent); -} - -.membership-summary-card span { - color: var(--color-ink-secondary); - font-size: var(--type-caption); -} - -.membership-summary-card strong { - color: var(--color-ink); - font-family: var(--font-display); - font-size: var(--type-title-lg); - font-weight: 400; - font-variant-numeric: tabular-nums; -} - -.membership-summary-card small { - color: var(--color-ink-tertiary); - font-size: var(--type-caption); - line-height: 1.5; -} - -.membership-celestial-visual { - position: relative; - z-index: 1; - width: 220px; - height: 220px; - justify-self: end; -} - -.membership-orbit { - position: absolute; - border: 1px solid color-mix(in srgb, var(--color-action) 34%, transparent); - border-radius: 50%; -} - -.membership-orbit-outer { - inset: 10px 14px; - transform: rotate(-12deg); -} - -.membership-orbit-inner { - inset: 42px 54px; - border-color: color-mix(in srgb, var(--color-ink-tertiary) 42%, transparent); - transform: rotate(20deg); -} - -.membership-orbit-mini { - inset: 76px 90px; - border-color: color-mix(in srgb, var(--color-action) 26%, transparent); - border-style: dashed; -} - -.membership-orbit-dot { - position: absolute; - width: 9px; - height: 9px; - border-radius: 50%; - background: var(--color-action); - box-shadow: 0 0 0 5px color-mix(in srgb, var(--color-action-soft) 72%, transparent); -} - -.membership-orbit-dot-primary { - top: 28px; - right: 38px; -} - -.membership-orbit-dot-secondary { - bottom: 34px; - left: 34px; - width: 6px; - height: 6px; - background: var(--color-ink-tertiary); - box-shadow: none; -} - -.membership-celestial-mark { - position: absolute; - top: 50%; - left: 50%; - width: 52px; - height: 52px; - border: 1px solid color-mix(in srgb, var(--color-action) 18%, var(--color-border)); - border-radius: 50%; - background: color-mix(in srgb, var(--color-canvas) 88%, transparent) url("/jyotish-logo.png") center / 30px 30px no-repeat; - box-shadow: 0 14px 36px -24px rgba(29, 29, 31, .48); - transform: translate(-50%, -50%); -} - -.membership-section-heading { - display: flex; - align-items: baseline; - justify-content: space-between; - gap: var(--space-4); - margin-bottom: var(--space-4); -} - -.membership-section-heading > div { - display: grid; - gap: var(--space-1); -} - -.membership-section-heading h2 { - margin: 0; - color: var(--color-ink); - font-family: var(--font-display); - font-size: var(--type-title-lg); - font-weight: 400; - letter-spacing: -.02em; -} - -.membership-section-heading p { - margin: 0; - color: var(--color-ink-secondary); - font-size: var(--type-body-sm); - line-height: 1.55; -} - -.membership-orders-refresh { - flex: 0 0 auto; - padding: 6px 12px; - border: 1px solid var(--color-border); - border-radius: var(--radius-sm); - background: var(--color-canvas); - color: var(--color-ink-secondary); - cursor: pointer; - font-size: var(--type-caption); -} - -.membership-order-list { - display: grid; - gap: var(--space-2); - margin: 0; - padding: 0; - list-style: none; -} - -.membership-order-row { - display: grid; - grid-template-columns: minmax(0, 1fr) auto auto; - align-items: center; - gap: var(--space-4); - padding: var(--space-3) var(--space-4); - border: 1px solid var(--color-border); - border-radius: var(--radius-md); - background: var(--color-canvas); -} - -.membership-order-row > div { - display: grid; - gap: 2px; - min-width: 0; -} - -.membership-order-row strong { - color: var(--color-ink); - font-size: var(--type-body-sm); - font-weight: 600; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.membership-order-row small { - color: var(--color-ink-tertiary); - font-size: var(--type-caption); - font-variant-numeric: tabular-nums; -} - -.membership-order-row b { - color: var(--color-ink); - font-size: var(--type-body-sm); - font-variant-numeric: tabular-nums; - font-weight: 600; -} - -.membership-order-status { - padding: 3px 9px; - border-radius: 999px; - font-size: var(--type-caption); -} - -.membership-order-status.status-paid { - background: var(--color-success-muted); - color: var(--color-success); -} - -.membership-order-status.status-pending { - background: var(--color-action-soft); - color: var(--color-action-hover); -} - -.membership-order-status.status-failed { - background: var(--color-danger-muted); - color: var(--color-danger); -} - -.membership-empty { - margin: 0; - padding: var(--space-5); - border: 1px dashed var(--color-border-strong); - border-radius: var(--radius-md); - color: var(--color-ink-secondary); - font-size: var(--type-body-sm); - text-align: center; -} - -.membership-plan-grid, -.membership-credit-grid { - display: grid; - grid-template-columns: 1fr; - gap: var(--space-4); -} - -.membership-plan-card, -.membership-credit-card { - position: relative; - min-width: 0; - display: flex; - flex-direction: column; - gap: var(--space-3); - padding: var(--space-6); - border: 1px solid var(--color-border); - border-radius: var(--radius-xl); - background: var(--color-canvas); - box-shadow: var(--shadow-soft); - overflow: hidden; -} - -.membership-plan-card--recommended { - border-color: color-mix(in srgb, var(--color-action) 52%, var(--color-border)); - background: color-mix(in srgb, var(--color-action-soft) 46%, var(--color-canvas)); - box-shadow: 0 1px 2px rgba(29, 29, 31, .06), 0 14px 34px -20px rgba(133, 67, 47, .34); -} - -.membership-plan-card--recommended::before { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: var(--color-action); - content: ""; -} - -.membership-plan-card--current { - border-color: color-mix(in srgb, var(--color-success) 40%, var(--color-border)); -} - -.membership-card-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: var(--space-3); -} - -.membership-card-kicker { - display: block; - margin-bottom: 4px; - color: var(--color-action); - font-size: var(--type-overline); - font-weight: 600; - letter-spacing: .05em; -} - -.membership-card-header h3, -.membership-credit-copy h3 { - margin: 0; - color: var(--color-ink); - font-family: var(--font-display); - font-size: var(--type-title-md); - font-weight: 400; - letter-spacing: -.01em; -} - -.membership-card-badges { - display: flex; - flex-wrap: wrap; - gap: var(--space-1); - justify-content: flex-end; -} - -.membership-badge { - padding: 3px 9px; - border-radius: 999px; - font-size: var(--type-caption); - font-weight: 600; -} - -.membership-badge--recommended { - background: var(--color-action); - color: var(--color-on-dark); -} - -.membership-badge--current { - background: var(--color-success-muted); - color: var(--color-success); -} - -.membership-card-price { - margin: 0; - color: var(--color-ink); - font-family: var(--font-display); - font-size: var(--type-display-sm); - font-weight: 400; - font-variant-numeric: tabular-nums; - letter-spacing: -.02em; -} - -.membership-card-price small { - color: var(--color-ink-secondary); - font-size: var(--type-caption); - font-family: var(--font-body); - font-weight: 400; - letter-spacing: 0; -} - -.membership-card-audience { - margin: 0; - color: var(--color-ink-secondary); - font-size: var(--type-body-sm); - line-height: 1.6; -} - -.membership-card-entitlements { - display: grid; - gap: var(--space-1); - margin: 0; - padding: 0; - list-style: none; -} - -.membership-card-entitlements li { - position: relative; - padding-left: var(--space-4); - color: var(--color-ink-secondary); - font-size: var(--type-body-sm); - line-height: 1.55; -} - -.membership-card-entitlements li::before { - position: absolute; - top: .62em; - left: 0; - width: 6px; - height: 6px; - border-radius: 50%; - background: color-mix(in srgb, var(--color-action) 60%, transparent); - content: ""; -} - -.membership-rules { - margin-top: auto; - border-top: 1px solid var(--color-border); - padding-top: var(--space-3); -} - -.membership-rules summary { - cursor: pointer; - color: var(--color-ink-secondary); - font-size: var(--type-caption); - font-weight: 600; - user-select: none; -} - -.membership-rules ul { - display: grid; - gap: var(--space-1); - margin: var(--space-2) 0 0; - padding: 0 0 0 var(--space-4); - color: var(--color-ink-tertiary); - font-size: var(--type-caption); - line-height: 1.55; -} - -.membership-buy { - width: 100%; - margin-top: var(--space-2); -} - -.membership-credit-card { - gap: var(--space-2); -} - -.membership-credit-copy p { - margin: var(--space-1) 0 0; - color: var(--color-ink-secondary); - font-size: var(--type-body-sm); - line-height: 1.55; -} - -.membership-payment-panel { - display: grid; - grid-template-columns: auto minmax(0, 1fr) auto; - align-items: center; - gap: var(--space-4); - padding: var(--space-5) var(--space-6); - border: 1px solid color-mix(in srgb, var(--color-action) 30%, var(--color-border)); - border-radius: var(--radius-lg); - background: var(--color-action-soft); -} - -.membership-payment-icon { - display: grid; - place-items: center; - color: var(--color-action); -} - -.membership-payment-icon svg { - width: 28px; - height: 28px; -} - -.membership-payment-copy { - min-width: 0; - display: grid; - gap: var(--space-1); -} - -.membership-payment-copy h3 { - margin: 0; - color: var(--color-ink); - font-size: var(--type-title-md); - font-weight: 600; -} - -.membership-payment-copy p { - margin: 0; - color: var(--color-ink-secondary); - font-size: var(--type-body-sm); - line-height: 1.55; - font-variant-numeric: tabular-nums; -} - -.membership-payment-panel .dialog-actions { - margin: 0; -} - -.membership-redeem { - width: min(100%, 480px); -} +.membership-page { height: 100dvh; min-height: 100dvh; overflow-y: auto; background: var(--color-canvas); } +.membership-shell { width: min(1160px, 100%); display: grid; gap: var(--space-6); margin: 0 auto; padding: var(--space-6) var(--space-5) var(--space-16); } +.membership-loading { padding: var(--space-16) var(--space-5); color: var(--color-ink-secondary); text-align: center; } +.membership-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); } +.membership-header-left, .membership-header-actions { min-width: 0; display: flex; align-items: center; gap: var(--space-3); } +.membership-header-actions { gap: var(--space-2); } +.membership-back, .membership-orders-entry, .membership-redeem-entry { min-height: 44px; display: inline-flex; align-items: center; gap: var(--space-2); padding: 0 12px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-canvas); color: var(--color-ink-secondary); cursor: pointer; font-size: 14px; text-decoration: none; } +.membership-redeem-entry { color: var(--color-action); } +.membership-back:hover, .membership-orders-entry:hover, .membership-redeem-entry:hover { border-color: var(--color-border-strong); color: var(--color-ink); } +.membership-back svg, .membership-redeem-entry svg { width: 16px; height: 16px; } +.membership-title { margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-title-lg); font-weight: 650; letter-spacing: -.02em; } + +.membership-hero { min-height: 0; display: block; padding: var(--space-8); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas-soft); } +.membership-hero-copy { max-width: 760px; } +.membership-greeting { margin: 0 0 var(--space-3); color: var(--color-ink-secondary); font-size: var(--type-body-sm); } +.membership-hero h2 { max-width: 680px; margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: clamp(28px, 4vw, 40px); font-weight: 650; letter-spacing: -.03em; line-height: 1.12; text-wrap: balance; } +.membership-summary { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; margin-top: var(--space-6); border-top: 1px solid var(--color-border); } +.membership-summary-card { min-width: 0; display: grid; gap: var(--space-1); padding: var(--space-4) 0 0; border: 0; border-radius: 0; background: transparent; } +.membership-summary-card + .membership-summary-card { padding-left: var(--space-5); border-left: 1px solid var(--color-border); } +.membership-summary-card span { color: var(--color-ink-secondary); font-size: var(--type-caption); } +.membership-summary-card strong { color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-title-md); font-weight: 650; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; } +.membership-summary-card small { color: var(--color-ink-tertiary); font-size: var(--type-caption); line-height: 1.5; } + +.membership-section-heading { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-4); } +.membership-section-heading > div { display: grid; gap: var(--space-1); } +.membership-section-heading h2 { margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-title-md); font-weight: 650; letter-spacing: -.01em; } +.membership-section-heading p { margin: 0; color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.55; } +.membership-orders-refresh { flex: 0 0 auto; padding: 6px 10px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-canvas); color: var(--color-ink-secondary); cursor: pointer; font-size: var(--type-caption); } +.membership-order-list { display: grid; gap: 0; margin: 0; padding: 0; border-top: 1px solid var(--color-border); list-style: none; } +.membership-order-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: var(--space-4); padding: var(--space-4) 0; border-bottom: 1px solid var(--color-border); background: transparent; } +.membership-order-row > div { min-width: 0; display: grid; gap: 2px; } +.membership-order-row strong { overflow: hidden; color: var(--color-ink); font-size: var(--type-body-sm); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; } +.membership-order-row small { color: var(--color-ink-tertiary); font-size: var(--type-caption); font-variant-numeric: tabular-nums; } +.membership-order-row b { color: var(--color-ink); font-size: var(--type-body-sm); font-weight: 600; font-variant-numeric: tabular-nums; } +.membership-order-status { padding: 0; border-radius: 0; background: transparent; font-size: var(--type-caption); font-weight: 650; } +.membership-order-status.status-paid { color: var(--color-success); } +.membership-order-status.status-pending { color: var(--color-action-hover); } +.membership-order-status.status-failed { color: var(--color-danger); } +.membership-empty { margin: 0; padding: var(--space-5) 0; border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); color: var(--color-ink-secondary); font-size: var(--type-body-sm); text-align: center; } + +.membership-plan-grid, .membership-credit-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4); } +.membership-plan-card, .membership-credit-card { min-width: 0; display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-6); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas); box-shadow: none; } +.membership-plan-card--recommended { border-color: var(--color-border-strong); background: var(--color-canvas); } +.membership-plan-card--current { border-color: var(--color-action); } +.membership-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); } +.membership-card-header h3, .membership-credit-copy h3 { margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-title-md); font-weight: 650; letter-spacing: -.01em; } +.membership-card-meta { margin: 4px 0 0; color: var(--color-ink-tertiary); font-size: var(--type-caption); } +.membership-status { color: var(--color-action); font-size: var(--type-caption); font-weight: 650; white-space: nowrap; } +.membership-status.is-current { color: var(--color-success); } +.membership-card-price { margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-display-sm); font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -.02em; } +.membership-card-price small { color: var(--color-ink-secondary); font-family: var(--font-body); font-size: var(--type-caption); font-weight: 400; letter-spacing: 0; } +.membership-card-audience { margin: 0; color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.6; } +.membership-card-entitlements { display: grid; gap: var(--space-2); margin: 0; padding: 0 0 0 18px; } +.membership-card-entitlements li { color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.55; } +.membership-rules { margin-top: auto; padding-top: var(--space-3); border-top: 1px solid var(--color-border); } +.membership-rules summary { color: var(--color-ink-secondary); cursor: pointer; font-size: var(--type-caption); font-weight: 600; user-select: none; } +.membership-rules ul { display: grid; gap: var(--space-1); margin: var(--space-2) 0 0; padding: 0 0 0 var(--space-4); color: var(--color-ink-tertiary); font-size: var(--type-caption); line-height: 1.55; } +.membership-buy { width: 100%; margin-top: var(--space-2); } +.membership-credit-card { gap: var(--space-2); } +.membership-credit-copy p:not(.membership-card-meta) { margin: var(--space-2) 0 0; color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.55; } + +.membership-payment-panel { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-4); padding: var(--space-5) 0; border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); background: transparent; } +.membership-payment-icon { display: grid; place-items: center; color: var(--color-action); } +.membership-payment-icon svg { width: 24px; height: 24px; } +.membership-payment-copy { min-width: 0; display: grid; gap: var(--space-1); } +.membership-payment-copy h3 { margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-title-md); font-weight: 650; } +.membership-payment-copy p { margin: 0; color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.55; font-variant-numeric: tabular-nums; } +.membership-payment-panel .dialog-actions { margin: 0; } +.membership-redeem { width: min(100%, 480px); } + +.membership-tabs { width: fit-content; display: inline-flex; align-items: center; gap: 0; margin-bottom: var(--space-5); border-bottom: 1px solid var(--color-border); } +.membership-tab { min-height: 44px; padding: 0 16px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--color-ink-secondary); cursor: pointer; font-size: var(--type-body-sm); font-weight: 600; } +.membership-tab:hover { color: var(--color-ink); } +.membership-tab:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; } +.membership-tab[data-active] { border-bottom-color: var(--color-action); background: transparent; color: var(--color-action); box-shadow: none; } +.membership-panel { min-width: 0; } +.membership-plan-card--highlighted { border-color: var(--color-action); outline: 2px solid color-mix(in srgb, var(--color-action) 38%, transparent); outline-offset: 2px; } +.membership-payment-error { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-4); padding: var(--space-3) 0; border-top: 1px solid color-mix(in srgb, var(--color-danger) 48%, var(--color-border)); border-bottom: 1px solid color-mix(in srgb, var(--color-danger) 32%, var(--color-border)); background: transparent; } +.membership-payment-error p { margin: 0; color: var(--color-danger); font-size: var(--type-body-sm); line-height: 1.55; } @media (max-width: 767px) { - .membership-hero { - grid-template-columns: 1fr; - padding: var(--space-6); - } - - .membership-celestial-visual { - display: none; - } - - .membership-summary { - grid-template-columns: 1fr; - } - - .membership-order-row { - grid-template-columns: minmax(0, 1fr) auto; - } - - .membership-order-row b { - display: none; - } - - .membership-payment-panel { - grid-template-columns: auto minmax(0, 1fr); - } - - .membership-payment-panel .dialog-actions { - grid-column: 1 / -1; - } + .membership-shell { padding-inline: var(--space-4); } + .membership-header { align-items: flex-start; } + .membership-header-left { align-items: flex-start; } + .membership-title { padding-top: 9px; font-size: var(--type-title-md); } + .membership-header-actions { flex-wrap: wrap; justify-content: flex-end; } + .membership-hero { padding: var(--space-6); } + .membership-summary { grid-template-columns: 1fr; } + .membership-summary-card + .membership-summary-card { margin-top: var(--space-4); padding: var(--space-4) 0 0; border-top: 1px solid var(--color-border); border-left: 0; } + .membership-order-row { grid-template-columns: minmax(0, 1fr) auto; } + .membership-order-row b { display: none; } + .membership-payment-panel { grid-template-columns: auto minmax(0, 1fr); } + .membership-payment-panel .dialog-actions { grid-column: 1 / -1; } } @media (max-width: 639px) { - .membership-plan-card--recommended { - order: -1; - } + .membership-header { display: grid; } + .membership-header-actions { justify-content: flex-start; } + .membership-plan-card--recommended { order: -1; } + .membership-payment-error { align-items: flex-start; flex-direction: column; } } @media (min-width: 640px) { - .membership-plan-grid, - .membership-credit-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } + .membership-plan-grid, .membership-credit-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1024px) { - .membership-plan-grid, - .membership-credit-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } -} - -@media (prefers-reduced-motion: reduce) { - .membership-plan-card, - .membership-credit-card, - .membership-hero { - animation: none; - } -} - -.membership-tabs { - display: inline-flex; - align-items: center; - width: fit-content; - gap: 4px; - margin-bottom: var(--space-5); - padding: 4px; - border: 1px solid var(--color-border); - border-radius: var(--radius-lg); - background: var(--color-canvas-soft); -} - -.membership-tab { - min-height: 44px; - padding: 0 16px; - border: 1px solid transparent; - border-radius: var(--radius-md); - background: transparent; - color: var(--color-ink-secondary); - cursor: pointer; - font-size: var(--type-body-sm); - font-weight: 600; -} - -.membership-tab:hover { - color: var(--color-ink); -} - -.membership-tab:focus-visible { - outline: 2px solid color-mix(in srgb, var(--color-action) 46%, transparent); - outline-offset: 2px; -} - -.membership-tab[data-active] { - border-color: var(--color-border); - background: var(--color-canvas); - color: var(--color-action); - box-shadow: var(--shadow-soft); -} - -.membership-panel { - min-width: 0; -} - -.membership-plan-card--highlighted { - border-color: var(--color-action); - outline: 2px solid color-mix(in srgb, var(--color-action) 38%, transparent); - outline-offset: 2px; -} - -.membership-payment-error { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--space-4); - margin-bottom: var(--space-4); - padding: var(--space-3) var(--space-4); - border: 1px solid color-mix(in srgb, var(--color-danger) 42%, var(--color-border)); - border-radius: var(--radius-md); - background: var(--color-danger-muted); -} - -.membership-payment-error p { - margin: 0; - color: var(--color-danger); - font-size: var(--type-body-sm); - line-height: 1.55; -} - -@media (max-width: 639px) { - .membership-payment-error { - align-items: flex-start; - flex-direction: column; - } + .membership-plan-grid, .membership-credit-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } } .rectification-message-wrap { display: grid; gap: var(--space-2); } @@ -2835,7 +2084,7 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled list-style: none; } .rectification-activity summary::-webkit-details-marker { display: none; } -.rectification-activity summary::before { content: "+"; color: var(--color-ink-tertiary); font-family: var(--font-mono); } +.rectification-activity summary::before { content: "+"; color: var(--color-ink-tertiary); } .rectification-activity[open] summary::before { content: "−"; } .rectification-activity summary:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; } .rectification-activity ol { @@ -2859,3 +2108,40 @@ input:not([class^="ant-"]):not([class*=" ant-"]):not(.ant-picker input):disabled background: var(--color-canvas); color: var(--color-ink-secondary); } + +/* Admin: quiet operational surface. */ +.admin-app-shell { + min-height: 100dvh; + background: #f3f2ee; + color: #1d1d1f; + font-family: var(--font-body); +} +.admin-app-shell .ant-layout { background: #f3f2ee; } +.admin-app-shell .ant-layout-sider { border-right: 1px solid #d8d6cf; box-shadow: none !important; } +.admin-app-shell .ant-layout-header { border-bottom: 1px solid #d8d6cf; box-shadow: none !important; } +.admin-app-shell .ant-layout-content { padding: 22px; } +.admin-app-shell .ant-menu { border-inline-end: 0 !important; background: transparent !important; } +.admin-app-shell .ant-menu-item, .admin-app-shell .ant-menu-submenu-title { margin-inline: 8px; width: calc(100% - 16px); } +.admin-app-shell .ant-card { border-color: #d8d6cf; box-shadow: none !important; } +.admin-app-shell .ant-card-head { border-bottom-color: #d8d6cf; } +.admin-app-shell .ant-card .ant-card { border-radius: 0; } +.admin-app-shell .ant-card .ant-card:not(:last-child) { border-bottom: 0; } +.admin-app-shell .ant-list-bordered { border-color: #d8d6cf; border-radius: 6px; } +.admin-app-shell .ant-table-wrapper .ant-table { background: #fbfaf7; } +.admin-app-shell .ant-table-wrapper .ant-table-container { border-radius: 6px; } +.admin-app-shell .ant-table-wrapper .ant-table-thead > tr > th { font-size: 12px; font-weight: 650; } +.admin-app-shell .ant-table-wrapper .ant-table-cell { line-height: 1.45; } +.admin-app-shell .ant-tag { margin-inline-end: 4px; border-radius: 4px; font-weight: 550; } +.admin-app-shell .ant-alert { border-radius: 6px; box-shadow: none; } +.admin-app-shell .ant-statistic-title { color: #5f5f59; font-size: 12px; } +.admin-app-shell .ant-statistic-content { font-size: 22px; font-weight: 650; } +.admin-app-shell .ant-typography h1, .admin-app-shell h1.ant-typography { font-family: var(--font-body); font-size: 26px; font-weight: 680; letter-spacing: -.025em; } +.admin-app-shell .ant-typography h2, .admin-app-shell h2.ant-typography { font-family: var(--font-body); font-size: 21px; font-weight: 650; letter-spacing: -.015em; } +.admin-app-shell .ant-typography h3, .admin-app-shell h3.ant-typography { font-family: var(--font-body); font-size: 17px; font-weight: 650; } +.admin-app-shell code { font-family: var(--font-mono); } +.admin-text-list { max-width: 680px; color: #5f5f59; line-height: 1.65; white-space: normal; overflow-wrap: anywhere; } +.admin-loading { min-height: 100dvh; display: grid; place-content: center; justify-items: center; gap: 12px; background: #f3f2ee; color: #5f5f59; } + +@media (max-width: 767px) { + .admin-app-shell .ant-layout-content { padding: 14px; } +} diff --git a/frontend/src/app/membership/page.tsx b/frontend/src/app/membership/page.tsx index 3fc79b24..4a75e776 100644 --- a/frontend/src/app/membership/page.tsx +++ b/frontend/src/app/membership/page.tsx @@ -294,7 +294,7 @@ function MembershipContent() {

{account?.user.email ? `账户:${account.user.email}` : "欢迎回来"}

- {activeSubscription ? "保持会员状态,持续获得完整权益" : "开通会员,解锁完整咨询体验"} + {activeSubscription ? "查看当前会员权益" : "选择会员套餐"}

@@ -310,14 +310,6 @@ function MembershipContent() {
-
@@ -367,13 +359,10 @@ function MembershipContent() { >
- {planDisplayLabel(alias ?? "monthly")}

{product.name}

+

{planDisplayLabel(alias ?? "monthly")}

-
- {recommended && 推荐} - {isCurrent && 当前套餐} -
+ {(isCurrent || recommended) && {isCurrent ? "当前套餐" : "推荐"}}

{formatPrice(product.priceCents, product.currency)} @@ -418,8 +407,8 @@ function MembershipContent() { {creditPacks.map((product) => (

- {product.credits > 0 ? `${product.credits} 点` : "点数包"}

{product.name}

+

{product.credits > 0 ? `${product.credits} 点` : "点数包"}

{product.description || "按需补充咨询点数"}

{formatPrice(product.priceCents, product.currency)}

diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index e51b8aa2..a0dbb1a1 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -3,8 +3,6 @@ import Link from "next/link"; import dynamic from "next/dynamic"; import { ArrowUp, ArrowUpRight, Sparkles, Square, X } from "lucide-react"; -import { useGSAP } from "@gsap/react"; -import { gsap } from "gsap"; import { useEffect, useRef, useState } from "react"; import type { FormEvent, KeyboardEvent } from "react"; import { AppSidebar } from "@/components/app-sidebar"; @@ -114,8 +112,6 @@ import { } from "@/lib/public-models"; import { selfHostedOtpActions } from "@/modules/identity/client"; -gsap.registerPlugin(useGSAP); - const BirthTimeRectification = dynamic( () => import("@/components/birth-time-rectification").then((module) => module.BirthTimeRectification), { @@ -1061,7 +1057,6 @@ export default function Home() { const closeButton = useRef(null); const onboardingPaywallShown = useRef(false); const composerInput = useRef(null); - const starterWorkbench = useRef(null); const pendingConsultation = useRef(null); const cancellationRequests = useRef(new Map>()); const cancellationFeedbackRequest = useRef(null); @@ -3125,39 +3120,6 @@ export default function Home() { } - useGSAP(() => { - if (!starterHomeVisible || !starterWorkbench.current) return; - const motion = gsap.matchMedia(); - motion.add("(prefers-reduced-motion: no-preference)", () => { - const timeline = gsap.timeline({ defaults: { ease: "power3.out" } }); - timeline - .from(".starter-hero-copy > *", { - autoAlpha: 0, - duration: 0.62, - stagger: 0.07, - y: 18, - }) - .from(".starter-celestial-visual", { - autoAlpha: 0, - duration: 0.76, - scale: 0.94, - }, 0.08) - .from(".product-entrypoint-card", { - autoAlpha: 0, - duration: 0.54, - stagger: 0.08, - y: 20, - }, 0.2) - .from(".starter-theme-card", { - autoAlpha: 0, - duration: 0.46, - stagger: 0.055, - y: 14, - }, 0.34); - }); - return () => motion.revert(); - }, { dependencies: [activeSession?.id, starterHomeVisible], scope: starterWorkbench }); - function submit(event: FormEvent) { event.preventDefault(); if (!profileComplete) { @@ -3178,7 +3140,7 @@ export default function Home() { if (!hydrated || (!account && !accountError)) { return (
- +
); } @@ -3315,7 +3277,6 @@ export default function Home() {
- 先完成出生资料 出生日期与时间
@@ -3372,10 +3333,10 @@ export default function Home() { {profileComplete && presetMessageFinished && !rectificationSurfaceOpen && (onboardingPending ? (
- +
) : ( -
+

{daypartGreeting},{profile.name.trim()}。

@@ -3384,13 +3345,6 @@ export default function Home() { ? "从此刻最在意的事开始,我会结合你的星盘证据,帮你把问题拆得更清楚。" : "你可以先了解一般占星知识;完成生时校正后,再讨论个人星盘结论。"}

-
@@ -3403,7 +3357,6 @@ export default function Home() { onClick={draftDailyStarlanguageQuestion} />
- {personalChartAvailable ? "每日观察" : "一般知识"}

{personalChartAvailable ? "今日星语" : "如何看每日趋势"}

{personalChartAvailable ? dailyStarlanguage?.trend : "了解印度占星通常会用哪些因素观察一天的主题。"}

@@ -3421,7 +3374,6 @@ export default function Home() { onClick={() => void openRectificationFromHomepage()} />
- 出生资料

生时校正

{rectificationEntrySummary?.hasResumableCase ? "新建一段独立校正;未完成的记录仍可从左侧历史会话继续。" @@ -3438,7 +3390,7 @@ export default function Home() {

-

或者,从一个主题开始

+

从一个主题开始

选择最接近你当下的问题。

diff --git a/frontend/src/app/reports/[reportId]/not-found.tsx b/frontend/src/app/reports/[reportId]/not-found.tsx index b004872d..00c16a4d 100644 --- a/frontend/src/app/reports/[reportId]/not-found.tsx +++ b/frontend/src/app/reports/[reportId]/not-found.tsx @@ -11,7 +11,7 @@ export default function ReportNotFound() {

该报告不存在、已删除,或不属于当前账号。

- diff --git a/frontend/src/components/admin/admin-app.tsx b/frontend/src/components/admin/admin-app.tsx index 271f406a..931aa593 100644 --- a/frontend/src/components/admin/admin-app.tsx +++ b/frontend/src/components/admin/admin-app.tsx @@ -31,7 +31,67 @@ export function AdminApp({ children }: { children: ReactNode }) { const notificationProvider = useNotificationProvider(); return (
- + } onClick={() => openAssignment()}>按邮箱分配角色 : RBAC} + extra={canManage ? : 只读权限} > 六类系统角色可在此分配和撤销。每次变更都需要邮箱验证码与操作原因;最后一位 Owner 受服务端保护,不能被撤销。 diff --git a/frontend/src/components/admin/audit-logs-resource.tsx b/frontend/src/components/admin/audit-logs-resource.tsx index 0b7479ad..0490c4bf 100644 --- a/frontend/src/components/admin/audit-logs-resource.tsx +++ b/frontend/src/components/admin/audit-logs-resource.tsx @@ -1,6 +1,6 @@ "use client"; -import { Descriptions, Tag, type TableColumnsType } from "antd"; +import { Descriptions, type TableColumnsType } from "antd"; import { formatAdminDate, ResourceTable } from "@/components/admin/resource-table"; @@ -18,7 +18,7 @@ type AuditRecord = { const columns: TableColumnsType = [ { title: "操作者", dataIndex: "actorEmail", sorter: true }, - { title: "角色", dataIndex: "actorRole", render: (value) => {value} }, + { title: "角色", dataIndex: "actorRole" }, { title: "动作", dataIndex: "action", sorter: true }, { title: "目标 ID", dataIndex: "targetId" }, { title: "Request ID", dataIndex: "requestId" }, diff --git a/frontend/src/components/admin/billing-operations-resources.tsx b/frontend/src/components/admin/billing-operations-resources.tsx index bd6bc93b..04c3016d 100644 --- a/frontend/src/components/admin/billing-operations-resources.tsx +++ b/frontend/src/components/admin/billing-operations-resources.tsx @@ -470,9 +470,7 @@ export function UsageResource() { { title: "资金来源", dataIndex: "source", - render: (value) => ( - {value} - ), + render: (value) => value, }, { title: "模型", @@ -541,9 +539,7 @@ export function ModelReleasesResource() { { title: "动作", dataIndex: "action", - render: (value) => ( - {value} - ), + render: (value) => value, }, { title: "管理员", diff --git a/frontend/src/components/admin/credit-transactions-resource.tsx b/frontend/src/components/admin/credit-transactions-resource.tsx index 4e1ebff7..17071dba 100644 --- a/frontend/src/components/admin/credit-transactions-resource.tsx +++ b/frontend/src/components/admin/credit-transactions-resource.tsx @@ -1,6 +1,6 @@ "use client"; -import { Tag, type TableColumnsType } from "antd"; +import { type TableColumnsType } from "antd"; import { formatAdminDate, ResourceTable } from "@/components/admin/resource-table"; @@ -19,7 +19,7 @@ type TransactionRecord = { const columns: TableColumnsType = [ { title: "用户", dataIndex: "email", render: (value) => value || "—" }, - { title: "类型", dataIndex: "type", sorter: true, render: (value) => {value} }, + { title: "类型", dataIndex: "type", sorter: true }, { title: "变动", dataIndex: "amount", sorter: true, render: (value) => value > 0 ? `+${value}` : value }, { title: "余额", dataIndex: "balanceAfter", sorter: true }, { title: "请求 ID", dataIndex: "requestId" }, diff --git a/frontend/src/components/admin/feature-flags-management.tsx b/frontend/src/components/admin/feature-flags-management.tsx index 906cead1..ac889177 100644 --- a/frontend/src/components/admin/feature-flags-management.tsx +++ b/frontend/src/components/admin/feature-flags-management.tsx @@ -4,7 +4,7 @@ import { PlusOutlined } from "@ant-design/icons"; import { useGetIdentity } from "@refinedev/core"; import { useTable } from "@refinedev/antd"; import { List } from "@refinedev/antd"; -import { App, Button, Form, Input, InputNumber, Modal, Select, Space, Switch, Table, Tag, Typography, type TableColumnsType } from "antd"; +import { App, Button, Form, Input, InputNumber, Modal, Select, Space, Switch, Table, Typography, type TableColumnsType } from "antd"; import { useState } from "react"; import { adminRequestJson, type AdminIdentity } from "@/lib/admin/providers"; @@ -122,7 +122,7 @@ export default function FeatureFlagsManagement() { const columns: TableColumnsType = [ { title: "开关", render: (_, item) => {item.flagKey}v{item.version} }, - { title: "状态", render: (_, item) => {item.status}{item.enabled ? 开启 : 关闭} }, + { title: "状态", render: (_, item) => {item.status === "published" ? "已发布" : item.status === "draft" ? "草稿" : item.status} · {item.enabled ? "已开启" : "已关闭"} }, { title: "灰度", dataIndex: "rolloutPercentage", render: (value) => `${value}%` }, { title: "配置", dataIndex: "config", render: (value) => {JSON.stringify(value)} }, { title: "发布时间", dataIndex: "publishedAt", render: formatAdminDate }, diff --git a/frontend/src/components/admin/mfa-security.tsx b/frontend/src/components/admin/mfa-security.tsx index 9239fe2d..cd3ce357 100644 --- a/frontend/src/components/admin/mfa-security.tsx +++ b/frontend/src/components/admin/mfa-security.tsx @@ -12,7 +12,6 @@ import { Radio, Space, Spin, - Tag, Typography, } from "antd"; import { useEffect, useState } from "react"; @@ -97,7 +96,7 @@ export default function MfaSecurity() { if (!data) return; setEnrollment(data); setBackupCodes(data.backupCodes); - setNotice("请先保存恢复码,再使用认证器生成的 6 位验证码完成 enrollment。未验证前 MFA 不会启用。"); + setNotice("请先保存恢复码,再使用认证器生成的 6 位验证码完成 MFA 绑定。未验证前 MFA 不会启用。"); } async function verify({ code }: { code: string }) { @@ -105,14 +104,14 @@ export default function MfaSecurity() { if (!data) return; setStatus(data); setEnrollment(undefined); - setNotice("当前管理员 session 已完成真实第二因素验证。高风险操作仍需随后完成权限范围内的邮箱验证码。"); + setNotice("当前管理员会话已完成真实第二因素验证。高风险操作仍需随后完成权限范围内的邮箱验证码。"); } async function recover({ code }: { code: string }) { const data = await run("recover", () => mfaRequest({ action: "recover", code })); if (!data) return; setStatus(data); - setNotice("恢复码已消费,当前 session 已完成 MFA 验证。请在恢复访问后重新生成恢复码。"); + setNotice("恢复码已消费,当前会话已完成 MFA 验证。请在恢复访问后重新生成恢复码。"); } async function regenerate({ password }: { password: string }) { @@ -132,7 +131,7 @@ export default function MfaSecurity() { setEnrollment(undefined); setBackupCodes(undefined); setNotice(data.required - ? "MFA 已禁用。该角色要求 MFA,因此高风险写入现已关闭,重新 enrollment 后才能恢复。" + ? "MFA 已禁用。该角色要求 MFA,因此高风险写入现已关闭,重新绑定后才能恢复。" : "MFA 已禁用,当前 MFA 与邮箱重认证证明均已撤销。"); } @@ -144,7 +143,7 @@ export default function MfaSecurity() {
安全验证 - 管理员 MFA 使用 Better Auth 的真实 TOTP 与一次性恢复码。MFA 证明只绑定当前 server session,短时有效且可随 session 撤销。 + 管理员 MFA 使用 Better Auth 的真实 TOTP 与一次性恢复码。MFA 证明只绑定当前服务端会话,短时有效且可随会话撤销。
@@ -154,24 +153,24 @@ export default function MfaSecurity() { type="warning" showIcon message="当前角色强制要求 MFA" - description="在 enrollment 完成前,所有高风险写入都会 fail closed。" + description="在 MFA 绑定完成前,所有高风险写入均默认拒绝。" /> : null} - {status?.required ? "必须 MFA" : "可选 MFA"} + {status?.required ? "必须 MFA" : "可选 MFA"} - - {status?.enrolled ? "已启用" : "未启用"} + + {status?.enrolled ? "已启用" : "未启用"} - - {status?.verified ? "已验证" : "未验证"} + + {status?.verified ? "已验证" : "未验证"} - + {status?.highRiskWritesEnabled ? "可发起邮箱重认证" : "已关闭"} - + @@ -182,11 +181,11 @@ export default function MfaSecurity() { - + : null} - {enrollment ? + {enrollment ? : null} - {status?.enrolled && !status.verified ? + {status?.enrolled && !status.verified ? 高权限操作前,先用认证器验证码或一次性恢复码完成真实第二因素。 setFactor(event.target.value as Factor)}> 认证器验证码 @@ -234,7 +233,7 @@ export default function MfaSecurity() { /> : null} @@ -255,7 +254,7 @@ export default function MfaSecurity() {
禁用 MFA - 禁用会轮换 Better Auth session,并撤销当前 MFA 与邮箱重认证证明。 + 禁用会轮换 Better Auth 会话,并撤销当前 MFA 与邮箱重认证证明。
diff --git a/frontend/src/components/admin/model-management.tsx b/frontend/src/components/admin/model-management.tsx index 23ac356b..760e3c40 100644 --- a/frontend/src/components/admin/model-management.tsx +++ b/frontend/src/components/admin/model-management.tsx @@ -17,7 +17,6 @@ import { Space, Switch, Table, - Tag, Typography, type TableColumnsType, } from "antd"; @@ -298,8 +297,8 @@ export default function ModelManagement() { { title: "供应商", render: (_, item) => {item.name}{item.code} }, { title: "类型", dataIndex: "providerType", render: (value: ProviderType) => providerTypeLabels[value] }, { title: "地址", dataIndex: "baseUrl", render: (value, item) => value ?? (item.providerType === "anthropic" ? "Anthropic 官方" : "OpenAI 官方") }, - { title: "密钥状态", render: (_, item) => {item.secretConfigured ? "已配置" : "未配置"} }, - { title: "状态", dataIndex: "enabled", render: (value) => value ? 启用 : 停用 }, + { title: "密钥状态", render: (_, item) => {item.secretConfigured ? "已配置" : "未配置"} }, + { title: "状态", dataIndex: "enabled", render: (value) => {value ? "启用" : "停用"} }, { title: "更新时间", dataIndex: "updatedAt", render: formatAdminDate }, { title: "操作", render: (_, item) => canWrite ? : null }, ]; @@ -307,11 +306,11 @@ export default function ModelManagement() { const modelColumns: TableColumnsType = [ { title: "模型", render: (_, item) => {item.label}{item.modelId} · v{item.version} }, { title: "供应商模型", render: (_, item) => `${item.providerCode} / ${item.providerModel}` }, - { title: "档位", dataIndex: "modelTier", render: (value: ModelVersion["modelTier"]) => {modelTierLabels[value]} }, + { title: "档位", dataIndex: "modelTier", render: (value: ModelVersion["modelTier"]) => modelTierLabels[value] }, { title: "点数", dataIndex: "creditCost" }, { title: "成本/百万 Token", render: (_, item) => `$${(item.inputCostMicrousdPerMillion / 1_000_000).toFixed(4)} / $${(item.outputCostMicrousdPerMillion / 1_000_000).toFixed(4)}` }, - { title: "路由", render: (_, item) => {item.isDefault && 默认}回退模型:{item.fallbackModelId ?? "—"} }, - { title: "状态", render: (_, item) => {modelStatusLabels[item.status] ?? item.status}{item.enabled ? 启用 : 停用} }, + { title: "路由", render: (_, item) => {item.isDefault && 默认模型}回退模型:{item.fallbackModelId ?? "—"} }, + { title: "状态", render: (_, item) => {modelStatusLabels[item.status] ?? item.status} · {item.enabled ? "启用" : "停用"} }, { title: "发布时间", dataIndex: "publishedAt", render: formatAdminDate }, { title: "操作", diff --git a/frontend/src/components/admin/package-management.tsx b/frontend/src/components/admin/package-management.tsx index b77d2731..0cf93c09 100644 --- a/frontend/src/components/admin/package-management.tsx +++ b/frontend/src/components/admin/package-management.tsx @@ -2,7 +2,7 @@ import { PlusOutlined } from "@ant-design/icons"; import { List } from "@refinedev/antd"; -import { Alert, App, Button, Card, Form, Input, InputNumber, Modal, Popconfirm, Row, Col, Space, Switch, Table, Tag, Typography, type TableColumnsType } from "antd"; +import { Alert, App, Button, Card, Form, Input, InputNumber, Modal, Popconfirm, Row, Col, Space, Switch, Table, Typography, type TableColumnsType } from "antd"; import { useCallback, useEffect, useState } from "react"; const { Text } = Typography; @@ -134,7 +134,7 @@ export function PackageManagement() { { title: "价格", dataIndex: "priceCents", align: "right", render: formatMoney }, { title: "点数", dataIndex: "credits", align: "right" }, { title: "排序", dataIndex: "sortOrder", align: "right" }, - { title: "状态", dataIndex: "enabled", render: (enabled) => {enabled ? "启用" : "停用"} }, + { title: "状态", dataIndex: "enabled", render: (enabled) => {enabled ? "启用" : "停用"} }, { title: "操作", key: "actions", fixed: "right", render: (_, item) => {item.enabled && disablePackage(item.id)}>} }, ]; diff --git a/frontend/src/components/admin/payment-management.tsx b/frontend/src/components/admin/payment-management.tsx index 26b98e3b..35f329d6 100644 --- a/frontend/src/components/admin/payment-management.tsx +++ b/frontend/src/components/admin/payment-management.tsx @@ -234,7 +234,7 @@ export default function PaymentManagement() { > 配置兼容标准 Z-Pay / 易支付协议的支付网关、商户凭据、回调地址与对话页开关。 - {epaySettings && 来源:{{ database: "数据库", environment: "环境变量", unconfigured: "未配置" }[epaySettings.source]}{epaySettings.complete ? "配置完整" : "配置不完整"}{epaySettings.keyConfigured ? "密钥已配置" : "密钥未配置"}{epaySettings.chatEnabled ? "对话支付开放" : "对话支付关闭"}} + {epaySettings && 来源:{{ database: "数据库", environment: "环境变量", unconfigured: "未配置" }[epaySettings.source]} · {epaySettings.complete ? "配置完整" : "配置不完整"} · {epaySettings.keyConfigured ? "密钥已配置" : "密钥未配置"} · {epaySettings.chatEnabled ? "对话支付开放" : "对话支付关闭"}} {epayError && void loadEpaySettings()}>重试} />} form={epayForm} layout="vertical" onFinish={prepareEpaySettings} requiredMark="optional"> diff --git a/frontend/src/components/admin/product-management.tsx b/frontend/src/components/admin/product-management.tsx index 0de6b955..4c1ad5f0 100644 --- a/frontend/src/components/admin/product-management.tsx +++ b/frontend/src/components/admin/product-management.tsx @@ -17,7 +17,6 @@ import { Space, Switch, Table, - Tag, Typography, type TableColumnsType, } from "antd"; @@ -225,11 +224,11 @@ export default function ProductManagement() { dataIndex: "name", render: (_, item) => {item.name}{item.code} · v{item.version}, }, - { title: "类型", dataIndex: "productType", render: (value: Product["productType"]) => {productTypeLabels[value]} }, + { title: "类型", dataIndex: "productType", render: (value: Product["productType"]) => productTypeLabels[value] }, { title: "周期", render: (_, item) => item.billingPeriod === "none" ? billingPeriodLabels.none : `${item.intervalCount} 个周期(${billingPeriodLabels[item.billingPeriod]})` }, { title: "价格", render: (_, item) => `¥${(item.priceCents / 100).toFixed(2)}` }, - { title: "权益", dataIndex: "entitlements", render: (items: Entitlement[]) => {items.map((item) => {item.featureKey}:{allowanceTypeLabels[item.allowanceType] ?? item.allowanceType}{item.allowanceCount === null ? "" : ` ${item.allowanceCount}`} · {resetPeriodLabels[item.resetPeriod] ?? item.resetPeriod})} }, - { title: "状态", render: (_, item) => {item.status}{item.enabled ? 可售 : 停用} }, + { title: "权益", dataIndex: "entitlements", render: (items: Entitlement[]) =>
{items.map((item) => `${item.featureKey}:${allowanceTypeLabels[item.allowanceType] ?? item.allowanceType}${item.allowanceCount === null ? "" : ` ${item.allowanceCount}`} · ${resetPeriodLabels[item.resetPeriod] ?? item.resetPeriod}`).join(";") || "—"}
}, + { title: "状态", render: (_, item) => {item.status === "published" ? "已发布" : item.status === "draft" ? "草稿" : item.status} · {item.enabled ? "可售" : "停用"} }, { title: "更新时间", dataIndex: "updatedAt", render: formatAdminDate }, { title: "操作", diff --git a/frontend/src/components/admin/roles-resource.tsx b/frontend/src/components/admin/roles-resource.tsx index 166e3876..5db7a3bb 100644 --- a/frontend/src/components/admin/roles-resource.tsx +++ b/frontend/src/components/admin/roles-resource.tsx @@ -1,7 +1,7 @@ "use client"; import { useTable } from "@refinedev/antd"; -import { Alert, Card, Space, Table, Tag } from "antd"; +import { Alert, Card, Table, Typography } from "antd"; interface RoleRecord { id: string; @@ -30,8 +30,8 @@ export default function RolesResource() { columns={[ { title: "角色", dataIndex: "name" }, { title: "说明", dataIndex: "description" }, - { title: "MFA", dataIndex: "requiresMfa", render: (value: boolean) => value ? 必需 : 普通 }, - { title: "权限", dataIndex: "permissions", render: (permissions: string[]) => {permissions.map((permission) => {permission})} }, + { title: "MFA", dataIndex: "requiresMfa", render: (value: boolean) => {value ? "必需" : "普通"} }, + { title: "权限", dataIndex: "permissions", render: (permissions: string[]) =>
{permissions.join(" · ") || "—"}
}, ]} /> diff --git a/frontend/src/components/admin/users-resource.tsx b/frontend/src/components/admin/users-resource.tsx index 5ca5ab46..55d01131 100644 --- a/frontend/src/components/admin/users-resource.tsx +++ b/frontend/src/components/admin/users-resource.tsx @@ -1,7 +1,7 @@ "use client"; import { useGetIdentity } from "@refinedev/core"; -import { App, Button, Space, Tag, Typography, type TableColumnsType } from "antd"; +import { App, Button, Space, Typography, type TableColumnsType } from "antd"; import { useState } from "react"; import { ReasonActionModal } from "./reason-action-modal"; @@ -92,7 +92,7 @@ export default function UsersPage() { const columns: TableColumnsType = [ { title: "邮箱", dataIndex: "email", sorter: true }, { title: "姓名", dataIndex: "name", sorter: true, render: (value) => value || "—" }, - { title: "角色", dataIndex: "role", render: (value) => {value} }, + { title: "角色", dataIndex: "role" }, { title: "积分", dataIndex: "credits", sorter: true }, { title: "出生资料", @@ -115,7 +115,7 @@ export default function UsersPage() { }, }, { title: "邮箱验证", dataIndex: "emailVerified", render: (value) => value ? "已验证" : "未验证" }, - { title: "状态", dataIndex: "banned", render: (value) => value ? 已禁用 : 正常 }, + { title: "状态", dataIndex: "banned", render: (value) => {value ? "已禁用" : "正常"} }, { title: "注册时间", dataIndex: "createdAt", sorter: true, render: formatAdminDate }, ...(canReset ? [{ title: "操作", diff --git a/frontend/src/components/email-otp-login.tsx b/frontend/src/components/email-otp-login.tsx index d6c15c41..184c9a63 100644 --- a/frontend/src/components/email-otp-login.tsx +++ b/frontend/src/components/email-otp-login.tsx @@ -290,7 +290,6 @@ export function EmailOtpLogin({ Jyotisha
-

Vedic astrology · 印度占星

在星图与当下之间,
找到可以行动的 线索。 diff --git a/frontend/src/components/personal-report/personal-report-center.tsx b/frontend/src/components/personal-report/personal-report-center.tsx index 681a39b8..1a2f0484 100644 --- a/frontend/src/components/personal-report/personal-report-center.tsx +++ b/frontend/src/components/personal-report/personal-report-center.tsx @@ -131,7 +131,7 @@ export function PersonalReportCenter() {