@roxyapi/ui 0.2.3 → 0.3.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.
Files changed (119) hide show
  1. package/AGENTS.md +15 -10
  2. package/README.md +15 -10
  3. package/dist/cdn/components/compatibility-card.js.map +1 -1
  4. package/dist/cdn/components/dasha-timeline.js +8 -8
  5. package/dist/cdn/components/dasha-timeline.js.map +2 -2
  6. package/dist/cdn/components/divisional-chart.js +35 -23
  7. package/dist/cdn/components/divisional-chart.js.map +4 -4
  8. package/dist/cdn/components/guna-milan.js.map +1 -1
  9. package/dist/cdn/components/kp-chart.js +306 -0
  10. package/dist/cdn/components/kp-chart.js.map +7 -0
  11. package/dist/cdn/components/kp-planets-table.js.map +1 -1
  12. package/dist/cdn/components/kp-ruling-planets.js +269 -0
  13. package/dist/cdn/components/kp-ruling-planets.js.map +7 -0
  14. package/dist/cdn/components/location-search.js +7 -5
  15. package/dist/cdn/components/location-search.js.map +3 -3
  16. package/dist/cdn/components/moon-phase.js.map +1 -1
  17. package/dist/cdn/components/nakshatra-card.js +229 -0
  18. package/dist/cdn/components/nakshatra-card.js.map +7 -0
  19. package/dist/cdn/components/natal-chart.js +228 -115
  20. package/dist/cdn/components/natal-chart.js.map +4 -4
  21. package/dist/cdn/components/numerology-card.js +3 -3
  22. package/dist/cdn/components/numerology-card.js.map +2 -2
  23. package/dist/cdn/components/panchang-table.js.map +1 -1
  24. package/dist/cdn/components/shadbala-table.js.map +1 -1
  25. package/dist/cdn/components/synastry-chart.js +3 -3
  26. package/dist/cdn/components/synastry-chart.js.map +2 -2
  27. package/dist/cdn/components/transits-table.js.map +1 -1
  28. package/dist/cdn/components/vedic-kundli.js +34 -22
  29. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  30. package/dist/cdn/components/vedic-planets-table.js +231 -0
  31. package/dist/cdn/components/vedic-planets-table.js.map +7 -0
  32. package/dist/cdn/components/western-planets-table.js +220 -0
  33. package/dist/cdn/components/western-planets-table.js.map +7 -0
  34. package/dist/cdn/roxy-ui.js +1078 -331
  35. package/dist/cdn/roxy-ui.js.map +4 -4
  36. package/dist/components/compatibility-card.js.map +1 -1
  37. package/dist/components/dasha-timeline.d.ts.map +1 -1
  38. package/dist/components/dasha-timeline.js.map +2 -2
  39. package/dist/components/divisional-chart.d.ts +5 -3
  40. package/dist/components/divisional-chart.d.ts.map +1 -1
  41. package/dist/components/divisional-chart.js +159 -38
  42. package/dist/components/divisional-chart.js.map +3 -3
  43. package/dist/components/guna-milan.js.map +1 -1
  44. package/dist/components/kp-chart.d.ts +26 -0
  45. package/dist/components/kp-chart.d.ts.map +1 -0
  46. package/dist/components/kp-chart.js +382 -0
  47. package/dist/components/kp-chart.js.map +7 -0
  48. package/dist/components/kp-planets-table.js.map +1 -1
  49. package/dist/components/kp-ruling-planets.d.ts +20 -0
  50. package/dist/components/kp-ruling-planets.d.ts.map +1 -0
  51. package/dist/components/kp-ruling-planets.js +275 -0
  52. package/dist/components/kp-ruling-planets.js.map +7 -0
  53. package/dist/components/location-search.d.ts.map +1 -1
  54. package/dist/components/location-search.js +9 -2
  55. package/dist/components/location-search.js.map +2 -2
  56. package/dist/components/moon-phase.js.map +1 -1
  57. package/dist/components/nakshatra-card.d.ts +18 -0
  58. package/dist/components/nakshatra-card.d.ts.map +1 -0
  59. package/dist/components/nakshatra-card.js +231 -0
  60. package/dist/components/nakshatra-card.js.map +7 -0
  61. package/dist/components/natal-chart.d.ts +28 -0
  62. package/dist/components/natal-chart.d.ts.map +1 -1
  63. package/dist/components/natal-chart.js +401 -104
  64. package/dist/components/natal-chart.js.map +2 -2
  65. package/dist/components/numerology-card.d.ts.map +1 -1
  66. package/dist/components/numerology-card.js.map +2 -2
  67. package/dist/components/panchang-table.js.map +1 -1
  68. package/dist/components/shadbala-table.js.map +1 -1
  69. package/dist/components/synastry-chart.js.map +2 -2
  70. package/dist/components/transits-table.js.map +1 -1
  71. package/dist/components/vedic-kundli.d.ts +7 -3
  72. package/dist/components/vedic-kundli.d.ts.map +1 -1
  73. package/dist/components/vedic-kundli.js +209 -87
  74. package/dist/components/vedic-kundli.js.map +3 -3
  75. package/dist/components/vedic-planets-table.d.ts +21 -0
  76. package/dist/components/vedic-planets-table.d.ts.map +1 -0
  77. package/dist/components/vedic-planets-table.js +355 -0
  78. package/dist/components/vedic-planets-table.js.map +7 -0
  79. package/dist/components/western-planets-table.d.ts +21 -0
  80. package/dist/components/western-planets-table.d.ts.map +1 -0
  81. package/dist/components/western-planets-table.js +350 -0
  82. package/dist/components/western-planets-table.js.map +7 -0
  83. package/dist/index.cjs +2042 -695
  84. package/dist/index.cjs.map +4 -4
  85. package/dist/index.d.ts +5 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2029 -682
  88. package/dist/index.js.map +4 -4
  89. package/dist/manifest.d.ts.map +1 -1
  90. package/dist/manifest.json +23 -18
  91. package/dist/styles/tokens.css +4 -0
  92. package/dist/types/types.gen.d.ts +343 -49
  93. package/dist/types/types.gen.d.ts.map +1 -1
  94. package/dist/utils/degree.d.ts +12 -0
  95. package/dist/utils/degree.d.ts.map +1 -1
  96. package/dist/utils/format.d.ts +1 -1
  97. package/dist/utils/kundli-render.d.ts +85 -12
  98. package/dist/utils/kundli-render.d.ts.map +1 -1
  99. package/dist/version.d.ts +1 -1
  100. package/package.json +1 -1
  101. package/src/components/dasha-timeline.ts +1 -7
  102. package/src/components/divisional-chart.ts +27 -41
  103. package/src/components/kp-chart.ts +313 -0
  104. package/src/components/kp-ruling-planets.ts +196 -0
  105. package/src/components/location-search.ts +16 -2
  106. package/src/components/nakshatra-card.ts +149 -0
  107. package/src/components/natal-chart.ts +408 -119
  108. package/src/components/numerology-card.ts +1 -5
  109. package/src/components/vedic-kundli.ts +30 -40
  110. package/src/components/vedic-planets-table.ts +184 -0
  111. package/src/components/western-planets-table.ts +180 -0
  112. package/src/index.ts +5 -0
  113. package/src/manifest.ts +146 -84
  114. package/src/styles/tokens.css +4 -0
  115. package/src/types/types.gen.ts +343 -49
  116. package/src/utils/degree.ts +21 -0
  117. package/src/utils/format.ts +1 -1
  118. package/src/utils/kundli-render.ts +234 -29
  119. package/src/version.ts +1 -1
