feat(chart): 星盘改用行星符号与颜色,度数进行星表
北印星盘(星盘页 / 校正右栏 / 我的报告共用 VedicChartSvg)宫内不再画 「水 19°」「罗逆 29°」这类显示文本——一宫三颗星就叠三行、字号压到 8。 改成九个彩色符号横排,每行最多 3 个;逆行是符号下方一道同色横线, 第 1 宫加 As 小标,盘下方两行图例。度数、星宿、顺逆下沉到星盘页的 行星表,列从四列扩到八列,首行是上升,度数精确到分。 - 符号字体:vendored 的 9 字形 Noto Sans Symbols 子集(OFL,1.5 KB), 经 next/font/local 挂成 --font-planet-glyphs;♀ ♂ 带 U+FE0E 防 iOS 画成表情。构建镜像不能联网,所以必须自带,与 Inter 同一条理由。 - 颜色:--color-planet-* 九个 token,:root 与两个深色块各一份。只用于 认星不表吉凶,罗计共用中性灰。挂 is-* 修饰类而非行内 style——报告 文档的标记合同禁止渲染结果出现 style=,星盘不做例外。 - 数据来源:toNorthIndianChart() 加结构化 occupantGlyphs(星盘页与 markdown fence 走这条);校正与报告两条路线的模型只有引擎 / golden 显示文本,按首字解析,解析由测试锁住。 - 星宿沿用引擎返回名:仓库无中文宿名表,印度 27 宿与中国二十八宿不是 同一套,不自造对照。 tsc 0 错,lint 0 error,npm test 3471→3484 条、36 红与基线逐条相同, / 仍 Static,首屏 JS gzip +0.29%。 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
84b293fb47
commit
5a1dcbd2a1
Binary file not shown.
@@ -3,3 +3,14 @@ File: InterVariable-latin.woff2
|
||||
Taken from @fontsource-variable/inter@5.3.0 files/inter-latin-wght-normal.woff2
|
||||
Upstream: https://github.com/rsms/inter
|
||||
License: SIL Open Font License 1.1 (OFL.txt)
|
||||
|
||||
Noto Sans Symbols — 9-glyph planet subset
|
||||
File: NotoSansSymbols-planets.woff2
|
||||
Taken from https://fonts.googleapis.com/css2?family=Noto+Sans+Symbols&text=☉☽☿♀♂♃♄☊☋
|
||||
(the CSS that URL returns points at one fonts.gstatic.com subset file; that file is this one)
|
||||
Glyphs: U+2609 ☉ 日 · U+263D ☽ 月 · U+263F ☿ 水 · U+2640 ♀ 金 · U+2642 ♂ 火 ·
|
||||
U+2643 ♃ 木 · U+2644 ♄ 土 · U+260A ☊ 罗 · U+260B ☋ 计
|
||||
Upstream: https://github.com/notofonts/symbols
|
||||
License: SIL Open Font License 1.1 (OFL.txt), © the Noto Project Authors
|
||||
Why vendored: the publish image has no network at build time, so next/font/google
|
||||
cannot be used. Same reason as Inter above.
|
||||
|
||||
@@ -47,6 +47,15 @@
|
||||
--color-dark-hover: var(--color-dark-hover);
|
||||
--color-dark-muted: var(--color-dark-muted);
|
||||
--color-dark-border: var(--color-dark-border);
|
||||
--color-planet-sun: var(--color-planet-sun);
|
||||
--color-planet-moon: var(--color-planet-moon);
|
||||
--color-planet-mars: var(--color-planet-mars);
|
||||
--color-planet-mercury: var(--color-planet-mercury);
|
||||
--color-planet-jupiter: var(--color-planet-jupiter);
|
||||
--color-planet-venus: var(--color-planet-venus);
|
||||
--color-planet-saturn: var(--color-planet-saturn);
|
||||
--color-planet-node: var(--color-planet-node);
|
||||
--color-planet-ascendant: var(--color-planet-ascendant);
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
@@ -103,6 +112,19 @@
|
||||
--color-dark-hover: rgba(251, 250, 247, .1);
|
||||
--color-dark-muted: #aaa8a2;
|
||||
--color-dark-border: rgba(251, 250, 247, .16);
|
||||
/* Planet identity colours for the North Indian chart and the chart page's
|
||||
planet table. They answer "which body is this", nothing else — no benefic
|
||||
or malefic reading is encoded here, which is why Rahu and Ketu share one
|
||||
neutral grey. Both nodes and the ascendant are chart points, not bodies. */
|
||||
--color-planet-sun: #c94f4f;
|
||||
--color-planet-moon: #4c7fd1;
|
||||
--color-planet-mars: #d2553c;
|
||||
--color-planet-mercury: #3f9a6b;
|
||||
--color-planet-jupiter: #c9902e;
|
||||
--color-planet-venus: #c9689b;
|
||||
--color-planet-saturn: #5b6bb0;
|
||||
--color-planet-node: #6b7280;
|
||||
--color-planet-ascendant: #b0413e;
|
||||
--shadow-soft: 0 1px 2px rgba(29, 29, 31, .06), 0 8px 20px -18px rgba(29, 29, 31, .2);
|
||||
--shadow-elevated: 0 1px 2px rgba(29, 29, 31, .07), 0 12px 28px -16px rgba(29, 29, 31, .18);
|
||||
/* Display and body share one sans stack. The old value led with two Anthropic
|
||||
@@ -241,6 +263,18 @@
|
||||
/* Hairlines that were dark-on-light have to become light-on-dark. */
|
||||
--ring-hairline: oklch(1 0 0 / .14);
|
||||
--sheen: rgba(255, 255, 255, .16);
|
||||
|
||||
/* Planet identity colours, lifted for a dark ground. Same roles, same shared
|
||||
node grey; the hues are raised rather than inverted. */
|
||||
--color-planet-sun: #e07a7a;
|
||||
--color-planet-moon: #7fa6e6;
|
||||
--color-planet-mars: #e6866f;
|
||||
--color-planet-mercury: #6cc39a;
|
||||
--color-planet-jupiter: #e0b45a;
|
||||
--color-planet-venus: #e08fbb;
|
||||
--color-planet-saturn: #8d9be0;
|
||||
--color-planet-node: #a1a7b3;
|
||||
--color-planet-ascendant: #e07b78;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +347,18 @@
|
||||
/* Hairlines that were dark-on-light have to become light-on-dark. */
|
||||
--ring-hairline: oklch(1 0 0 / .14);
|
||||
--sheen: rgba(255, 255, 255, .16);
|
||||
|
||||
/* Planet identity colours, lifted for a dark ground. Same roles, same shared
|
||||
node grey; the hues are raised rather than inverted. */
|
||||
--color-planet-sun: #e07a7a;
|
||||
--color-planet-moon: #7fa6e6;
|
||||
--color-planet-mars: #e6866f;
|
||||
--color-planet-mercury: #6cc39a;
|
||||
--color-planet-jupiter: #e0b45a;
|
||||
--color-planet-venus: #e08fbb;
|
||||
--color-planet-saturn: #8d9be0;
|
||||
--color-planet-node: #a1a7b3;
|
||||
--color-planet-ascendant: #e07b78;
|
||||
}
|
||||
|
||||
|
||||
@@ -4147,6 +4193,63 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
.personal-report-chart-svg .personal-report-chart-diamond { fill: none; stroke: var(--color-border-strong); stroke-width: 1.25; }
|
||||
.personal-report-chart-svg text { fill: currentColor; }
|
||||
.personal-report-chart-svg .personal-report-chart-muted { fill: var(--color-ink-muted, var(--color-ink-tertiary)); }
|
||||
/* Planets are symbols, not labels. Sizes are viewBox units of the 400-unit
|
||||
square: at the ~318px the chart page gives the stage, 22 units lands near
|
||||
17px, which is why the old blanket `text { font-size: 16px }` override had to
|
||||
become per-class — it would have shrunk the symbols instead of lifting the
|
||||
sign numbers. The stack leads with the vendored 9-glyph Noto subset so the
|
||||
set renders identically on Android and Linux, where no system face covers it.
|
||||
U+FE0E after ♀ and ♂ is what keeps iOS from drawing them as emoji, and it is
|
||||
applied at the string, not here. */
|
||||
.personal-report-chart-svg .personal-report-chart-glyph,
|
||||
.personal-report-chart-svg .personal-report-chart-legend-glyph {
|
||||
font-family: var(--font-planet-glyphs), "Apple Symbols", "Segoe UI Symbol", "Noto Sans Symbols", serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
.personal-report-chart-svg .personal-report-chart-glyph { font-size: 22px; }
|
||||
.personal-report-chart-svg .personal-report-chart-legend-glyph { font-size: 14px; }
|
||||
/* Retrograde is a bar under the symbol in the symbol's own colour; the chart no
|
||||
longer writes the character 逆 anywhere. */
|
||||
.personal-report-chart-svg .personal-report-chart-retrograde { stroke-width: 1.9; }
|
||||
/* House 1 of a North Indian chart is the ascendant by construction. */
|
||||
.personal-report-chart-svg .personal-report-chart-asc {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -.02em;
|
||||
}
|
||||
.personal-report-chart-svg .personal-report-chart-overflow {
|
||||
font-size: 13px;
|
||||
fill: var(--color-ink-tertiary);
|
||||
}
|
||||
/* Only reached by an occupant string that names no known body — the label is
|
||||
drawn as written rather than dropped. */
|
||||
.personal-report-chart-svg .personal-report-chart-occupant-text { font-size: 12px; }
|
||||
.personal-report-chart-svg .personal-report-chart-legend {
|
||||
font-size: 12px;
|
||||
fill: var(--color-ink-tertiary);
|
||||
}
|
||||
/* One colour per body, carried by a modifier class rather than an inline
|
||||
`style` — the personal report's markup contract forbids a style attribute
|
||||
anywhere in the rendered document, and the chart is not an exception to it.
|
||||
`text` takes fill; the retrograde bar takes stroke. Painting both on one
|
||||
selector would outline the symbols. */
|
||||
.personal-report-chart-svg text.is-sun { fill: var(--color-planet-sun); }
|
||||
.personal-report-chart-svg line.is-sun { stroke: var(--color-planet-sun); }
|
||||
.personal-report-chart-svg text.is-moon { fill: var(--color-planet-moon); }
|
||||
.personal-report-chart-svg line.is-moon { stroke: var(--color-planet-moon); }
|
||||
.personal-report-chart-svg text.is-mars { fill: var(--color-planet-mars); }
|
||||
.personal-report-chart-svg line.is-mars { stroke: var(--color-planet-mars); }
|
||||
.personal-report-chart-svg text.is-mercury { fill: var(--color-planet-mercury); }
|
||||
.personal-report-chart-svg line.is-mercury { stroke: var(--color-planet-mercury); }
|
||||
.personal-report-chart-svg text.is-jupiter { fill: var(--color-planet-jupiter); }
|
||||
.personal-report-chart-svg line.is-jupiter { stroke: var(--color-planet-jupiter); }
|
||||
.personal-report-chart-svg text.is-venus { fill: var(--color-planet-venus); }
|
||||
.personal-report-chart-svg line.is-venus { stroke: var(--color-planet-venus); }
|
||||
.personal-report-chart-svg text.is-saturn { fill: var(--color-planet-saturn); }
|
||||
.personal-report-chart-svg line.is-saturn { stroke: var(--color-planet-saturn); }
|
||||
.personal-report-chart-svg text.is-node { fill: var(--color-planet-node); }
|
||||
.personal-report-chart-svg line.is-node { stroke: var(--color-planet-node); }
|
||||
.personal-report-chart-svg text.is-ascendant { fill: var(--color-planet-ascendant); }
|
||||
.personal-report-chart-figure {
|
||||
min-width: 0;
|
||||
max-width: 360px;
|
||||
@@ -4643,7 +4746,13 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
padding: var(--space-3);
|
||||
}
|
||||
.chart-page-vedic-stage .personal-report-chart-svg { margin-top: 0; }
|
||||
.chart-page-vedic-stage .personal-report-chart-svg text { font-size: 16px; }
|
||||
/* Only the small type is lifted for the chart page's narrow stage. Raising
|
||||
every `text` would also resize the planet symbols, which are already sized
|
||||
for this width. */
|
||||
.chart-page-vedic-stage .personal-report-chart-svg .personal-report-chart-muted { font-size: 16px; }
|
||||
.chart-page-vedic-stage .personal-report-chart-svg .personal-report-chart-asc { font-size: 15px; }
|
||||
.chart-page-vedic-stage .personal-report-chart-svg .personal-report-chart-legend { font-size: 14px; }
|
||||
.chart-page-vedic-stage .personal-report-chart-svg .personal-report-chart-legend-glyph { font-size: 16px; }
|
||||
/* One key/value table replaces the `.chart-page-center-card` overlay (two lines
|
||||
on mobile, six on desktop, sat on the chart's geometric centre) and the
|
||||
`.chart-page-params-below` card that repeated the same six lines for mobile.
|
||||
@@ -4689,7 +4798,9 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
}
|
||||
.chart-page-planet-table {
|
||||
width: 100%;
|
||||
min-width: 26rem;
|
||||
/* Eight columns now (symbol+name, longitude, speed, house, nakshatra, its
|
||||
lord, pada, dignity); 26rem was sized for four and crushed the last three. */
|
||||
min-width: 34rem;
|
||||
border-collapse: collapse;
|
||||
background: var(--color-canvas);
|
||||
font-size: var(--type-body-sm);
|
||||
@@ -4713,6 +4824,28 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
font-size: var(--type-caption);
|
||||
font-weight: 500;
|
||||
}
|
||||
.chart-page-planet-table th,
|
||||
.chart-page-planet-table td { white-space: nowrap; }
|
||||
/* The symbol column repeats the chart's colour so a row and a house read as the
|
||||
same body; the stack matches the chart's for the same coverage reason. */
|
||||
.chart-page-planet-glyph {
|
||||
font-family: var(--font-planet-glyphs), "Apple Symbols", "Segoe UI Symbol", "Noto Sans Symbols", serif;
|
||||
font-size: var(--type-title-sm);
|
||||
font-weight: 600;
|
||||
}
|
||||
.chart-page-planet-abbr { color: var(--color-ink-tertiary); }
|
||||
.chart-page-planet-glyph.is-sun { color: var(--color-planet-sun); }
|
||||
.chart-page-planet-glyph.is-moon { color: var(--color-planet-moon); }
|
||||
.chart-page-planet-glyph.is-mars { color: var(--color-planet-mars); }
|
||||
.chart-page-planet-glyph.is-mercury { color: var(--color-planet-mercury); }
|
||||
.chart-page-planet-glyph.is-jupiter { color: var(--color-planet-jupiter); }
|
||||
.chart-page-planet-glyph.is-venus { color: var(--color-planet-venus); }
|
||||
.chart-page-planet-glyph.is-saturn { color: var(--color-planet-saturn); }
|
||||
.chart-page-planet-glyph.is-node { color: var(--color-planet-node); }
|
||||
.chart-page-planet-glyph.is-ascendant { color: var(--color-planet-ascendant); font-weight: 700; }
|
||||
.chart-page-planet-table td.chart-page-planet-mid { text-align: center; }
|
||||
/* Figures line up column-wise instead of drifting with glyph width. */
|
||||
.chart-page-planet-num { font-variant-numeric: tabular-nums; }
|
||||
.chart-page-boundary {
|
||||
margin: var(--space-4) 0 0;
|
||||
color: var(--color-ink-tertiary);
|
||||
|
||||
@@ -15,6 +15,22 @@ const inter = localFont({
|
||||
weight: "100 900",
|
||||
});
|
||||
|
||||
// Vendored 9-glyph Noto Sans Symbols subset (OFL) — ☉ ☽ ☿ ♀ ♂ ♃ ♄ ☊ ☋, 1.5 KB.
|
||||
// The North Indian chart draws planets as these symbols, so the face has to be
|
||||
// present rather than hoped for: Apple Symbols / Segoe UI Symbol cover the set
|
||||
// on their own platforms, Android and most Linux browsers do not.
|
||||
// `adjustFontFallback: false` on purpose: the synthetic Arial-metric fallback
|
||||
// next/font/local would otherwise inject carries its own ♀ ♂ and would swallow
|
||||
// the rest of the stack for the glyphs it cannot draw.
|
||||
const planetGlyphs = localFont({
|
||||
src: "./fonts/NotoSansSymbols-planets.woff2",
|
||||
display: "swap",
|
||||
variable: "--font-planet-glyphs",
|
||||
weight: "400",
|
||||
style: "normal",
|
||||
adjustFontFallback: false,
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Jyotisha · 印度占星",
|
||||
description: "与 Mastra Agent 对话,基于星盘证据讨论事业、关系与时间窗口。",
|
||||
@@ -32,7 +48,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
|
||||
&& process.env.NEXT_PUBLIC_ENABLE_REACT_DEVTOOLS === "1";
|
||||
|
||||
return (
|
||||
<html lang="zh-CN" className={inter.variable} suppressHydrationWarning>
|
||||
<html lang="zh-CN" className={`${inter.variable} ${planetGlyphs.variable}`} suppressHydrationWarning>
|
||||
<head>
|
||||
{/* Synchronous on purpose: a pinned theme must be on <html> before the
|
||||
first paint, or the page flashes the other theme on every load. */}
|
||||
|
||||
Reference in New Issue
Block a user