fix(ui): restyle personal report pages to the product reading room
Independent Staging Quality Gate / validate (push) Successful in 8m31s
Independent Staging Quality Gate / publish (push) Successful in 1m58s

The report centre and reader were a second newspaper identity. They now reuse canvas, hairline, and serif display tokens so the document feels like the rest of Jyotisha.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-04 16:30:44 +08:00
co-authored by Cursor
parent 41f973f036
commit 7b1354a79b
12 changed files with 759 additions and 214 deletions
+665 -140
View File
@@ -122,8 +122,8 @@
/* The personal report's paper surface. Declared here so the dark blocks can
override it; see the note on .personal-report-reader. */
--report-accent: #85432f;
--report-paper: #f8f5ee;
--report-rule: #c9c2b7;
--report-paper: #fbfaf7;
--report-rule: #d8d6cf;
/* Hairlines and sheens that are dark-on-light here and light-on-dark there. */
--ring-hairline: oklch(0 0 0 / .1);
--sheen: rgba(255, 255, 255, .54);
@@ -608,7 +608,7 @@ button:disabled { cursor: default; opacity: .45; }
@media (prefers-reduced-transparency: reduce) {
.sidebar { background: var(--sidebar-solid); backdrop-filter: none; }
.chat-header, .composer-wrap { background: var(--color-canvas); backdrop-filter: none; }
.chat-header, .composer-wrap, .personal-report-actions { background: var(--color-canvas); backdrop-filter: none; }
}
@media (prefers-contrast: more) {
@@ -3232,45 +3232,248 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
.payment-qr-badge svg { display: block; width: 100%; height: 100%; }
/* Global report centre — quiet archive, independent from chat sessions. */
.report-center-shell { width: 100%; height: 100%; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 0 clamp(20px, 5vw, 72px) 72px; background: var(--color-canvas-soft); color: var(--color-ink); }
.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: 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: 44px; display: inline-flex; align-items: center; gap: 7px; padding: 0 8px; border: 0; background: transparent; color: var(--color-ink-secondary); cursor: pointer; }
.report-center-shell {
width: 100%;
height: 100%;
min-height: 0;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
padding: 0 var(--space-6) var(--space-16);
background: var(--color-canvas-soft);
color: var(--color-ink);
}
.report-center-topbar,
.report-center-hero,
.report-center-section {
width: min(900px, 100%);
margin-inline: auto;
}
.report-center-topbar {
min-height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-5);
color: var(--color-ink-tertiary);
font-size: var(--type-overline);
}
.report-center-back {
min-height: 44px;
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 0 var(--space-3);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-canvas);
color: var(--color-ink-secondary);
font-size: var(--type-body-sm);
font-weight: 500;
text-decoration: none;
}
.report-center-back:hover { border-color: var(--color-border-strong); color: var(--color-ink); }
.report-center-back:focus-visible,
.report-center-section-heading button:focus-visible,
.personal-report-back:focus-visible,
.personal-report-disclosure:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
.report-center-back svg,
.report-center-section-heading button svg,
.personal-report-back svg,
.personal-report-action-end svg { width: 16px; height: 16px; }
.report-center-hero {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: end;
gap: var(--space-8);
padding: var(--space-10) 0 var(--space-8);
}
.report-center-hero > div { max-width: 760px; }
.report-center-hero h1 {
margin: 0;
color: var(--color-ink);
font-family: var(--font-display);
font-size: var(--type-display-lg);
font-weight: 400;
letter-spacing: -1px;
line-height: 1.1;
text-wrap: balance;
}
.report-center-hero > div > p:not(.report-center-meta) {
max-width: 660px;
margin: var(--space-4) 0 0;
color: var(--color-ink-secondary);
font-size: var(--type-body-md);
line-height: 1.65;
text-wrap: pretty;
}
.report-center-meta {
margin: var(--space-4) 0 0;
color: var(--color-ink-tertiary);
font-size: var(--type-caption);
line-height: 1.4;
}
.report-center-section-heading {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-6);
margin-bottom: var(--space-4);
}
.report-center-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: -.3px;
}
.report-center-section-heading button {
min-height: 44px;
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 0 var(--space-2);
border: 0;
background: transparent;
color: var(--color-ink-secondary);
cursor: pointer;
font-size: var(--type-body-sm);
}
.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: 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: 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-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: 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 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; }
.report-center-list { display: grid; gap: var(--space-3); }
.report-center-card {
min-width: 0;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: var(--space-6);
padding: var(--space-5);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-canvas);
}
.report-center-card-body { min-width: 0; display: grid; gap: var(--space-1); }
.report-center-status {
width: fit-content;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 2px 10px;
border-radius: 999px;
background: var(--color-canvas-muted);
color: var(--color-ink-secondary);
font-size: var(--type-caption);
font-weight: 500;
}
.report-center-status.is-ready { background: var(--color-success-muted); color: var(--color-success); }
.report-center-status.is-generating { background: var(--color-action-soft); color: var(--color-action); }
.report-center-status.is-failed,
.report-center-failure { background: var(--color-danger-muted); color: var(--color-danger); }
.report-center-failure {
max-width: 220px;
padding: 8px 12px;
border-radius: var(--radius-sm);
font-family: var(--font-mono);
font-size: var(--type-caption);
overflow-wrap: anywhere;
}
.report-center-card h3 {
margin: 0;
color: var(--color-ink);
font-family: var(--font-body);
font-size: var(--type-title-md);
font-weight: 500;
}
.report-center-card p {
margin: 0;
color: var(--color-ink-secondary);
font-size: var(--type-body-sm);
line-height: 1.55;
}
.report-center-card small { color: var(--color-ink-tertiary); font-size: var(--type-caption); }
.report-center-card-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
gap: var(--space-2);
}
.report-center-export-error {
flex-basis: 100%;
color: var(--color-danger);
font-size: var(--type-body-sm);
text-align: right;
}
.report-center-empty {
min-height: 220px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-2);
padding: var(--space-8);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-canvas);
color: var(--color-ink-tertiary);
text-align: center;
}
.report-center-empty h3 {
margin: var(--space-2) 0 0;
color: var(--color-ink);
font-family: var(--font-display);
font-size: var(--type-title-md);
font-weight: 400;
}
.report-center-empty p {
max-width: 460px;
margin: 0;
font-size: var(--type-body-sm);
line-height: 1.55;
text-wrap: pretty;
}
.report-center-alert {
margin: 0 0 var(--space-4);
padding: var(--space-3) var(--space-4);
border: 1px solid color-mix(in srgb, var(--color-danger) 32%, var(--color-border));
border-radius: var(--radius-md);
background: var(--color-danger-muted);
color: var(--color-danger);
font-size: var(--type-body-sm);
}
.report-center-message {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-4);
text-align: center;
}
.report-center-message h1 {
margin: 0;
font-family: var(--font-display);
font-size: var(--type-display-sm);
font-weight: 400;
letter-spacing: -.3px;
}
.report-center-message p { margin: 0; color: var(--color-ink-secondary); font-size: var(--type-body-sm); }
@media (max-width: 720px) {
.report-center-hero { grid-template-columns: 1fr; align-items: start; gap: 24px; padding-block: 40px 34px; }
.report-center-shell { padding-inline: var(--space-4); }
.report-center-hero { grid-template-columns: 1fr; align-items: start; gap: var(--space-6); padding-block: var(--space-8) var(--space-6); }
.report-center-hero h1 { font-size: var(--type-display-md); letter-spacing: -.5px; }
.report-center-hero > button { width: 100%; }
.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-card { grid-template-columns: 1fr; gap: var(--space-4); }
.report-center-card-actions,
.report-center-card > a,
.report-center-card > button,
.report-center-failure { justify-self: start; }
.report-center-export-error { text-align: left; }
.report-center-section-heading { align-items: center; }
}
@@ -3293,129 +3496,432 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
-webkit-overflow-scrolling: touch;
touch-action: pan-y;
scrollbar-gutter: stable;
background: var(--report-paper);
background: var(--color-canvas-soft);
}
.personal-report-reader-body { width: 100%; padding: 0 var(--space-6) var(--space-16); }
.personal-report-actions {
position: sticky;
top: 0;
z-index: 20;
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
background: var(--color-frosted);
backdrop-filter: saturate(130%) blur(20px);
}
.personal-report-actions > div {
width: min(900px, 100%);
min-height: 54px;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-4);
margin: 0 auto;
padding: var(--space-2) var(--space-6);
}
.personal-report-back {
min-height: 44px;
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 0 var(--space-3);
border-radius: var(--radius-sm);
color: var(--color-ink-secondary);
font-size: var(--type-body-sm);
text-decoration: none;
}
.personal-report-back:hover { color: var(--color-ink); background: var(--color-canvas-muted); }
.personal-report-action-end { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3); }
.personal-report-action-end > span {
max-width: 440px;
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--color-warning);
font-size: var(--type-caption);
line-height: 1.45;
}
.personal-report-reader-body { width: 100%; padding: 0 24px 64px; }
.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); }
.personal-report-back svg, .personal-report-action-end svg { width: 16px; height: 16px; }
.personal-report-action-end { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.personal-report-action-end > span { max-width: 440px; display: inline-flex; align-items: center; gap: 6px; color: var(--color-warning); font-size: 13px; line-height: 1.45; }
.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-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; }
.personal-report-metadata > div { min-width: 0; display: grid; grid-template-columns: 68px minmax(0, 1fr); gap: 10px; }
.personal-report-metadata dt { color: var(--color-ink-tertiary); }
.personal-report-metadata dd { min-width: 0; margin: 0; color: var(--color-ink); overflow-wrap: anywhere; }
.personal-report-facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 38px 0 0; padding: 27px 0 24px; border-top: 1px solid var(--report-rule); border-bottom: 1px solid var(--report-rule); }
.personal-report-facts > div { min-width: 0; padding: 0 22px; text-align: center; }
.personal-report-facts > div + div { border-left: 1px solid var(--report-rule); }
.personal-report-facts dd { margin: 0; color: var(--color-ink); font-size: 21px; font-weight: 650; line-height: 1.35; overflow-wrap: anywhere; }
.personal-report-facts dt { margin-top: 6px; color: var(--color-ink-tertiary); font-size: 13px; }
.personal-report-state {
width: 100%;
height: 100%;
min-height: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-4);
padding: var(--space-6);
overflow-x: hidden;
overflow-y: auto;
background: var(--color-canvas-soft);
color: var(--color-ink);
text-align: center;
}
.personal-report-state h1 {
margin: 0;
font-family: var(--font-display);
font-size: var(--type-display-sm);
font-weight: 400;
letter-spacing: -.3px;
text-wrap: balance;
}
.personal-report-state p {
max-width: 36rem;
margin: 0;
color: var(--color-ink-secondary);
font-size: var(--type-body-sm);
line-height: 1.55;
text-wrap: pretty;
}
.personal-report-section-heading { margin-bottom: 20px; }
.personal-report-section-heading > p { margin: 0 0 4px; color: var(--report-accent); font-size: 11px; font-weight: 650; letter-spacing: .12em; text-transform: uppercase; }
.personal-report-section-heading h2 { margin: 0; font-family: var(--font-body); font-size: 27px; font-weight: 700; letter-spacing: -.025em; line-height: 1.3; }
.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-document {
width: min(900px, 100%);
margin: var(--space-8) auto 0;
padding: var(--space-10) var(--space-8) var(--space-8);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-canvas);
color: var(--color-ink);
font-family: var(--font-body);
font-size: var(--type-body-md);
line-height: 1.65;
}
.personal-report-section { margin: 0 0 var(--space-12); }
.personal-report-cover-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(220px, 32%);
gap: var(--space-10);
align-items: end;
}
.personal-report-kicker,
.personal-report-section-heading > p {
margin: 0 0 var(--space-1);
color: var(--color-ink-tertiary);
font-size: var(--type-overline);
font-weight: 500;
letter-spacing: 1.5px;
}
.personal-report-cover .personal-report-kicker { margin-bottom: var(--space-3); }
.personal-report-cover h1 {
margin: 0;
font-family: var(--font-display);
font-size: var(--type-display-lg);
font-weight: 400;
letter-spacing: -1px;
line-height: 1.1;
text-wrap: balance;
}
.personal-report-deck {
max-width: 620px;
margin: var(--space-4) 0 0;
color: var(--color-ink-secondary);
font-size: var(--type-body-md);
line-height: 1.65;
text-wrap: pretty;
}
.personal-report-metadata { display: grid; gap: var(--space-2); margin: 0; }
.personal-report-metadata > div { min-width: 0; display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: var(--space-3); }
.personal-report-metadata dt { color: var(--color-ink-tertiary); font-size: var(--type-caption); font-weight: 500; }
.personal-report-metadata dd { min-width: 0; margin: 0; color: var(--color-ink); overflow-wrap: anywhere; font-size: var(--type-body-sm); }
.personal-report-facts {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 0;
margin: var(--space-8) 0 0;
padding: 0;
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-canvas-muted);
}
.personal-report-facts > div { min-width: 0; padding: var(--space-5) var(--space-4); text-align: center; }
.personal-report-facts > div + div { border-left: 1px solid var(--color-border); }
.personal-report-facts dd {
margin: 0;
color: var(--color-ink);
font-family: var(--font-display);
font-size: var(--type-title-md);
font-weight: 400;
line-height: 1.35;
overflow-wrap: anywhere;
}
.personal-report-facts dt { margin-top: 6px; color: var(--color-ink-tertiary); font-size: var(--type-caption); }
.personal-report-section-heading { margin-bottom: var(--space-5); }
.personal-report-section-heading h2 {
margin: 0;
font-family: var(--font-display);
font-size: var(--type-display-sm);
font-weight: 400;
letter-spacing: -.3px;
line-height: 1.2;
text-wrap: balance;
}
.personal-report-narrative p {
margin: 0 0 var(--space-4);
color: var(--color-ink-strong);
font-size: var(--type-body-md);
line-height: 1.65;
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 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-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-summary { max-width: 760px; }
.personal-report-callout {
margin: var(--space-6) 0 0;
padding: var(--space-4);
border: 1px solid color-mix(in srgb, var(--color-action) 22%, var(--color-border));
border-radius: var(--radius-md);
background: var(--color-action-soft);
color: var(--color-ink-strong);
}
.personal-report-callout strong { color: var(--color-action); font-weight: 500; }
.personal-report-priorities {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0 var(--space-8);
margin: var(--space-5) 0 0;
padding-left: 20px;
}
.personal-report-priorities li {
padding: var(--space-3) 0 var(--space-3) 4px;
color: var(--color-ink-secondary);
font-size: var(--type-body-sm);
}
.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; }
.personal-report-subheading { min-height: 38px; display: flex; align-items: baseline; gap: 10px; padding-bottom: 9px; border-bottom: 1px solid var(--report-rule); }
.personal-report-subheading h2, .personal-report-subheading h3 { margin: 0; font-family: var(--font-body); font-size: 20px; font-weight: 700; line-height: 1.4; }
.personal-report-subheading span { color: var(--color-ink-secondary); font-size: 13px; }
.personal-report-chart-svg { display: block; width: 100%; height: auto; margin-top: 14px; }
.personal-report-lead-grid {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(260px, .9fr);
gap: var(--space-8);
align-items: start;
}
.personal-report-subheading {
min-height: 38px;
display: flex;
align-items: baseline;
gap: var(--space-3);
padding-bottom: var(--space-2);
border-bottom: 1px solid var(--color-border);
}
.personal-report-subheading h2,
.personal-report-subheading h3 {
margin: 0;
font-family: var(--font-display);
font-size: var(--type-title-lg);
font-weight: 400;
line-height: 1.3;
}
.personal-report-subheading span { color: var(--color-ink-secondary); font-size: var(--type-caption); }
.personal-report-chart-svg { display: block; width: 100%; height: auto; margin-top: var(--space-4); color: var(--color-ink); }
.personal-report-chart-svg .personal-report-chart-cell { fill: none; stroke: var(--color-ink-strong); stroke-width: 1.25; }
.personal-report-chart-svg .personal-report-chart-core { fill: var(--color-canvas-muted); stroke: var(--color-ink-strong); stroke-width: 1.25; }
.personal-report-chart-svg .personal-report-chart-diamond { fill: none; stroke: var(--color-ink-strong); stroke-width: 1.25; }
.personal-report-chart-svg text { fill: currentColor; }
.personal-report-chart-svg .personal-report-chart-muted { fill: var(--color-ink-tertiary); }
.personal-report-chart-figure { min-width: 0; margin: 0; }
.personal-report-chart-figure figcaption { margin-top: 10px; color: var(--color-ink-tertiary); font-size: 11px; line-height: 1.55; }
.personal-report-chart-figure figcaption {
margin-top: var(--space-3);
color: var(--color-ink-tertiary);
font-size: var(--type-caption);
line-height: 1.55;
}
.personal-report-key-evidence { min-width: 0; }
.personal-report-key-evidence table, .personal-report-table-wrap table { width: 100%; min-width: 0; border-collapse: collapse; table-layout: fixed; text-align: left; }
.personal-report-key-evidence th, .personal-report-key-evidence td, .personal-report-table-wrap th, .personal-report-table-wrap td { padding: 9px 8px; border-bottom: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); vertical-align: top; overflow-wrap: anywhere; }
.personal-report-key-evidence thead th, .personal-report-table-wrap thead th { color: var(--color-ink-secondary); font-size: 11px; font-weight: 650; letter-spacing: .04em; }
.personal-report-key-evidence tbody th { width: 30%; color: var(--color-ink); font-size: 13px; font-weight: 550; }
.personal-report-key-evidence tbody td { color: var(--color-ink-strong); font-size: 13px; }
.personal-report-key-evidence table,
.personal-report-table-wrap table {
width: 100%;
min-width: 0;
border-collapse: collapse;
table-layout: fixed;
text-align: left;
}
.personal-report-key-evidence th,
.personal-report-key-evidence td,
.personal-report-table-wrap th,
.personal-report-table-wrap td {
padding: 10px 8px;
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);
vertical-align: top;
overflow-wrap: anywhere;
}
.personal-report-key-evidence thead th,
.personal-report-table-wrap thead th {
color: var(--color-ink-secondary);
font-size: var(--type-overline);
font-weight: 500;
}
.personal-report-key-evidence tbody th { width: 30%; color: var(--color-ink); font-size: var(--type-body-sm); font-weight: 500; }
.personal-report-key-evidence tbody td { color: var(--color-ink-strong); font-size: var(--type-body-sm); }
.personal-report-chart-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 38px; }
.personal-report-chart-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
.personal-report-chart-grid.is-single { grid-template-columns: minmax(0, 520px); }
.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-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: var(--color-warning); }
.personal-report-claim-status.is-danger { color: var(--color-danger); }
.personal-report-chart-card {
min-width: 0;
padding: var(--space-5);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-canvas-muted);
}
.personal-report-chart-card > header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.personal-report-chart-card h3 { margin: 0; font-family: var(--font-body); font-size: var(--type-title-md); font-weight: 500; }
.personal-report-claim-status {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
padding: 2px 10px;
border-radius: 999px;
background: var(--color-canvas);
color: var(--color-ink-secondary);
font-size: var(--type-caption);
font-weight: 500;
line-height: 1.5;
}
.personal-report-claim-status.is-success { background: var(--color-success-muted); color: var(--color-success); }
.personal-report-claim-status.is-warning { background: var(--color-action-soft); color: var(--color-warning); }
.personal-report-claim-status.is-danger { background: var(--color-danger-muted); 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-planet-table { margin-top: var(--space-4); font-size: var(--type-caption); }
.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: 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-themes { padding-top: 0; }
.personal-report-theme {
padding: var(--space-6);
margin-top: var(--space-4);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-canvas-muted);
}
.personal-report-theme > header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--space-4);
margin-bottom: var(--space-4);
}
.personal-report-theme h3 {
margin: 0;
font-family: var(--font-body);
font-size: var(--type-title-md);
font-weight: 500;
line-height: 1.4;
}
.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 {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-6);
margin: var(--space-5) 0 0;
padding: var(--space-4) 0 0;
border-top: 1px solid var(--color-border);
}
.personal-report-theme-details h4 { margin: 0 0 7px; color: var(--color-ink); font-size: var(--type-caption); font-weight: 500; }
.personal-report-theme-details ul { margin: 0; padding-left: 18px; color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.7; }
.personal-report-theme-details li + li { margin-top: 4px; }
.personal-report-evidence-links { display: flex; flex-wrap: wrap; gap: 7px 16px; margin: 16px 0 0 44px; padding: 0; list-style: none; color: var(--color-ink-tertiary); font-size: 11px; }
.personal-report-evidence-links a { color: var(--report-accent); text-decoration-color: color-mix(in srgb, var(--report-accent) 35%, transparent); text-underline-offset: 3px; }
.personal-report-evidence-links {
display: flex;
flex-wrap: wrap;
gap: 7px 16px;
margin: var(--space-4) 0 0;
padding: 0;
list-style: none;
color: var(--color-ink-tertiary);
font-size: var(--type-caption);
}
.personal-report-evidence-links a {
color: var(--report-accent);
text-decoration-color: color-mix(in srgb, var(--report-accent) 35%, transparent);
text-underline-offset: 3px;
}
.personal-report-appendix { position: relative; padding-top: 34px; border-top: 1px solid var(--report-rule); }
.personal-report-appendix { position: relative; padding-top: var(--space-2); }
.personal-report-appendix > .personal-report-section-heading { margin-bottom: 0; }
.personal-report-appendix-details > summary { position: absolute; top: 34px; right: 0; display: inline-flex; align-items: center; }
.personal-report-disclosure { min-height: 38px; padding: 0 12px; border: 1px solid var(--report-rule); border-radius: 6px; background: transparent; color: var(--color-ink); cursor: pointer; font-size: 13px; list-style: none; }
.personal-report-appendix-details > summary { position: absolute; top: var(--space-2); right: 0; display: inline-flex; align-items: center; }
.personal-report-disclosure {
min-height: 44px;
padding: 0 12px;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-canvas);
color: var(--color-ink);
cursor: pointer;
font-size: var(--type-caption);
list-style: none;
}
.personal-report-disclosure::-webkit-details-marker { display: none; }
.personal-report-disclosure:hover { border-color: var(--report-accent); color: var(--report-accent); }
.personal-report-appendix-intro { margin: 12px 0 24px; color: var(--color-ink-secondary); font-size: 13px; }
.personal-report-appendix h3 { margin: 28px 0 10px; font-size: 16px; }
.personal-report-audit-table { font-size: 12px; }
.personal-report-disclosure:hover { border-color: var(--color-border-strong); color: var(--color-action); }
.personal-report-appendix-intro { margin: 12px 0 24px; color: var(--color-ink-secondary); font-size: var(--type-body-sm); }
.personal-report-appendix h3 {
margin: var(--space-6) 0 var(--space-3);
font-family: var(--font-display);
font-size: var(--type-title-md);
font-weight: 400;
}
.personal-report-audit-table { font-size: var(--type-caption); }
.personal-report-audit-table th:nth-child(1) { width: 24%; }
.personal-report-audit-table th:nth-child(2), .personal-report-audit-table th:nth-child(3) { width: 12%; }
.personal-report-audit-table td strong, .personal-report-audit-table td small { display: block; }
.personal-report-audit-table td small { color: var(--color-ink-tertiary); font-size: 10px; }
.personal-report-audit-table th:nth-child(2),
.personal-report-audit-table th:nth-child(3) { width: 12%; }
.personal-report-audit-table td strong,
.personal-report-audit-table td small { display: block; }
.personal-report-audit-table td small { color: var(--color-ink-tertiary); font-size: var(--type-caption); }
.personal-report-conflicts { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.personal-report-conflicts li { display: grid; gap: 3px; padding: 12px 0; border-bottom: 1px solid color-mix(in srgb, var(--report-rule) 68%, transparent); }
.personal-report-conflicts span { color: var(--color-ink-secondary); font-size: 13px; }
.personal-report-conflicts li {
display: grid;
gap: 3px;
padding: var(--space-3) 0;
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);
}
.personal-report-conflicts span { color: var(--color-ink-secondary); font-size: var(--type-body-sm); }
.personal-report-conflicts small { color: var(--color-ink-tertiary); }
.personal-report-blocked-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.personal-report-blocked-list li { padding: 3px 8px; border: 1px solid color-mix(in srgb, var(--color-danger) 35%, transparent); border-radius: 999px; color: var(--color-danger); font-size: 11px; }
.personal-report-disclaimer { padding-top: 26px; border-top: 1px solid var(--report-rule); }
.personal-report-disclaimer h2 { margin: 0 0 8px; font-size: 16px; }
.personal-report-disclaimer p { margin: 0; color: var(--color-ink-secondary); font-size: 12px; line-height: 1.75; }
.personal-report-footer { display: flex; justify-content: space-between; gap: 20px; padding-top: 20px; border-top: 1px solid var(--report-rule); color: var(--color-ink-tertiary); font-size: 10px; }
.personal-report-blocked-list li {
padding: 4px 10px;
border-radius: 999px;
background: var(--color-danger-muted);
color: var(--color-danger);
font-size: var(--type-caption);
}
.personal-report-disclaimer { padding-top: var(--space-6); border-top: 1px solid var(--color-border); }
.personal-report-disclaimer h2 {
margin: 0 0 var(--space-2);
font-family: var(--font-display);
font-size: var(--type-title-md);
font-weight: 400;
}
.personal-report-disclaimer p { margin: 0; color: var(--color-ink-secondary); font-size: var(--type-caption); line-height: 1.75; }
.personal-report-footer {
display: flex;
justify-content: space-between;
gap: var(--space-5);
padding-top: var(--space-5);
border-top: 1px solid var(--color-border);
color: var(--color-ink-tertiary);
font-size: var(--type-caption);
}
.personal-report-footer span:last-child { overflow-wrap: anywhere; text-align: right; }
.personal-report-avoid-break { break-inside: avoid-page; }
.personal-report-avoid-break-row { break-inside: avoid; }
@media (max-width: 760px) {
.personal-report-reader-body { padding: 0 16px 48px; }
.personal-report-actions > div { min-height: 50px; padding: 6px 16px; }
.personal-report-reader-body { padding: 0 var(--space-4) var(--space-12); }
.personal-report-actions > div { min-height: 50px; padding: 6px var(--space-4); }
.personal-report-action-end > span { display: none; }
.personal-report-document { padding: 34px 0 24px; font-size: 14px; }
.personal-report-section { margin-bottom: 44px; }
.personal-report-cover-grid { grid-template-columns: 1fr; gap: 26px; }
.personal-report-cover h1 { font-size: clamp(40px, 13vw, 54px); }
.personal-report-document { margin-top: var(--space-5); padding: var(--space-6) var(--space-4) var(--space-5); }
.personal-report-section { margin-bottom: var(--space-10); }
.personal-report-cover-grid { grid-template-columns: 1fr; gap: var(--space-6); }
.personal-report-cover h1 { font-size: var(--type-display-md); letter-spacing: -.5px; }
.personal-report-metadata { gap: 7px; }
.personal-report-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 0; }
.personal-report-facts > div { padding: 17px 8px; }
.personal-report-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.personal-report-facts > div { padding: var(--space-4) var(--space-2); }
.personal-report-facts > div + div { border-left: 0; }
.personal-report-facts > div:nth-child(even) { border-left: 1px solid var(--report-rule); }
.personal-report-facts > div:nth-child(n + 3) { border-top: 1px solid var(--report-rule); }
.personal-report-facts dd { font-size: 17px; }
.personal-report-facts > div:nth-child(even) { border-left: 1px solid var(--color-border); }
.personal-report-facts > div:nth-child(n + 3) { border-top: 1px solid var(--color-border); }
.personal-report-facts dd { font-size: var(--type-title-sm); }
.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 .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-lead-grid,
.personal-report-chart-grid,
.personal-report-chart-grid.is-single { grid-template-columns: 1fr; gap: var(--space-6); }
.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: var(--space-4); }
.personal-report-footer { display: grid; }
.personal-report-footer span:last-child { text-align: left; }
}
@@ -3432,6 +3938,7 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
--color-ink-tertiary: #6a6963;
--color-canvas: #fbfaf7;
--color-canvas-soft: #f3f2ee;
--color-canvas-muted: #ebe9e3;
--color-border: #d8d6cf;
--color-border-strong: #b8b5ad;
--color-action: #85432f;
@@ -3441,8 +3948,8 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
--color-success: #28633e;
--color-warning: #b07b22;
--report-accent: #85432f;
--report-paper: #f8f5ee;
--report-rule: #c9c2b7;
--report-paper: #fbfaf7;
--report-rule: #d8d6cf;
}
html, body { width: auto !important; height: auto !important; min-height: 0 !important; overflow: visible !important; background: #fff !important; }
* { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
@@ -3451,24 +3958,42 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
.personal-report-appendix-details:not([open]) > .personal-report-print-always { display: block !important; }
.personal-report-reader { width: auto !important; height: auto !important; min-height: 0 !important; overflow: visible !important; background: #fff !important; }
.personal-report-reader-body { width: auto !important; padding: 0 !important; }
.personal-report-document { width: auto !important; max-width: none !important; margin: 0 !important; padding: 0 !important; background: #fff !important; font-size: 9.6pt; line-height: 1.66; }
.personal-report-document {
width: auto !important;
max-width: none !important;
margin: 0 !important;
padding: 0 !important;
border: 0 !important;
border-radius: 0 !important;
background: #fff !important;
font-size: 9.6pt;
line-height: 1.66;
}
.personal-report-section { margin-bottom: 9mm; }
.personal-report-cover-grid { grid-template-columns: minmax(0, 1fr) 66mm; gap: 12mm; }
.personal-report-cover h1 { font-size: 30pt; }
.personal-report-deck { font-size: 10pt; }
.personal-report-facts { margin-top: 8mm; padding: 5mm 0; }
.personal-report-facts { margin-top: 8mm; }
.personal-report-facts dd { font-size: 13pt; }
.personal-report-section-heading h2 { font-size: 18pt; }
.personal-report-narrative p { font-size: 9.6pt; line-height: 1.72; orphans: 3; widows: 3; }
.personal-report-lead-grid { grid-template-columns: minmax(0, 1.04fr) minmax(64mm, .96fr); gap: 8mm; }
.personal-report-chart-svg { max-width: none; margin-top: 3mm; }
.personal-report-chart-grid, .personal-report-chart-grid.is-single { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.personal-report-chart-grid,
.personal-report-chart-grid.is-single { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.personal-report-chart-grid.is-single { max-width: 118mm; }
.personal-report-table-wrap { max-width: none !important; overflow: visible !important; }
.personal-report-table-wrap table, .personal-report-key-evidence table { width: 100% !important; min-width: 0 !important; table-layout: fixed !important; }
.personal-report-table-wrap th, .personal-report-table-wrap td, .personal-report-key-evidence th, .personal-report-key-evidence td { overflow-wrap: anywhere !important; word-break: break-word; }
.personal-report-theme { padding: 6mm 0; }
.personal-report-theme h3, .personal-report-subheading h2, .personal-report-subheading h3, .personal-report-appendix h3 { break-after: avoid-page; }
.personal-report-table-wrap table,
.personal-report-key-evidence table { width: 100% !important; min-width: 0 !important; table-layout: fixed !important; }
.personal-report-table-wrap th,
.personal-report-table-wrap td,
.personal-report-key-evidence th,
.personal-report-key-evidence td { overflow-wrap: anywhere !important; word-break: break-word; }
.personal-report-theme { padding: 6mm; margin-top: 4mm; }
.personal-report-theme h3,
.personal-report-subheading h2,
.personal-report-subheading h3,
.personal-report-appendix h3 { break-after: avoid-page; }
.personal-report-theme-details { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.personal-report-footer { margin-top: 8mm; }
.personal-report-avoid-break { break-inside: avoid-page; }
@@ -20,12 +20,10 @@ export default function ReportError({
}, [error]);
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<main className="personal-report-state">
<TriangleAlert aria-hidden="true" className="size-8 text-danger" />
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="max-w-md text-sm text-ink-secondary">
</p>
<h1></h1>
<p></p>
<Button type="button" variant="outline" onClick={() => unstable_retry()}>
</Button>
@@ -3,11 +3,9 @@ import "../../site-styles";
export default function ReportLoading() {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<main className="personal-report-state">
<InlineSpinner className="text-primary" size={32} />
<p className="text-ink" role="status">
</p>
<p role="status"></p>
</main>
);
}
@@ -7,11 +7,9 @@ import "../../site-styles";
export default function ReportNotFound() {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="max-w-md text-sm text-ink-secondary">
</p>
<main className="personal-report-state">
<h1></h1>
<p></p>
<Button render={<Link href="/" />} nativeButton={false} variant="outline">
</Button>
@@ -20,6 +20,8 @@ import { useRouter } from "next/navigation";
import { FileText } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
export const DEFAULT_REPORT_THEMES = ["career", "marriage", "wealth", "timing", "health"] as const;
export interface PersonalReportCreateRequest {
@@ -190,15 +192,15 @@ export function GeneratePersonalReportButton({
}
return (
<button
<Button
type="button"
className="inline-flex min-h-11 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-lg border border-border bg-canvas px-3 py-1.5 text-sm text-ink transition-colors hover:bg-canvas-muted disabled:pointer-events-none disabled:opacity-50"
className="shrink-0 whitespace-nowrap"
onClick={() => void handleGenerate()}
disabled={submitting}
title="根据已保存的具体出生分钟生成完整报告;未校正会标明方向性参考"
>
<FileText aria-hidden="true" className="size-4" />
<FileText aria-hidden="true" />
{submitting ? "正在创建…" : "生成完整报告"}
</button>
</Button>
);
}
@@ -221,7 +221,7 @@ export function PersonalReportCenter() {
return (
<article className="report-center-card" key={report.id}>
<div className="report-center-card-body">
<div className={`report-center-status is-${report.status}`}>
<div className={`report-center-status is-${report.status}`} role={report.status === "generating" ? "status" : undefined}>
<StatusIcon status={report.status} />{copy.label}
</div>
<h3>{report.reportType === "personal_thematic" ? "个人主题报告" : "个人完整报告"}</h3>
@@ -229,7 +229,7 @@ export function PersonalReportCenter() {
<small>{formatDate(report.createdAt)} · {report.depth} · {report.themes.join(" / ") || "综合主题"}</small>
</div>
{report.status === "ready" ? (
<div className="flex flex-wrap items-center justify-end gap-2 max-[720px]:justify-start">
<div className="report-center-card-actions">
<Button render={<Link href={`/reports/${encodeURIComponent(report.id)}`} />} nativeButton={false} variant="outline">
</Button>
@@ -243,7 +243,7 @@ export function PersonalReportCenter() {
</Button>
{exportError?.reportId === report.id ? (
<span className="basis-full text-right text-sm text-destructive max-[720px]:text-left" role="alert">
<span className="report-center-export-error" role="alert">
{exportError.message}
</span>
) : null}
@@ -197,6 +197,7 @@ function ReportCover({ document, d1 }: { document: ReportDocument; d1: ChartV1 |
<header className="personal-report-cover personal-report-section">
<div className="personal-report-cover-grid">
<div>
<p className="personal-report-kicker"></p>
<h1>{document.subject.displayName}</h1>
<p className="personal-report-deck">{document.executiveSummary.headline}</p>
</div>
@@ -229,17 +229,15 @@ export function PersonalReportPage({ reportId }: { reportId: string }) {
if (state.phase === "loading" || state.phase === "generating") {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<main className="personal-report-state">
<InlineSpinner className="text-primary" size={32} />
<p className="text-ink" role="status">
<p role="status">
{generating ? (progressLabel ?? "报告正在生成中,请稍候…") : "正在加载报告…"}
</p>
{generating && (
<>
<p className="text-sm text-ink-tertiary"> {formatWaitedDuration(waitedMs)}</p>
<p className="max-w-md text-sm text-ink-secondary">
</p>
<p> {formatWaitedDuration(waitedMs)}</p>
<p></p>
<Button render={<Link href="/reports" />} nativeButton={false} variant="ghost"></Button>
</>
)}
@@ -249,13 +247,11 @@ export function PersonalReportPage({ reportId }: { reportId: string }) {
if (state.phase === "timed-out") {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<main className="personal-report-state">
<Clock3 aria-hidden="true" className="size-8 text-ink-secondary" />
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="text-sm text-ink-tertiary"> {formatWaitedDuration(waitedMs)}</p>
<p className="max-w-md text-sm text-ink-secondary">
</p>
<h1></h1>
<p> {formatWaitedDuration(waitedMs)}</p>
<p></p>
<div className="flex flex-wrap items-center justify-center gap-3">
<Button type="button" variant="default" onClick={() => keepWaiting()}>
@@ -270,11 +266,9 @@ export function PersonalReportPage({ reportId }: { reportId: string }) {
if (state.phase === "unauthorized") {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="max-w-md text-sm text-ink-secondary">
</p>
<main className="personal-report-state">
<h1></h1>
<p></p>
<Button render={<Link href="/login" />} nativeButton={false} variant="default">
</Button>
@@ -284,11 +278,9 @@ export function PersonalReportPage({ reportId }: { reportId: string }) {
if (state.phase === "not-found") {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="max-w-md text-sm text-ink-secondary">
</p>
<main className="personal-report-state">
<h1></h1>
<p></p>
<Button render={<Link href="/reports" />} nativeButton={false} variant="outline">
</Button>
@@ -298,14 +290,12 @@ export function PersonalReportPage({ reportId }: { reportId: string }) {
if (state.phase === "failed") {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<main className="personal-report-state">
<TriangleAlert aria-hidden="true" className="size-8 text-warning" />
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="max-w-md text-sm text-ink-secondary">
{state.failureSummary ?? "生成过程中出现问题,未产出可用报告。请稍后重试。"}
</p>
<h1></h1>
<p>{state.failureSummary ?? "生成过程中出现问题,未产出可用报告。请稍后重试。"}</p>
{state.failureCode && (
<p className="font-mono text-xs text-ink-tertiary">{state.failureCode}</p>
<p>{state.failureCode}</p>
)}
<Button render={<Link href="/reports" />} nativeButton={false} variant="outline">
@@ -316,10 +306,10 @@ export function PersonalReportPage({ reportId }: { reportId: string }) {
if (state.phase === "invalid" || state.phase === "network-error") {
return (
<main className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 text-center">
<main className="personal-report-state">
<TriangleAlert aria-hidden="true" className="size-8 text-danger" />
<h1 className="text-xl font-semibold text-ink"></h1>
<p className="max-w-md text-sm text-ink-secondary">
<h1></h1>
<p>
{state.phase === "invalid"
? `报告数据未通过校验(${state.message}),已停止渲染。`
: "网络连接失败,请检查网络后重试。"}
@@ -91,7 +91,6 @@ function PlanetList({ lines }: { lines: string[] }) {
x={6 + column * 49}
y={45 + row * rowStep}
fontSize={fontSize}
fill="#1d1d1f"
>
{truncateSvgLabel(line, maxCharacters)}
</text>
@@ -141,15 +140,13 @@ export function VedicChartSvg({ chart, ariaLabel }: VedicChartSvgProps) {
y={cell.y}
width={CELL}
height={CELL}
fill="none"
stroke="#32322f"
strokeWidth={1.25}
className="personal-report-chart-cell"
/>
<text x={cell.x + 5} y={cell.y + 15} fontSize={10} fill="#6a6963">
<text x={cell.x + 5} y={cell.y + 15} fontSize={10} className="personal-report-chart-muted">
{houseNumber}
</text>
{house && (
<text x={cell.x + 5} y={cell.y + 30} fontSize={12} fontWeight={600} fill="#32322f">
<text x={cell.x + 5} y={cell.y + 30} fontSize={12} fontWeight={600}>
{house.sign}
</text>
)}
@@ -164,18 +161,14 @@ export function VedicChartSvg({ chart, ariaLabel }: VedicChartSvgProps) {
y={CELL}
width={CELL * 2}
height={CELL * 2}
fill="#f3f2ee"
stroke="#32322f"
strokeWidth={1.25}
className="personal-report-chart-core"
/>
<path
d={`M ${CELL * 2} ${CELL} L ${CELL * 3} ${CELL * 2} L ${CELL * 2} ${CELL * 3} L ${CELL} ${CELL * 2} Z`}
fill="none"
stroke="#32322f"
strokeWidth={1.25}
className="personal-report-chart-diamond"
/>
{hasRetrogradeMarker && (
<text x={CHART_VIEWBOX_WIDTH - 6} y={CHART_VIEWBOX_HEIGHT - 4} textAnchor="end" fontSize={9} fill="#6a6963">
<text x={CHART_VIEWBOX_WIDTH - 6} y={CHART_VIEWBOX_HEIGHT - 4} textAnchor="end" fontSize={9} className="personal-report-chart-muted">
=
</text>
)}