@roxyapi/ui 0.4.1 → 0.6.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 (235) hide show
  1. package/AGENTS.md +21 -0
  2. package/README.md +17 -1
  3. package/dist/cdn/components/ashtakavarga-grid.js +3 -362
  4. package/dist/cdn/components/ashtakavarga-grid.js.map +4 -4
  5. package/dist/cdn/components/biorhythm-chart.js +3 -226
  6. package/dist/cdn/components/biorhythm-chart.js.map +4 -4
  7. package/dist/cdn/components/choghadiya-grid.js +3 -232
  8. package/dist/cdn/components/choghadiya-grid.js.map +4 -4
  9. package/dist/cdn/components/compatibility-card.js +3 -231
  10. package/dist/cdn/components/compatibility-card.js.map +4 -4
  11. package/dist/cdn/components/dasha-timeline.js +3 -283
  12. package/dist/cdn/components/dasha-timeline.js.map +4 -4
  13. package/dist/cdn/components/data.js +3 -230
  14. package/dist/cdn/components/data.js.map +4 -4
  15. package/dist/cdn/components/divisional-chart.js +3 -356
  16. package/dist/cdn/components/divisional-chart.js.map +4 -4
  17. package/dist/cdn/components/dosha-card.js +3 -226
  18. package/dist/cdn/components/dosha-card.js.map +4 -4
  19. package/dist/cdn/components/endpoint-form.js +2 -243
  20. package/dist/cdn/components/endpoint-form.js.map +2 -2
  21. package/dist/cdn/components/guna-milan.js +3 -270
  22. package/dist/cdn/components/guna-milan.js.map +4 -4
  23. package/dist/cdn/components/hexagram.js +3 -247
  24. package/dist/cdn/components/hexagram.js.map +4 -4
  25. package/dist/cdn/components/horoscope-card.js +3 -281
  26. package/dist/cdn/components/horoscope-card.js.map +4 -4
  27. package/dist/cdn/components/kp-chart.js +3 -278
  28. package/dist/cdn/components/kp-chart.js.map +4 -4
  29. package/dist/cdn/components/kp-planets-table.js +3 -196
  30. package/dist/cdn/components/kp-planets-table.js.map +4 -4
  31. package/dist/cdn/components/kp-ruling-planets.js +3 -241
  32. package/dist/cdn/components/kp-ruling-planets.js.map +4 -4
  33. package/dist/cdn/components/location-search.js +2 -240
  34. package/dist/cdn/components/location-search.js.map +2 -2
  35. package/dist/cdn/components/moon-phase.js +3 -223
  36. package/dist/cdn/components/moon-phase.js.map +4 -4
  37. package/dist/cdn/components/nakshatra-card.js +3 -201
  38. package/dist/cdn/components/nakshatra-card.js.map +4 -4
  39. package/dist/cdn/components/natal-chart.js +3 -563
  40. package/dist/cdn/components/natal-chart.js.map +4 -4
  41. package/dist/cdn/components/numerology-card.js +3 -233
  42. package/dist/cdn/components/numerology-card.js.map +4 -4
  43. package/dist/cdn/components/panchang-table.js +3 -220
  44. package/dist/cdn/components/panchang-table.js.map +4 -4
  45. package/dist/cdn/components/shadbala-table.js +3 -284
  46. package/dist/cdn/components/shadbala-table.js.map +4 -4
  47. package/dist/cdn/components/synastry-chart.js +3 -399
  48. package/dist/cdn/components/synastry-chart.js.map +4 -4
  49. package/dist/cdn/components/tarot-card.js +3 -261
  50. package/dist/cdn/components/tarot-card.js.map +4 -4
  51. package/dist/cdn/components/tarot-spread.js +3 -249
  52. package/dist/cdn/components/tarot-spread.js.map +4 -4
  53. package/dist/cdn/components/transits-table.js +3 -382
  54. package/dist/cdn/components/transits-table.js.map +4 -4
  55. package/dist/cdn/components/vedic-kundli.js +3 -305
  56. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  57. package/dist/cdn/components/vedic-planets-table.js +3 -203
  58. package/dist/cdn/components/vedic-planets-table.js.map +4 -4
  59. package/dist/cdn/components/western-planets-table.js +3 -192
  60. package/dist/cdn/components/western-planets-table.js.map +4 -4
  61. package/dist/cdn/components/yoga-list.js +3 -306
  62. package/dist/cdn/components/yoga-list.js.map +4 -4
  63. package/dist/cdn/roxy-ui.js +3 -5102
  64. package/dist/cdn/roxy-ui.js.map +4 -4
  65. package/dist/cdn/widgets.js +1 -114
  66. package/dist/components/ashtakavarga-grid.d.ts +1 -0
  67. package/dist/components/ashtakavarga-grid.d.ts.map +1 -1
  68. package/dist/components/ashtakavarga-grid.js +1 -531
  69. package/dist/components/ashtakavarga-grid.js.map +4 -4
  70. package/dist/components/biorhythm-chart.d.ts +1 -0
  71. package/dist/components/biorhythm-chart.d.ts.map +1 -1
  72. package/dist/components/biorhythm-chart.js +1 -332
  73. package/dist/components/biorhythm-chart.js.map +4 -4
  74. package/dist/components/choghadiya-grid.d.ts +1 -0
  75. package/dist/components/choghadiya-grid.d.ts.map +1 -1
  76. package/dist/components/choghadiya-grid.js +1 -351
  77. package/dist/components/choghadiya-grid.js.map +4 -4
  78. package/dist/components/compatibility-card.d.ts +1 -0
  79. package/dist/components/compatibility-card.d.ts.map +1 -1
  80. package/dist/components/compatibility-card.js +1 -313
  81. package/dist/components/compatibility-card.js.map +4 -4
  82. package/dist/components/dasha-timeline.d.ts +1 -0
  83. package/dist/components/dasha-timeline.d.ts.map +1 -1
  84. package/dist/components/dasha-timeline.js +1 -401
  85. package/dist/components/dasha-timeline.js.map +4 -4
  86. package/dist/components/data.d.ts +1 -0
  87. package/dist/components/data.d.ts.map +1 -1
  88. package/dist/components/data.js +1 -362
  89. package/dist/components/data.js.map +4 -4
  90. package/dist/components/divisional-chart.d.ts +1 -0
  91. package/dist/components/divisional-chart.d.ts.map +1 -1
  92. package/dist/components/divisional-chart.js +1 -886
  93. package/dist/components/divisional-chart.js.map +4 -4
  94. package/dist/components/dosha-card.d.ts +1 -0
  95. package/dist/components/dosha-card.d.ts.map +1 -1
  96. package/dist/components/dosha-card.js +1 -293
  97. package/dist/components/dosha-card.js.map +4 -4
  98. package/dist/components/endpoint-form.js +1 -505
  99. package/dist/components/endpoint-form.js.map +3 -3
  100. package/dist/components/guna-milan.d.ts +1 -0
  101. package/dist/components/guna-milan.d.ts.map +1 -1
  102. package/dist/components/guna-milan.js +1 -374
  103. package/dist/components/guna-milan.js.map +4 -4
  104. package/dist/components/hexagram.d.ts +1 -0
  105. package/dist/components/hexagram.d.ts.map +1 -1
  106. package/dist/components/hexagram.js +1 -380
  107. package/dist/components/hexagram.js.map +4 -4
  108. package/dist/components/horoscope-card.d.ts +1 -0
  109. package/dist/components/horoscope-card.d.ts.map +1 -1
  110. package/dist/components/horoscope-card.js +1 -381
  111. package/dist/components/horoscope-card.js.map +4 -4
  112. package/dist/components/kp-chart.d.ts +1 -0
  113. package/dist/components/kp-chart.d.ts.map +1 -1
  114. package/dist/components/kp-chart.js +1 -395
  115. package/dist/components/kp-chart.js.map +4 -4
  116. package/dist/components/kp-planets-table.d.ts +1 -0
  117. package/dist/components/kp-planets-table.d.ts.map +1 -1
  118. package/dist/components/kp-planets-table.js +1 -246
  119. package/dist/components/kp-planets-table.js.map +4 -4
  120. package/dist/components/kp-ruling-planets.d.ts +1 -0
  121. package/dist/components/kp-ruling-planets.d.ts.map +1 -1
  122. package/dist/components/kp-ruling-planets.js +1 -288
  123. package/dist/components/kp-ruling-planets.js.map +4 -4
  124. package/dist/components/location-search.js +1 -461
  125. package/dist/components/location-search.js.map +3 -3
  126. package/dist/components/moon-phase.d.ts +1 -0
  127. package/dist/components/moon-phase.d.ts.map +1 -1
  128. package/dist/components/moon-phase.js +1 -327
  129. package/dist/components/moon-phase.js.map +4 -4
  130. package/dist/components/nakshatra-card.d.ts +1 -0
  131. package/dist/components/nakshatra-card.d.ts.map +1 -1
  132. package/dist/components/nakshatra-card.js +1 -244
  133. package/dist/components/nakshatra-card.js.map +4 -4
  134. package/dist/components/natal-chart.d.ts +1 -1
  135. package/dist/components/natal-chart.d.ts.map +1 -1
  136. package/dist/components/natal-chart.js +1 -1040
  137. package/dist/components/natal-chart.js.map +4 -4
  138. package/dist/components/numerology-card.d.ts +1 -0
  139. package/dist/components/numerology-card.d.ts.map +1 -1
  140. package/dist/components/numerology-card.js +1 -315
  141. package/dist/components/numerology-card.js.map +4 -4
  142. package/dist/components/panchang-table.d.ts +1 -0
  143. package/dist/components/panchang-table.d.ts.map +1 -1
  144. package/dist/components/panchang-table.js +1 -350
  145. package/dist/components/panchang-table.js.map +4 -4
  146. package/dist/components/shadbala-table.d.ts +1 -0
  147. package/dist/components/shadbala-table.d.ts.map +1 -1
  148. package/dist/components/shadbala-table.js +1 -413
  149. package/dist/components/shadbala-table.js.map +4 -4
  150. package/dist/components/synastry-chart.d.ts +1 -0
  151. package/dist/components/synastry-chart.d.ts.map +1 -1
  152. package/dist/components/synastry-chart.js +1 -658
  153. package/dist/components/synastry-chart.js.map +4 -4
  154. package/dist/components/tarot-card.d.ts +1 -0
  155. package/dist/components/tarot-card.d.ts.map +1 -1
  156. package/dist/components/tarot-card.js +1 -333
  157. package/dist/components/tarot-card.js.map +4 -4
  158. package/dist/components/tarot-spread.d.ts +1 -0
  159. package/dist/components/tarot-spread.d.ts.map +1 -1
  160. package/dist/components/tarot-spread.js +1 -310
  161. package/dist/components/tarot-spread.js.map +4 -4
  162. package/dist/components/transits-table.d.ts +3 -0
  163. package/dist/components/transits-table.d.ts.map +1 -1
  164. package/dist/components/transits-table.js +1 -548
  165. package/dist/components/transits-table.js.map +4 -4
  166. package/dist/components/vedic-kundli.d.ts +1 -0
  167. package/dist/components/vedic-kundli.d.ts.map +1 -1
  168. package/dist/components/vedic-kundli.js +1 -802
  169. package/dist/components/vedic-kundli.js.map +4 -4
  170. package/dist/components/vedic-planets-table.d.ts +1 -0
  171. package/dist/components/vedic-planets-table.d.ts.map +1 -1
  172. package/dist/components/vedic-planets-table.js +1 -368
  173. package/dist/components/vedic-planets-table.js.map +4 -4
  174. package/dist/components/western-planets-table.d.ts +1 -0
  175. package/dist/components/western-planets-table.d.ts.map +1 -1
  176. package/dist/components/western-planets-table.js +1 -363
  177. package/dist/components/western-planets-table.js.map +4 -4
  178. package/dist/components/yoga-list.d.ts +1 -0
  179. package/dist/components/yoga-list.d.ts.map +1 -1
  180. package/dist/components/yoga-list.js +1 -383
  181. package/dist/components/yoga-list.js.map +4 -4
  182. package/dist/index.cjs +1 -8653
  183. package/dist/index.cjs.map +4 -4
  184. package/dist/index.js +1 -8633
  185. package/dist/index.js.map +4 -4
  186. package/dist/types/index.d.ts +1 -1
  187. package/dist/types/index.d.ts.map +1 -1
  188. package/dist/types/types.gen.d.ts +590 -202
  189. package/dist/types/types.gen.d.ts.map +1 -1
  190. package/dist/utils/disclosure.d.ts +16 -0
  191. package/dist/utils/disclosure.d.ts.map +1 -0
  192. package/dist/utils/kundli-render.d.ts.map +1 -1
  193. package/dist/utils/kundli-styles.d.ts.map +1 -1
  194. package/dist/utils/markup-data.d.ts +57 -0
  195. package/dist/utils/markup-data.d.ts.map +1 -0
  196. package/dist/utils/tablist.d.ts +44 -0
  197. package/dist/utils/tablist.d.ts.map +1 -0
  198. package/dist/version.d.ts +1 -1
  199. package/package.json +3 -1
  200. package/src/components/ashtakavarga-grid.ts +9 -0
  201. package/src/components/biorhythm-chart.ts +9 -0
  202. package/src/components/choghadiya-grid.ts +9 -0
  203. package/src/components/compatibility-card.ts +9 -0
  204. package/src/components/dasha-timeline.ts +19 -1
  205. package/src/components/data.ts +9 -0
  206. package/src/components/divisional-chart.ts +11 -0
  207. package/src/components/dosha-card.ts +9 -0
  208. package/src/components/guna-milan.ts +9 -0
  209. package/src/components/hexagram.ts +9 -0
  210. package/src/components/horoscope-card.ts +9 -0
  211. package/src/components/kp-chart.ts +9 -0
  212. package/src/components/kp-planets-table.ts +9 -0
  213. package/src/components/kp-ruling-planets.ts +9 -0
  214. package/src/components/moon-phase.ts +9 -0
  215. package/src/components/nakshatra-card.ts +9 -0
  216. package/src/components/natal-chart.ts +46 -62
  217. package/src/components/numerology-card.ts +9 -0
  218. package/src/components/panchang-table.ts +9 -0
  219. package/src/components/shadbala-table.ts +9 -0
  220. package/src/components/synastry-chart.ts +9 -0
  221. package/src/components/tarot-card.ts +9 -0
  222. package/src/components/tarot-spread.ts +9 -0
  223. package/src/components/transits-table.ts +54 -18
  224. package/src/components/vedic-kundli.ts +11 -1
  225. package/src/components/vedic-planets-table.ts +9 -0
  226. package/src/components/western-planets-table.ts +9 -0
  227. package/src/components/yoga-list.ts +9 -0
  228. package/src/types/index.ts +1 -1
  229. package/src/types/types.gen.ts +602 -200
  230. package/src/utils/disclosure.ts +62 -0
  231. package/src/utils/kundli-render.ts +21 -35
  232. package/src/utils/kundli-styles.ts +0 -31
  233. package/src/utils/markup-data.ts +115 -0
  234. package/src/utils/tablist.ts +124 -0
  235. package/src/version.ts +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/components/divisional-chart.ts", "../../src/tokens/index.ts", "../../src/utils/base-styles.ts", "../../src/utils/kundli-render.ts", "../../src/utils/degree.ts", "../../src/utils/string.ts", "../../src/utils/kundli-styles.ts"],
