@roxyapi/ui 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +6 -0
- package/README.md +327 -14
- package/THEMING.md +24 -7
- package/dist/cdn/components/ashtakavarga-grid.js +349 -0
- package/dist/cdn/components/ashtakavarga-grid.js.map +7 -0
- package/dist/cdn/components/biorhythm-chart.js +15 -22
- package/dist/cdn/components/biorhythm-chart.js.map +3 -3
- package/dist/cdn/components/choghadiya-grid.js +239 -0
- package/dist/cdn/components/choghadiya-grid.js.map +7 -0
- package/dist/cdn/components/compatibility-card.js +36 -34
- package/dist/cdn/components/compatibility-card.js.map +4 -4
- package/dist/cdn/components/dasha-timeline.js +35 -39
- package/dist/cdn/components/dasha-timeline.js.map +4 -4
- package/dist/cdn/components/data.js +9 -9
- package/dist/cdn/components/data.js.map +4 -4
- package/dist/cdn/components/divisional-chart.js +279 -0
- package/dist/cdn/components/divisional-chart.js.map +7 -0
- package/dist/cdn/components/dosha-card.js +49 -49
- package/dist/cdn/components/dosha-card.js.map +3 -3
- package/dist/cdn/components/endpoint-form.js +47 -28
- package/dist/cdn/components/endpoint-form.js.map +4 -4
- package/dist/cdn/components/guna-milan.js +66 -24
- package/dist/cdn/components/guna-milan.js.map +4 -4
- package/dist/cdn/components/hexagram.js +26 -26
- package/dist/cdn/components/hexagram.js.map +3 -3
- package/dist/cdn/components/horoscope-card.js +47 -40
- package/dist/cdn/components/horoscope-card.js.map +4 -4
- package/dist/cdn/components/kp-planets-table.js +10 -10
- package/dist/cdn/components/kp-planets-table.js.map +4 -4
- package/dist/cdn/components/location-search.js +6 -6
- package/dist/cdn/components/location-search.js.map +3 -3
- package/dist/cdn/components/moon-phase.js +18 -18
- package/dist/cdn/components/moon-phase.js.map +4 -4
- package/dist/cdn/components/natal-chart.js +240 -24
- package/dist/cdn/components/natal-chart.js.map +4 -4
- package/dist/cdn/components/numerology-card.js +40 -31
- package/dist/cdn/components/numerology-card.js.map +4 -4
- package/dist/cdn/components/panchang-table.js +30 -30
- package/dist/cdn/components/panchang-table.js.map +4 -4
- package/dist/cdn/components/shadbala-table.js +312 -0
- package/dist/cdn/components/shadbala-table.js.map +7 -0
- package/dist/cdn/components/synastry-chart.js +129 -39
- package/dist/cdn/components/synastry-chart.js.map +4 -4
- package/dist/cdn/components/tarot-card.js +49 -20
- package/dist/cdn/components/tarot-card.js.map +3 -3
- package/dist/cdn/components/tarot-spread.js +43 -27
- package/dist/cdn/components/tarot-spread.js.map +3 -3
- package/dist/cdn/components/transits-table.js +391 -0
- package/dist/cdn/components/transits-table.js.map +7 -0
- package/dist/cdn/components/vedic-kundli.js +63 -27
- package/dist/cdn/components/vedic-kundli.js.map +4 -4
- package/dist/cdn/components/yoga-list.js +334 -0
- package/dist/cdn/components/yoga-list.js.map +7 -0
- package/dist/cdn/roxy-ui.js +2104 -544
- package/dist/cdn/roxy-ui.js.map +4 -4
- package/dist/components/ashtakavarga-grid.d.ts +26 -0
- package/dist/components/ashtakavarga-grid.d.ts.map +1 -0
- package/dist/components/ashtakavarga-grid.js +457 -0
- package/dist/components/ashtakavarga-grid.js.map +7 -0
- package/dist/components/biorhythm-chart.d.ts +2 -46
- package/dist/components/biorhythm-chart.d.ts.map +1 -1
- package/dist/components/biorhythm-chart.js +24 -23
- package/dist/components/biorhythm-chart.js.map +2 -2
- package/dist/components/choghadiya-grid.d.ts +19 -0
- package/dist/components/choghadiya-grid.d.ts.map +1 -0
- package/dist/components/choghadiya-grid.js +304 -0
- package/dist/components/choghadiya-grid.js.map +7 -0
- package/dist/components/compatibility-card.d.ts +2 -27
- package/dist/components/compatibility-card.d.ts.map +1 -1
- package/dist/components/compatibility-card.js +50 -29
- package/dist/components/compatibility-card.js.map +3 -3
- package/dist/components/dasha-timeline.d.ts +2 -31
- package/dist/components/dasha-timeline.d.ts.map +1 -1
- package/dist/components/dasha-timeline.js +32 -30
- package/dist/components/dasha-timeline.js.map +3 -3
- package/dist/components/data.d.ts +11 -7
- package/dist/components/data.d.ts.map +1 -1
- package/dist/components/data.js +16 -6
- package/dist/components/data.js.map +3 -3
- package/dist/components/divisional-chart.d.ts +20 -0
- package/dist/components/divisional-chart.d.ts.map +1 -0
- package/dist/components/divisional-chart.js +471 -0
- package/dist/components/divisional-chart.js.map +7 -0
- package/dist/components/dosha-card.d.ts +2 -16
- package/dist/components/dosha-card.d.ts.map +1 -1
- package/dist/components/dosha-card.js +45 -43
- package/dist/components/dosha-card.js.map +2 -2
- package/dist/components/endpoint-form.d.ts +2 -0
- package/dist/components/endpoint-form.d.ts.map +1 -1
- package/dist/components/endpoint-form.js +71 -11
- package/dist/components/endpoint-form.js.map +3 -3
- package/dist/components/guna-milan.d.ts +2 -20
- package/dist/components/guna-milan.d.ts.map +1 -1
- package/dist/components/guna-milan.js +79 -20
- package/dist/components/guna-milan.js.map +4 -4
- package/dist/components/hexagram.d.ts +3 -27
- package/dist/components/hexagram.d.ts.map +1 -1
- package/dist/components/hexagram.js +48 -15
- package/dist/components/hexagram.js.map +2 -2
- package/dist/components/horoscope-card.d.ts +2 -20
- package/dist/components/horoscope-card.d.ts.map +1 -1
- package/dist/components/horoscope-card.js +54 -18
- package/dist/components/horoscope-card.js.map +3 -3
- package/dist/components/kp-planets-table.d.ts +2 -21
- package/dist/components/kp-planets-table.d.ts.map +1 -1
- package/dist/components/kp-planets-table.js +10 -4
- package/dist/components/kp-planets-table.js.map +3 -3
- package/dist/components/location-search.d.ts +5 -14
- package/dist/components/location-search.d.ts.map +1 -1
- package/dist/components/location-search.js +45 -5
- package/dist/components/location-search.js.map +2 -2
- package/dist/components/moon-phase.d.ts +4 -21
- package/dist/components/moon-phase.d.ts.map +1 -1
- package/dist/components/moon-phase.js +34 -4
- package/dist/components/moon-phase.js.map +3 -3
- package/dist/components/natal-chart.d.ts +9 -43
- package/dist/components/natal-chart.d.ts.map +1 -1
- package/dist/components/natal-chart.js +346 -79
- package/dist/components/natal-chart.js.map +3 -3
- package/dist/components/numerology-card.d.ts +5 -37
- package/dist/components/numerology-card.d.ts.map +1 -1
- package/dist/components/numerology-card.js +58 -30
- package/dist/components/numerology-card.js.map +3 -3
- package/dist/components/panchang-table.d.ts +3 -62
- package/dist/components/panchang-table.d.ts.map +1 -1
- package/dist/components/panchang-table.js +62 -32
- package/dist/components/panchang-table.js.map +3 -3
- package/dist/components/shadbala-table.d.ts +18 -0
- package/dist/components/shadbala-table.d.ts.map +1 -0
- package/dist/components/shadbala-table.js +400 -0
- package/dist/components/shadbala-table.js.map +7 -0
- package/dist/components/synastry-chart.d.ts +9 -28
- package/dist/components/synastry-chart.d.ts.map +1 -1
- package/dist/components/synastry-chart.js +201 -56
- package/dist/components/synastry-chart.js.map +3 -3
- package/dist/components/tarot-card.d.ts +5 -29
- package/dist/components/tarot-card.d.ts.map +1 -1
- package/dist/components/tarot-card.js +59 -20
- package/dist/components/tarot-card.js.map +2 -2
- package/dist/components/tarot-spread.d.ts +2 -24
- package/dist/components/tarot-spread.d.ts.map +1 -1
- package/dist/components/tarot-spread.js +39 -13
- package/dist/components/tarot-spread.js.map +2 -2
- package/dist/components/transits-table.d.ts +21 -0
- package/dist/components/transits-table.d.ts.map +1 -0
- package/dist/components/transits-table.js +515 -0
- package/dist/components/transits-table.js.map +7 -0
- package/dist/components/vedic-kundli.d.ts +5 -28
- package/dist/components/vedic-kundli.d.ts.map +1 -1
- package/dist/components/vedic-kundli.js +147 -83
- package/dist/components/vedic-kundli.js.map +3 -3
- package/dist/components/yoga-list.d.ts +29 -0
- package/dist/components/yoga-list.d.ts.map +1 -0
- package/dist/components/yoga-list.js +389 -0
- package/dist/components/yoga-list.js.map +7 -0
- package/dist/index.cjs +3693 -1180
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3709 -1196
- package/dist/index.js.map +4 -4
- package/dist/manifest.d.ts +43 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.json +7 -2
- package/dist/styles/tokens.css +73 -1
- package/dist/tokens/index.d.ts +6 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.gen.d.ts +27811 -0
- package/dist/types/types.gen.d.ts.map +1 -0
- package/dist/utils/debounce.d.ts +9 -1
- package/dist/utils/debounce.d.ts.map +1 -1
- package/dist/utils/format.d.ts +29 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/kundli-render.d.ts +63 -0
- package/dist/utils/kundli-render.d.ts.map +1 -0
- package/dist/utils/string.d.ts +14 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +7 -1
- package/src/components/ashtakavarga-grid.ts +354 -0
- package/src/components/biorhythm-chart.ts +39 -84
- package/src/components/choghadiya-grid.ts +185 -0
- package/src/components/compatibility-card.ts +85 -52
- package/src/components/dasha-timeline.ts +55 -73
- package/src/components/data.ts +28 -16
- package/src/components/divisional-chart.ts +214 -0
- package/src/components/dosha-card.ts +72 -68
- package/src/components/endpoint-form.ts +80 -18
- package/src/components/guna-milan.ts +87 -47
- package/src/components/hexagram.ts +53 -43
- package/src/components/horoscope-card.ts +59 -43
- package/src/components/kp-planets-table.ts +8 -27
- package/src/components/location-search.ts +47 -23
- package/src/components/moon-phase.ts +28 -25
- package/src/components/natal-chart.ts +364 -110
- package/src/components/numerology-card.ts +86 -84
- package/src/components/panchang-table.ts +40 -78
- package/src/components/shadbala-table.ts +286 -0
- package/src/components/synastry-chart.ts +213 -97
- package/src/components/tarot-card.ts +76 -62
- package/src/components/tarot-spread.ts +72 -45
- package/src/components/transits-table.ts +350 -0
- package/src/components/vedic-kundli.ts +59 -173
- package/src/components/yoga-list.ts +328 -0
- package/src/index.ts +18 -26
- package/src/manifest.ts +340 -0
- package/src/styles/tokens.css +73 -1
- package/src/tokens/index.ts +14 -0
- package/src/types/types.gen.ts +3 -3
- package/src/utils/debounce.ts +23 -4
- package/src/utils/format.ts +75 -0
- package/src/utils/kundli-render.ts +197 -0
- package/src/utils/string.ts +23 -0
- package/src/version.ts +2 -0
- package/dist/utils/motion.d.ts +0 -13
- package/dist/utils/motion.d.ts.map +0 -1
- package/src/utils/motion.ts +0 -18
|
@@ -1,53 +1,27 @@
|
|
|
1
1
|
import { css, html, LitElement, nothing, svg } from 'lit';
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
-
import { PLANET_GLYPH, SIGN_GLYPH } from '../tokens/index.js';
|
|
3
|
+
import { PLANET_GLYPH, SIGN_GLYPH, SIGNS_ORDER } from '../tokens/index.js';
|
|
4
|
+
import type { NatalChartResponse } from '../types/index.js';
|
|
4
5
|
import { baseStyles } from '../utils/base-styles.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
sign?: string;
|
|
13
|
-
house?: number;
|
|
14
|
-
retrograde?: boolean;
|
|
15
|
-
isRetrograde?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface AspectEntry {
|
|
19
|
-
planet1?: string;
|
|
20
|
-
planet2?: string;
|
|
21
|
-
aspect?: string;
|
|
22
|
-
orb?: number;
|
|
23
|
-
}
|
|
6
|
+
import { polarToCartesian } from '../utils/degree.js';
|
|
7
|
+
import {
|
|
8
|
+
ASPECT_CLASS,
|
|
9
|
+
formatNumber,
|
|
10
|
+
normalizeAspect,
|
|
11
|
+
} from '../utils/format.js';
|
|
12
|
+
import { capitalize } from '../utils/string.js';
|
|
24
13
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
number?: number;
|
|
28
|
-
cusp?: number;
|
|
29
|
-
sign?: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface NatalChartData {
|
|
33
|
-
planets?: PlanetEntry[] | Record<string, PlanetEntry>;
|
|
34
|
-
houses?: HouseEntry[];
|
|
35
|
-
aspects?: AspectEntry[];
|
|
36
|
-
ascendant?: number | { longitude?: number; sign?: string };
|
|
37
|
-
midheaven?: number | { longitude?: number; sign?: string };
|
|
38
|
-
birthDetails?: {
|
|
39
|
-
date?: string;
|
|
40
|
-
time?: string;
|
|
41
|
-
location?: string;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
14
|
+
type PlanetEntry = NatalChartResponse['planets'][number];
|
|
15
|
+
type AspectEntry = NatalChartResponse['aspects'][number];
|
|
44
16
|
|
|
45
|
-
const SIZE =
|
|
17
|
+
const SIZE = 420;
|
|
46
18
|
const CENTER = SIZE / 2;
|
|
47
|
-
const OUTER_R =
|
|
48
|
-
const SIGN_R =
|
|
49
|
-
const HOUSE_R =
|
|
50
|
-
const PLANET_R =
|
|
19
|
+
const OUTER_R = 164;
|
|
20
|
+
const SIGN_R = 146;
|
|
21
|
+
const HOUSE_R = 120;
|
|
22
|
+
const PLANET_R = 96;
|
|
23
|
+
const ANGLE_TICK_R = 178;
|
|
24
|
+
const ANGLE_LABEL_R = 196;
|
|
51
25
|
|
|
52
26
|
/**
|
|
53
27
|
* Western natal chart wheel. Renders the 12 zodiac signs, 12 houses, planet
|
|
@@ -109,9 +83,36 @@ export class RoxyNatalChart extends LitElement {
|
|
|
109
83
|
}
|
|
110
84
|
|
|
111
85
|
.aspect {
|
|
112
|
-
stroke:
|
|
113
|
-
stroke-width: 0.6;
|
|
86
|
+
stroke-width: 0.8;
|
|
114
87
|
fill: none;
|
|
88
|
+
opacity: 0.55;
|
|
89
|
+
}
|
|
90
|
+
.aspect-trine,
|
|
91
|
+
.aspect-sextile {
|
|
92
|
+
stroke: var(--roxy-success, #16a34a);
|
|
93
|
+
}
|
|
94
|
+
.aspect-square,
|
|
95
|
+
.aspect-opposition {
|
|
96
|
+
stroke: var(--roxy-danger, #dc2626);
|
|
97
|
+
}
|
|
98
|
+
.aspect-conjunction {
|
|
99
|
+
stroke: var(--roxy-accent-fg, #b45309);
|
|
100
|
+
}
|
|
101
|
+
.aspect-other {
|
|
102
|
+
stroke: var(--roxy-muted, #71717a);
|
|
103
|
+
opacity: 0.4;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.angle-marker {
|
|
107
|
+
fill: var(--roxy-accent-fg, #b45309);
|
|
108
|
+
font-size: 10px;
|
|
109
|
+
font-weight: 700;
|
|
110
|
+
font-family: var(--roxy-font-sans);
|
|
111
|
+
letter-spacing: 0.04em;
|
|
112
|
+
}
|
|
113
|
+
.angle-tick {
|
|
114
|
+
stroke: var(--roxy-accent-fg, #b45309);
|
|
115
|
+
stroke-width: 1.5;
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
.legend {
|
|
@@ -121,20 +122,168 @@ export class RoxyNatalChart extends LitElement {
|
|
|
121
122
|
flex-wrap: wrap;
|
|
122
123
|
gap: var(--roxy-space-md, 1rem);
|
|
123
124
|
}
|
|
125
|
+
.legend-swatch {
|
|
126
|
+
display: inline-block;
|
|
127
|
+
width: 8px;
|
|
128
|
+
height: 8px;
|
|
129
|
+
border-radius: 50%;
|
|
130
|
+
margin-right: 4px;
|
|
131
|
+
vertical-align: middle;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.details {
|
|
135
|
+
margin-top: var(--roxy-space-md, 1rem);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.pill-row {
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-wrap: wrap;
|
|
141
|
+
gap: var(--roxy-space-xs, 0.25rem);
|
|
142
|
+
margin-bottom: var(--roxy-space-xs, 0.25rem);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.pill {
|
|
146
|
+
padding: 2px 8px;
|
|
147
|
+
border-radius: var(--roxy-radius-sm, 4px);
|
|
148
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
149
|
+
background: color-mix(in srgb, var(--roxy-fg, #0f172a) 8%, transparent);
|
|
150
|
+
color: var(--roxy-fg, #0f172a);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.pill--success {
|
|
154
|
+
background: color-mix(in srgb, var(--roxy-success, #16a34a) 15%, transparent);
|
|
155
|
+
color: var(--roxy-success, #16a34a);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.pill--danger {
|
|
159
|
+
background: color-mix(in srgb, var(--roxy-danger, #dc2626) 15%, transparent);
|
|
160
|
+
color: var(--roxy-danger, #dc2626);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.pill--muted {
|
|
164
|
+
background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent);
|
|
165
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.summary {
|
|
169
|
+
color: var(--roxy-fg, #0f172a);
|
|
170
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
171
|
+
margin: var(--roxy-space-md, 1rem) 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.dist-grid {
|
|
175
|
+
display: grid;
|
|
176
|
+
grid-template-columns: 1fr 1fr;
|
|
177
|
+
gap: var(--roxy-space-md, 1rem);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@container (max-width: 639px) {
|
|
181
|
+
.dist-grid {
|
|
182
|
+
grid-template-columns: 1fr;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.dist-section h3 {
|
|
187
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
188
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
189
|
+
color: var(--roxy-muted, #71717a);
|
|
190
|
+
margin: 0 0 var(--roxy-space-xs, 0.25rem);
|
|
191
|
+
text-transform: uppercase;
|
|
192
|
+
letter-spacing: 0.05em;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.dist-row {
|
|
196
|
+
display: grid;
|
|
197
|
+
grid-template-columns: 4rem 1fr 1.5rem;
|
|
198
|
+
align-items: center;
|
|
199
|
+
gap: var(--roxy-space-xs, 0.25rem);
|
|
200
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
201
|
+
color: var(--roxy-fg, #0f172a);
|
|
202
|
+
margin-bottom: 4px;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.dist-bar {
|
|
206
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 20%, transparent);
|
|
207
|
+
height: 6px;
|
|
208
|
+
border-radius: 3px;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.dist-bar > span {
|
|
212
|
+
display: block;
|
|
213
|
+
height: 100%;
|
|
214
|
+
background: var(--roxy-accent, #f59e0b);
|
|
215
|
+
border-radius: 3px;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.interpretations {
|
|
219
|
+
margin-top: var(--roxy-space-md, 1rem);
|
|
220
|
+
}
|
|
221
|
+
.interpretations h3 {
|
|
222
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
223
|
+
font-weight: 600;
|
|
224
|
+
color: var(--roxy-muted, #71717a);
|
|
225
|
+
text-transform: uppercase;
|
|
226
|
+
letter-spacing: 0.06em;
|
|
227
|
+
margin: 0 0 var(--roxy-space-sm, 0.5rem);
|
|
228
|
+
}
|
|
229
|
+
.interp-card {
|
|
230
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
231
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
232
|
+
padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
|
|
233
|
+
margin-bottom: var(--roxy-space-xs, 0.25rem);
|
|
234
|
+
}
|
|
235
|
+
.interp-card summary {
|
|
236
|
+
cursor: pointer;
|
|
237
|
+
font-weight: 500;
|
|
238
|
+
color: var(--roxy-fg, #0f172a);
|
|
239
|
+
}
|
|
240
|
+
.interp-card summary small {
|
|
241
|
+
color: var(--roxy-muted, #71717a);
|
|
242
|
+
margin-left: 0.5em;
|
|
243
|
+
font-weight: 400;
|
|
244
|
+
}
|
|
245
|
+
.interp-body {
|
|
246
|
+
margin-top: var(--roxy-space-xs, 0.25rem);
|
|
247
|
+
color: var(--roxy-fg, #0f172a);
|
|
248
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
249
|
+
}
|
|
250
|
+
.interp-keywords {
|
|
251
|
+
display: flex;
|
|
252
|
+
flex-wrap: wrap;
|
|
253
|
+
gap: 0.25rem;
|
|
254
|
+
margin-top: 0.5rem;
|
|
255
|
+
}
|
|
256
|
+
.interp-keywords .kw {
|
|
257
|
+
padding: 1px 8px;
|
|
258
|
+
border-radius: 9999px;
|
|
259
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 14%, transparent);
|
|
260
|
+
color: var(--roxy-accent-fg, #b45309);
|
|
261
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
262
|
+
}
|
|
124
263
|
`,
|
|
125
264
|
];
|
|
126
265
|
|
|
127
266
|
@property({ attribute: false })
|
|
128
|
-
data:
|
|
267
|
+
data: NatalChartResponse | null = null;
|
|
129
268
|
|
|
130
269
|
@property({ type: String, attribute: 'house-system', reflect: true })
|
|
131
270
|
houseSystem: 'placidus' | 'whole-sign' | 'equal' | 'koch' = 'placidus';
|
|
132
271
|
|
|
133
272
|
private getPlanets(): PlanetEntry[] {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
273
|
+
return this.data?.planets ?? [];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private getAscendant(): number {
|
|
277
|
+
return this.data?.ascendant?.longitude ?? 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private getMidheaven(): number | null {
|
|
281
|
+
const m = this.data?.midheaven?.longitude;
|
|
282
|
+
return typeof m === 'number' ? m : null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private toAngle(lon: number): number {
|
|
286
|
+
return 180 + this.getAscendant() - lon;
|
|
138
287
|
}
|
|
139
288
|
|
|
140
289
|
render() {
|
|
@@ -149,11 +298,7 @@ export class RoxyNatalChart extends LitElement {
|
|
|
149
298
|
${
|
|
150
299
|
this.data.birthDetails
|
|
151
300
|
? html`<div class="meta">
|
|
152
|
-
${[
|
|
153
|
-
this.data.birthDetails.date,
|
|
154
|
-
this.data.birthDetails.time,
|
|
155
|
-
this.data.birthDetails.location,
|
|
156
|
-
]
|
|
301
|
+
${[this.data.birthDetails.date, this.data.birthDetails.time]
|
|
157
302
|
.filter(Boolean)
|
|
158
303
|
.join(' · ')}
|
|
159
304
|
</div>`
|
|
@@ -193,18 +338,43 @@ export class RoxyNatalChart extends LitElement {
|
|
|
193
338
|
/>
|
|
194
339
|
${this.renderSpokes()} ${this.renderSigns()} ${this.renderHouseNumbers()}
|
|
195
340
|
${this.renderAspects(planets, aspects)} ${this.renderPlanets(planets)}
|
|
341
|
+
${this.renderAngles()}
|
|
196
342
|
</svg>
|
|
197
343
|
<div class="legend">
|
|
198
344
|
<span>${planets.length} planets</span>
|
|
199
345
|
<span>${aspects.length} aspects</span>
|
|
200
|
-
<span
|
|
346
|
+
<span><span class="legend-swatch" style="background: var(--roxy-success)"></span>harmonious</span>
|
|
347
|
+
<span><span class="legend-swatch" style="background: var(--roxy-danger)"></span>challenging</span>
|
|
201
348
|
</div>
|
|
349
|
+
${this.renderDetails()}
|
|
350
|
+
${this.renderInterpretations()}
|
|
202
351
|
</div>`;
|
|
203
352
|
}
|
|
204
353
|
|
|
354
|
+
private renderAngles() {
|
|
355
|
+
const asc = this.getAscendant();
|
|
356
|
+
const mc = this.getMidheaven();
|
|
357
|
+
const items = [this.renderAngleMark(asc, 'ASC')];
|
|
358
|
+
if (mc !== null) items.push(this.renderAngleMark(mc, 'MC'));
|
|
359
|
+
return items;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private renderAngleMark(longitude: number, label: string) {
|
|
363
|
+
const angle = this.toAngle(longitude);
|
|
364
|
+
const tickInner = polarToCartesian(CENTER, CENTER, OUTER_R, angle);
|
|
365
|
+
const tickOuter = polarToCartesian(CENTER, CENTER, ANGLE_TICK_R, angle);
|
|
366
|
+
const labelPos = polarToCartesian(CENTER, CENTER, ANGLE_LABEL_R, angle);
|
|
367
|
+
return svg`
|
|
368
|
+
<g>
|
|
369
|
+
<line class="angle-tick" x1=${tickInner.x} y1=${tickInner.y} x2=${tickOuter.x} y2=${tickOuter.y} />
|
|
370
|
+
<text class="angle-marker" x=${labelPos.x} y=${labelPos.y} text-anchor="middle" dominant-baseline="central">${label}</text>
|
|
371
|
+
</g>
|
|
372
|
+
`;
|
|
373
|
+
}
|
|
374
|
+
|
|
205
375
|
private renderSpokes() {
|
|
206
376
|
return Array.from({ length: 12 }, (_, i) => {
|
|
207
|
-
const angle = i * 30
|
|
377
|
+
const angle = this.toAngle(i * 30);
|
|
208
378
|
const start = polarToCartesian(CENTER, CENTER, HOUSE_R, angle);
|
|
209
379
|
const end = polarToCartesian(CENTER, CENTER, OUTER_R, angle);
|
|
210
380
|
return svg`<line class="wheel-line" x1=${start.x} y1=${start.y} x2=${end.x} y2=${end.y} stroke-width="0.8" />`;
|
|
@@ -212,87 +382,171 @@ export class RoxyNatalChart extends LitElement {
|
|
|
212
382
|
}
|
|
213
383
|
|
|
214
384
|
private renderSigns() {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
'Taurus',
|
|
218
|
-
'Gemini',
|
|
219
|
-
'Cancer',
|
|
220
|
-
'Leo',
|
|
221
|
-
'Virgo',
|
|
222
|
-
'Libra',
|
|
223
|
-
'Scorpio',
|
|
224
|
-
'Sagittarius',
|
|
225
|
-
'Capricorn',
|
|
226
|
-
'Aquarius',
|
|
227
|
-
'Pisces',
|
|
228
|
-
];
|
|
229
|
-
return order.map((sign, i) => {
|
|
230
|
-
const angle = i * 30 + 15 - 90;
|
|
385
|
+
return SIGNS_ORDER.map((sign, i) => {
|
|
386
|
+
const angle = this.toAngle(i * 30 + 15);
|
|
231
387
|
const pos = polarToCartesian(CENTER, CENTER, SIGN_R, angle);
|
|
232
388
|
return svg`<text class="sign-glyph" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${SIGN_GLYPH[sign]}</text>`;
|
|
233
389
|
});
|
|
234
390
|
}
|
|
235
391
|
|
|
236
392
|
private renderHouseNumbers() {
|
|
393
|
+
const ascSignIndex = Math.floor(this.getAscendant() / 30);
|
|
237
394
|
return Array.from({ length: 12 }, (_, i) => {
|
|
238
|
-
const angle = i * 30 + 15
|
|
395
|
+
const angle = this.toAngle(i * 30 + 15);
|
|
239
396
|
const pos = polarToCartesian(CENTER, CENTER, HOUSE_R - 12, angle);
|
|
240
|
-
|
|
397
|
+
const houseNum = ((i - ascSignIndex + 12) % 12) + 1;
|
|
398
|
+
return svg`<text class="house-num" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${houseNum}</text>`;
|
|
241
399
|
});
|
|
242
400
|
}
|
|
243
401
|
|
|
244
402
|
private renderPlanets(planets: PlanetEntry[]) {
|
|
245
403
|
return planets.map((p) => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
? p.longitude
|
|
249
|
-
: typeof p.degree === 'number'
|
|
250
|
-
? p.degree
|
|
251
|
-
: NaN;
|
|
252
|
-
if (!Number.isFinite(lon)) return nothing;
|
|
253
|
-
const angle = lon - 90;
|
|
404
|
+
if (!Number.isFinite(p.longitude)) return nothing;
|
|
405
|
+
const angle = this.toAngle(p.longitude);
|
|
254
406
|
const pos = polarToCartesian(CENTER, CENTER, PLANET_R, angle);
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
return svg`<text class="planet-glyph" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central"><title>${name}${retro}</title>${
|
|
407
|
+
const glyph = PLANET_GLYPH[capitalize(p.name)] ?? p.name.slice(0, 2);
|
|
408
|
+
const retro = p.isRetrograde ? ' R' : '';
|
|
409
|
+
const display = retro ? `${glyph}ᴿ` : glyph;
|
|
410
|
+
return svg`<text class="planet-glyph" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central"><title>${p.name}${retro}</title>${display}</text>`;
|
|
259
411
|
});
|
|
260
412
|
}
|
|
261
413
|
|
|
414
|
+
private renderDetails() {
|
|
415
|
+
const summary = this.data?.summary;
|
|
416
|
+
const ai = this.data?.aspectsInterpretation;
|
|
417
|
+
if (!summary && !ai) return nothing;
|
|
418
|
+
|
|
419
|
+
const retrogrades = summary?.retrogradePlanets ?? [];
|
|
420
|
+
const elementDist = summary?.elementDistribution ?? {};
|
|
421
|
+
const modalityDist = summary?.modalityDistribution ?? {};
|
|
422
|
+
const elementMax = Math.max(1, ...Object.values(elementDist));
|
|
423
|
+
const modalityMax = Math.max(1, ...Object.values(modalityDist));
|
|
424
|
+
|
|
425
|
+
return html`<div class="details">
|
|
426
|
+
${
|
|
427
|
+
summary?.dominantElement || summary?.dominantModality
|
|
428
|
+
? html`<div class="pill-row">
|
|
429
|
+
${summary.dominantElement ? html`<span class="pill">Dominant element: ${summary.dominantElement}</span>` : nothing}
|
|
430
|
+
${summary.dominantModality ? html`<span class="pill">Dominant modality: ${summary.dominantModality}</span>` : nothing}
|
|
431
|
+
</div>`
|
|
432
|
+
: nothing
|
|
433
|
+
}
|
|
434
|
+
${
|
|
435
|
+
ai
|
|
436
|
+
? html`<div class="pill-row">
|
|
437
|
+
<span class="pill pill--success">Harmonious ${ai.harmonious}</span>
|
|
438
|
+
<span class="pill pill--danger">Challenging ${ai.challenging}</span>
|
|
439
|
+
<span class="pill pill--muted">Neutral ${ai.neutral}</span>
|
|
440
|
+
</div>`
|
|
441
|
+
: nothing
|
|
442
|
+
}
|
|
443
|
+
${
|
|
444
|
+
retrogrades.length > 0
|
|
445
|
+
? html`<div class="pill-row">
|
|
446
|
+
${retrogrades.map((p) => {
|
|
447
|
+
const glyph = PLANET_GLYPH[p] ?? p.slice(0, 2);
|
|
448
|
+
return html`<span class="pill pill--muted">${glyph} ${p} R</span>`;
|
|
449
|
+
})}
|
|
450
|
+
</div>`
|
|
451
|
+
: nothing
|
|
452
|
+
}
|
|
453
|
+
${ai?.summary ? html`<p class="summary">${ai.summary}</p>` : nothing}
|
|
454
|
+
${
|
|
455
|
+
Object.keys(elementDist).length > 0 ||
|
|
456
|
+
Object.keys(modalityDist).length > 0
|
|
457
|
+
? html`<div class="dist-grid">
|
|
458
|
+
${
|
|
459
|
+
Object.keys(elementDist).length > 0
|
|
460
|
+
? html`<div class="dist-section">
|
|
461
|
+
<h3>Elements</h3>
|
|
462
|
+
${Object.entries(elementDist).map(
|
|
463
|
+
([label, count]) => html`<div class="dist-row">
|
|
464
|
+
<span>${label}</span>
|
|
465
|
+
<div class="dist-bar"><span style="width: ${Math.round((count / elementMax) * 100)}%"></span></div>
|
|
466
|
+
<span>${count}</span>
|
|
467
|
+
</div>`,
|
|
468
|
+
)}
|
|
469
|
+
</div>`
|
|
470
|
+
: nothing
|
|
471
|
+
}
|
|
472
|
+
${
|
|
473
|
+
Object.keys(modalityDist).length > 0
|
|
474
|
+
? html`<div class="dist-section">
|
|
475
|
+
<h3>Modalities</h3>
|
|
476
|
+
${Object.entries(modalityDist).map(
|
|
477
|
+
([label, count]) => html`<div class="dist-row">
|
|
478
|
+
<span>${label}</span>
|
|
479
|
+
<div class="dist-bar"><span style="width: ${Math.round((count / modalityMax) * 100)}%"></span></div>
|
|
480
|
+
<span>${count}</span>
|
|
481
|
+
</div>`,
|
|
482
|
+
)}
|
|
483
|
+
</div>`
|
|
484
|
+
: nothing
|
|
485
|
+
}
|
|
486
|
+
</div>`
|
|
487
|
+
: nothing
|
|
488
|
+
}
|
|
489
|
+
</div>`;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
private renderInterpretations() {
|
|
493
|
+
const planets = this.getPlanets().filter((p) => p.interpretation);
|
|
494
|
+
if (planets.length === 0) return nothing;
|
|
495
|
+
return html`<section class="interpretations">
|
|
496
|
+
<h3>Planet readings</h3>
|
|
497
|
+
${planets.map((p) => {
|
|
498
|
+
const interp = p.interpretation!;
|
|
499
|
+
const glyph = PLANET_GLYPH[capitalize(p.name)] ?? '';
|
|
500
|
+
const deg = formatNumber(p.degree ?? 0, 1);
|
|
501
|
+
return html`<details class="interp-card">
|
|
502
|
+
<summary>${glyph} ${p.name} <small>${p.sign ?? ''} ${deg}</small></summary>
|
|
503
|
+
<div class="interp-body">
|
|
504
|
+
${interp.summary ? html`<p class="interp-summary">${interp.summary}</p>` : nothing}
|
|
505
|
+
${interp.detailed ? html`<p class="interp-detail">${interp.detailed}</p>` : nothing}
|
|
506
|
+
${
|
|
507
|
+
interp.keywords?.length
|
|
508
|
+
? html`<div class="interp-keywords">${interp.keywords.map((k) => html`<span class="kw">${k}</span>`)}</div>`
|
|
509
|
+
: nothing
|
|
510
|
+
}
|
|
511
|
+
</div>
|
|
512
|
+
</details>`;
|
|
513
|
+
})}
|
|
514
|
+
</section>`;
|
|
515
|
+
}
|
|
516
|
+
|
|
262
517
|
private renderAspects(planets: PlanetEntry[], aspects: AspectEntry[]) {
|
|
263
518
|
const planetMap = new Map<string, number>();
|
|
264
519
|
for (const p of planets) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
: typeof p.degree === 'number'
|
|
269
|
-
? p.degree
|
|
270
|
-
: null;
|
|
271
|
-
if (lon === null) continue;
|
|
272
|
-
const name = capitalize(p.name ?? p.planet ?? '');
|
|
273
|
-
if (name) planetMap.set(name, lon);
|
|
520
|
+
if (typeof p.longitude !== 'number') continue;
|
|
521
|
+
const name = capitalize(p.name);
|
|
522
|
+
if (name) planetMap.set(name, p.longitude);
|
|
274
523
|
}
|
|
275
524
|
return aspects.map((a) => {
|
|
276
|
-
const l1 = planetMap.get(capitalize(a.planet1
|
|
277
|
-
const l2 = planetMap.get(capitalize(a.planet2
|
|
525
|
+
const l1 = planetMap.get(capitalize(a.planet1));
|
|
526
|
+
const l2 = planetMap.get(capitalize(a.planet2));
|
|
278
527
|
if (l1 === undefined || l2 === undefined) return nothing;
|
|
279
|
-
const p1 = polarToCartesian(
|
|
280
|
-
|
|
281
|
-
|
|
528
|
+
const p1 = polarToCartesian(
|
|
529
|
+
CENTER,
|
|
530
|
+
CENTER,
|
|
531
|
+
PLANET_R - 18,
|
|
532
|
+
this.toAngle(l1),
|
|
533
|
+
);
|
|
534
|
+
const p2 = polarToCartesian(
|
|
535
|
+
CENTER,
|
|
536
|
+
CENTER,
|
|
537
|
+
PLANET_R - 18,
|
|
538
|
+
this.toAngle(l2),
|
|
539
|
+
);
|
|
540
|
+
const aspectName = normalizeAspect(a);
|
|
541
|
+
const aspectClass = ASPECT_CLASS[aspectName] ?? 'aspect-other';
|
|
542
|
+
const orbLabel = formatNumber(a.orb, 1);
|
|
543
|
+
return svg`<line class=${`aspect ${aspectClass}`} x1=${p1.x} y1=${p1.y} x2=${p2.x} y2=${p2.y}><title>${a.planet1} ${aspectName || ''} ${a.planet2}${orbLabel ? ` (orb ${orbLabel}°)` : ''}</title></line>`;
|
|
282
544
|
});
|
|
283
545
|
}
|
|
284
546
|
}
|
|
285
547
|
|
|
286
|
-
function capitalize(s: string): string {
|
|
287
|
-
if (!s) return '';
|
|
288
|
-
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
548
|
declare global {
|
|
292
549
|
interface HTMLElementTagNameMap {
|
|
293
550
|
'roxy-natal-chart': RoxyNatalChart;
|
|
294
551
|
}
|
|
295
552
|
}
|
|
296
|
-
|
|
297
|
-
// Export for external use
|
|
298
|
-
export { longitudeToSignPosition };
|