@@ -21,6 +21,18 @@ export declare function normalizeLongitude(lon: number): number;
21
21
  export declare function longitudeToSignPosition(longitude: number): SignPosition;
22
22
  /** Compact display string like "12° Leo 34'". Used in chart labels. */
23
23
  export declare function formatSignPosition(longitude: number): string;
24
+ /**
25
+ * The point diametrically opposite a longitude (e.g. Descendant from
26
+ * Ascendant, IC from MC). Exact derivation, always 180 degrees away.
27
+ */
28
+ export declare function oppositePoint(longitude: number): number;
29
+ /**
30
+ * Midpoint of the forward arc from `start` to `end` (both ecliptic
31
+ * longitudes). Handles the 360/0 wrap, so a house spanning 350 to 20 degrees
32
+ * yields a midpoint of 5, not 185. Used to place house numbers between two
33
+ * cusps regardless of how unequal the house is.
34
+ */
35
+ export declare function arcMidpoint(start: number, end: number): number;
24
36
  /** Polar to cartesian for SVG wheel positioning. Angle in degrees, 0 at 3 o'clock. */
25
37
  export declare function polarToCartesian(cx: number, cy: number, radius: number, angleDeg: number): {
26
38
  x: number;
@@ -1 +1 @@
1
- {"version":3,"file":"degree.d.ts","sourceRoot":"","sources":["../../src/utils/degree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAevE;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAC/B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAM1B"}
1
+ {"version":3,"file":"degree.d.ts","sourceRoot":"","sources":["../../src/utils/degree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAevE;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAC/B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAM1B"}
@@ -19,7 +19,7 @@ export declare function formatPercent(value: unknown, dp?: number): string;
19
19
  */
20
20
  export declare const ASPECT_CLASS: Record<string, string>;
21
21
  /**
22
- * Normalize an aspect entry's `type` field to a lowercase, hyphen-separated
22
+ * Normalize the `type` field on an aspect entry to a lowercase, hyphen-separated
23
23
  * canonical name (`SEMI_SEXTILE` → `semi-sextile`). Accepts any aspect-shaped
24
24
  * object so both natal and synastry inter-aspect entries can share this.
25
25
  */
@@ -8,6 +8,34 @@ export declare const KUNDLI_CENTER = 150;
8
8
  * rashi keys to the title-cased SIGNS_ORDER tokens.
9
9
  */
10
10
  export declare const RASHI_TO_SIGN: Record<string, string>;
11
+ /**
12
+ * A planet placed in a kundli house. This is a render-only view model, not an
13
+ * API type: it carries just enough per-graha detail to draw a compact label
14
+ * (abbreviation plus degree-within-sign plus retrograde mark) and a rich SVG
15
+ * `<title>` tooltip (full position, nakshatra, pada, avastha). Both the D1
16
+ * birth chart and the Dx divisional charts feed it from their `meta` map.
17
+ */
18
+ export interface PlacedGraha {
19
+ graha: string;
20
+ longitude?: number;
21
+ nakshatra?: {
22
+ name?: string;
23
+ pada?: number;
24
+ lord?: string;
25
+ };
26
+ isRetrograde?: boolean;
27
+ awastha?: string;
28
+ }
29
+ export interface HouseDef {
30
+ /** 1-based cell number. For the sign-fixed styles (south, east) this is the rashi index, Aries = 1. */
31
+ number: number;
32
+ /** Sign name (TitleCase, e.g. "Aries"). */
33
+ sign: string;
34
+ /** Planets occupying this house, with full detail for label + tooltip. */
35
+ planets: PlacedGraha[];
36
+ /** Whether this house is the ascendant (Lagna). */
37
+ isLagna: boolean;
38
+ }
11
39
  /**
12
40
  * South Indian fixed-house square grid: house centers for planet text labels.
13
41
  * House 1 is fixed top-center; positions are in the 300x300 viewBox.
@@ -32,19 +60,35 @@ export declare const NORTH_HOUSE_CENTERS: Record<number, {
32
60
  x: number;
33
61
  y: number;
34
62
  }>;
35
- export interface HouseDef {
36
- /** 1-based house number. */
37
- number: number;
38
- /** Sign name (TitleCase, e.g. "Aries"). */
39
- sign: string;
40
- /** Planet abbreviation strings to display. */
41
- planets: string[];
42
- /** Whether this house is the ascendant (Lagna). */
43
- isLagna: boolean;
44
- }
45
63
  /**
46
- * Render a single house group: lagna highlight, sign abbreviation, planet labels.
47
- * Returns an SVG fragment for use inside an `<svg>` element.
64
+ * East Indian style: a fixed-sign square (like South Indian) cut by both
65
+ * diagonals and an inner diamond joining the side midpoints, giving 12 cells.
66
+ * The four inner-diamond quadrilaterals hold the cardinal-position signs
67
+ * (cell 1, 4, 7, 10) and the eight corner half-triangles fill between them,
68
+ * laid out clockwise from the top so cell `n` holds the n-th rashi (Aries = 1).
69
+ * Centers are the visual midpoints of those cells in the 300x300 viewBox,
70
+ * derived from the frame geometry (square 10..290, diagonals, side-midpoint
71
+ * diamond).
72
+ *
73
+ * @remarks The cell geometry is exact; the rashi-to-cell order follows the
74
+ * common clockwise-from-top convention and is slated for a regional
75
+ * reference-image confirmation pass (see docs/todo.md "East Indian polish").
76
+ */
77
+ export declare const EAST_HOUSE_CENTERS: Record<number, {
78
+ x: number;
79
+ y: number;
80
+ }>;
81
+ /**
82
+ * East Indian sign abbreviation positions, nudged toward the outer edge of
83
+ * every cell so the abbreviation and the planet stack do not collide.
84
+ */
85
+ export declare const EAST_SIGN_POSITIONS: Record<number, {
86
+ x: number;
87
+ y: number;
88
+ }>;
89
+ /**
90
+ * Render a single south-Indian house group: lagna highlight, sign
91
+ * abbreviation, planet labels with degree and tooltip.
48
92
  */
49
93
  export declare function renderSouthHouseGroup(h: HouseDef): TemplateResult | typeof nothing;
50
94
  /**
@@ -60,4 +104,33 @@ export declare function renderNorthHouseGroup(h: HouseDef): TemplateResult | typ
60
104
  * Render the south-Indian square frame (border diamond + inner square + radial lines).
61
105
  */
62
106
  export declare function renderSouthFrame(): TemplateResult;
107
+ /**
108
+ * Render the east-Indian square frame: outer square, both diagonals, and the
109
+ * inner diamond joining the four side midpoints. Twelve triangular cells.
110
+ */
111
+ export declare function renderEastFrame(): TemplateResult;
112
+ /**
113
+ * Render an east-Indian house group. East Indian charts are sign-fixed like
114
+ * the south style, so this mirrors `renderSouthHouseGroup` with the east cell
115
+ * centers and a smaller line height to fit the triangular cells.
116
+ */
117
+ export declare function renderEastHouseGroup(h: HouseDef): TemplateResult | typeof nothing;
118
+ /**
119
+ * Bucket a graha-keyed `meta` map (from a D1 or Dx chart response) into the 12
120
+ * sign-indexed houses. Shared by the kundli and divisional chart components so
121
+ * both render the same rich per-graha detail. The Lagna entry is consumed only
122
+ * to flag the ascendant cell, not rendered as a planet.
123
+ */
124
+ export declare function buildHousesFromMeta(meta: Record<string, {
125
+ graha?: string;
126
+ rashi?: string;
127
+ longitude?: number;
128
+ nakshatra?: {
129
+ name?: string;
130
+ pada?: number;
131
+ lord?: string;
132
+ };
133
+ isRetrograde?: boolean;
134
+ awastha?: string;
135
+ }>): HouseDef[];
63
136
  //# sourceMappingURL=kundli-render.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"kundli-render.d.ts","sourceRoot":"","sources":["../../src/utils/kundli-render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAO,MAAM,KAAK,CAAC;AAInC,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAEhD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAaxE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAazE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAaxE,CAAC;AAEF,MAAM,WAAW,QAAQ;IACxB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mDAAmD;IACnD,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,CAAC,EAAE,QAAQ,GACT,cAAc,GAAG,OAAO,OAAO,CAqCjC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAUjD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,CAAC,EAAE,QAAQ,GACT,cAAc,GAAG,OAAO,OAAO,CA2BjC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAajD"}
1
+ {"version":3,"file":"kundli-render.d.ts","sourceRoot":"","sources":["../../src/utils/kundli-render.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const ROXY_UI_VERSION = "0.2.3";
1
+ export declare const ROXY_UI_VERSION = "0.3.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roxyapi/ui",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Web components for the RoxyAPI catalog. Drop-in charts, tables, cards, forms for astrology, tarot, numerology, biorhythm, I Ching, crystals, dreams, angel numbers, and more. One key, beautiful in 30 minutes.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -13,13 +13,7 @@ type DashaData =
13
13
  | GetMajorDashasResponse
14
14
  | GetSubDashasResponse;
15
15
 
16
- type DashaPeriod = {
17
- planet: string;
18
- startDate: string;
19
- endDate: string;
20
- durationYears: number;
21
- interpretation?: string;
22
- };
16
+ type DashaPeriod = GetMajorDashasResponse['mahadashas'][number];
23
17
 
24
18
  /**
25
19
  * Dasha timeline. Renders /vedic-astrology/dasha/{current,major,sub/{...}}.
@@ -1,27 +1,25 @@
1
1
  import { css, html, LitElement, nothing } from 'lit';
2
2
  import { customElement, property } from 'lit/decorators.js';
3
- import { PLANET_GLYPH, RASHI_KEYS } from '../tokens/index.js';
3
+ import { PLANET_GLYPH } from '../tokens/index.js';
4
4
  import type { DivisionalChartResponse } from '../types/index.js';
5
5
  import { baseStyles } from '../utils/base-styles.js';
6
- import type { HouseDef } from '../utils/kundli-render.js';
7
6
  import {
8
- RASHI_TO_SIGN,
7
+ buildHousesFromMeta,
8
+ type HouseDef,
9
+ renderEastFrame,
10
+ renderEastHouseGroup,
9
11
  renderNorthFrame,
10
12
  renderNorthHouseGroup,
11
13
  renderSouthFrame,
12
14
  renderSouthHouseGroup,
13
15
  } from '../utils/kundli-render.js';
14
16
 
15
- type RashiBucket = {
16
- rashi?: string;
17
- signs?: Array<{ graha: string; isRetrograde?: boolean }>;
18
- };
19
- type ChartByRashi = { [key: string]: RashiBucket | unknown };
20
-
21
17
  /**
22
18
  * Divisional chart renderer (D2-D60). Accepts a DivisionalChartResponse and
23
- * renders the same south/north kundli wheel as the birth chart, plus division
24
- * metadata and Vargottama planet pills.
19
+ * renders the same south/north/east kundli wheel as the birth chart, plus
20
+ * division metadata and Vargottama planet pills. The varga response carries a
21
+ * graha-keyed `chart.meta` map (no per-rashi buckets), so houses are bucketed
22
+ * from that map.
25
23
  */
26
24
  @customElement('roxy-divisional-chart')
27
25
  export class RoxyDivisionalChart extends LitElement {
@@ -124,31 +122,11 @@ export class RoxyDivisionalChart extends LitElement {
124
122
  data: DivisionalChartResponse | null = null;
125
123
 
126
124
  @property({ type: String, reflect: true, attribute: 'chart-style' })
127
- chartStyle: 'south' | 'north' = 'south';
125
+ chartStyle: 'south' | 'north' | 'east' = 'south';
128
126
 
129
127
  private buildHouses(): HouseDef[] {
130
- if (!this.data) return [];
131
- const chart = this.data.chart as ChartByRashi;
132
- const meta =
133
- (this.data.chart as { meta?: Record<string, { rashi?: string }> }).meta ??
134
- {};
135
- const lagnaSign = meta.Lagna?.rashi ?? '';
136
- const houses: HouseDef[] = [];
137
- for (let i = 0; i < 12; i++) {
138
- const key = RASHI_KEYS[i];
139
- const bucket = chart[key] as RashiBucket | undefined;
140
- const planets = (bucket?.signs ?? []).map((p) => p.graha).filter(Boolean);
141
- const sign = RASHI_TO_SIGN[key] ?? '';
142
- houses.push({
143
- number: i + 1,
144
- sign,
145
- planets,
146
- isLagna: lagnaSign
147
- ? lagnaSign.toLowerCase() === sign.toLowerCase()
148
- : false,
149
- });
150
- }
151
- return houses;
128
+ if (!this.data?.chart?.meta) return [];
129
+ return buildHousesFromMeta(this.data.chart.meta);
152
130
  }
153
131
 
154
132
  render() {
@@ -157,7 +135,19 @@ export class RoxyDivisionalChart extends LitElement {
157
135
 
158
136
  const { division, vargottama } = this.data;
159
137
  const houses = this.buildHouses();
160
- const isNorth = this.chartStyle === 'north';
138
+ const style = this.chartStyle;
139
+ const frame =
140
+ style === 'north'
141
+ ? renderNorthFrame()
142
+ : style === 'east'
143
+ ? renderEastFrame()
144
+ : renderSouthFrame();
145
+ const houseGroup =
146
+ style === 'north'
147
+ ? renderNorthHouseGroup
148
+ : style === 'east'
149
+ ? renderEastHouseGroup
150
+ : renderSouthHouseGroup;
161
151
 
162
152
  return html`<div class="wrap">
163
153
  <div class="header">
@@ -182,12 +172,8 @@ export class RoxyDivisionalChart extends LitElement {
182
172
  aria-label="D${division.number} ${division.name} divisional chart with twelve sign houses"
183
173
  >
184
174
  <title>D${division.number} ${division.name}</title>
185
- ${isNorth ? renderNorthFrame() : renderSouthFrame()}
186
- ${
187
- isNorth
188
- ? houses.map((h) => renderNorthHouseGroup(h))
189
- : houses.map((h) => renderSouthHouseGroup(h))
190
- }
175
+ ${frame}
176
+ ${houses.map((h) => houseGroup(h))}
191
177
  </svg>
192
178
 
193
179
  ${
@@ -0,0 +1,313 @@
1
+ import { css, html, LitElement, nothing } from 'lit';
2
+ import { customElement, property, state } from 'lit/decorators.js';
3
+ import type { KpChartResponse } from '../types/index.js';
4
+ import { baseStyles } from '../utils/base-styles.js';
5
+ import { formatNumber } from '../utils/format.js';
6
+
7
+ type Tab = 'planets' | 'cusps';
8
+
9
+ /** A planet or node row, normalized so planets and Rahu/Ketu share a table. */
10
+ interface KpBody {
11
+ name: string;
12
+ sign?: string;
13
+ house?: number;
14
+ nakshatra?: string;
15
+ starLord?: string;
16
+ subLord?: string;
17
+ subSubLord?: string;
18
+ kpNumber?: number;
19
+ retrograde?: boolean;
20
+ }
21
+
22
+ /**
23
+ * KP (Krishnamurti Paddhati) chart. Renders /vedic-astrology/kp/chart: the
24
+ * Ascendant with its full stellar hierarchy, a planets-and-nodes table, and a
25
+ * Placidus cusps table. The cusp and planet sub lords are the primary
26
+ * predictive surface in KP astrology, so each row carries star lord, sub lord,
27
+ * sub-sub lord, and KP number (1-249).
28
+ */
29
+ @customElement('roxy-kp-chart')
30
+ export class RoxyKpChart extends LitElement {
31
+ static styles = [
32
+ baseStyles,
33
+ css`
34
+ .wrap {
35
+ border: 1px solid var(--roxy-border, #e4e4e7);
36
+ border-radius: var(--roxy-radius-md, 8px);
37
+ background: var(--roxy-bg, #fff);
38
+ overflow: auto;
39
+ box-shadow: var(--roxy-shadow-sm);
40
+ }
41
+ .head {
42
+ padding: var(--roxy-space-md, 1rem);
43
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
44
+ display: grid;
45
+ gap: var(--roxy-space-xs, 0.25rem);
46
+ }
47
+ .title {
48
+ margin: 0;
49
+ font-size: var(--roxy-text-lg, 1.125rem);
50
+ font-weight: var(--roxy-weight-bold, 600);
51
+ }
52
+ .asc,
53
+ .ayan {
54
+ color: var(--roxy-muted, #71717a);
55
+ font-size: var(--roxy-text-sm, 0.875rem);
56
+ }
57
+ .asc strong {
58
+ color: var(--roxy-fg, #0a0a0a);
59
+ }
60
+ .tablist {
61
+ display: flex;
62
+ gap: 2px;
63
+ padding: 0 var(--roxy-space-md, 1rem);
64
+ border-bottom: 2px solid var(--roxy-border, #e4e4e7);
65
+ }
66
+ .tab {
67
+ padding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);
68
+ font-size: var(--roxy-text-sm, 0.875rem);
69
+ background: none;
70
+ border: none;
71
+ border-bottom: 2px solid transparent;
72
+ margin-bottom: -2px;
73
+ cursor: pointer;
74
+ color: var(--roxy-muted, #71717a);
75
+ font-family: inherit;
76
+ }
77
+ .tab[aria-selected='true'] {
78
+ color: var(--roxy-accent-fg, #b45309);
79
+ border-bottom-color: var(--roxy-accent, #f59e0b);
80
+ font-weight: var(--roxy-weight-bold, 600);
81
+ }
82
+ .tab:hover:not([aria-selected='true']) {
83
+ color: var(--roxy-fg, #0a0a0a);
84
+ }
85
+ table {
86
+ width: 100%;
87
+ border-collapse: collapse;
88
+ font-size: var(--roxy-text-sm, 0.875rem);
89
+ min-width: 620px;
90
+ }
91
+ thead {
92
+ background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 20%, transparent);
93
+ }
94
+ th,
95
+ td {
96
+ padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
97
+ text-align: left;
98
+ white-space: nowrap;
99
+ }
100
+ th {
101
+ color: var(--roxy-muted, #71717a);
102
+ font-weight: var(--roxy-weight-bold, 600);
103
+ text-transform: uppercase;
104
+ font-size: var(--roxy-text-xs, 0.75rem);
105
+ letter-spacing: 0.04em;
106
+ }
107
+ tbody tr {
108
+ border-top: 1px solid var(--roxy-border, #e4e4e7);
109
+ }
110
+ td.body {
111
+ font-weight: var(--roxy-weight-bold, 600);
112
+ color: var(--roxy-fg, #0a0a0a);
113
+ }
114
+ .retro {
115
+ color: var(--roxy-warning-fg, #9a3412);
116
+ font-size: var(--roxy-text-xs, 0.75rem);
117
+ font-weight: var(--roxy-weight-bold, 600);
118
+ margin-left: 4px;
119
+ }
120
+ .num {
121
+ font-variant-numeric: tabular-nums;
122
+ }
123
+ `,
124
+ ];
125
+
126
+ @property({ attribute: false })
127
+ data: KpChartResponse | null = null;
128
+
129
+ @state()
130
+ private activeTab: Tab = 'planets';
131
+
132
+ /** Merge the 7 planets and the two nodes into one ordered body list. */
133
+ private bodies(): KpBody[] {
134
+ const d = this.data;
135
+ if (!d) return [];
136
+ const rows: KpBody[] = (d.planets ?? []).map((p) => ({
137
+ name: p.planet,
138
+ sign: p.sign,
139
+ house: p.house,
140
+ nakshatra: p.nakshatra,
141
+ starLord: p.starLord,
142
+ subLord: p.subLord,
143
+ subSubLord: p.subSubLord,
144
+ kpNumber: p.kpNumber,
145
+ retrograde: p.retrograde,
146
+ }));
147
+ const nodes = d.nodes;
148
+ for (const [name, node] of [
149
+ ['Rahu', nodes?.rahu],
150
+ ['Ketu', nodes?.ketu],
151
+ ] as const) {
152
+ if (node) {
153
+ rows.push({
154
+ name,
155
+ sign: node.sign,
156
+ house: node.house,
157
+ nakshatra: node.nakshatra,
158
+ starLord: node.starLord,
159
+ subLord: node.subLord,
160
+ subSubLord: node.subSubLord,
161
+ retrograde: true,
162
+ });
163
+ }
164
+ }
165
+ return rows;
166
+ }
167
+
168
+ private onTabKeyDown(e: KeyboardEvent) {
169
+ if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;
170
+ e.preventDefault();
171
+ this.activeTab = this.activeTab === 'planets' ? 'cusps' : 'planets';
172
+ const next = this.activeTab;
173
+ requestAnimationFrame(() => {
174
+ this.shadowRoot
175
+ ?.querySelector<HTMLButtonElement>(`#tab-${next}`)
176
+ ?.focus();
177
+ });
178
+ }
179
+
180
+ render() {
181
+ if (!this.data)
182
+ return html`<div class="roxy-empty" role="status">No KP chart data</div>`;
183
+ const d = this.data;
184
+ const asc = d.ascendant;
185
+
186
+ return html`<div class="wrap" aria-label="KP chart" tabindex="0">
187
+ <header class="head">
188
+ <h2 class="title">KP chart</h2>
189
+ ${
190
+ asc
191
+ ? html`<div class="asc">
192
+ Ascendant: <strong>${asc.sign ?? ''}</strong>
193
+ ${asc.nakshatra ? html`· ${asc.nakshatra}` : nothing}
194
+ ${asc.subLord ? html`· sub lord ${asc.subLord}` : nothing}
195
+ ${typeof asc.kpNumber === 'number' ? html`· KP ${asc.kpNumber}` : nothing}
196
+ </div>`
197
+ : nothing
198
+ }
199
+ ${
200
+ typeof d.meta?.ayanamsa === 'number'
201
+ ? html`<div class="ayan">
202
+ ${d.meta.ayanamsaType ?? 'Ayanamsa'}: ${formatNumber(d.meta.ayanamsa, 4)}°
203
+ ${d.meta.houseSystem ? html`· ${d.meta.houseSystem} houses` : nothing}
204
+ </div>`
205
+ : nothing
206
+ }
207
+ </header>
208
+
209
+ <div
210
+ class="tablist"
211
+ role="tablist"
212
+ aria-label="KP chart views"
213
+ @keydown=${this.onTabKeyDown}
214
+ >
215
+ ${(['planets', 'cusps'] as const).map(
216
+ (t) => html`<button
217
+ class="tab"
218
+ role="tab"
219
+ id="tab-${t}"
220
+ aria-selected=${this.activeTab === t ? 'true' : 'false'}
221
+ aria-controls="panel-${t}"
222
+ tabindex=${this.activeTab === t ? '0' : '-1'}
223
+ @click=${() => {
224
+ this.activeTab = t;
225
+ }}
226
+ >
227
+ ${t === 'planets' ? 'Planets' : 'Cusps'}
228
+ </button>`,
229
+ )}
230
+ </div>
231
+
232
+ <div id="panel-${this.activeTab}" role="tabpanel" aria-labelledby="tab-${this.activeTab}">
233
+ ${this.activeTab === 'planets' ? this.renderPlanets() : this.renderCusps()}
234
+ </div>
235
+ </div>`;
236
+ }
237
+
238
+ private renderPlanets() {
239
+ const bodies = this.bodies();
240
+ if (!bodies.length)
241
+ return html`<p class="roxy-empty" role="status">No planets</p>`;
242
+ return html`<table role="table" aria-label="KP planets and nodes">
243
+ <thead>
244
+ <tr>
245
+ <th scope="col">Body</th>
246
+ <th scope="col">Sign</th>
247
+ <th scope="col">House</th>
248
+ <th scope="col">Nakshatra</th>
249
+ <th scope="col">Star lord</th>
250
+ <th scope="col">Sub lord</th>
251
+ <th scope="col">Sub sub lord</th>
252
+ <th scope="col">KP no.</th>
253
+ </tr>
254
+ </thead>
255
+ <tbody>
256
+ ${bodies.map(
257
+ (b) => html`<tr>
258
+ <td class="body">
259
+ ${b.name}${b.retrograde ? html`<span class="retro">R</span>` : nothing}
260
+ </td>
261
+ <td>${b.sign ?? ''}</td>
262
+ <td class="num">${typeof b.house === 'number' ? b.house : ''}</td>
263
+ <td>${b.nakshatra ?? ''}</td>
264
+ <td>${b.starLord ?? ''}</td>
265
+ <td>${b.subLord ?? ''}</td>
266
+ <td>${b.subSubLord ?? ''}</td>
267
+ <td class="num">${typeof b.kpNumber === 'number' ? b.kpNumber : ''}</td>
268
+ </tr>`,
269
+ )}
270
+ </tbody>
271
+ </table>`;
272
+ }
273
+
274
+ private renderCusps() {
275
+ const cusps = this.data?.cusps ?? [];
276
+ if (!cusps.length)
277
+ return html`<p class="roxy-empty" role="status">No cusps</p>`;
278
+ return html`<table role="table" aria-label="KP Placidus cusps">
279
+ <thead>
280
+ <tr>
281
+ <th scope="col">House</th>
282
+ <th scope="col">Sign</th>
283
+ <th scope="col">Sign lord</th>
284
+ <th scope="col">Nakshatra</th>
285
+ <th scope="col">Star lord</th>
286
+ <th scope="col">Sub lord</th>
287
+ <th scope="col">Sub sub lord</th>
288
+ <th scope="col">KP no.</th>
289
+ </tr>
290
+ </thead>
291
+ <tbody>
292
+ ${cusps.map(
293
+ (c) => html`<tr>
294
+ <td class="body num">${c.house}</td>
295
+ <td>${c.sign ?? ''}</td>
296
+ <td>${c.signLord ?? ''}</td>
297
+ <td>${c.nakshatra ?? ''}</td>
298
+ <td>${c.starLord ?? ''}</td>
299
+ <td>${c.subLord ?? ''}</td>
300
+ <td>${c.subSubLord ?? ''}</td>
301
+ <td class="num">${typeof c.kpNumber === 'number' ? c.kpNumber : ''}</td>
302
+ </tr>`,
303
+ )}
304
+ </tbody>
305
+ </table>`;
306
+ }
307
+ }
308
+
309
+ declare global {
310
+ interface HTMLElementTagNameMap {
311
+ 'roxy-kp-chart': RoxyKpChart;
312
+ }
313
+ }