4
- "sourcesContent": ["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { PLANET_GLYPH } from '../tokens/index.js';\nimport type { DivisionalChartResponse } from '../types/index.js';\nimport { baseStyles } from '../utils/base-styles.js';\nimport {\n\ttype ChartStyle,\n\ttype KundliViewModel,\n\trenderKundliStyleTablist,\n\trenderKundliSvg,\n\ttoKundliViewModel,\n} from '../utils/kundli-render.js';\nimport { kundliStyles } from '../utils/kundli-styles.js';\n\n/**\n * Divisional chart renderer (D2-D60). Accepts a DivisionalChartResponse and\n * renders the same South / North / East kundli grid as the birth chart, plus\n * division metadata and Vargottama planet pills. A visible tablist lets the\n * end user switch styles at runtime. The varga response carries a graha-keyed\n * `chart.meta` map (no per-rashi buckets), so houses are bucketed from that\n * map.\n */\n@customElement('roxy-divisional-chart')\nexport class RoxyDivisionalChart extends LitElement {\n\tstatic styles = [\n\t\tbaseStyles,\n\t\tkundliStyles,\n\t\tcss`\n\t\t\t.division-meta {\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t\tcolor: var(--roxy-muted, #71717a);\n\t\t\t\tmargin: 0;\n\t\t\t}\n\t\t\t.significance {\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t\tcolor: var(--roxy-muted, #71717a);\n\t\t\t\tborder-left: 2px solid var(--roxy-border, #e4e4e7);\n\t\t\t\tpadding-left: var(--roxy-space-sm, 0.5rem);\n\t\t\t\tmargin: 0;\n\t\t\t}\n\t\t\t.vargottama-row {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-wrap: wrap;\n\t\t\t\tgap: var(--roxy-space-xs, 0.25rem);\n\t\t\t\talign-items: center;\n\t\t\t}\n\t\t\t.vargottama-label {\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t\tcolor: var(--roxy-muted, #71717a);\n\t\t\t\tfont-weight: 500;\n\t\t\t\tmargin-right: var(--roxy-space-xs, 0.25rem);\n\t\t\t}\n\t\t\t.vargottama-pill {\n\t\t\t\tdisplay: inline-flex;\n\t\t\t\talign-items: center;\n\t\t\t\tgap: 0.2em;\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t\tfont-weight: 600;\n\t\t\t\tpadding: 0.15em 0.6em;\n\t\t\t\tborder-radius: 999px;\n\t\t\t\tbackground: color-mix(in srgb, var(--roxy-accent, #f59e0b) 22%, transparent);\n\t\t\t\tcolor: var(--roxy-fg, #0a0a0a);\n\t\t\t\tborder: 1px solid color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);\n\t\t\t}\n\t\t`,\n\t];\n\n\t@property({ attribute: false })\n\tdata: DivisionalChartResponse | null = null;\n\n\t@property({ type: String, reflect: true, attribute: 'chart-style' })\n\tchartStyle: ChartStyle = 'north';\n\n\tprivate setStyle = (next: ChartStyle) => {\n\t\tthis.chartStyle = next;\n\t};\n\n\tprivate viewModel(): KundliViewModel | null {\n\t\tif (!this.data?.chart?.meta) return null;\n\t\tconst { division } = this.data;\n\t\tconst label = `D${division.number} ${division.name}`;\n\t\treturn toKundliViewModel(this.data.chart.meta, label);\n\t}\n\n\trender() {\n\t\tconst vm = this.viewModel();\n\t\tif (!this.data || !vm)\n\t\t\treturn html`<div class=\"roxy-empty\" role=\"status\">No divisional chart data</div>`;\n\n\t\tconst { division, vargottama } = this.data;\n\n\t\treturn html`<div class=\"wrap\">\n\t\t\t<div class=\"header\">\n\t\t\t\t<div>\n\t\t\t\t\t<h2 class=\"title\">\n\t\t\t\t\t\tD${division.number} ${division.name}\n\t\t\t\t\t\t${\n\t\t\t\t\t\t\tdivision.sanskritName && division.sanskritName !== division.name\n\t\t\t\t\t\t\t\t? html`<span class=\"division-meta\"> \u00B7 ${division.sanskritName}</span>`\n\t\t\t\t\t\t\t\t: nothing\n\t\t\t\t\t\t}\n\t\t\t\t\t</h2>\n\t\t\t\t\t${\n\t\t\t\t\t\tdivision.significance\n\t\t\t\t\t\t\t? html`<p class=\"significance\">${division.significance}</p>`\n\t\t\t\t\t\t\t: nothing\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t${renderKundliStyleTablist(this.chartStyle, this.setStyle)}\n\t\t\t</div>\n\n\t\t\t<svg\n\t\t\t\tviewBox=\"0 0 400 400\"\n\t\t\t\tpreserveAspectRatio=\"xMidYMid meet\"\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label=\"D${division.number} ${division.name} divisional chart with twelve sign houses\"\n\t\t\t>\n\t\t\t\t<title>D${division.number} ${division.name}</title>\n\t\t\t\t${renderKundliSvg(vm, this.chartStyle)}\n\t\t\t</svg>\n\n\t\t\t${\n\t\t\t\tvargottama && vargottama.length > 0\n\t\t\t\t\t? html`<div class=\"vargottama-row\" role=\"list\" aria-label=\"Vargottama planets\">\n\t\t\t\t\t\t<span class=\"vargottama-label\">Vargottama:</span>\n\t\t\t\t\t\t${vargottama.map(\n\t\t\t\t\t\t\t(planet) =>\n\t\t\t\t\t\t\t\thtml`<span class=\"vargottama-pill\" role=\"listitem\">\n\t\t\t\t\t\t\t\t\t${PLANET_GLYPH[planet] ?? ''} ${planet}\n\t\t\t\t\t\t\t\t</span>`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t</div>`;\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'roxy-divisional-chart': RoxyDivisionalChart;\n\t}\n}\n", "/**\n * Symbol constants used across components. Single source of truth so chart\n * wheels, card headers, hexagram displays, and panchang tables stay visually\n * consistent.\n */\n\nexport const PLANET_GLYPH: Record<string, string> = {\n\tSun: '\u2609',\n\tMoon: '\u263D',\n\tMercury: '\u263F',\n\tVenus: '\u2640',\n\tEarth: '\u2641',\n\tMars: '\u2642',\n\tJupiter: '\u2643',\n\tSaturn: '\u2644',\n\tUranus: '\u2645',\n\tNeptune: '\u2646',\n\tPluto: '\u2647',\n\tRahu: '\u260A',\n\tKetu: '\u260B',\n\tAscendant: 'Asc',\n\tLagna: 'La',\n\tNorthNode: '\u260A',\n\tSouthNode: '\u260B',\n\t'North node': '\u260A',\n\t'South node': '\u260B',\n\tChiron: '\u26B7',\n\tLilith: '\u26B8',\n\t'Black moon lilith': '\u26B8',\n};\n\nexport const PLANET_ABBR: Record<string, string> = {\n\tSun: 'Su',\n\tMoon: 'Mo',\n\tMercury: 'Me',\n\tVenus: 'Ve',\n\tMars: 'Ma',\n\tJupiter: 'Ju',\n\tSaturn: 'Sa',\n\tUranus: 'Ur',\n\tNeptune: 'Ne',\n\tPluto: 'Pl',\n\tRahu: 'Ra',\n\tKetu: 'Ke',\n\tAscendant: 'Asc',\n\tLagna: 'La',\n};\n\nexport const SIGN_GLYPH: Record<string, string> = {\n\tAries: '\u2648',\n\tTaurus: '\u2649',\n\tGemini: '\u264A',\n\tCancer: '\u264B',\n\tLeo: '\u264C',\n\tVirgo: '\u264D',\n\tLibra: '\u264E',\n\tScorpio: '\u264F',\n\tSagittarius: '\u2650',\n\tCapricorn: '\u2651',\n\tAquarius: '\u2652',\n\tPisces: '\u2653',\n};\n\nexport const SIGN_ABBR: Record<string, string> = {\n\tAries: 'Ar',\n\tTaurus: 'Ta',\n\tGemini: 'Ge',\n\tCancer: 'Cn',\n\tLeo: 'Le',\n\tVirgo: 'Vi',\n\tLibra: 'Li',\n\tScorpio: 'Sc',\n\tSagittarius: 'Sg',\n\tCapricorn: 'Cp',\n\tAquarius: 'Aq',\n\tPisces: 'Pi',\n};\n\nexport const SIGNS_ORDER = [\n\t'Aries',\n\t'Taurus',\n\t'Gemini',\n\t'Cancer',\n\t'Leo',\n\t'Virgo',\n\t'Libra',\n\t'Scorpio',\n\t'Sagittarius',\n\t'Capricorn',\n\t'Aquarius',\n\t'Pisces',\n] as const;\n\n/**\n * Lowercase rashi keys in canonical zodiac order. Derived from `SIGNS_ORDER`\n * so the two stay in lockstep. The /vedic-astrology/birth-chart response\n * carries planet buckets keyed by these names.\n */\nexport const RASHI_KEYS = SIGNS_ORDER.map((s) =>\n\ts.toLowerCase(),\n) as readonly Lowercase<(typeof SIGNS_ORDER)[number]>[];\n\n/** Aspect symbols. Used by synastry and natal chart aspect tables. */\nexport const ASPECT_SYMBOL: Record<string, string> = {\n\tconjunction: '\u260C',\n\topposition: '\u260D',\n\ttrine: '\u25B3',\n\tsquare: '\u25A1',\n\tsextile: '\u2731',\n\tquincunx: '\u22BB',\n\tsemisextile: '\u22BC',\n};\n\n/** Trigrams used by I Ching hexagrams. Eight trigrams compose 64 hexagrams. */\nexport const TRIGRAM_GLYPH: Record<string, string> = {\n\theaven: '\u2630',\n\tlake: '\u2631',\n\tfire: '\u2632',\n\tthunder: '\u2633',\n\twind: '\u2634',\n\twater: '\u2635',\n\tmountain: '\u2636',\n\tearth: '\u2637',\n\tHeaven: '\u2630',\n\tLake: '\u2631',\n\tFire: '\u2632',\n\tThunder: '\u2633',\n\tWind: '\u2634',\n\tWater: '\u2635',\n\tMountain: '\u2636',\n\tEarth: '\u2637',\n};\n\n/** Moon phase emoji set. Used by moon phase card. */\nexport const MOON_PHASE_EMOJI: Record<string, string> = {\n\t'new moon': '\uD83C\uDF11',\n\t'waxing crescent': '\uD83C\uDF12',\n\t'first quarter': '\uD83C\uDF13',\n\t'waxing gibbous': '\uD83C\uDF14',\n\t'full moon': '\uD83C\uDF15',\n\t'waning gibbous': '\uD83C\uDF16',\n\t'last quarter': '\uD83C\uDF17',\n\t'waning crescent': '\uD83C\uDF18',\n};\n", "import { css } from 'lit';\n\n/**\n * Shared host styles every component pulls in. Sets default font, color,\n * container query support, and the entry fade-in.\n */\nexport const baseStyles = css`\n\t:host {\n\t\tdisplay: block;\n\t\tcontainer-type: inline-size;\n\t\tfont-family: var(\n\t\t\t--roxy-font-sans,\n\t\t\tsystem-ui,\n\t\t\t-apple-system,\n\t\t\tBlinkMacSystemFont,\n\t\t\t'Segoe UI',\n\t\t\tRoboto,\n\t\t\tsans-serif\n\t\t);\n\t\tcolor: var(--roxy-fg, #0a0a0a);\n\t\tbackground: transparent;\n\t\tfont-size: var(--roxy-text-base, 1rem);\n\t\tline-height: var(--roxy-leading-normal, 1.5);\n\t\tanimation: roxy-fade-in var(--roxy-motion-duration, 200ms)\n\t\t\tvar(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1)) both;\n\t}\n\n\t*,\n\t*::before,\n\t*::after {\n\t\tbox-sizing: border-box;\n\t}\n\n\t@keyframes roxy-fade-in {\n\t\tfrom {\n\t\t\topacity: 0;\n\t\t\ttransform: translateY(2px);\n\t\t}\n\t\tto {\n\t\t\topacity: 1;\n\t\t\ttransform: translateY(0);\n\t\t}\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\t:host {\n\t\t\tanimation: none;\n\t\t}\n\t}\n\n\t.roxy-skeleton {\n\t\tbackground: linear-gradient(\n\t\t\t90deg,\n\t\t\tvar(--roxy-border, #e4e4e7) 0%,\n\t\t\tcolor-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent) 50%,\n\t\t\tvar(--roxy-border, #e4e4e7) 100%\n\t\t);\n\t\tbackground-size: 200% 100%;\n\t\tanimation: roxy-shimmer 1.4s ease-in-out infinite;\n\t\tborder-radius: var(--roxy-radius-md, 8px);\n\t}\n\n\t@keyframes roxy-shimmer {\n\t\t0% {\n\t\t\tbackground-position: 200% 0;\n\t\t}\n\t\t100% {\n\t\t\tbackground-position: -200% 0;\n\t\t}\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.roxy-skeleton {\n\t\t\tanimation: none;\n\t\t}\n\t}\n\n\t.roxy-empty {\n\t\tpadding: var(--roxy-space-lg, 1.5rem);\n\t\tcolor: var(--roxy-muted, #71717a);\n\t\ttext-align: center;\n\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t}\n\n\t:host(:focus-within) .roxy-card {\n\t\toutline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));\n\t\toutline-offset: 2px;\n\t}\n\n\t/* Force the text-style variant on every Unicode glyph in the component.\n\t * macOS and iOS substitute coloured emoji glyphs for the planetary and\n\t * gender Unicode code points (Mars, Venus, Mercury, etc.) when the\n\t * system colour-emoji font wins font selection. The text-style variant\n\t * keeps glyphs monochrome so they inherit the surrounding fill colour\n\t * and match the brand palette consistently across platforms.\n\t *\n\t * font-variant-emoji is part of CSS Fonts 4 (Safari 17+, Chrome 134+,\n\t * Firefox 139+). On older browsers the rule is silently ignored.\n\t */\n\t:host {\n\t\tfont-variant-emoji: text;\n\t}\n`;\n", "import type { TemplateResult } from 'lit';\nimport { html, nothing, svg } from 'lit';\nimport { PLANET_ABBR, SIGN_ABBR, SIGNS_ORDER } from '../tokens/index.js';\nimport { longitudeToSignPosition } from './degree.js';\nimport { capitalize } from './string.js';\n\n/**\n * Canonical viewBox geometry for every kundli style. The chart is drawn into a\n * 360-unit square centred in a 400-unit viewBox, leaving a 20-unit gutter for\n * outer labels. All coordinates below are derived from these constants; change\n * them and every cell relocates correctly.\n *\n * @remarks SVG is vector-only and scales without raster loss, so the chart\n * remains crisp from a phone screen to a wall projector. Hosts size the chart\n * by setting `width` on the surrounding container; the SVG keeps a 1:1 aspect\n * ratio via the viewBox.\n */\nconst VIEW_BOX = 400;\nconst MARGIN = 20;\nconst INNER = VIEW_BOX - 2 * MARGIN; // 360\nconst CENTRE = VIEW_BOX / 2; // 200\n\n/**\n * Lowercase rashi key (`\"aries\"`) to canonical title-cased sign name (`\"Aries\"`).\n * Bridges API lowercase rashi strings to the SIGNS_ORDER tokens used everywhere\n * else in the render.\n */\nconst RASHI_TO_SIGN: Record<string, string> = Object.fromEntries(\n\tSIGNS_ORDER.map((s) => [s.toLowerCase(), s] as const),\n);\n\n/**\n * A graha placed inside a kundli cell. Render-only view model fed from a\n * `meta` map on the API response. Carries enough detail to draw a compact\n * in-cell label (abbreviation, whole degree, retrograde mark) and a rich SVG\n * `<title>` tooltip (exact position, nakshatra, pada, avastha).\n */\nexport interface PlacedGraha {\n\tgraha: string;\n\tlongitude?: number;\n\tnakshatra?: { name?: string; pada?: number; lord?: string };\n\tisRetrograde?: boolean;\n\tawastha?: string;\n}\n\n/**\n * Unified view model used by every kundli style. Caller passes a graha-keyed\n * `meta` map (from `/vedic-astrology/birth-chart`, `/divisional-chart`, or\n * `/navamsa`) through {@link toKundliViewModel} to produce this shape.\n *\n * `placements` is keyed by lowercase rashi name (`\"aries\"`, `\"taurus\"`, ...)\n * so the sign-fixed styles can index directly. The Lagna entry is not\n * counted as a planet; it only flags the ascendant cell.\n */\nexport interface KundliViewModel {\n\tlagnaSign: string;\n\tplacements: Record<string, PlacedGraha[]>;\n\tdivisionLabel?: string;\n}\n\n/**\n * Kundli regional styles. Sign-fixed (south, east) and house-fixed (north).\n * Exposed so consumers can type their own `chart-style` attribute reflection.\n */\nexport type ChartStyle = 'south' | 'north' | 'east';\n\nconst CHART_STYLES: ReadonlyArray<{ id: ChartStyle; label: string }> = [\n\t{ id: 'north', label: 'North' },\n\t{ id: 'south', label: 'South' },\n\t{ id: 'east', label: 'East' },\n];\n\nconst RETRO_MARK = '\u02B3';\n\n/**\n * True when the placed graha's longitude maps to a sign other than the cell\n * it occupies. The API preserves the D1 sidereal longitude on every chart, so\n * inside a D2..D60 cell that longitude refers to the D1 sign, not the cell's\n * divisional sign. In that case the degree-within-sign is not meaningful and\n * must be hidden from the in-cell label.\n */\nfunction isDivisionalPlacement(p: PlacedGraha, cellSign: string): boolean {\n\tif (typeof p.longitude !== 'number' || !Number.isFinite(p.longitude)) {\n\t\treturn false;\n\t}\n\treturn (\n\t\tlongitudeToSignPosition(p.longitude).sign.toLowerCase() !==\n\t\tcellSign.toLowerCase()\n\t);\n}\n\n/**\n * Compact in-cell graha label: abbreviation, optional whole-degree, retrograde\n * mark. The degree is shown only when the longitude actually maps to the cell\n * the graha is rendered in (the D1 case); divisional placements show the\n * abbreviation alone since the API longitude refers to D1, not the divisional\n * sign.\n */\nfunction grahaLabel(p: PlacedGraha, cellSign: string): string {\n\tconst abbr = PLANET_ABBR[capitalize(p.graha)] ?? p.graha.slice(0, 2);\n\tconst retro = p.isRetrograde ? RETRO_MARK : '';\n\tif (\n\t\ttypeof p.longitude !== 'number' ||\n\t\t!Number.isFinite(p.longitude) ||\n\t\tisDivisionalPlacement(p, cellSign)\n\t) {\n\t\treturn `${abbr}${retro}`;\n\t}\n\tconst { degree } = longitudeToSignPosition(p.longitude);\n\treturn `${abbr} ${degree}\u00B0${retro}`;\n}\n\n/**\n * Full-detail tooltip surfaced via the SVG `<title>` for each planet label.\n * Includes planet name, the divisional placement (when the longitude does not\n * match the cell, the cell's rashi is preferred), the exact D1 longitude as\n * the original reference, nakshatra and pada, avastha, and the retrograde\n * flag. Surfaces on hover or long-press without crowding the cell.\n */\nfunction grahaTitle(p: PlacedGraha, cellSign: string): string {\n\tconst parts: string[] = [capitalize(p.graha)];\n\tconst divisional = isDivisionalPlacement(p, cellSign);\n\tif (divisional) {\n\t\tparts.push(`in ${cellSign}`);\n\t}\n\tif (typeof p.longitude === 'number' && Number.isFinite(p.longitude)) {\n\t\tconst sp = longitudeToSignPosition(p.longitude);\n\t\tconst minute = String(sp.minute).padStart(2, '0');\n\t\tparts.push(\n\t\t\tdivisional\n\t\t\t\t? `D1: ${sp.degree}\u00B0${minute}' ${sp.sign}`\n\t\t\t\t: `${sp.degree}\u00B0${minute}' ${sp.sign}`,\n\t\t);\n\t}\n\tif (p.nakshatra?.name) {\n\t\tconst pada = p.nakshatra.pada ? ` pada ${p.nakshatra.pada}` : '';\n\t\tparts.push(`${p.nakshatra.name}${pada}`);\n\t}\n\tif (p.awastha) parts.push(p.awastha);\n\tif (p.isRetrograde) parts.push('retrograde');\n\treturn parts.join(' \u00B7 ');\n}\n\n/**\n * Render a vertically centred stack of planet labels at `(cx, baseY)`, one\n * line per planet, with an SVG `<title>` per line carrying the full tooltip.\n * The stack auto-centres on `baseY` regardless of count so a 1-planet cell\n * and a 5-planet cell both look intentional.\n */\nfunction renderPlanetStack(\n\tplanets: PlacedGraha[],\n\tcellSign: string,\n\tcx: number,\n\tbaseY: number,\n\tlineHeight: number,\n): TemplateResult[] {\n\tconst startY = baseY - ((planets.length - 1) * lineHeight) / 2;\n\treturn planets.map((p, j) => {\n\t\tconst yPos = startY + j * lineHeight;\n\t\treturn svg`<text class=\"planet-text\" x=${cx} y=${yPos} text-anchor=\"middle\" dominant-baseline=\"central\">${grahaLabel(\n\t\t\tp,\n\t\t\tcellSign,\n\t\t)}<title>${grahaTitle(p, cellSign)}</title></text>`;\n\t});\n}\n\n/**\n * Bucket a graha-keyed `meta` map (D1 birth chart or D2..D60 divisional\n * chart) into the unified {@link KundliViewModel} the renderer consumes. The\n * Lagna entry is recognised by `graha === 'Lagna'` (or key `\"Lagna\"`) and\n * sets `lagnaSign`; it is not bucketed as a placed planet.\n *\n * @param meta - Graha-keyed map; missing rashi entries are skipped.\n * @param divisionLabel - Optional title written inside the chart centre.\n */\nexport function toKundliViewModel(\n\tmeta: Record<\n\t\tstring,\n\t\t{\n\t\t\tgraha?: string;\n\t\t\trashi?: string;\n\t\t\tlongitude?: number;\n\t\t\tnakshatra?: { name?: string; pada?: number; lord?: string };\n\t\t\tisRetrograde?: boolean;\n\t\t\tawastha?: string;\n\t\t}\n\t>,\n\tdivisionLabel?: string,\n): KundliViewModel {\n\tconst placements: Record<string, PlacedGraha[]> = {};\n\tfor (const sign of SIGNS_ORDER) placements[sign.toLowerCase()] = [];\n\tlet lagnaSign = '';\n\tfor (const [name, pos] of Object.entries(meta ?? {})) {\n\t\tconst rashiKey = (pos?.rashi ?? '').toLowerCase();\n\t\tif (name === 'Lagna' || pos?.graha === 'Lagna') {\n\t\t\tlagnaSign = RASHI_TO_SIGN[rashiKey] ?? '';\n\t\t\tcontinue;\n\t\t}\n\t\tif (!rashiKey || !(rashiKey in placements)) continue;\n\t\tplacements[rashiKey]?.push({\n\t\t\tgraha: pos.graha ?? name,\n\t\t\tlongitude: pos.longitude,\n\t\t\tnakshatra: pos.nakshatra,\n\t\t\tisRetrograde: pos.isRetrograde,\n\t\t\tawastha: pos.awastha,\n\t\t});\n\t}\n\treturn { lagnaSign, placements, divisionLabel };\n}\n\n// ---------------------------------------------------------------------------\n// South Indian: 4x4 grid with central 2x2 hollow. Signs are FIXED to cells\n// (Pisces top-left corner, clockwise); houses rotate from the Lagna cell.\n// ---------------------------------------------------------------------------\n\nconst SOUTH_CELL = INNER / 4; // 90\n\n/**\n * Sign-to-cell column/row in the South Indian fixed-sign grid. Pisces sits in\n * the top-left corner and the remaining signs proceed clockwise around the\n * 12 perimeter cells. (col, row) origin is the chart top-left.\n */\nconst SOUTH_CELL_GRID: Record<string, { col: number; row: number }> = {\n\tPisces: { col: 0, row: 0 },\n\tAries: { col: 1, row: 0 },\n\tTaurus: { col: 2, row: 0 },\n\tGemini: { col: 3, row: 0 },\n\tCancer: { col: 3, row: 1 },\n\tLeo: { col: 3, row: 2 },\n\tVirgo: { col: 3, row: 3 },\n\tLibra: { col: 2, row: 3 },\n\tScorpio: { col: 1, row: 3 },\n\tSagittarius: { col: 0, row: 3 },\n\tCapricorn: { col: 0, row: 2 },\n\tAquarius: { col: 0, row: 1 },\n};\n\nfunction southCellRect(sign: string): {\n\tx: number;\n\ty: number;\n\tw: number;\n\th: number;\n} {\n\tconst g = SOUTH_CELL_GRID[sign] ?? { col: 0, row: 0 };\n\treturn {\n\t\tx: MARGIN + g.col * SOUTH_CELL,\n\t\ty: MARGIN + g.row * SOUTH_CELL,\n\t\tw: SOUTH_CELL,\n\t\th: SOUTH_CELL,\n\t};\n}\n\n/**\n * South Indian frame: outer square, the two full-span grid lines, and the\n * partial inner lines that bound the central 2x2 hollow on each edge.\n */\nfunction renderSouthFrame(divisionLabel?: string): TemplateResult {\n\tconst a = MARGIN;\n\tconst b = MARGIN + SOUTH_CELL; // 110\n\tconst c = MARGIN + 2 * SOUTH_CELL; // 200\n\tconst d = MARGIN + 3 * SOUTH_CELL; // 290\n\tconst e = VIEW_BOX - MARGIN; // 380\n\treturn svg`\n\t\t<rect class=\"line\" x=${a} y=${a} width=${INNER} height=${INNER} stroke-width=\"1.5\" fill=\"none\" />\n\t\t<line class=\"line\" x1=${a} y1=${b} x2=${e} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${a} y1=${d} x2=${e} y2=${d} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${b} y1=${a} x2=${b} y2=${e} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${d} y1=${a} x2=${d} y2=${e} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${a} y1=${c} x2=${b} y2=${c} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${d} y1=${c} x2=${e} y2=${c} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${c} y1=${a} x2=${c} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${c} y1=${d} x2=${c} y2=${e} stroke-width=\"1\" />\n\t\t${\n\t\t\tdivisionLabel\n\t\t\t\t? svg`<text class=\"centre-label\" x=${CENTRE} y=${CENTRE} text-anchor=\"middle\" dominant-baseline=\"central\">${divisionLabel}</text>`\n\t\t\t\t: nothing\n\t\t}\n\t`;\n}\n\n/**\n * House number for a given sign relative to a Lagna sign. House 1 is the\n * Lagna cell; subsequent houses follow the zodiac in order. Returns 0 when\n * the Lagna sign is unknown so the caller can skip rendering the badge.\n */\nfunction houseNumberInSign(sign: string, lagnaSign: string): number {\n\tconst lagnaIdx = SIGNS_ORDER.findIndex((s) => s === lagnaSign);\n\tconst signIdx = SIGNS_ORDER.findIndex((s) => s === sign);\n\tif (lagnaIdx === -1 || signIdx === -1) return 0;\n\treturn ((signIdx - lagnaIdx + 12) % 12) + 1;\n}\n\nfunction renderSouthCell(\n\tsign: string,\n\tplanets: PlacedGraha[],\n\tisLagna: boolean,\n\thouseNum: number,\n): TemplateResult {\n\tconst r = southCellRect(sign);\n\tconst cx = r.x + r.w / 2;\n\tconst cy = r.y + r.h / 2;\n\tconst signAbbr = SIGN_ABBR[sign] ?? sign.slice(0, 2);\n\t// Inset the Lagna diagonal so it does not collide with the chart frame on\n\t// corner cells (Pisces, Gemini, Virgo, Sagittarius) or with the sign label\n\t// in the top-left of every cell.\n\tconst slashInset = 14;\n\treturn svg`\n\t\t<g class=${isLagna ? 'cell lagna' : 'cell'}>\n\t\t\t${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`\n\t\t\t\t\t\t<rect class=\"lagna-bg\" x=${r.x} y=${r.y} width=${r.w} height=${r.h} />\n\t\t\t\t\t\t<line class=\"lagna-slash\" x1=${r.x + r.w - slashInset} y1=${r.y + slashInset} x2=${r.x + slashInset} y2=${r.y + r.h - slashInset} stroke-width=\"1.2\" />\n\t\t\t\t\t`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t\t<text class=\"sign-text\" x=${r.x + 6} y=${r.y + 12} text-anchor=\"start\" dominant-baseline=\"central\">${signAbbr}</text>\n\t\t\t${\n\t\t\t\thouseNum > 0\n\t\t\t\t\t? svg`<text class=\"house-num\" x=${r.x + r.w - 6} y=${r.y + 12} text-anchor=\"end\" dominant-baseline=\"central\">${houseNum}</text>`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t\t${planets.length ? renderPlanetStack(planets, sign, cx, cy + 4, 14) : nothing}\n\t\t</g>\n\t`;\n}\n\nfunction renderSouthSvg(vm: KundliViewModel): TemplateResult {\n\tconst lagnaKey = vm.lagnaSign.toLowerCase();\n\treturn svg`\n\t\t${renderSouthFrame(vm.divisionLabel)}\n\t\t${SIGNS_ORDER.map((sign) =>\n\t\t\trenderSouthCell(\n\t\t\t\tsign,\n\t\t\t\tvm.placements[sign.toLowerCase()] ?? [],\n\t\t\t\tsign.toLowerCase() === lagnaKey,\n\t\t\t\thouseNumberInSign(sign, vm.lagnaSign),\n\t\t\t),\n\t\t)}\n\t`;\n}\n\n// ---------------------------------------------------------------------------\n// North Indian: outer square + inscribed midpoint diamond + both outer\n// diagonals. 12 cells: 4 cardinal diamonds + 8 corner triangles. Houses are\n// FIXED (H1 always top-centre); signs rotate from the Lagna sign.\n// ---------------------------------------------------------------------------\n\nconst NORTH_VERTICES = {\n\ttl: { x: MARGIN, y: MARGIN },\n\ttr: { x: VIEW_BOX - MARGIN, y: MARGIN },\n\tbr: { x: VIEW_BOX - MARGIN, y: VIEW_BOX - MARGIN },\n\tbl: { x: MARGIN, y: VIEW_BOX - MARGIN },\n\ttop: { x: CENTRE, y: MARGIN },\n\tright: { x: VIEW_BOX - MARGIN, y: CENTRE },\n\tbottom: { x: CENTRE, y: VIEW_BOX - MARGIN },\n\tleft: { x: MARGIN, y: CENTRE },\n\ttlMid: { x: CENTRE - INNER / 4, y: CENTRE - INNER / 4 },\n\ttrMid: { x: CENTRE + INNER / 4, y: CENTRE - INNER / 4 },\n\tbrMid: { x: CENTRE + INNER / 4, y: CENTRE + INNER / 4 },\n\tblMid: { x: CENTRE - INNER / 4, y: CENTRE + INNER / 4 },\n} as const;\n\n/**\n * Centroid (geometric mean) of an arbitrary set of polygon vertices. Used by\n * every cell that needs a label-anchor point; defining it once keeps the\n * North diamond and East triangle math identical.\n */\nfunction centroidOf(pts: Array<{ x: number; y: number }>): {\n\tx: number;\n\ty: number;\n} {\n\tconst x = pts.reduce((s, p) => s + p.x, 0) / pts.length;\n\tconst y = pts.reduce((s, p) => s + p.y, 0) / pts.length;\n\treturn { x, y };\n}\n\n/**\n * House centres for the North Indian diamond. Numbered 1..12 counter-clockwise\n * from the top diamond (H1 is always the ascendant cell). Centroids derived\n * from the canonical geometry above; do not edit by eye, recompute if you\n * change `VIEW_BOX` or `MARGIN`.\n */\nconst NORTH_HOUSE_CENTERS: Record<number, { x: number; y: number }> = {\n\t1: { x: CENTRE, y: NORTH_VERTICES.tlMid.y },\n\t2: centroidOf([NORTH_VERTICES.tl, NORTH_VERTICES.top, NORTH_VERTICES.tlMid]),\n\t3: centroidOf([NORTH_VERTICES.tl, NORTH_VERTICES.left, NORTH_VERTICES.tlMid]),\n\t4: { x: NORTH_VERTICES.tlMid.x, y: CENTRE },\n\t5: centroidOf([NORTH_VERTICES.bl, NORTH_VERTICES.left, NORTH_VERTICES.blMid]),\n\t6: centroidOf([\n\t\tNORTH_VERTICES.bl,\n\t\tNORTH_VERTICES.bottom,\n\t\tNORTH_VERTICES.blMid,\n\t]),\n\t7: { x: CENTRE, y: NORTH_VERTICES.blMid.y },\n\t8: centroidOf([\n\t\tNORTH_VERTICES.br,\n\t\tNORTH_VERTICES.bottom,\n\t\tNORTH_VERTICES.brMid,\n\t]),\n\t9: centroidOf([\n\t\tNORTH_VERTICES.br,\n\t\tNORTH_VERTICES.right,\n\t\tNORTH_VERTICES.brMid,\n\t]),\n\t10: { x: NORTH_VERTICES.brMid.x, y: CENTRE },\n\t11: centroidOf([\n\t\tNORTH_VERTICES.tr,\n\t\tNORTH_VERTICES.right,\n\t\tNORTH_VERTICES.trMid,\n\t]),\n\t12: centroidOf([NORTH_VERTICES.tr, NORTH_VERTICES.top, NORTH_VERTICES.trMid]),\n};\n\n/**\n * Rashi number (1..12, Aries=1) occupying the given house when the Lagna sits\n * in `lagnaSign`. House 1 is the Lagna sign; subsequent houses follow the\n * zodiac in order.\n */\nfunction rashiInHouse(houseNum: number, lagnaSign: string): number {\n\tconst lagnaIdx = SIGNS_ORDER.findIndex((s) => s === lagnaSign);\n\tif (lagnaIdx === -1) return houseNum;\n\treturn ((lagnaIdx + houseNum - 1) % 12) + 1;\n}\n\nfunction renderNorthFrame(divisionLabel?: string): TemplateResult {\n\tconst { tl, tr, br, bl, top, right, bottom, left } = NORTH_VERTICES;\n\treturn svg`\n\t\t<rect class=\"line\" x=${tl.x} y=${tl.y} width=${INNER} height=${INNER} stroke-width=\"1.5\" fill=\"none\" />\n\t\t<polygon class=\"line\" points=\"${top.x},${top.y} ${right.x},${right.y} ${bottom.x},${bottom.y} ${left.x},${left.y}\" stroke-width=\"1\" fill=\"none\" />\n\t\t<line class=\"line\" x1=${tl.x} y1=${tl.y} x2=${br.x} y2=${br.y} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${tr.x} y1=${tr.y} x2=${bl.x} y2=${bl.y} stroke-width=\"1\" />\n\t\t${\n\t\t\tdivisionLabel\n\t\t\t\t? svg`<text class=\"centre-label\" x=${CENTRE} y=${CENTRE} text-anchor=\"middle\" dominant-baseline=\"central\">${divisionLabel}</text>`\n\t\t\t\t: nothing\n\t\t}\n\t`;\n}\n\nfunction renderNorthCell(\n\thouseNum: number,\n\trashiNum: number,\n\tsign: string,\n\tplanets: PlacedGraha[],\n\tisLagna: boolean,\n): TemplateResult {\n\tconst c = NORTH_HOUSE_CENTERS[houseNum];\n\tif (!c) return svg``;\n\t// Tight cells (H2/3/5/6/8/9/11/12 corner triangles) clip the rasi number\n\t// when it sits too high above the centroid. Clamp the upward offset based\n\t// on the cell's distance from the chart vertical centre so the label\n\t// always stays comfortably inside its triangle or diamond.\n\tconst rashiOffsetY = Math.min(14, Math.abs(c.y - CENTRE) * 0.45 + 6);\n\tconst ascOffsetY = rashiOffsetY + 12;\n\treturn svg`\n\t\t<g class=${isLagna ? 'cell lagna' : 'cell'}>\n\t\t\t<text class=\"rashi-num\" x=${c.x} y=${c.y - rashiOffsetY} text-anchor=\"middle\" dominant-baseline=\"central\">${rashiNum}</text>\n\t\t\t${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<text class=\"lagna-marker\" x=${c.x} y=${c.y - ascOffsetY} text-anchor=\"middle\" dominant-baseline=\"central\">Asc</text>`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t\t${planets.length ? renderPlanetStack(planets, sign, c.x, c.y + 8, 12) : nothing}\n\t\t</g>\n\t`;\n}\n\nfunction renderNorthSvg(vm: KundliViewModel): TemplateResult {\n\tconst lagnaSign = vm.lagnaSign || 'Aries';\n\treturn svg`\n\t\t${renderNorthFrame(vm.divisionLabel)}\n\t\t${Array.from({ length: 12 }, (_, i) => {\n\t\t\tconst houseNum = i + 1;\n\t\t\tconst rashiNum = rashiInHouse(houseNum, lagnaSign);\n\t\t\tconst sign = SIGNS_ORDER[rashiNum - 1] ?? 'Aries';\n\t\t\treturn renderNorthCell(\n\t\t\t\thouseNum,\n\t\t\t\trashiNum,\n\t\t\t\tsign,\n\t\t\t\tvm.placements[sign.toLowerCase()] ?? [],\n\t\t\t\thouseNum === 1,\n\t\t\t);\n\t\t})}\n\t`;\n}\n\n// ---------------------------------------------------------------------------\n// East Indian (Bengali / Maithili): 3x3 underlying grid, 4 edge rectangles +\n// 4 corner cells each split by a diagonal from the outer chart corner to the\n// inner corner of the centre cell. Aries fixed top-centre; signs proceed\n// counter-clockwise. Houses rotate from the Lagna.\n// ---------------------------------------------------------------------------\n\nconst EAST_CELL = INNER / 3; // 120\n\ninterface EastCell {\n\t/** Vertices of the cell polygon, in viewBox units. */\n\tpoints: Array<{ x: number; y: number }>;\n\t/** Visual centroid for label placement. */\n\tcentroid: { x: number; y: number };\n}\n\nfunction eastCells(): Record<string, EastCell> {\n\tconst a = MARGIN; // 20\n\tconst b = MARGIN + EAST_CELL; // 140\n\tconst c = MARGIN + 2 * EAST_CELL; // 260\n\tconst d = VIEW_BOX - MARGIN; // 380\n\tconst aries = [\n\t\t{ x: b, y: a },\n\t\t{ x: c, y: a },\n\t\t{ x: c, y: b },\n\t\t{ x: b, y: b },\n\t];\n\tconst cancer = [\n\t\t{ x: a, y: b },\n\t\t{ x: b, y: b },\n\t\t{ x: b, y: c },\n\t\t{ x: a, y: c },\n\t];\n\tconst libra = [\n\t\t{ x: b, y: c },\n\t\t{ x: c, y: c },\n\t\t{ x: c, y: d },\n\t\t{ x: b, y: d },\n\t];\n\tconst capricorn = [\n\t\t{ x: c, y: b },\n\t\t{ x: d, y: b },\n\t\t{ x: d, y: c },\n\t\t{ x: c, y: c },\n\t];\n\tconst taurus = [\n\t\t{ x: a, y: a },\n\t\t{ x: b, y: a },\n\t\t{ x: b, y: b },\n\t];\n\tconst gemini = [\n\t\t{ x: a, y: a },\n\t\t{ x: b, y: b },\n\t\t{ x: a, y: b },\n\t];\n\tconst leo = [\n\t\t{ x: a, y: c },\n\t\t{ x: b, y: c },\n\t\t{ x: a, y: d },\n\t];\n\tconst virgo = [\n\t\t{ x: b, y: c },\n\t\t{ x: b, y: d },\n\t\t{ x: a, y: d },\n\t];\n\tconst scorpio = [\n\t\t{ x: c, y: c },\n\t\t{ x: c, y: d },\n\t\t{ x: d, y: d },\n\t];\n\tconst sagittarius = [\n\t\t{ x: c, y: c },\n\t\t{ x: d, y: d },\n\t\t{ x: d, y: c },\n\t];\n\tconst aquarius = [\n\t\t{ x: d, y: a },\n\t\t{ x: d, y: b },\n\t\t{ x: c, y: b },\n\t];\n\tconst pisces = [\n\t\t{ x: c, y: a },\n\t\t{ x: d, y: a },\n\t\t{ x: c, y: b },\n\t];\n\tconst polys = {\n\t\tAries: aries,\n\t\tTaurus: taurus,\n\t\tGemini: gemini,\n\t\tCancer: cancer,\n\t\tLeo: leo,\n\t\tVirgo: virgo,\n\t\tLibra: libra,\n\t\tScorpio: scorpio,\n\t\tSagittarius: sagittarius,\n\t\tCapricorn: capricorn,\n\t\tAquarius: aquarius,\n\t\tPisces: pisces,\n\t} as const;\n\tconst out: Record<string, EastCell> = {};\n\tfor (const [sign, points] of Object.entries(polys)) {\n\t\tout[sign] = { points: [...points], centroid: centroidOf(points) };\n\t}\n\treturn out;\n}\n\nconst EAST_CELLS = eastCells();\n\nfunction renderEastFrame(divisionLabel?: string): TemplateResult {\n\tconst a = MARGIN;\n\tconst b = MARGIN + EAST_CELL;\n\tconst c = MARGIN + 2 * EAST_CELL;\n\tconst d = VIEW_BOX - MARGIN;\n\treturn svg`\n\t\t<rect class=\"line\" x=${a} y=${a} width=${INNER} height=${INNER} stroke-width=\"1.5\" fill=\"none\" />\n\t\t<line class=\"line\" x1=${a} y1=${b} x2=${b} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${c} y1=${b} x2=${d} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${a} y1=${c} x2=${b} y2=${c} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${c} y1=${c} x2=${d} y2=${c} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${b} y1=${a} x2=${b} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${b} y1=${c} x2=${b} y2=${d} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${c} y1=${a} x2=${c} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${c} y1=${c} x2=${c} y2=${d} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${a} y1=${a} x2=${b} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${d} y1=${a} x2=${c} y2=${b} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${d} y1=${d} x2=${c} y2=${c} stroke-width=\"1\" />\n\t\t<line class=\"line\" x1=${a} y1=${d} x2=${b} y2=${c} stroke-width=\"1\" />\n\t\t${\n\t\t\tdivisionLabel\n\t\t\t\t? svg`<text class=\"centre-label\" x=${CENTRE} y=${CENTRE} text-anchor=\"middle\" dominant-baseline=\"central\">${divisionLabel}</text>`\n\t\t\t\t: nothing\n\t\t}\n\t`;\n}\n\nfunction renderEastCell(\n\tsign: string,\n\tplanets: PlacedGraha[],\n\tisLagna: boolean,\n\thouseNum: number,\n): TemplateResult {\n\tconst cell = EAST_CELLS[sign];\n\tif (!cell) return svg``;\n\tconst { centroid: cen, points } = cell;\n\tconst signAbbr = SIGN_ABBR[sign] ?? sign.slice(0, 2);\n\tconst polyPoints = points.map((p) => `${p.x},${p.y}`).join(' ');\n\treturn svg`\n\t\t<g class=${isLagna ? 'cell lagna' : 'cell'}>\n\t\t\t${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<polygon class=\"lagna-bg\" points=${polyPoints} />`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t\t<text class=\"sign-text\" x=${cen.x} y=${cen.y - 16} text-anchor=\"middle\" dominant-baseline=\"central\">${signAbbr}</text>\n\t\t\t${\n\t\t\t\thouseNum > 0\n\t\t\t\t\t? svg`<text class=\"house-num\" x=${cen.x + 18} y=${cen.y - 16} text-anchor=\"start\" dominant-baseline=\"central\">${houseNum}</text>`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t\t${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<text class=\"lagna-marker\" x=${cen.x} y=${cen.y - 30} text-anchor=\"middle\" dominant-baseline=\"central\">Asc</text>`\n\t\t\t\t\t: nothing\n\t\t\t}\n\t\t\t${planets.length ? renderPlanetStack(planets, sign, cen.x, cen.y + 4, 12) : nothing}\n\t\t</g>\n\t`;\n}\n\nfunction renderEastSvg(vm: KundliViewModel): TemplateResult {\n\tconst lagnaKey = vm.lagnaSign.toLowerCase();\n\treturn svg`\n\t\t${renderEastFrame(vm.divisionLabel)}\n\t\t${SIGNS_ORDER.map((sign) =>\n\t\t\trenderEastCell(\n\t\t\t\tsign,\n\t\t\t\tvm.placements[sign.toLowerCase()] ?? [],\n\t\t\t\tsign.toLowerCase() === lagnaKey,\n\t\t\t\thouseNumberInSign(sign, vm.lagnaSign),\n\t\t\t),\n\t\t)}\n\t`;\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Render the kundli body for the requested style. Returns the SVG inner\n * content; the caller wraps it in an `<svg>` element with the canonical\n * viewBox `0 0 400 400` and applies its own theming CSS.\n */\nexport function renderKundliSvg(\n\tvm: KundliViewModel,\n\tstyle: ChartStyle,\n): TemplateResult {\n\tswitch (style) {\n\t\tcase 'north':\n\t\t\treturn renderNorthSvg(vm);\n\t\tcase 'east':\n\t\t\treturn renderEastSvg(vm);\n\t\tdefault:\n\t\t\treturn renderSouthSvg(vm);\n\t}\n}\n\n/**\n * Render a WAI-ARIA-compliant tablist that lets the end user switch between\n * South / North / East kundli styles at runtime. The hosting component owns\n * the `chartStyle` state; this helper renders the buttons and wires the\n * arrow-key navigation plus click handler.\n *\n * @param active - The currently selected style.\n * @param setStyle - Callback the host component uses to update its state.\n */\nexport function renderKundliStyleTablist(\n\tactive: ChartStyle,\n\tsetStyle: (next: ChartStyle) => void,\n): TemplateResult {\n\tconst onKeyDown = (e: KeyboardEvent) => {\n\t\tconst idx = CHART_STYLES.findIndex((s) => s.id === active);\n\t\tif (e.key === 'ArrowRight') {\n\t\t\te.preventDefault();\n\t\t\tconst next = CHART_STYLES[(idx + 1) % CHART_STYLES.length];\n\t\t\tif (next) setStyle(next.id);\n\t\t} else if (e.key === 'ArrowLeft') {\n\t\t\te.preventDefault();\n\t\t\tconst next =\n\t\t\t\tCHART_STYLES[(idx - 1 + CHART_STYLES.length) % CHART_STYLES.length];\n\t\t\tif (next) setStyle(next.id);\n\t\t}\n\t};\n\treturn html`<div\n\t\tclass=\"kundli-tablist\"\n\t\trole=\"tablist\"\n\t\taria-label=\"Kundli style\"\n\t\t@keydown=${onKeyDown}\n\t>\n\t\t${CHART_STYLES.map(\n\t\t\t(s) => html`<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"kundli-tab\"\n\t\t\t\trole=\"tab\"\n\t\t\t\tid=\"kundli-tab-${s.id}\"\n\t\t\t\taria-selected=${active === s.id ? 'true' : 'false'}\n\t\t\t\ttabindex=${active === s.id ? '0' : '-1'}\n\t\t\t\t@click=${() => setStyle(s.id)}\n\t\t\t>\n\t\t\t\t${s.label}\n\t\t\t</button>`,\n\t\t)}\n\t</div>`;\n}\n", "/**\n * Math helpers for converting raw ecliptic longitude decimals into the\n * sign / degree / minute / second triplet used across chart components.\n */\n\nimport { SIGNS_ORDER } from '../tokens/index.js';\n\nexport interface SignPosition {\n\tsign: string;\n\tsignIndex: number;\n\tdegree: number;\n\tminute: number;\n\tsecond: number;\n}\n\n/**\n * Wrap longitude into [0, 360) so negative or out-of-range values still\n * resolve to a real sign. Robust to wonky upstream data.\n */\nexport function normalizeLongitude(lon: number): number {\n\tconst wrapped = lon % 360;\n\treturn wrapped < 0 ? wrapped + 360 : wrapped;\n}\n\n/**\n * Convert decimal ecliptic longitude (0-360) into sign/degree/minute/second.\n * Used by every chart wheel and aspect table.\n */\nexport function longitudeToSignPosition(longitude: number): SignPosition {\n\tconst lon = normalizeLongitude(longitude);\n\tconst signIndex = Math.floor(lon / 30) % 12;\n\tconst within = lon % 30;\n\tconst degree = Math.floor(within);\n\tconst minuteFloat = (within - degree) * 60;\n\tconst minute = Math.floor(minuteFloat);\n\tconst second = Math.round((minuteFloat - minute) * 60);\n\treturn {\n\t\tsign: SIGNS_ORDER[signIndex] ?? 'Aries',\n\t\tsignIndex,\n\t\tdegree,\n\t\tminute,\n\t\tsecond,\n\t};\n}\n\n/** Compact display string like \"12\u00B0 Leo 34'\". Used in chart labels. */\nexport function formatSignPosition(longitude: number): string {\n\tconst { sign, degree, minute } = longitudeToSignPosition(longitude);\n\treturn `${degree}\u00B0 ${sign} ${String(minute).padStart(2, '0')}'`;\n}\n\n/**\n * The point diametrically opposite a longitude (e.g. Descendant from\n * Ascendant, IC from MC). Exact derivation, always 180 degrees away.\n */\nexport function oppositePoint(longitude: number): number {\n\treturn normalizeLongitude(longitude + 180);\n}\n\n/**\n * Midpoint of the forward arc from `start` to `end` (both ecliptic\n * longitudes). Handles the 360/0 wrap, so a house spanning 350 to 20 degrees\n * yields a midpoint of 5, not 185. Used to place house numbers between two\n * cusps regardless of how unequal the house is.\n */\nexport function arcMidpoint(start: number, end: number): number {\n\tconst s = normalizeLongitude(start);\n\tlet span = normalizeLongitude(end) - s;\n\tif (span < 0) span += 360;\n\treturn normalizeLongitude(s + span / 2);\n}\n\n/** Polar to cartesian for SVG wheel positioning. Angle in degrees, 0 at 3 o'clock. */\nexport function polarToCartesian(\n\tcx: number,\n\tcy: number,\n\tradius: number,\n\tangleDeg: number,\n): { x: number; y: number } {\n\tconst angleRad = (angleDeg * Math.PI) / 180;\n\treturn {\n\t\tx: cx + radius * Math.cos(angleRad),\n\t\ty: cy + radius * Math.sin(angleRad),\n\t};\n}\n", "/**\n * Shared string helpers used across components. Single source of truth so the\n * same formatting rules apply to every key/label/title that surfaces in the\n * shadow tree.\n *\n * - `capitalize`: title-cases the first character, lowercases the rest. Used\n * when matching API-supplied planet/sign names against the glyph maps in\n * `tokens/index.ts`, which use canonical TitleCase keys.\n * - `humanize`: turns an API key (`birth_date`, `birthDate`, `mahadasha-end`)\n * into a label suitable for display (\"Birth date\", \"Mahadasha end\").\n */\n\nexport function capitalize(s: string): string {\n\tif (!s) return '';\n\treturn s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nexport function humanize(s: string): string {\n\treturn s\n\t\t.replace(/[_-]+/g, ' ')\n\t\t.replace(/([a-z])([A-Z])/g, '$1 $2')\n\t\t.replace(/^\\w/, (c) => c.toUpperCase());\n}\n", "import { css } from 'lit';\n\n/**\n * Shared CSS for every kundli renderer (`<roxy-vedic-kundli>`,\n * `<roxy-divisional-chart>`, and any future `<roxy-navamsa-chart>`). Centralises\n * the SVG layout (responsive viewBox + aspect ratio), the line/text classes,\n * and the Lagna highlight so the three components stay visually identical.\n *\n * @remarks Font sizes are written in viewBox user units (the chart is 400\u00D7400\n * inside a 1:1 aspect-ratio container), so they scale linearly from a 320px\n * phone surface to a wall projector without raster loss. The Lagna palette\n * tracks `--roxy-accent` so host themes flow through unchanged.\n */\nexport const kundliStyles = css`\n\t.wrap {\n\t\tdisplay: grid;\n\t\tgap: var(--roxy-space-md, 1rem);\n\t}\n\t.header {\n\t\tdisplay: flex;\n\t\tflex-wrap: wrap;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tgap: var(--roxy-space-sm, 0.5rem);\n\t}\n\t.title {\n\t\tfont-size: var(--roxy-text-lg, 1.125rem);\n\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t\tmargin: 0;\n\t}\n\t.kundli-tablist {\n\t\tdisplay: inline-flex;\n\t\tgap: 2px;\n\t\tborder-bottom: 2px solid var(--roxy-border, #e4e4e7);\n\t}\n\t.kundli-tab {\n\t\tpadding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);\n\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\tbackground: none;\n\t\tborder: none;\n\t\tborder-bottom: 2px solid transparent;\n\t\tmargin-bottom: -2px;\n\t\tcursor: pointer;\n\t\tcolor: var(--roxy-muted, #71717a);\n\t\tfont-family: inherit;\n\t\ttransition: color var(--roxy-motion-duration, 200ms)\n\t\t\tvar(--roxy-motion-easing, ease);\n\t}\n\t.kundli-tab[aria-selected='true'] {\n\t\tcolor: var(--roxy-accent-fg, #b45309);\n\t\tborder-bottom-color: var(--roxy-accent, #f59e0b);\n\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t}\n\t.kundli-tab:hover:not([aria-selected='true']) {\n\t\tcolor: var(--roxy-fg, #0a0a0a);\n\t}\n\t.kundli-tab:focus-visible {\n\t\toutline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));\n\t\toutline-offset: 2px;\n\t\tborder-radius: 4px;\n\t}\n\tsvg {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\tmax-width: 560px;\n\t\taspect-ratio: 1 / 1;\n\t\theight: auto;\n\t\tmargin: 0 auto;\n\t}\n\t.line {\n\t\tfill: transparent;\n\t\tstroke: var(--roxy-border, #d4d4d8);\n\t}\n\t.sign-text {\n\t\tfill: var(--roxy-muted, #71717a);\n\t\tfont-size: 11px;\n\t\tfont-weight: 500;\n\t\tfont-family: var(--roxy-font-sans);\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.04em;\n\t}\n\t.rashi-num {\n\t\tfill: var(--roxy-muted, #71717a);\n\t\tfont-size: 12px;\n\t\tfont-weight: 500;\n\t\tfont-family: var(--roxy-font-sans);\n\t}\n\t.house-num {\n\t\tfill: var(--roxy-accent-fg, #b45309);\n\t\tfont-size: 11px;\n\t\tfont-weight: 600;\n\t\tfont-family: var(--roxy-font-sans);\n\t\topacity: 0.85;\n\t}\n\t.planet-text {\n\t\tfill: var(--roxy-fg, #0a0a0a);\n\t\tfont-size: 13px;\n\t\tfont-weight: 600;\n\t\tfont-family: var(--roxy-font-sans);\n\t}\n\t.centre-label {\n\t\tfill: var(--roxy-muted, #71717a);\n\t\tfont-size: 14px;\n\t\tfont-weight: 600;\n\t\tfont-family: var(--roxy-font-sans);\n\t\tletter-spacing: 0.02em;\n\t}\n\t.lagna-marker {\n\t\tfill: var(--roxy-accent-fg, #b45309);\n\t\tfont-size: 10px;\n\t\tfont-weight: 700;\n\t\tfont-family: var(--roxy-font-sans);\n\t\tletter-spacing: 0.08em;\n\t\ttext-transform: uppercase;\n\t}\n\t.lagna-bg {\n\t\tfill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 14%, transparent);\n\t}\n\t.lagna-slash {\n\t\tstroke: var(--roxy-accent, #f59e0b);\n\t\tstroke-linecap: round;\n\t\topacity: 0.7;\n\t}\n`;\n"],
5
- "mappings": "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",
6
- "names": ["css", "html", "nothing", "css", "html", "nothing", "css"]
3
+ "sources": ["../../src/components/divisional-chart.ts", "../../src/tokens/index.ts", "../../src/utils/base-styles.ts", "../../src/utils/kundli-render.ts", "../../src/utils/degree.ts", "../../src/utils/string.ts", "../../src/utils/tablist.ts", "../../src/utils/kundli-styles.ts", "../../src/utils/markup-data.ts"],
4
+ "sourcesContent": ["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { PLANET_GLYPH } from '../tokens/index.js';\nimport type { DivisionalChartResponse } from '../types/index.js';\nimport { baseStyles } from '../utils/base-styles.js';\nimport {\n\ttype ChartStyle,\n\ttype KundliViewModel,\n\trenderKundliStyleTablist,\n\trenderKundliSvg,\n\ttoKundliViewModel,\n} from '../utils/kundli-render.js';\nimport { kundliStyles } from '../utils/kundli-styles.js';\nimport { MarkupDataController } from '../utils/markup-data.js';\nimport { tablistStyles } from '../utils/tablist.js';\n\n/**\n * Divisional chart renderer (D2-D60). Accepts a DivisionalChartResponse and\n * renders the same South / North / East kundli grid as the birth chart, plus\n * division metadata and Vargottama planet pills. A visible tablist lets the\n * end user switch styles at runtime. The varga response carries a graha-keyed\n * `chart.meta` map (no per-rashi buckets), so houses are bucketed from that\n * map.\n */\n@customElement('roxy-divisional-chart')\nexport class RoxyDivisionalChart extends LitElement {\n\tstatic styles = [\n\t\tbaseStyles,\n\t\tkundliStyles,\n\t\ttablistStyles,\n\t\tcss`.division-meta{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);margin:0}.significance{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);border-left:2px solid var(--roxy-border,#e4e4e7);padding-left:var(--roxy-space-sm,.5rem);margin:0}.vargottama-row{gap:var(--roxy-space-xs,.25rem);flex-wrap:wrap;align-items:center;display:flex}.vargottama-label{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);margin-right:var(--roxy-space-xs,.25rem);font-weight:500}.vargottama-pill{font-size:var(--roxy-text-sm,.875rem);background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 22%, transparent);color:var(--roxy-fg,#0a0a0a);border:1px solid color-mix(in srgb, var(--roxy-accent,#f59e0b) 45%, transparent);border-radius:999px;align-items:center;gap:.2em;padding:.15em .6em;font-weight:600;display:inline-flex}`,\n\t];\n\n\tconstructor() {\n\t\tsuper();\n\t\t// Enables hydrating `data` from a direct-child\n\t\t// <script type=\"application/json\" class=\"roxy-data\"> for server-rendered\n\t\t// and cached consumers. The JavaScript `data` property still wins.\n\t\tnew MarkupDataController(this);\n\t}\n\n\t@property({ attribute: false })\n\tdata: DivisionalChartResponse | null = null;\n\n\t@property({ type: String, reflect: true, attribute: 'chart-style' })\n\tchartStyle: ChartStyle = 'north';\n\n\tprivate setStyle = (next: ChartStyle) => {\n\t\tthis.chartStyle = next;\n\t};\n\n\tprivate viewModel(): KundliViewModel | null {\n\t\tif (!this.data?.chart?.meta) return null;\n\t\tconst { division } = this.data;\n\t\tconst label = `D${division.number} ${division.name}`;\n\t\treturn toKundliViewModel(this.data.chart.meta, label);\n\t}\n\n\trender() {\n\t\tconst vm = this.viewModel();\n\t\tif (!this.data || !vm)\n\t\t\treturn html`<div class=\"roxy-empty\" role=\"status\">No divisional chart data</div>`;\n\n\t\tconst { division, vargottama } = this.data;\n\n\t\treturn html`<div class=\"wrap\"><div class=\"header\"><div><h2 class=\"title\">D${division.number} ${division.name} ${\n\t\t\t\t\t\t\tdivision.sanskritName && division.sanskritName !== division.name\n\t\t\t\t\t\t\t\t? html`<span class=\"division-meta\">\u00B7 ${division.sanskritName}</span>`\n\t\t\t\t\t\t\t\t: nothing\n\t\t\t\t\t\t}</h2>${\n\t\t\t\t\t\tdivision.significance\n\t\t\t\t\t\t\t? html`<p class=\"significance\">${division.significance}</p>`\n\t\t\t\t\t\t\t: nothing\n\t\t\t\t\t}</div>${renderKundliStyleTablist(this.chartStyle, this.setStyle)}</div><svg viewBox=\"0 0 400 400\" preserveAspectRatio=\"xMidYMid meet\" role=\"img\" aria-label=\"D${division.number} ${division.name} divisional chart with twelve sign houses\"><title>D${division.number} ${division.name}</title>${renderKundliSvg(vm, this.chartStyle)}</svg> ${\n\t\t\t\tvargottama && vargottama.length > 0\n\t\t\t\t\t? html`<div class=\"vargottama-row\" role=\"list\" aria-label=\"Vargottama planets\"><span class=\"vargottama-label\">Vargottama:</span> ${vargottama.map(\n\t\t\t\t\t\t\t(planet) =>\n\t\t\t\t\t\t\t\thtml`<span class=\"vargottama-pill\" role=\"listitem\">${PLANET_GLYPH[planet] ?? ''} ${planet}</span>`,\n\t\t\t\t\t\t)}</div>`\n\t\t\t\t\t: nothing\n\t\t\t}</div>`;\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'roxy-divisional-chart': RoxyDivisionalChart;\n\t}\n}\n", "/**\n * Symbol constants used across components. Single source of truth so chart\n * wheels, card headers, hexagram displays, and panchang tables stay visually\n * consistent.\n */\n\nexport const PLANET_GLYPH: Record<string, string> = {\n\tSun: '\u2609',\n\tMoon: '\u263D',\n\tMercury: '\u263F',\n\tVenus: '\u2640',\n\tEarth: '\u2641',\n\tMars: '\u2642',\n\tJupiter: '\u2643',\n\tSaturn: '\u2644',\n\tUranus: '\u2645',\n\tNeptune: '\u2646',\n\tPluto: '\u2647',\n\tRahu: '\u260A',\n\tKetu: '\u260B',\n\tAscendant: 'Asc',\n\tLagna: 'La',\n\tNorthNode: '\u260A',\n\tSouthNode: '\u260B',\n\t'North node': '\u260A',\n\t'South node': '\u260B',\n\tChiron: '\u26B7',\n\tLilith: '\u26B8',\n\t'Black moon lilith': '\u26B8',\n};\n\nexport const PLANET_ABBR: Record<string, string> = {\n\tSun: 'Su',\n\tMoon: 'Mo',\n\tMercury: 'Me',\n\tVenus: 'Ve',\n\tMars: 'Ma',\n\tJupiter: 'Ju',\n\tSaturn: 'Sa',\n\tUranus: 'Ur',\n\tNeptune: 'Ne',\n\tPluto: 'Pl',\n\tRahu: 'Ra',\n\tKetu: 'Ke',\n\tAscendant: 'Asc',\n\tLagna: 'La',\n};\n\nexport const SIGN_GLYPH: Record<string, string> = {\n\tAries: '\u2648',\n\tTaurus: '\u2649',\n\tGemini: '\u264A',\n\tCancer: '\u264B',\n\tLeo: '\u264C',\n\tVirgo: '\u264D',\n\tLibra: '\u264E',\n\tScorpio: '\u264F',\n\tSagittarius: '\u2650',\n\tCapricorn: '\u2651',\n\tAquarius: '\u2652',\n\tPisces: '\u2653',\n};\n\nexport const SIGN_ABBR: Record<string, string> = {\n\tAries: 'Ar',\n\tTaurus: 'Ta',\n\tGemini: 'Ge',\n\tCancer: 'Cn',\n\tLeo: 'Le',\n\tVirgo: 'Vi',\n\tLibra: 'Li',\n\tScorpio: 'Sc',\n\tSagittarius: 'Sg',\n\tCapricorn: 'Cp',\n\tAquarius: 'Aq',\n\tPisces: 'Pi',\n};\n\nexport const SIGNS_ORDER = [\n\t'Aries',\n\t'Taurus',\n\t'Gemini',\n\t'Cancer',\n\t'Leo',\n\t'Virgo',\n\t'Libra',\n\t'Scorpio',\n\t'Sagittarius',\n\t'Capricorn',\n\t'Aquarius',\n\t'Pisces',\n] as const;\n\n/**\n * Lowercase rashi keys in canonical zodiac order. Derived from `SIGNS_ORDER`\n * so the two stay in lockstep. The /vedic-astrology/birth-chart response\n * carries planet buckets keyed by these names.\n */\nexport const RASHI_KEYS = SIGNS_ORDER.map((s) =>\n\ts.toLowerCase(),\n) as readonly Lowercase<(typeof SIGNS_ORDER)[number]>[];\n\n/** Aspect symbols. Used by synastry and natal chart aspect tables. */\nexport const ASPECT_SYMBOL: Record<string, string> = {\n\tconjunction: '\u260C',\n\topposition: '\u260D',\n\ttrine: '\u25B3',\n\tsquare: '\u25A1',\n\tsextile: '\u2731',\n\tquincunx: '\u22BB',\n\tsemisextile: '\u22BC',\n};\n\n/** Trigrams used by I Ching hexagrams. Eight trigrams compose 64 hexagrams. */\nexport const TRIGRAM_GLYPH: Record<string, string> = {\n\theaven: '\u2630',\n\tlake: '\u2631',\n\tfire: '\u2632',\n\tthunder: '\u2633',\n\twind: '\u2634',\n\twater: '\u2635',\n\tmountain: '\u2636',\n\tearth: '\u2637',\n\tHeaven: '\u2630',\n\tLake: '\u2631',\n\tFire: '\u2632',\n\tThunder: '\u2633',\n\tWind: '\u2634',\n\tWater: '\u2635',\n\tMountain: '\u2636',\n\tEarth: '\u2637',\n};\n\n/** Moon phase emoji set. Used by moon phase card. */\nexport const MOON_PHASE_EMOJI: Record<string, string> = {\n\t'new moon': '\uD83C\uDF11',\n\t'waxing crescent': '\uD83C\uDF12',\n\t'first quarter': '\uD83C\uDF13',\n\t'waxing gibbous': '\uD83C\uDF14',\n\t'full moon': '\uD83C\uDF15',\n\t'waning gibbous': '\uD83C\uDF16',\n\t'last quarter': '\uD83C\uDF17',\n\t'waning crescent': '\uD83C\uDF18',\n};\n", "import { css } from 'lit';\n\n/**\n * Shared host styles every component pulls in. Sets default font, color,\n * container query support, and the entry fade-in.\n */\nexport const baseStyles = css`:host{font-family:var(--roxy-font-sans,system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-base,1rem);line-height:var(--roxy-leading-normal,1.5);animation:roxy-fade-in var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1)) both;background:0 0;display:block;container-type:inline-size}*,:before,:after{box-sizing:border-box}@keyframes roxy-fade-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){:host{animation:none}}.roxy-skeleton{background:linear-gradient(90deg, var(--roxy-border,#e4e4e7) 0%, color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent) 50%, var(--roxy-border,#e4e4e7) 100%);border-radius:var(--roxy-radius-md,8px);background-size:200% 100%;animation:1.4s ease-in-out infinite roxy-shimmer}@keyframes roxy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.roxy-skeleton{animation:none}}.roxy-empty{padding:var(--roxy-space-lg,1.5rem);color:var(--roxy-muted,#71717a);text-align:center;font-size:var(--roxy-text-sm,.875rem)}:host(:focus-within) .roxy-card{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}:host{font-variant-emoji:text}`;\n", "import type { TemplateResult } from 'lit';\nimport { nothing, svg } from 'lit';\nimport { PLANET_ABBR, SIGN_ABBR, SIGNS_ORDER } from '../tokens/index.js';\nimport { longitudeToSignPosition } from './degree.js';\nimport { capitalize } from './string.js';\nimport { renderTablist } from './tablist.js';\n\n/**\n * Canonical viewBox geometry for every kundli style. The chart is drawn into a\n * 360-unit square centred in a 400-unit viewBox, leaving a 20-unit gutter for\n * outer labels. All coordinates below are derived from these constants; change\n * them and every cell relocates correctly.\n *\n * @remarks SVG is vector-only and scales without raster loss, so the chart\n * remains crisp from a phone screen to a wall projector. Hosts size the chart\n * by setting `width` on the surrounding container; the SVG keeps a 1:1 aspect\n * ratio via the viewBox.\n */\nconst VIEW_BOX = 400;\nconst MARGIN = 20;\nconst INNER = VIEW_BOX - 2 * MARGIN; // 360\nconst CENTRE = VIEW_BOX / 2; // 200\n\n/**\n * Lowercase rashi key (`\"aries\"`) to canonical title-cased sign name (`\"Aries\"`).\n * Bridges API lowercase rashi strings to the SIGNS_ORDER tokens used everywhere\n * else in the render.\n */\nconst RASHI_TO_SIGN: Record<string, string> = Object.fromEntries(\n\tSIGNS_ORDER.map((s) => [s.toLowerCase(), s] as const),\n);\n\n/**\n * A graha placed inside a kundli cell. Render-only view model fed from a\n * `meta` map on the API response. Carries enough detail to draw a compact\n * in-cell label (abbreviation, whole degree, retrograde mark) and a rich SVG\n * `<title>` tooltip (exact position, nakshatra, pada, avastha).\n */\nexport interface PlacedGraha {\n\tgraha: string;\n\tlongitude?: number;\n\tnakshatra?: { name?: string; pada?: number; lord?: string };\n\tisRetrograde?: boolean;\n\tawastha?: string;\n}\n\n/**\n * Unified view model used by every kundli style. Caller passes a graha-keyed\n * `meta` map (from `/vedic-astrology/birth-chart`, `/divisional-chart`, or\n * `/navamsa`) through {@link toKundliViewModel} to produce this shape.\n *\n * `placements` is keyed by lowercase rashi name (`\"aries\"`, `\"taurus\"`, ...)\n * so the sign-fixed styles can index directly. The Lagna entry is not\n * counted as a planet; it only flags the ascendant cell.\n */\nexport interface KundliViewModel {\n\tlagnaSign: string;\n\tplacements: Record<string, PlacedGraha[]>;\n\tdivisionLabel?: string;\n}\n\n/**\n * Kundli regional styles. Sign-fixed (south, east) and house-fixed (north).\n * Exposed so consumers can type their own `chart-style` attribute reflection.\n */\nexport type ChartStyle = 'south' | 'north' | 'east';\n\nconst CHART_STYLES: ReadonlyArray<{ id: ChartStyle; label: string }> = [\n\t{ id: 'north', label: 'North' },\n\t{ id: 'south', label: 'South' },\n\t{ id: 'east', label: 'East' },\n];\n\nconst RETRO_MARK = '\u02B3';\n\n/**\n * True when the placed graha's longitude maps to a sign other than the cell\n * it occupies. The API preserves the D1 sidereal longitude on every chart, so\n * inside a D2..D60 cell that longitude refers to the D1 sign, not the cell's\n * divisional sign. In that case the degree-within-sign is not meaningful and\n * must be hidden from the in-cell label.\n */\nfunction isDivisionalPlacement(p: PlacedGraha, cellSign: string): boolean {\n\tif (typeof p.longitude !== 'number' || !Number.isFinite(p.longitude)) {\n\t\treturn false;\n\t}\n\treturn (\n\t\tlongitudeToSignPosition(p.longitude).sign.toLowerCase() !==\n\t\tcellSign.toLowerCase()\n\t);\n}\n\n/**\n * Compact in-cell graha label: abbreviation, optional whole-degree, retrograde\n * mark. The degree is shown only when the longitude actually maps to the cell\n * the graha is rendered in (the D1 case); divisional placements show the\n * abbreviation alone since the API longitude refers to D1, not the divisional\n * sign.\n */\nfunction grahaLabel(p: PlacedGraha, cellSign: string): string {\n\tconst abbr = PLANET_ABBR[capitalize(p.graha)] ?? p.graha.slice(0, 2);\n\tconst retro = p.isRetrograde ? RETRO_MARK : '';\n\tif (\n\t\ttypeof p.longitude !== 'number' ||\n\t\t!Number.isFinite(p.longitude) ||\n\t\tisDivisionalPlacement(p, cellSign)\n\t) {\n\t\treturn `${abbr}${retro}`;\n\t}\n\tconst { degree } = longitudeToSignPosition(p.longitude);\n\treturn `${abbr} ${degree}\u00B0${retro}`;\n}\n\n/**\n * Full-detail tooltip surfaced via the SVG `<title>` for each planet label.\n * Includes planet name, the divisional placement (when the longitude does not\n * match the cell, the cell's rashi is preferred), the exact D1 longitude as\n * the original reference, nakshatra and pada, avastha, and the retrograde\n * flag. Surfaces on hover or long-press without crowding the cell.\n */\nfunction grahaTitle(p: PlacedGraha, cellSign: string): string {\n\tconst parts: string[] = [capitalize(p.graha)];\n\tconst divisional = isDivisionalPlacement(p, cellSign);\n\tif (divisional) {\n\t\tparts.push(`in ${cellSign}`);\n\t}\n\tif (typeof p.longitude === 'number' && Number.isFinite(p.longitude)) {\n\t\tconst sp = longitudeToSignPosition(p.longitude);\n\t\tconst minute = String(sp.minute).padStart(2, '0');\n\t\tparts.push(\n\t\t\tdivisional\n\t\t\t\t? `D1: ${sp.degree}\u00B0${minute}' ${sp.sign}`\n\t\t\t\t: `${sp.degree}\u00B0${minute}' ${sp.sign}`,\n\t\t);\n\t}\n\tif (p.nakshatra?.name) {\n\t\tconst pada = p.nakshatra.pada ? ` pada ${p.nakshatra.pada}` : '';\n\t\tparts.push(`${p.nakshatra.name}${pada}`);\n\t}\n\tif (p.awastha) parts.push(p.awastha);\n\tif (p.isRetrograde) parts.push('retrograde');\n\treturn parts.join(' \u00B7 ');\n}\n\n/**\n * Render a vertically centred stack of planet labels at `(cx, baseY)`, one\n * line per planet, with an SVG `<title>` per line carrying the full tooltip.\n * The stack auto-centres on `baseY` regardless of count so a 1-planet cell\n * and a 5-planet cell both look intentional.\n */\nfunction renderPlanetStack(\n\tplanets: PlacedGraha[],\n\tcellSign: string,\n\tcx: number,\n\tbaseY: number,\n\tlineHeight: number,\n): TemplateResult[] {\n\tconst startY = baseY - ((planets.length - 1) * lineHeight) / 2;\n\treturn planets.map((p, j) => {\n\t\tconst yPos = startY + j * lineHeight;\n\t\treturn svg`<text class=\"planet-text\" x=\"${cx}\" y=\"${yPos}\" text-anchor=\"middle\" dominant-baseline=\"central\">${grahaLabel(\n\t\t\tp,\n\t\t\tcellSign,\n\t\t)}<title>${grahaTitle(p, cellSign)}</title></text>`;\n\t});\n}\n\n/**\n * Bucket a graha-keyed `meta` map (D1 birth chart or D2..D60 divisional\n * chart) into the unified {@link KundliViewModel} the renderer consumes. The\n * Lagna entry is recognised by `graha === 'Lagna'` (or key `\"Lagna\"`) and\n * sets `lagnaSign`; it is not bucketed as a placed planet.\n *\n * @param meta - Graha-keyed map; missing rashi entries are skipped.\n * @param divisionLabel - Optional title written inside the chart centre.\n */\nexport function toKundliViewModel(\n\tmeta: Record<\n\t\tstring,\n\t\t{\n\t\t\tgraha?: string;\n\t\t\trashi?: string;\n\t\t\tlongitude?: number;\n\t\t\tnakshatra?: { name?: string; pada?: number; lord?: string };\n\t\t\tisRetrograde?: boolean;\n\t\t\tawastha?: string;\n\t\t}\n\t>,\n\tdivisionLabel?: string,\n): KundliViewModel {\n\tconst placements: Record<string, PlacedGraha[]> = {};\n\tfor (const sign of SIGNS_ORDER) placements[sign.toLowerCase()] = [];\n\tlet lagnaSign = '';\n\tfor (const [name, pos] of Object.entries(meta ?? {})) {\n\t\tconst rashiKey = (pos?.rashi ?? '').toLowerCase();\n\t\tif (name === 'Lagna' || pos?.graha === 'Lagna') {\n\t\t\tlagnaSign = RASHI_TO_SIGN[rashiKey] ?? '';\n\t\t\tcontinue;\n\t\t}\n\t\tif (!rashiKey || !(rashiKey in placements)) continue;\n\t\tplacements[rashiKey]?.push({\n\t\t\tgraha: pos.graha ?? name,\n\t\t\tlongitude: pos.longitude,\n\t\t\tnakshatra: pos.nakshatra,\n\t\t\tisRetrograde: pos.isRetrograde,\n\t\t\tawastha: pos.awastha,\n\t\t});\n\t}\n\treturn { lagnaSign, placements, divisionLabel };\n}\n\n// ---------------------------------------------------------------------------\n// South Indian: 4x4 grid with central 2x2 hollow. Signs are FIXED to cells\n// (Pisces top-left corner, clockwise); houses rotate from the Lagna cell.\n// ---------------------------------------------------------------------------\n\nconst SOUTH_CELL = INNER / 4; // 90\n\n/**\n * Sign-to-cell column/row in the South Indian fixed-sign grid. Pisces sits in\n * the top-left corner and the remaining signs proceed clockwise around the\n * 12 perimeter cells. (col, row) origin is the chart top-left.\n */\nconst SOUTH_CELL_GRID: Record<string, { col: number; row: number }> = {\n\tPisces: { col: 0, row: 0 },\n\tAries: { col: 1, row: 0 },\n\tTaurus: { col: 2, row: 0 },\n\tGemini: { col: 3, row: 0 },\n\tCancer: { col: 3, row: 1 },\n\tLeo: { col: 3, row: 2 },\n\tVirgo: { col: 3, row: 3 },\n\tLibra: { col: 2, row: 3 },\n\tScorpio: { col: 1, row: 3 },\n\tSagittarius: { col: 0, row: 3 },\n\tCapricorn: { col: 0, row: 2 },\n\tAquarius: { col: 0, row: 1 },\n};\n\nfunction southCellRect(sign: string): {\n\tx: number;\n\ty: number;\n\tw: number;\n\th: number;\n} {\n\tconst g = SOUTH_CELL_GRID[sign] ?? { col: 0, row: 0 };\n\treturn {\n\t\tx: MARGIN + g.col * SOUTH_CELL,\n\t\ty: MARGIN + g.row * SOUTH_CELL,\n\t\tw: SOUTH_CELL,\n\t\th: SOUTH_CELL,\n\t};\n}\n\n/**\n * South Indian frame: outer square, the two full-span grid lines, and the\n * partial inner lines that bound the central 2x2 hollow on each edge.\n */\nfunction renderSouthFrame(divisionLabel?: string): TemplateResult {\n\tconst a = MARGIN;\n\tconst b = MARGIN + SOUTH_CELL; // 110\n\tconst c = MARGIN + 2 * SOUTH_CELL; // 200\n\tconst d = MARGIN + 3 * SOUTH_CELL; // 290\n\tconst e = VIEW_BOX - MARGIN; // 380\n\treturn svg`<rect class=\"line\" x=\"${a}\" y=\"${a}\" width=\"${INNER}\" height=\"${INNER}\" stroke-width=\"1.5\" fill=\"none\"><line class=\"line\" x1=\"${a}\" y1=\"${b}\" x2=\"${e}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${a}\" y1=\"${d}\" x2=\"${e}\" y2=\"${d}\" stroke-width=\"1\"><line class=\"line\" x1=\"${b}\" y1=\"${a}\" x2=\"${b}\" y2=\"${e}\" stroke-width=\"1\"><line class=\"line\" x1=\"${d}\" y1=\"${a}\" x2=\"${d}\" y2=\"${e}\" stroke-width=\"1\"><line class=\"line\" x1=\"${a}\" y1=\"${c}\" x2=\"${b}\" y2=\"${c}\" stroke-width=\"1\"><line class=\"line\" x1=\"${d}\" y1=\"${c}\" x2=\"${e}\" y2=\"${c}\" stroke-width=\"1\"><line class=\"line\" x1=\"${c}\" y1=\"${a}\" x2=\"${c}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${c}\" y1=\"${d}\" x2=\"${c}\" y2=\"${e}\" stroke-width=\"1\">${\n\t\t\tdivisionLabel\n\t\t\t\t? svg`<text class=\"centre-label\" x=\"${CENTRE}\" y=\"${CENTRE}\" text-anchor=\"middle\" dominant-baseline=\"central\">${divisionLabel}</text>`\n\t\t\t\t: nothing\n\t\t}`;\n}\n\n/**\n * House number for a given sign relative to a Lagna sign. House 1 is the\n * Lagna cell; subsequent houses follow the zodiac in order. Returns 0 when\n * the Lagna sign is unknown so the caller can skip rendering the badge.\n */\nfunction houseNumberInSign(sign: string, lagnaSign: string): number {\n\tconst lagnaIdx = SIGNS_ORDER.findIndex((s) => s === lagnaSign);\n\tconst signIdx = SIGNS_ORDER.findIndex((s) => s === sign);\n\tif (lagnaIdx === -1 || signIdx === -1) return 0;\n\treturn ((signIdx - lagnaIdx + 12) % 12) + 1;\n}\n\nfunction renderSouthCell(\n\tsign: string,\n\tplanets: PlacedGraha[],\n\tisLagna: boolean,\n\thouseNum: number,\n): TemplateResult {\n\tconst r = southCellRect(sign);\n\tconst cx = r.x + r.w / 2;\n\tconst cy = r.y + r.h / 2;\n\tconst signAbbr = SIGN_ABBR[sign] ?? sign.slice(0, 2);\n\t// Inset the Lagna diagonal so it does not collide with the chart frame on\n\t// corner cells (Pisces, Gemini, Virgo, Sagittarius) or with the sign label\n\t// in the top-left of every cell.\n\tconst slashInset = 14;\n\treturn svg`<g class=\"${isLagna ? 'cell lagna' : 'cell'}\">${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<rect class=\"lagna-bg\" x=\"${r.x}\" y=\"${r.y}\" width=\"${r.w}\" height=\"${r.h}\"><line class=\"lagna-slash\" x1=\"${r.x + r.w - slashInset}\" y1=\"${r.y + slashInset}\" x2=\"${r.x + slashInset}\" y2=\"${r.y + r.h - slashInset}\" stroke-width=\"1.2\">`\n\t\t\t\t\t: nothing\n\t\t\t}<text class=\"sign-text\" x=\"${r.x + 6}\" y=\"${r.y + 12}\" text-anchor=\"start\" dominant-baseline=\"central\">${signAbbr}</text>${\n\t\t\t\thouseNum > 0\n\t\t\t\t\t? svg`<text class=\"house-num\" x=\"${r.x + r.w - 6}\" y=\"${r.y + 12}\" text-anchor=\"end\" dominant-baseline=\"central\">${houseNum}</text>`\n\t\t\t\t\t: nothing\n\t\t\t} ${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<text class=\"lagna-marker\" x=\"${cx}\" y=\"${r.y + 26}\" text-anchor=\"middle\" dominant-baseline=\"central\">Asc</text>`\n\t\t\t\t\t: nothing\n\t\t\t} ${planets.length ? renderPlanetStack(planets, sign, cx, cy + 4, 14) : nothing}</g>`;\n}\n\nfunction renderSouthSvg(vm: KundliViewModel): TemplateResult {\n\tconst lagnaKey = vm.lagnaSign.toLowerCase();\n\treturn svg`${renderSouthFrame(vm.divisionLabel)} ${SIGNS_ORDER.map((sign) =>\n\t\t\trenderSouthCell(\n\t\t\t\tsign,\n\t\t\t\tvm.placements[sign.toLowerCase()] ?? [],\n\t\t\t\tsign.toLowerCase() === lagnaKey,\n\t\t\t\thouseNumberInSign(sign, vm.lagnaSign),\n\t\t\t),\n\t\t)}`;\n}\n\n// ---------------------------------------------------------------------------\n// North Indian: outer square + inscribed midpoint diamond + both outer\n// diagonals. 12 cells: 4 cardinal diamonds + 8 corner triangles. Houses are\n// FIXED (H1 always top-centre); signs rotate from the Lagna sign.\n// ---------------------------------------------------------------------------\n\nconst NORTH_VERTICES = {\n\ttl: { x: MARGIN, y: MARGIN },\n\ttr: { x: VIEW_BOX - MARGIN, y: MARGIN },\n\tbr: { x: VIEW_BOX - MARGIN, y: VIEW_BOX - MARGIN },\n\tbl: { x: MARGIN, y: VIEW_BOX - MARGIN },\n\ttop: { x: CENTRE, y: MARGIN },\n\tright: { x: VIEW_BOX - MARGIN, y: CENTRE },\n\tbottom: { x: CENTRE, y: VIEW_BOX - MARGIN },\n\tleft: { x: MARGIN, y: CENTRE },\n\ttlMid: { x: CENTRE - INNER / 4, y: CENTRE - INNER / 4 },\n\ttrMid: { x: CENTRE + INNER / 4, y: CENTRE - INNER / 4 },\n\tbrMid: { x: CENTRE + INNER / 4, y: CENTRE + INNER / 4 },\n\tblMid: { x: CENTRE - INNER / 4, y: CENTRE + INNER / 4 },\n} as const;\n\n/**\n * Centroid (geometric mean) of an arbitrary set of polygon vertices. Used by\n * every cell that needs a label-anchor point; defining it once keeps the\n * North diamond and East triangle math identical.\n */\nfunction centroidOf(pts: Array<{ x: number; y: number }>): {\n\tx: number;\n\ty: number;\n} {\n\tconst x = pts.reduce((s, p) => s + p.x, 0) / pts.length;\n\tconst y = pts.reduce((s, p) => s + p.y, 0) / pts.length;\n\treturn { x, y };\n}\n\n/**\n * House centres for the North Indian diamond. Numbered 1..12 counter-clockwise\n * from the top diamond (H1 is always the ascendant cell). Centroids derived\n * from the canonical geometry above; do not edit by eye, recompute if you\n * change `VIEW_BOX` or `MARGIN`.\n */\nconst NORTH_HOUSE_CENTERS: Record<number, { x: number; y: number }> = {\n\t1: { x: CENTRE, y: NORTH_VERTICES.tlMid.y },\n\t2: centroidOf([NORTH_VERTICES.tl, NORTH_VERTICES.top, NORTH_VERTICES.tlMid]),\n\t3: centroidOf([NORTH_VERTICES.tl, NORTH_VERTICES.left, NORTH_VERTICES.tlMid]),\n\t4: { x: NORTH_VERTICES.tlMid.x, y: CENTRE },\n\t5: centroidOf([NORTH_VERTICES.bl, NORTH_VERTICES.left, NORTH_VERTICES.blMid]),\n\t6: centroidOf([\n\t\tNORTH_VERTICES.bl,\n\t\tNORTH_VERTICES.bottom,\n\t\tNORTH_VERTICES.blMid,\n\t]),\n\t7: { x: CENTRE, y: NORTH_VERTICES.blMid.y },\n\t8: centroidOf([\n\t\tNORTH_VERTICES.br,\n\t\tNORTH_VERTICES.bottom,\n\t\tNORTH_VERTICES.brMid,\n\t]),\n\t9: centroidOf([\n\t\tNORTH_VERTICES.br,\n\t\tNORTH_VERTICES.right,\n\t\tNORTH_VERTICES.brMid,\n\t]),\n\t10: { x: NORTH_VERTICES.brMid.x, y: CENTRE },\n\t11: centroidOf([\n\t\tNORTH_VERTICES.tr,\n\t\tNORTH_VERTICES.right,\n\t\tNORTH_VERTICES.trMid,\n\t]),\n\t12: centroidOf([NORTH_VERTICES.tr, NORTH_VERTICES.top, NORTH_VERTICES.trMid]),\n};\n\n/**\n * Rashi number (1..12, Aries=1) occupying the given house when the Lagna sits\n * in `lagnaSign`. House 1 is the Lagna sign; subsequent houses follow the\n * zodiac in order.\n */\nfunction rashiInHouse(houseNum: number, lagnaSign: string): number {\n\tconst lagnaIdx = SIGNS_ORDER.findIndex((s) => s === lagnaSign);\n\tif (lagnaIdx === -1) return houseNum;\n\treturn ((lagnaIdx + houseNum - 1) % 12) + 1;\n}\n\nfunction renderNorthFrame(divisionLabel?: string): TemplateResult {\n\tconst { tl, tr, br, bl, top, right, bottom, left } = NORTH_VERTICES;\n\treturn svg`<rect class=\"line\" x=\"${tl.x}\" y=\"${tl.y}\" width=\"${INNER}\" height=\"${INNER}\" stroke-width=\"1.5\" fill=\"none\"><polygon class=\"line\" points=\"${top.x},${top.y} ${right.x},${right.y} ${bottom.x},${bottom.y} ${left.x},${left.y}\" stroke-width=\"1\" fill=\"none\"><line class=\"line\" x1=\"${tl.x}\" y1=\"${tl.y}\" x2=\"${br.x}\" y2=\"${br.y}\" stroke-width=\"1\"><line class=\"line\" x1=\"${tr.x}\" y1=\"${tr.y}\" x2=\"${bl.x}\" y2=\"${bl.y}\" stroke-width=\"1\">${\n\t\t\tdivisionLabel\n\t\t\t\t? svg`<text class=\"centre-label\" x=\"${CENTRE}\" y=\"${CENTRE}\" text-anchor=\"middle\" dominant-baseline=\"central\">${divisionLabel}</text>`\n\t\t\t\t: nothing\n\t\t}`;\n}\n\nfunction renderNorthCell(\n\thouseNum: number,\n\trashiNum: number,\n\tsign: string,\n\tplanets: PlacedGraha[],\n\tisLagna: boolean,\n): TemplateResult {\n\tconst c = NORTH_HOUSE_CENTERS[houseNum];\n\tif (!c) return svg``;\n\t// Tight cells (H2/3/5/6/8/9/11/12 corner triangles) clip the rasi number\n\t// when it sits too high above the centroid. Clamp the upward offset based\n\t// on the cell's distance from the chart vertical centre so the label\n\t// always stays comfortably inside its triangle or diamond.\n\tconst rashiOffsetY = Math.min(14, Math.abs(c.y - CENTRE) * 0.45 + 6);\n\tconst ascOffsetY = rashiOffsetY + 12;\n\t// North cells carry only a rasi number by convention. The ascendant also\n\t// names its sign so the reader can see which sign rises without translating\n\t// the number; other cells stay number-only.\n\tconst rashiLabel = isLagna\n\t\t? `${rashiNum} \u00B7 ${SIGN_ABBR[sign] ?? sign.slice(0, 2)}`\n\t\t: `${rashiNum}`;\n\treturn svg`<g class=\"${isLagna ? 'cell lagna' : 'cell'}\"><text class=\"rashi-num\" x=\"${c.x}\" y=\"${c.y - rashiOffsetY}\" text-anchor=\"middle\" dominant-baseline=\"central\">${rashiLabel}</text>${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<text class=\"lagna-marker\" x=\"${c.x}\" y=\"${c.y - ascOffsetY}\" text-anchor=\"middle\" dominant-baseline=\"central\">Asc</text>`\n\t\t\t\t\t: nothing\n\t\t\t} ${planets.length ? renderPlanetStack(planets, sign, c.x, c.y + 8, 12) : nothing}</g>`;\n}\n\nfunction renderNorthSvg(vm: KundliViewModel): TemplateResult {\n\tconst lagnaSign = vm.lagnaSign || 'Aries';\n\treturn svg`${renderNorthFrame(vm.divisionLabel)} ${Array.from({ length: 12 }, (_, i) => {\n\t\t\tconst houseNum = i + 1;\n\t\t\tconst rashiNum = rashiInHouse(houseNum, lagnaSign);\n\t\t\tconst sign = SIGNS_ORDER[rashiNum - 1] ?? 'Aries';\n\t\t\treturn renderNorthCell(\n\t\t\t\thouseNum,\n\t\t\t\trashiNum,\n\t\t\t\tsign,\n\t\t\t\tvm.placements[sign.toLowerCase()] ?? [],\n\t\t\t\thouseNum === 1,\n\t\t\t);\n\t\t})}`;\n}\n\n// ---------------------------------------------------------------------------\n// East Indian (Bengali / Maithili): 3x3 underlying grid, 4 edge rectangles +\n// 4 corner cells each split by a diagonal from the outer chart corner to the\n// inner corner of the centre cell. Aries fixed top-centre; signs proceed\n// counter-clockwise. Houses rotate from the Lagna.\n// ---------------------------------------------------------------------------\n\nconst EAST_CELL = INNER / 3; // 120\n\ninterface EastCell {\n\t/** Vertices of the cell polygon, in viewBox units. */\n\tpoints: Array<{ x: number; y: number }>;\n\t/** Visual centroid for label placement. */\n\tcentroid: { x: number; y: number };\n}\n\nfunction eastCells(): Record<string, EastCell> {\n\tconst a = MARGIN; // 20\n\tconst b = MARGIN + EAST_CELL; // 140\n\tconst c = MARGIN + 2 * EAST_CELL; // 260\n\tconst d = VIEW_BOX - MARGIN; // 380\n\tconst aries = [\n\t\t{ x: b, y: a },\n\t\t{ x: c, y: a },\n\t\t{ x: c, y: b },\n\t\t{ x: b, y: b },\n\t];\n\tconst cancer = [\n\t\t{ x: a, y: b },\n\t\t{ x: b, y: b },\n\t\t{ x: b, y: c },\n\t\t{ x: a, y: c },\n\t];\n\tconst libra = [\n\t\t{ x: b, y: c },\n\t\t{ x: c, y: c },\n\t\t{ x: c, y: d },\n\t\t{ x: b, y: d },\n\t];\n\tconst capricorn = [\n\t\t{ x: c, y: b },\n\t\t{ x: d, y: b },\n\t\t{ x: d, y: c },\n\t\t{ x: c, y: c },\n\t];\n\tconst taurus = [\n\t\t{ x: a, y: a },\n\t\t{ x: b, y: a },\n\t\t{ x: b, y: b },\n\t];\n\tconst gemini = [\n\t\t{ x: a, y: a },\n\t\t{ x: b, y: b },\n\t\t{ x: a, y: b },\n\t];\n\tconst leo = [\n\t\t{ x: a, y: c },\n\t\t{ x: b, y: c },\n\t\t{ x: a, y: d },\n\t];\n\tconst virgo = [\n\t\t{ x: b, y: c },\n\t\t{ x: b, y: d },\n\t\t{ x: a, y: d },\n\t];\n\tconst scorpio = [\n\t\t{ x: c, y: c },\n\t\t{ x: c, y: d },\n\t\t{ x: d, y: d },\n\t];\n\tconst sagittarius = [\n\t\t{ x: c, y: c },\n\t\t{ x: d, y: d },\n\t\t{ x: d, y: c },\n\t];\n\tconst aquarius = [\n\t\t{ x: d, y: a },\n\t\t{ x: d, y: b },\n\t\t{ x: c, y: b },\n\t];\n\tconst pisces = [\n\t\t{ x: c, y: a },\n\t\t{ x: d, y: a },\n\t\t{ x: c, y: b },\n\t];\n\tconst polys = {\n\t\tAries: aries,\n\t\tTaurus: taurus,\n\t\tGemini: gemini,\n\t\tCancer: cancer,\n\t\tLeo: leo,\n\t\tVirgo: virgo,\n\t\tLibra: libra,\n\t\tScorpio: scorpio,\n\t\tSagittarius: sagittarius,\n\t\tCapricorn: capricorn,\n\t\tAquarius: aquarius,\n\t\tPisces: pisces,\n\t} as const;\n\tconst out: Record<string, EastCell> = {};\n\tfor (const [sign, points] of Object.entries(polys)) {\n\t\tout[sign] = { points: [...points], centroid: centroidOf(points) };\n\t}\n\treturn out;\n}\n\nconst EAST_CELLS = eastCells();\n\nfunction renderEastFrame(divisionLabel?: string): TemplateResult {\n\tconst a = MARGIN;\n\tconst b = MARGIN + EAST_CELL;\n\tconst c = MARGIN + 2 * EAST_CELL;\n\tconst d = VIEW_BOX - MARGIN;\n\treturn svg`<rect class=\"line\" x=\"${a}\" y=\"${a}\" width=\"${INNER}\" height=\"${INNER}\" stroke-width=\"1.5\" fill=\"none\"><line class=\"line\" x1=\"${a}\" y1=\"${b}\" x2=\"${b}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${c}\" y1=\"${b}\" x2=\"${d}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${a}\" y1=\"${c}\" x2=\"${b}\" y2=\"${c}\" stroke-width=\"1\"><line class=\"line\" x1=\"${c}\" y1=\"${c}\" x2=\"${d}\" y2=\"${c}\" stroke-width=\"1\"><line class=\"line\" x1=\"${b}\" y1=\"${a}\" x2=\"${b}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${b}\" y1=\"${c}\" x2=\"${b}\" y2=\"${d}\" stroke-width=\"1\"><line class=\"line\" x1=\"${c}\" y1=\"${a}\" x2=\"${c}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${c}\" y1=\"${c}\" x2=\"${c}\" y2=\"${d}\" stroke-width=\"1\"><line class=\"line\" x1=\"${a}\" y1=\"${a}\" x2=\"${b}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${d}\" y1=\"${a}\" x2=\"${c}\" y2=\"${b}\" stroke-width=\"1\"><line class=\"line\" x1=\"${d}\" y1=\"${d}\" x2=\"${c}\" y2=\"${c}\" stroke-width=\"1\"><line class=\"line\" x1=\"${a}\" y1=\"${d}\" x2=\"${b}\" y2=\"${c}\" stroke-width=\"1\">${\n\t\t\tdivisionLabel\n\t\t\t\t? svg`<text class=\"centre-label\" x=\"${CENTRE}\" y=\"${CENTRE}\" text-anchor=\"middle\" dominant-baseline=\"central\">${divisionLabel}</text>`\n\t\t\t\t: nothing\n\t\t}`;\n}\n\nfunction renderEastCell(\n\tsign: string,\n\tplanets: PlacedGraha[],\n\tisLagna: boolean,\n\thouseNum: number,\n): TemplateResult {\n\tconst cell = EAST_CELLS[sign];\n\tif (!cell) return svg``;\n\tconst { centroid: cen, points } = cell;\n\tconst signAbbr = SIGN_ABBR[sign] ?? sign.slice(0, 2);\n\tconst polyPoints = points.map((p) => `${p.x},${p.y}`).join(' ');\n\treturn svg`<g class=\"${isLagna ? 'cell lagna' : 'cell'}\">${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<polygon class=\"lagna-bg\" points=\"${polyPoints}\">`\n\t\t\t\t\t: nothing\n\t\t\t}<text class=\"sign-text\" x=\"${cen.x}\" y=\"${cen.y - 16}\" text-anchor=\"middle\" dominant-baseline=\"central\">${signAbbr}</text>${\n\t\t\t\thouseNum > 0\n\t\t\t\t\t? svg`<text class=\"house-num\" x=\"${cen.x + 18}\" y=\"${cen.y - 16}\" text-anchor=\"start\" dominant-baseline=\"central\">${houseNum}</text>`\n\t\t\t\t\t: nothing\n\t\t\t} ${\n\t\t\t\tisLagna\n\t\t\t\t\t? svg`<text class=\"lagna-marker\" x=\"${cen.x}\" y=\"${cen.y - 30}\" text-anchor=\"middle\" dominant-baseline=\"central\">Asc</text>`\n\t\t\t\t\t: nothing\n\t\t\t} ${planets.length ? renderPlanetStack(planets, sign, cen.x, cen.y + 4, 12) : nothing}</g>`;\n}\n\nfunction renderEastSvg(vm: KundliViewModel): TemplateResult {\n\tconst lagnaKey = vm.lagnaSign.toLowerCase();\n\treturn svg`${renderEastFrame(vm.divisionLabel)} ${SIGNS_ORDER.map((sign) =>\n\t\t\trenderEastCell(\n\t\t\t\tsign,\n\t\t\t\tvm.placements[sign.toLowerCase()] ?? [],\n\t\t\t\tsign.toLowerCase() === lagnaKey,\n\t\t\t\thouseNumberInSign(sign, vm.lagnaSign),\n\t\t\t),\n\t\t)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Render the kundli body for the requested style. Returns the SVG inner\n * content; the caller wraps it in an `<svg>` element with the canonical\n * viewBox `0 0 400 400` and applies its own theming CSS.\n */\nexport function renderKundliSvg(\n\tvm: KundliViewModel,\n\tstyle: ChartStyle,\n): TemplateResult {\n\tswitch (style) {\n\t\tcase 'north':\n\t\t\treturn renderNorthSvg(vm);\n\t\tcase 'east':\n\t\t\treturn renderEastSvg(vm);\n\t\tdefault:\n\t\t\treturn renderSouthSvg(vm);\n\t}\n}\n\n/**\n * Render a WAI-ARIA-compliant tablist that lets the end user switch between\n * South / North / East kundli styles at runtime. The hosting component owns\n * the `chartStyle` state; this helper renders the buttons and wires the\n * arrow-key navigation plus click handler.\n *\n * @param active - The currently selected style.\n * @param setStyle - Callback the host component uses to update its state.\n */\nexport function renderKundliStyleTablist(\n\tactive: ChartStyle,\n\tsetStyle: (next: ChartStyle) => void,\n): TemplateResult {\n\treturn renderTablist({\n\t\titems: CHART_STYLES,\n\t\tactive,\n\t\tonSelect: setStyle,\n\t\tlabel: 'Kundli style',\n\t\tidPrefix: 'kundli',\n\t});\n}\n", "/**\n * Math helpers for converting raw ecliptic longitude decimals into the\n * sign / degree / minute / second triplet used across chart components.\n */\n\nimport { SIGNS_ORDER } from '../tokens/index.js';\n\nexport interface SignPosition {\n\tsign: string;\n\tsignIndex: number;\n\tdegree: number;\n\tminute: number;\n\tsecond: number;\n}\n\n/**\n * Wrap longitude into [0, 360) so negative or out-of-range values still\n * resolve to a real sign. Robust to wonky upstream data.\n */\nexport function normalizeLongitude(lon: number): number {\n\tconst wrapped = lon % 360;\n\treturn wrapped < 0 ? wrapped + 360 : wrapped;\n}\n\n/**\n * Convert decimal ecliptic longitude (0-360) into sign/degree/minute/second.\n * Used by every chart wheel and aspect table.\n */\nexport function longitudeToSignPosition(longitude: number): SignPosition {\n\tconst lon = normalizeLongitude(longitude);\n\tconst signIndex = Math.floor(lon / 30) % 12;\n\tconst within = lon % 30;\n\tconst degree = Math.floor(within);\n\tconst minuteFloat = (within - degree) * 60;\n\tconst minute = Math.floor(minuteFloat);\n\tconst second = Math.round((minuteFloat - minute) * 60);\n\treturn {\n\t\tsign: SIGNS_ORDER[signIndex] ?? 'Aries',\n\t\tsignIndex,\n\t\tdegree,\n\t\tminute,\n\t\tsecond,\n\t};\n}\n\n/** Compact display string like \"12\u00B0 Leo 34'\". Used in chart labels. */\nexport function formatSignPosition(longitude: number): string {\n\tconst { sign, degree, minute } = longitudeToSignPosition(longitude);\n\treturn `${degree}\u00B0 ${sign} ${String(minute).padStart(2, '0')}'`;\n}\n\n/**\n * The point diametrically opposite a longitude (e.g. Descendant from\n * Ascendant, IC from MC). Exact derivation, always 180 degrees away.\n */\nexport function oppositePoint(longitude: number): number {\n\treturn normalizeLongitude(longitude + 180);\n}\n\n/**\n * Midpoint of the forward arc from `start` to `end` (both ecliptic\n * longitudes). Handles the 360/0 wrap, so a house spanning 350 to 20 degrees\n * yields a midpoint of 5, not 185. Used to place house numbers between two\n * cusps regardless of how unequal the house is.\n */\nexport function arcMidpoint(start: number, end: number): number {\n\tconst s = normalizeLongitude(start);\n\tlet span = normalizeLongitude(end) - s;\n\tif (span < 0) span += 360;\n\treturn normalizeLongitude(s + span / 2);\n}\n\n/** Polar to cartesian for SVG wheel positioning. Angle in degrees, 0 at 3 o'clock. */\nexport function polarToCartesian(\n\tcx: number,\n\tcy: number,\n\tradius: number,\n\tangleDeg: number,\n): { x: number; y: number } {\n\tconst angleRad = (angleDeg * Math.PI) / 180;\n\treturn {\n\t\tx: cx + radius * Math.cos(angleRad),\n\t\ty: cy + radius * Math.sin(angleRad),\n\t};\n}\n", "/**\n * Shared string helpers used across components. Single source of truth so the\n * same formatting rules apply to every key/label/title that surfaces in the\n * shadow tree.\n *\n * - `capitalize`: title-cases the first character, lowercases the rest. Used\n * when matching API-supplied planet/sign names against the glyph maps in\n * `tokens/index.ts`, which use canonical TitleCase keys.\n * - `humanize`: turns an API key (`birth_date`, `birthDate`, `mahadasha-end`)\n * into a label suitable for display (\"Birth date\", \"Mahadasha end\").\n */\n\nexport function capitalize(s: string): string {\n\tif (!s) return '';\n\treturn s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nexport function humanize(s: string): string {\n\treturn s\n\t\t.replace(/[_-]+/g, ' ')\n\t\t.replace(/([a-z])([A-Z])/g, '$1 $2')\n\t\t.replace(/^\\w/, (c) => c.toUpperCase());\n}\n", "import type { TemplateResult } from 'lit';\nimport { css, html, nothing } from 'lit';\n\n/** A single tab in a {@link renderTablist} strip. */\nexport interface TablistItem<T extends string = string> {\n\tid: T;\n\tlabel: string;\n}\n\n/**\n * Shared styling for every horizontal tab strip in the library (natal chart\n * views, transits, kundli styles). Keeping one rule set means the tabs look\n * identical everywhere and theme through the same --roxy-* tokens.\n */\nexport const tablistStyles = css`.roxy-tablist{border-bottom:2px solid var(--roxy-border,#e4e4e7);gap:2px;display:flex}.roxy-tab{padding:var(--roxy-space-xs,.25rem) var(--roxy-space-md,1rem);font-size:var(--roxy-text-sm,.875rem);cursor:pointer;color:var(--roxy-muted,#71717a);transition:color var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,ease);background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-2px;font-family:inherit}.roxy-tab[aria-selected=true]{color:var(--roxy-accent-fg,#b45309);border-bottom-color:var(--roxy-accent,#f59e0b);font-weight:var(--roxy-weight-bold,600)}.roxy-tab:hover:not([aria-selected=true]){color:var(--roxy-fg,#0a0a0a)}.roxy-tab:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px;border-radius:4px}`;\n\n/**\n * Render a WAI-ARIA tablist. The host component owns the active-tab state; this\n * helper draws the buttons, wires click plus Left/Right arrow navigation with a\n * roving tabindex, and moves focus to the newly selected tab. Pair with\n * {@link tablistStyles}.\n *\n * Pass `controls: true` when each tab governs a sibling\n * `<div role=\"tabpanel\" id=\"${idPrefix}-panel-${id}\">` so the buttons advertise\n * `aria-controls`. Omit it for tablists that swap a single rendered view in\n * place with no separate panel element (the kundli style switch).\n *\n * @example\n * ```ts\n * renderTablist({\n * items: [{ id: 'wheel', label: 'Wheel' }, { id: 'grid', label: 'Aspect grid' }],\n * active: this.view,\n * onSelect: (v) => { this.view = v; },\n * label: 'Natal chart views',\n * idPrefix: 'natal',\n * controls: true,\n * })\n * ```\n */\nexport function renderTablist<T extends string>(opts: {\n\titems: ReadonlyArray<TablistItem<T>>;\n\tactive: T;\n\tonSelect: (id: T) => void;\n\tlabel: string;\n\tidPrefix: string;\n\tcontrols?: boolean;\n}): TemplateResult {\n\tconst { items, active, onSelect, label, idPrefix, controls = false } = opts;\n\tconst onKeyDown = (e: KeyboardEvent) => {\n\t\tif (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n\t\te.preventDefault();\n\t\tconst idx = items.findIndex((it) => it.id === active);\n\t\tif (idx === -1) return;\n\t\tconst delta = e.key === 'ArrowRight' ? 1 : -1;\n\t\tconst next = items[(idx + delta + items.length) % items.length];\n\t\tif (!next) return;\n\t\tonSelect(next.id);\n\t\tconst root = (e.currentTarget as HTMLElement).getRootNode() as\n\t\t\t| ShadowRoot\n\t\t\t| Document;\n\t\trequestAnimationFrame(() => {\n\t\t\troot\n\t\t\t\t.querySelector<HTMLButtonElement>(`#${idPrefix}-tab-${next.id}`)\n\t\t\t\t?.focus();\n\t\t});\n\t};\n\treturn html`<div class=\"roxy-tablist\" role=\"tablist\" aria-label=\"${label}\" @keydown=\"${onKeyDown}\">${items.map(\n\t\t\t(it) => html`<button type=\"button\" class=\"roxy-tab\" role=\"tab\" id=\"${idPrefix}-tab-${it.id}\" aria-selected=\"${active === it.id ? 'true' : 'false'}\" aria-controls=\"${\n\t\t\t\t\t// Only the active panel is rendered, so only the active tab points\n\t\t\t\t\t// at a live element; otherwise aria-controls would dangle.\n\t\t\t\t\tcontrols && active === it.id ? `${idPrefix}-panel-${it.id}` : nothing\n\t\t\t\t}\" tabindex=\"${active === it.id ? '0' : '-1'}\" @click=\"${() => onSelect(it.id)}\">${it.label}</button>`,\n\t\t)}</div>`;\n}\n", "import { css } from 'lit';\n\n/**\n * Shared CSS for every kundli renderer (`<roxy-vedic-kundli>`,\n * `<roxy-divisional-chart>`, and any future `<roxy-navamsa-chart>`). Centralises\n * the SVG layout (responsive viewBox + aspect ratio), the line/text classes,\n * and the Lagna highlight so the three components stay visually identical.\n *\n * @remarks Font sizes are written in viewBox user units (the chart is 400\u00D7400\n * inside a 1:1 aspect-ratio container), so they scale linearly from a 320px\n * phone surface to a wall projector without raster loss. The Lagna palette\n * tracks `--roxy-accent` so host themes flow through unchanged.\n */\nexport const kundliStyles = css`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.header{justify-content:space-between;align-items:center;gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}svg{aspect-ratio:1;width:100%;max-width:560px;height:auto;margin:0 auto;display:block}.line{fill:#0000;stroke:var(--roxy-border,#d4d4d8)}.sign-text{fill:var(--roxy-muted,#71717a);font-size:11px;font-weight:500;font-family:var(--roxy-font-sans);text-transform:uppercase;letter-spacing:.04em}.rashi-num{fill:var(--roxy-muted,#71717a);font-size:12px;font-weight:500;font-family:var(--roxy-font-sans)}.house-num{fill:var(--roxy-accent-fg,#b45309);font-size:11px;font-weight:600;font-family:var(--roxy-font-sans);opacity:.85}.planet-text{fill:var(--roxy-fg,#0a0a0a);font-size:13px;font-weight:600;font-family:var(--roxy-font-sans)}.centre-label{fill:var(--roxy-muted,#71717a);font-size:14px;font-weight:600;font-family:var(--roxy-font-sans);letter-spacing:.02em}.lagna-marker{fill:var(--roxy-accent-fg,#b45309);font-size:10px;font-weight:700;font-family:var(--roxy-font-sans);letter-spacing:.08em;text-transform:uppercase}.lagna-bg{fill:color-mix(in srgb, var(--roxy-accent,#f59e0b) 14%, transparent)}.lagna-slash{stroke:var(--roxy-accent,#f59e0b);stroke-linecap:round;opacity:.7}`;\n", "import type { ReactiveController, ReactiveControllerHost } from 'lit';\n\n/**\n * Marker class on the inline JSON script a server emits inside a component.\n *\n * @example\n * ```html\n * <roxy-natal-chart>\n * <script type=\"application/json\" class=\"roxy-data\">{ ...response... }</script>\n * </roxy-natal-chart>\n * ```\n */\nconst ROXY_DATA_CLASS = 'roxy-data';\n\n/**\n * True when the element is a `<script type=\"application/json\">`. Uses tag name and attribute rather than `instanceof HTMLScriptElement` so the check holds in every DOM implementation, including server-rendered and hydration runtimes where the constructor global may be absent.\n */\nfunction isJsonScript(el: Element): boolean {\n\treturn (\n\t\tel.nodeName === 'SCRIPT' && el.getAttribute('type') === 'application/json'\n\t);\n}\n\n/**\n * Host shape the controller drives: any reactive element that exposes a public `data` slot. The controller only writes `data` when the host left it unset, so the JavaScript property path always wins.\n */\ninterface DataHost extends ReactiveControllerHost, HTMLElement {\n\tdata?: unknown;\n}\n\n/**\n * Reactive controller that lets a component hydrate its `data` from embedded markup when no `data` property was assigned in JavaScript.\n *\n * @remarks\n * The server-side and cached-render model: a backend renders the RoxyAPI response into a direct-child `<script type=\"application/json\" class=\"roxy-data\">` element, ships static HTML, and never runs per-element JavaScript to assign a property. On connect this controller reads that script, parses it, and feeds the result to the host. The JavaScript property path is untouched and authoritative: if `host.data` already holds a value when the host connects, the controller does nothing and the markup is ignored.\n *\n * Source resolution order on connect, first hit wins:\n *\n * 1. `host.data` already set in JavaScript -> leave it, read nothing.\n * 2. A direct-child `<script type=\"application/json\" class=\"roxy-data\">` -> parse and use. Direct-child only, so a nested component's own script is never read by an ancestor.\n *\n * Fetching from a URL is intentionally unsupported: that would require a browser-visible key and breaks the server-rendered, cached model these consumers rely on.\n *\n * Timing: {@link hostConnected} runs inside the host `connectedCallback`. For an element parsed from server HTML, its direct children are present by the time the custom element upgrades and connects, so the script is readable here. For an element created with `document.createElement` and connected before any child is appended, there is nothing to read and the property path is the only source, which is exactly the existing behavior.\n *\n * Failure is safe: malformed JSON or a missing script leaves `host.data` untouched, so the host renders its normal empty state.\n *\n * Reading the script never mutates it, and only the marked script is touched, so any sibling fallback markup a server nested inside the element (for no-JavaScript, AMP, or crawler rendering) is left in place.\n *\n * @example\n * ```ts\n * import { MarkupDataController } from '../utils/markup-data.js';\n *\n * export class RoxyExample extends LitElement {\n * constructor() {\n * super();\n * new MarkupDataController(this);\n * }\n *\n * @property({ attribute: false })\n * data: ExampleResponse | null = null;\n * }\n * ```\n */\nexport class MarkupDataController<T = unknown> implements ReactiveController {\n\tprivate readonly host: DataHost;\n\n\tconstructor(host: DataHost) {\n\t\tthis.host = host;\n\t\thost.addController(this);\n\t}\n\n\thostConnected() {\n\t\t// Property path wins. If the consumer (React, vanilla `.data =`, the\n\t\t// widgets script, an MCP agent) already set data, never look at markup.\n\t\tif (this.host.data != null) return;\n\n\t\tconst parsed = this.read();\n\t\tif (parsed === undefined) return;\n\n\t\tthis.host.data = parsed as T;\n\t\tthis.host.requestUpdate();\n\t}\n\n\t/**\n\t * Resolve the embedded payload. Returns `undefined` when there is nothing valid to read so the caller can leave `host.data` untouched.\n\t */\n\tprivate read(): T | undefined {\n\t\tconst inline = this.findInlineScript();\n\t\treturn inline ? this.parse(inline.textContent) : undefined;\n\t}\n\n\t/**\n\t * Direct-child `<script type=\"application/json\" class=\"roxy-data\">`. Scoped to immediate children so a nested data-driven component never has its script read by an ancestor, and so sibling fallback markup is ignored.\n\t */\n\tprivate findInlineScript(): Element | null {\n\t\tfor (const child of Array.from(this.host.children)) {\n\t\t\tif (isJsonScript(child) && child.classList.contains(ROXY_DATA_CLASS)) {\n\t\t\t\treturn child;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate parse(text: string | null): T | undefined {\n\t\tif (!text?.trim()) return undefined;\n\t\ttry {\n\t\t\treturn JSON.parse(text) as T;\n\t\t} catch {\n\t\t\t// Malformed embedded JSON: fail safe, leave the host empty state in\n\t\t\t// place rather than throwing during connect.\n\t\t\treturn undefined;\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["css", "html", "LitElement", "nothing", "customElement", "property", "PLANET_GLYPH", "PLANET_ABBR", "SIGN_ABBR", "SIGNS_ORDER", "RASHI_KEYS", "s", "css", "baseStyles", "nothing", "svg", "normalizeLongitude", "lon", "wrapped", "longitudeToSignPosition", "longitude", "signIndex", "within", "degree", "minuteFloat", "minute", "second", "SIGNS_ORDER", "capitalize", "s", "css", "html", "nothing", "tablistStyles", "renderTablist", "opts", "items", "active", "onSelect", "label", "idPrefix", "controls", "e", "idx", "it", "delta", "next", "root", "VIEW_BOX", "MARGIN", "INNER", "CENTRE", "RASHI_TO_SIGN", "SIGNS_ORDER", "s", "CHART_STYLES", "RETRO_MARK", "isDivisionalPlacement", "p", "cellSign", "longitudeToSignPosition", "grahaLabel", "abbr", "PLANET_ABBR", "capitalize", "retro", "degree", "grahaTitle", "parts", "divisional", "sp", "minute", "pada", "renderPlanetStack", "planets", "cx", "baseY", "lineHeight", "startY", "j", "yPos", "svg", "toKundliViewModel", "meta", "divisionLabel", "placements", "sign", "lagnaSign", "name", "pos", "rashiKey", "SOUTH_CELL", "SOUTH_CELL_GRID", "southCellRect", "g", "renderSouthFrame", "a", "b", "c", "d", "e", "nothing", "houseNumberInSign", "lagnaIdx", "signIdx", "renderSouthCell", "isLagna", "houseNum", "r", "cy", "signAbbr", "SIGN_ABBR", "slashInset", "renderSouthSvg", "vm", "lagnaKey", "NORTH_VERTICES", "centroidOf", "pts", "x", "y", "NORTH_HOUSE_CENTERS", "rashiInHouse", "renderNorthFrame", "tl", "tr", "br", "bl", "top", "right", "bottom", "left", "renderNorthCell", "rashiNum", "rashiOffsetY", "ascOffsetY", "rashiLabel", "renderNorthSvg", "_", "i", "EAST_CELL", "eastCells", "polys", "out", "points", "EAST_CELLS", "renderEastFrame", "renderEastCell", "cell", "cen", "polyPoints", "renderEastSvg", "renderKundliSvg", "style", "renderKundliStyleTablist", "active", "setStyle", "renderTablist", "css", "kundliStyles", "ROXY_DATA_CLASS", "isJsonScript", "el", "MarkupDataController", "host", "parsed", "inline", "child", "text", "RoxyDivisionalChart", "LitElement", "next", "MarkupDataController", "division", "label", "toKundliViewModel", "vm", "html", "vargottama", "nothing", "renderKundliStyleTablist", "renderKundliSvg", "planet", "PLANET_GLYPH", "baseStyles", "kundliStyles", "tablistStyles", "css", "__decorateClass", "property", "customElement"]
7
7
  }
@@ -7,6 +7,7 @@ type DoshaData = ManglikResponse | KalsarpaResponse | SadhesatiResponse;
7
7
  */
8
8
  export declare class RoxyDoshaCard extends LitElement {
9
9
  static styles: import("lit").CSSResult[];
10
+ constructor();
10
11
  data: DoshaData | null;
11
12
  type: 'manglik' | 'kalsarpa' | 'sadhesati' | string;
12
13
  render(): import("lit").TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"dosha-card.d.ts","sourceRoot":"","sources":["../../src/components/dosha-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAErD,OAAO,KAAK,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,MAAM,mBAAmB,CAAC;AAG3B,KAAK,SAAS,GAAG,eAAe,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAQxE;;;GAGG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC5C,MAAM,CAAC,MAAM,4BA2FX;IAGF,IAAI,EAAE,SAAS,GAAG,IAAI,CAAQ;IAG9B,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,CAAa;IAEhE,MAAM;IA2EN,OAAO,CAAC,aAAa;CAerB;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,iBAAiB,EAAE,aAAa,CAAC;KACjC;CACD"}
1
+ {"version":3,"file":"dosha-card.d.ts","sourceRoot":"","sources":["../../src/components/dosha-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAErD,OAAO,KAAK,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,MAAM,mBAAmB,CAAC;AAI3B,KAAK,SAAS,GAAG,eAAe,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAQxE;;;GAGG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC5C,MAAM,CAAC,MAAM,4BA2FX;;IAWF,IAAI,EAAE,SAAS,GAAG,IAAI,CAAQ;IAG9B,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,CAAa;IAEhE,MAAM;IA2EN,OAAO,CAAC,aAAa;CAerB;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,iBAAiB,EAAE,aAAa,CAAC;KACjC;CACD"}