@roxyapi/ui 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/AGENTS.md +6 -0
  2. package/README.md +9 -3
  3. package/dist/cdn/components/ashtakavarga-grid.js +349 -0
  4. package/dist/cdn/components/ashtakavarga-grid.js.map +7 -0
  5. package/dist/cdn/components/choghadiya-grid.js +239 -0
  6. package/dist/cdn/components/choghadiya-grid.js.map +7 -0
  7. package/dist/cdn/components/compatibility-card.js +6 -6
  8. package/dist/cdn/components/compatibility-card.js.map +1 -1
  9. package/dist/cdn/components/dasha-timeline.js +4 -4
  10. package/dist/cdn/components/dasha-timeline.js.map +1 -1
  11. package/dist/cdn/components/data.js +9 -9
  12. package/dist/cdn/components/data.js.map +4 -4
  13. package/dist/cdn/components/divisional-chart.js +279 -0
  14. package/dist/cdn/components/divisional-chart.js.map +7 -0
  15. package/dist/cdn/components/dosha-card.js +39 -39
  16. package/dist/cdn/components/dosha-card.js.map +3 -3
  17. package/dist/cdn/components/endpoint-form.js +8 -8
  18. package/dist/cdn/components/endpoint-form.js.map +4 -4
  19. package/dist/cdn/components/guna-milan.js +64 -22
  20. package/dist/cdn/components/guna-milan.js.map +3 -3
  21. package/dist/cdn/components/hexagram.js +9 -9
  22. package/dist/cdn/components/hexagram.js.map +3 -3
  23. package/dist/cdn/components/horoscope-card.js +28 -21
  24. package/dist/cdn/components/horoscope-card.js.map +4 -4
  25. package/dist/cdn/components/kp-planets-table.js +4 -4
  26. package/dist/cdn/components/kp-planets-table.js.map +1 -1
  27. package/dist/cdn/components/location-search.js.map +2 -2
  28. package/dist/cdn/components/moon-phase.js +13 -13
  29. package/dist/cdn/components/moon-phase.js.map +3 -3
  30. package/dist/cdn/components/natal-chart.js +196 -22
  31. package/dist/cdn/components/natal-chart.js.map +4 -4
  32. package/dist/cdn/components/numerology-card.js +6 -6
  33. package/dist/cdn/components/numerology-card.js.map +4 -4
  34. package/dist/cdn/components/panchang-table.js +9 -9
  35. package/dist/cdn/components/panchang-table.js.map +1 -1
  36. package/dist/cdn/components/shadbala-table.js +312 -0
  37. package/dist/cdn/components/shadbala-table.js.map +7 -0
  38. package/dist/cdn/components/synastry-chart.js +21 -21
  39. package/dist/cdn/components/synastry-chart.js.map +4 -4
  40. package/dist/cdn/components/transits-table.js +391 -0
  41. package/dist/cdn/components/transits-table.js.map +7 -0
  42. package/dist/cdn/components/vedic-kundli.js +51 -29
  43. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  44. package/dist/cdn/components/yoga-list.js +334 -0
  45. package/dist/cdn/components/yoga-list.js.map +7 -0
  46. package/dist/cdn/roxy-ui.js +1872 -522
  47. package/dist/cdn/roxy-ui.js.map +4 -4
  48. package/dist/components/ashtakavarga-grid.d.ts +26 -0
  49. package/dist/components/ashtakavarga-grid.d.ts.map +1 -0
  50. package/dist/components/ashtakavarga-grid.js +457 -0
  51. package/dist/components/ashtakavarga-grid.js.map +7 -0
  52. package/dist/components/choghadiya-grid.d.ts +19 -0
  53. package/dist/components/choghadiya-grid.d.ts.map +1 -0
  54. package/dist/components/choghadiya-grid.js +304 -0
  55. package/dist/components/choghadiya-grid.js.map +7 -0
  56. package/dist/components/compatibility-card.js.map +1 -1
  57. package/dist/components/dasha-timeline.js.map +1 -1
  58. package/dist/components/data.d.ts +5 -7
  59. package/dist/components/data.d.ts.map +1 -1
  60. package/dist/components/data.js +7 -5
  61. package/dist/components/data.js.map +3 -3
  62. package/dist/components/divisional-chart.d.ts +20 -0
  63. package/dist/components/divisional-chart.d.ts.map +1 -0
  64. package/dist/components/divisional-chart.js +471 -0
  65. package/dist/components/divisional-chart.js.map +7 -0
  66. package/dist/components/dosha-card.d.ts.map +1 -1
  67. package/dist/components/dosha-card.js +33 -30
  68. package/dist/components/dosha-card.js.map +2 -2
  69. package/dist/components/endpoint-form.d.ts.map +1 -1
  70. package/dist/components/endpoint-form.js +5 -3
  71. package/dist/components/endpoint-form.js.map +3 -3
  72. package/dist/components/guna-milan.d.ts.map +1 -1
  73. package/dist/components/guna-milan.js +61 -12
  74. package/dist/components/guna-milan.js.map +3 -3
  75. package/dist/components/hexagram.js +17 -0
  76. package/dist/components/hexagram.js.map +2 -2
  77. package/dist/components/horoscope-card.d.ts.map +1 -1
  78. package/dist/components/horoscope-card.js +30 -3
  79. package/dist/components/horoscope-card.js.map +3 -3
  80. package/dist/components/kp-planets-table.js.map +1 -1
  81. package/dist/components/location-search.d.ts +2 -3
  82. package/dist/components/location-search.d.ts.map +1 -1
  83. package/dist/components/location-search.js.map +2 -2
  84. package/dist/components/moon-phase.js +17 -0
  85. package/dist/components/moon-phase.js.map +2 -2
  86. package/dist/components/natal-chart.d.ts +2 -0
  87. package/dist/components/natal-chart.d.ts.map +1 -1
  88. package/dist/components/natal-chart.js +243 -36
  89. package/dist/components/natal-chart.js.map +3 -3
  90. package/dist/components/numerology-card.d.ts.map +1 -1
  91. package/dist/components/numerology-card.js +5 -3
  92. package/dist/components/numerology-card.js.map +3 -3
  93. package/dist/components/panchang-table.js.map +1 -1
  94. package/dist/components/shadbala-table.d.ts +18 -0
  95. package/dist/components/shadbala-table.d.ts.map +1 -0
  96. package/dist/components/shadbala-table.js +400 -0
  97. package/dist/components/shadbala-table.js.map +7 -0
  98. package/dist/components/synastry-chart.d.ts.map +1 -1
  99. package/dist/components/synastry-chart.js +34 -29
  100. package/dist/components/synastry-chart.js.map +3 -3
  101. package/dist/components/transits-table.d.ts +21 -0
  102. package/dist/components/transits-table.d.ts.map +1 -0
  103. package/dist/components/transits-table.js +515 -0
  104. package/dist/components/transits-table.js.map +7 -0
  105. package/dist/components/vedic-kundli.d.ts +3 -6
  106. package/dist/components/vedic-kundli.d.ts.map +1 -1
  107. package/dist/components/vedic-kundli.js +132 -80
  108. package/dist/components/vedic-kundli.js.map +3 -3
  109. package/dist/components/yoga-list.d.ts +29 -0
  110. package/dist/components/yoga-list.d.ts.map +1 -0
  111. package/dist/components/yoga-list.js +389 -0
  112. package/dist/components/yoga-list.js.map +7 -0
  113. package/dist/index.cjs +2693 -971
  114. package/dist/index.cjs.map +4 -4
  115. package/dist/index.d.ts +7 -2
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +2712 -990
  118. package/dist/index.js.map +4 -4
  119. package/dist/manifest.d.ts +4 -10
  120. package/dist/manifest.d.ts.map +1 -1
  121. package/dist/manifest.json +7 -2
  122. package/dist/styles/tokens.css +26 -0
  123. package/dist/tokens/index.d.ts +6 -0
  124. package/dist/tokens/index.d.ts.map +1 -1
  125. package/dist/types/types.gen.d.ts +2 -2
  126. package/dist/utils/format.d.ts +15 -1
  127. package/dist/utils/format.d.ts.map +1 -1
  128. package/dist/utils/kundli-render.d.ts +63 -0
  129. package/dist/utils/kundli-render.d.ts.map +1 -0
  130. package/dist/utils/string.d.ts +14 -0
  131. package/dist/utils/string.d.ts.map +1 -0
  132. package/dist/version.d.ts +1 -1
  133. package/package.json +1 -1
  134. package/src/components/ashtakavarga-grid.ts +354 -0
  135. package/src/components/choghadiya-grid.ts +185 -0
  136. package/src/components/data.ts +8 -15
  137. package/src/components/divisional-chart.ts +214 -0
  138. package/src/components/dosha-card.ts +53 -36
  139. package/src/components/endpoint-form.ts +1 -7
  140. package/src/components/guna-milan.ts +74 -16
  141. package/src/components/horoscope-card.ts +8 -4
  142. package/src/components/location-search.ts +2 -3
  143. package/src/components/natal-chart.ts +251 -42
  144. package/src/components/numerology-card.ts +1 -7
  145. package/src/components/shadbala-table.ts +286 -0
  146. package/src/components/synastry-chart.ts +13 -39
  147. package/src/components/transits-table.ts +350 -0
  148. package/src/components/vedic-kundli.ts +38 -143
  149. package/src/components/yoga-list.ts +328 -0
  150. package/src/index.ts +8 -6
  151. package/src/manifest.ts +74 -100
  152. package/src/styles/tokens.css +26 -0
  153. package/src/tokens/index.ts +9 -0
  154. package/src/types/types.gen.ts +2 -2
  155. package/src/utils/format.ts +21 -3
  156. package/src/utils/kundli-render.ts +197 -0
  157. package/src/utils/string.ts +23 -0
  158. package/src/version.ts +1 -1
  159. package/dist/utils/motion.d.ts +0 -13
  160. package/dist/utils/motion.d.ts.map +0 -1
  161. package/src/utils/motion.ts +0 -18
@@ -0,0 +1,26 @@
1
+ import { LitElement } from 'lit';
2
+ import type { AshtakavargaResponse } from '../types/index.js';
3
+ type Tab = 'sarva' | 'bhinna' | 'pinda';
4
+ /**
5
+ * Ashtakavarga grid with three tabbed views: Sarvashtakavarga, Bhinnashtakavarga,
6
+ * and Shodhya Pinda. Pass `data` from /vedic-astrology/ashtakavarga.
7
+ */
8
+ export declare class RoxyAshtakavargaGrid extends LitElement {
9
+ static styles: import("lit").CSSResult[];
10
+ data: AshtakavargaResponse | null;
11
+ activeTab: Tab;
12
+ render(): import("lit").TemplateResult<1>;
13
+ private onTabKeyDown;
14
+ private focusActiveTab;
15
+ private heatClass;
16
+ private renderSarva;
17
+ private renderBhinna;
18
+ private renderPinda;
19
+ }
20
+ declare global {
21
+ interface HTMLElementTagNameMap {
22
+ 'roxy-ashtakavarga-grid': RoxyAshtakavargaGrid;
23
+ }
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=ashtakavarga-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ashtakavarga-grid.d.ts","sourceRoot":"","sources":["../../src/components/ashtakavarga-grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAGrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,KAAK,GAAG,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAUxC;;;GAGG;AACH,qBACa,oBAAqB,SAAQ,UAAU;IACnD,MAAM,CAAC,MAAM,4BAmIX;IAGF,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IAGzC,SAAS,EAAE,GAAG,CAAW;IAEzB,MAAM;IAwDN,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,WAAW;IAqCnB,OAAO,CAAC,YAAY;IAiCpB,OAAO,CAAC,WAAW;CA4BnB;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,wBAAwB,EAAE,oBAAoB,CAAC;KAC/C;CACD"}
@@ -0,0 +1,457 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+
12
+ // packages/ui/src/components/ashtakavarga-grid.ts
13
+ import { css as css2, html, LitElement, nothing } from "lit";
14
+ import { customElement, property, state } from "lit/decorators.js";
15
+
16
+ // packages/ui/src/tokens/index.ts
17
+ var SIGN_GLYPH = {
18
+ Aries: "\u2648",
19
+ Taurus: "\u2649",
20
+ Gemini: "\u264A",
21
+ Cancer: "\u264B",
22
+ Leo: "\u264C",
23
+ Virgo: "\u264D",
24
+ Libra: "\u264E",
25
+ Scorpio: "\u264F",
26
+ Sagittarius: "\u2650",
27
+ Capricorn: "\u2651",
28
+ Aquarius: "\u2652",
29
+ Pisces: "\u2653"
30
+ };
31
+ var SIGNS_ORDER = [
32
+ "Aries",
33
+ "Taurus",
34
+ "Gemini",
35
+ "Cancer",
36
+ "Leo",
37
+ "Virgo",
38
+ "Libra",
39
+ "Scorpio",
40
+ "Sagittarius",
41
+ "Capricorn",
42
+ "Aquarius",
43
+ "Pisces"
44
+ ];
45
+ var RASHI_KEYS = SIGNS_ORDER.map(
46
+ (s) => s.toLowerCase()
47
+ );
48
+
49
+ // packages/ui/src/utils/base-styles.ts
50
+ import { css } from "lit";
51
+ var baseStyles = css`
52
+ :host {
53
+ display: block;
54
+ container-type: inline-size;
55
+ font-family: var(
56
+ --roxy-font-sans,
57
+ system-ui,
58
+ -apple-system,
59
+ BlinkMacSystemFont,
60
+ 'Segoe UI',
61
+ Roboto,
62
+ sans-serif
63
+ );
64
+ color: var(--roxy-fg, #0a0a0a);
65
+ background: transparent;
66
+ font-size: var(--roxy-text-base, 1rem);
67
+ line-height: var(--roxy-leading-normal, 1.5);
68
+ animation: roxy-fade-in var(--roxy-motion-duration, 200ms)
69
+ var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1)) both;
70
+ }
71
+
72
+ *,
73
+ *::before,
74
+ *::after {
75
+ box-sizing: border-box;
76
+ }
77
+
78
+ @keyframes roxy-fade-in {
79
+ from {
80
+ opacity: 0;
81
+ transform: translateY(2px);
82
+ }
83
+ to {
84
+ opacity: 1;
85
+ transform: translateY(0);
86
+ }
87
+ }
88
+
89
+ @media (prefers-reduced-motion: reduce) {
90
+ :host {
91
+ animation: none;
92
+ }
93
+ }
94
+
95
+ .roxy-skeleton {
96
+ background: linear-gradient(
97
+ 90deg,
98
+ var(--roxy-border, #e4e4e7) 0%,
99
+ color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent) 50%,
100
+ var(--roxy-border, #e4e4e7) 100%
101
+ );
102
+ background-size: 200% 100%;
103
+ animation: roxy-shimmer 1.4s ease-in-out infinite;
104
+ border-radius: var(--roxy-radius-md, 8px);
105
+ }
106
+
107
+ @keyframes roxy-shimmer {
108
+ 0% {
109
+ background-position: 200% 0;
110
+ }
111
+ 100% {
112
+ background-position: -200% 0;
113
+ }
114
+ }
115
+
116
+ @media (prefers-reduced-motion: reduce) {
117
+ .roxy-skeleton {
118
+ animation: none;
119
+ }
120
+ }
121
+
122
+ .roxy-empty {
123
+ padding: var(--roxy-space-lg, 1.5rem);
124
+ color: var(--roxy-muted, #71717a);
125
+ text-align: center;
126
+ font-size: var(--roxy-text-sm, 0.875rem);
127
+ }
128
+
129
+ :host(:focus-within) .roxy-card {
130
+ outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
131
+ outline-offset: 2px;
132
+ }
133
+ `;
134
+
135
+ // packages/ui/src/components/ashtakavarga-grid.ts
136
+ var TAB_LABELS = {
137
+ sarva: "Sarvashtakavarga",
138
+ bhinna: "Bhinnashtakavarga",
139
+ pinda: "Shodhya Pinda"
140
+ };
141
+ var TABS = ["sarva", "bhinna", "pinda"];
142
+ var RoxyAshtakavargaGrid = class extends LitElement {
143
+ constructor() {
144
+ super(...arguments);
145
+ this.data = null;
146
+ this.activeTab = "sarva";
147
+ }
148
+ render() {
149
+ if (!this.data) {
150
+ return html`<div class="roxy-empty" role="status">No ashtakavarga data</div>`;
151
+ }
152
+ const signs = this.data.signs ?? [];
153
+ return html`<div class="wrap" aria-label="Ashtakavarga grid">
154
+ <div class="head">
155
+ <h2 class="title">Ashtakavarga</h2>
156
+ ${signs.length ? html`<p class="subtitle">${signs.length} signs</p>` : nothing}
157
+ </div>
158
+
159
+ <div
160
+ class="tablist"
161
+ role="tablist"
162
+ aria-label="Ashtakavarga views"
163
+ @keydown=${this.onTabKeyDown}
164
+ >
165
+ ${TABS.map(
166
+ (tab) => html`<button
167
+ class="tab"
168
+ role="tab"
169
+ id="tab-${tab}"
170
+ aria-selected=${this.activeTab === tab ? "true" : "false"}
171
+ aria-controls="panel-${tab}"
172
+ tabindex=${this.activeTab === tab ? "0" : "-1"}
173
+ @click=${() => {
174
+ this.activeTab = tab;
175
+ }}
176
+ >
177
+ ${TAB_LABELS[tab]}
178
+ </button>`
179
+ )}
180
+ </div>
181
+
182
+ <div
183
+ id="panel-${this.activeTab}"
184
+ role="tabpanel"
185
+ aria-labelledby="tab-${this.activeTab}"
186
+ >
187
+ ${this.activeTab === "sarva" ? this.renderSarva(signs) : this.activeTab === "bhinna" ? this.renderBhinna(signs) : this.renderPinda()}
188
+ </div>
189
+ </div>`;
190
+ }
191
+ onTabKeyDown(e) {
192
+ const idx = TABS.indexOf(this.activeTab);
193
+ if (e.key === "ArrowRight") {
194
+ e.preventDefault();
195
+ this.activeTab = TABS[(idx + 1) % TABS.length];
196
+ this.focusActiveTab();
197
+ } else if (e.key === "ArrowLeft") {
198
+ e.preventDefault();
199
+ this.activeTab = TABS[(idx - 1 + TABS.length) % TABS.length];
200
+ this.focusActiveTab();
201
+ }
202
+ }
203
+ focusActiveTab() {
204
+ requestAnimationFrame(() => {
205
+ const btn = this.shadowRoot?.querySelector(
206
+ `#tab-${this.activeTab}`
207
+ );
208
+ btn?.focus();
209
+ });
210
+ }
211
+ heatClass(count) {
212
+ if (count <= 1) return "heat-1";
213
+ if (count <= 2) return "heat-2";
214
+ if (count <= 3) return "heat-3";
215
+ if (count <= 4) return "heat-4";
216
+ if (count <= 5) return "heat-5";
217
+ if (count <= 6) return "heat-6";
218
+ return "heat-7";
219
+ }
220
+ renderSarva(signs) {
221
+ const sav = this.data.sarvashtakavarga;
222
+ if (!sav) return html`<p class="roxy-empty">No sarvashtakavarga data</p>`;
223
+ return html`<div class="overflow-scroll">
224
+ <table aria-label="Sarvashtakavarga bindu counts per sign">
225
+ <thead>
226
+ <tr>
227
+ <th scope="col">Sign</th>
228
+ <th scope="col">Bindus</th>
229
+ </tr>
230
+ </thead>
231
+ <tbody>
232
+ ${signs.map((sign, i) => {
233
+ const count = sav.bindus[i] ?? 0;
234
+ const hc = this.heatClass(count);
235
+ return html`<tr>
236
+ <td>
237
+ <div class="planet-cell">
238
+ <span class="glyph" aria-hidden="true">${SIGN_GLYPH[sign] ?? ""}</span>
239
+ ${sign}
240
+ </div>
241
+ </td>
242
+ <td class="${`heat-cell ${hc}`}">${count}</td>
243
+ </tr>`;
244
+ })}
245
+ </tbody>
246
+ <tfoot>
247
+ <tr class="total-row">
248
+ <td>Total</td>
249
+ <td>${sav.total}</td>
250
+ </tr>
251
+ </tfoot>
252
+ </table>
253
+ </div>`;
254
+ }
255
+ renderBhinna(signs) {
256
+ const bhinna = this.data.bhinnashtakavarga;
257
+ if (!bhinna?.length)
258
+ return html`<p class="roxy-empty">No bhinnashtakavarga data</p>`;
259
+ return html`<div class="overflow-scroll">
260
+ <table class="bhinna-table" aria-label="Bhinnashtakavarga planet-by-sign grid">
261
+ <thead>
262
+ <tr>
263
+ <th scope="col">Planet</th>
264
+ ${signs.map(
265
+ (s) => html`<th scope="col" title=${s}>${SIGN_GLYPH[s] ?? s.slice(0, 2)}</th>`
266
+ )}
267
+ <th scope="col">Total</th>
268
+ </tr>
269
+ </thead>
270
+ <tbody>
271
+ ${bhinna.map(
272
+ (row) => html`<tr>
273
+ <td>${row.planet}</td>
274
+ ${row.bindus.map((count) => {
275
+ const hc = this.heatClass(count);
276
+ return html`<td class="${`heat-cell ${hc}`}">${count}</td>`;
277
+ })}
278
+ <td>${row.total}</td>
279
+ </tr>`
280
+ )}
281
+ </tbody>
282
+ </table>
283
+ </div>`;
284
+ }
285
+ renderPinda() {
286
+ const pinda = this.data.shodhyaPinda;
287
+ if (!pinda?.length)
288
+ return html`<p class="roxy-empty">No shodhya pinda data</p>`;
289
+ return html`<div class="overflow-scroll">
290
+ <table aria-label="Shodhya Pinda planet strength scores">
291
+ <thead>
292
+ <tr>
293
+ <th scope="col">Planet</th>
294
+ <th scope="col">Rashi Pinda</th>
295
+ <th scope="col">Graha Pinda</th>
296
+ <th scope="col">Shodhya Pinda</th>
297
+ </tr>
298
+ </thead>
299
+ <tbody>
300
+ ${pinda.map(
301
+ (row) => html`<tr>
302
+ <td>${row.planet}</td>
303
+ <td>${row.rashiPinda}</td>
304
+ <td>${row.grahaPinda}</td>
305
+ <td>${row.shodhyaPinda}</td>
306
+ </tr>`
307
+ )}
308
+ </tbody>
309
+ </table>
310
+ </div>`;
311
+ }
312
+ };
313
+ RoxyAshtakavargaGrid.styles = [
314
+ baseStyles,
315
+ css2`
316
+ .wrap {
317
+ display: grid;
318
+ gap: var(--roxy-space-md, 1rem);
319
+ }
320
+
321
+ .head {
322
+ display: flex;
323
+ justify-content: space-between;
324
+ align-items: baseline;
325
+ gap: var(--roxy-space-md, 1rem);
326
+ flex-wrap: wrap;
327
+ }
328
+
329
+ .title {
330
+ font-size: var(--roxy-text-lg, 1.125rem);
331
+ font-weight: var(--roxy-weight-bold, 600);
332
+ margin: 0;
333
+ }
334
+
335
+ .subtitle {
336
+ color: var(--roxy-muted, #71717a);
337
+ font-size: var(--roxy-text-sm, 0.875rem);
338
+ margin: 0;
339
+ }
340
+
341
+ /* Tabs */
342
+ .tablist {
343
+ display: flex;
344
+ gap: 2px;
345
+ border-bottom: 2px solid var(--roxy-border, #e4e4e7);
346
+ }
347
+
348
+ .tab {
349
+ padding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);
350
+ font-size: var(--roxy-text-sm, 0.875rem);
351
+ background: none;
352
+ border: none;
353
+ border-bottom: 2px solid transparent;
354
+ margin-bottom: -2px;
355
+ cursor: pointer;
356
+ color: var(--roxy-muted, #71717a);
357
+ font-family: inherit;
358
+ transition: color var(--roxy-motion-duration, 200ms) var(--roxy-motion-easing, ease);
359
+ }
360
+
361
+ .tab[aria-selected='true'] {
362
+ color: var(--roxy-accent-fg, #b45309);
363
+ border-bottom-color: var(--roxy-accent, #f59e0b);
364
+ font-weight: var(--roxy-weight-bold, 600);
365
+ }
366
+
367
+ .tab:hover:not([aria-selected='true']) {
368
+ color: var(--roxy-fg, #0a0a0a);
369
+ }
370
+
371
+ /* Tables */
372
+ .overflow-scroll {
373
+ overflow-x: auto;
374
+ -webkit-overflow-scrolling: touch;
375
+ }
376
+
377
+ table {
378
+ width: 100%;
379
+ border-collapse: collapse;
380
+ font-size: var(--roxy-text-sm, 0.875rem);
381
+ }
382
+
383
+ th,
384
+ td {
385
+ padding: var(--roxy-space-sm, 0.5rem);
386
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
387
+ text-align: center;
388
+ }
389
+
390
+ th {
391
+ color: var(--roxy-muted, #71717a);
392
+ font-weight: var(--roxy-weight-bold, 600);
393
+ text-transform: uppercase;
394
+ font-size: var(--roxy-text-xs, 0.75rem);
395
+ letter-spacing: 0.06em;
396
+ }
397
+
398
+ td:first-child,
399
+ th:first-child {
400
+ text-align: left;
401
+ }
402
+
403
+ .glyph {
404
+ font-size: 1.1em;
405
+ margin-right: 3px;
406
+ line-height: 1;
407
+ }
408
+
409
+ .planet-cell {
410
+ display: flex;
411
+ align-items: center;
412
+ gap: 4px;
413
+ white-space: nowrap;
414
+ }
415
+
416
+ .total-row td {
417
+ font-weight: var(--roxy-weight-bold, 600);
418
+ border-top: 2px solid var(--roxy-border, #e4e4e7);
419
+ border-bottom: none;
420
+ }
421
+
422
+ /* Heat cells */
423
+ .heat-cell {
424
+ border-radius: var(--roxy-radius-sm, 4px);
425
+ font-weight: var(--roxy-weight-bold, 600);
426
+ min-width: 2rem;
427
+ font-variant-numeric: tabular-nums;
428
+ }
429
+
430
+ .heat-1 { background: var(--roxy-heat-1, #f0fdf4); color: var(--roxy-fg, #0a0a0a); }
431
+ .heat-2 { background: var(--roxy-heat-2, #d1fae5); color: var(--roxy-fg, #0a0a0a); }
432
+ .heat-3 { background: var(--roxy-heat-3, #a7f3d0); color: var(--roxy-fg, #0a0a0a); }
433
+ .heat-4 { background: var(--roxy-heat-4, #fde68a); color: var(--roxy-fg, #0a0a0a); }
434
+ .heat-5 { background: var(--roxy-heat-5, #fdba74); color: var(--roxy-fg, #0a0a0a); }
435
+ .heat-6 { background: var(--roxy-heat-6, #fb923c); color: var(--roxy-fg, #0a0a0a); }
436
+ .heat-7 { background: var(--roxy-heat-7, #ef4444); color: var(--roxy-fg, #0a0a0a); }
437
+
438
+ /* Bhinna grid: planet header column narrower */
439
+ .bhinna-table th:first-child,
440
+ .bhinna-table td:first-child {
441
+ min-width: 5rem;
442
+ }
443
+ `
444
+ ];
445
+ __decorateClass([
446
+ property({ attribute: false })
447
+ ], RoxyAshtakavargaGrid.prototype, "data", 2);
448
+ __decorateClass([
449
+ state()
450
+ ], RoxyAshtakavargaGrid.prototype, "activeTab", 2);
451
+ RoxyAshtakavargaGrid = __decorateClass([
452
+ customElement("roxy-ashtakavarga-grid")
453
+ ], RoxyAshtakavargaGrid);
454
+ export {
455
+ RoxyAshtakavargaGrid
456
+ };
457
+ //# sourceMappingURL=ashtakavarga-grid.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/components/ashtakavarga-grid.ts", "../../src/tokens/index.ts", "../../src/utils/base-styles.ts"],
4
+ "sourcesContent": ["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { SIGN_GLYPH } from '../tokens/index.js';\nimport type { AshtakavargaResponse } from '../types/index.js';\nimport { baseStyles } from '../utils/base-styles.js';\n\ntype Tab = 'sarva' | 'bhinna' | 'pinda';\n\nconst TAB_LABELS: Record<Tab, string> = {\n\tsarva: 'Sarvashtakavarga',\n\tbhinna: 'Bhinnashtakavarga',\n\tpinda: 'Shodhya Pinda',\n};\n\nconst TABS: Tab[] = ['sarva', 'bhinna', 'pinda'];\n\n/**\n * Ashtakavarga grid with three tabbed views: Sarvashtakavarga, Bhinnashtakavarga,\n * and Shodhya Pinda. Pass `data` from /vedic-astrology/ashtakavarga.\n */\n@customElement('roxy-ashtakavarga-grid')\nexport class RoxyAshtakavargaGrid extends LitElement {\n\tstatic styles = [\n\t\tbaseStyles,\n\t\tcss`\n\t\t\t.wrap {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgap: var(--roxy-space-md, 1rem);\n\t\t\t}\n\n\t\t\t.head {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: space-between;\n\t\t\t\talign-items: baseline;\n\t\t\t\tgap: var(--roxy-space-md, 1rem);\n\t\t\t\tflex-wrap: wrap;\n\t\t\t}\n\n\t\t\t.title {\n\t\t\t\tfont-size: var(--roxy-text-lg, 1.125rem);\n\t\t\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.subtitle {\n\t\t\t\tcolor: var(--roxy-muted, #71717a);\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t/* Tabs */\n\t\t\t.tablist {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 2px;\n\t\t\t\tborder-bottom: 2px solid var(--roxy-border, #e4e4e7);\n\t\t\t}\n\n\t\t\t.tab {\n\t\t\t\tpadding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t\tbackground: none;\n\t\t\t\tborder: none;\n\t\t\t\tborder-bottom: 2px solid transparent;\n\t\t\t\tmargin-bottom: -2px;\n\t\t\t\tcursor: pointer;\n\t\t\t\tcolor: var(--roxy-muted, #71717a);\n\t\t\t\tfont-family: inherit;\n\t\t\t\ttransition: color var(--roxy-motion-duration, 200ms) var(--roxy-motion-easing, ease);\n\t\t\t}\n\n\t\t\t.tab[aria-selected='true'] {\n\t\t\t\tcolor: var(--roxy-accent-fg, #b45309);\n\t\t\t\tborder-bottom-color: var(--roxy-accent, #f59e0b);\n\t\t\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t\t\t}\n\n\t\t\t.tab:hover:not([aria-selected='true']) {\n\t\t\t\tcolor: var(--roxy-fg, #0a0a0a);\n\t\t\t}\n\n\t\t\t/* Tables */\n\t\t\t.overflow-scroll {\n\t\t\t\toverflow-x: auto;\n\t\t\t\t-webkit-overflow-scrolling: touch;\n\t\t\t}\n\n\t\t\ttable {\n\t\t\t\twidth: 100%;\n\t\t\t\tborder-collapse: collapse;\n\t\t\t\tfont-size: var(--roxy-text-sm, 0.875rem);\n\t\t\t}\n\n\t\t\tth,\n\t\t\ttd {\n\t\t\t\tpadding: var(--roxy-space-sm, 0.5rem);\n\t\t\t\tborder-bottom: 1px solid var(--roxy-border, #e4e4e7);\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\tth {\n\t\t\t\tcolor: var(--roxy-muted, #71717a);\n\t\t\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tfont-size: var(--roxy-text-xs, 0.75rem);\n\t\t\t\tletter-spacing: 0.06em;\n\t\t\t}\n\n\t\t\ttd:first-child,\n\t\t\tth:first-child {\n\t\t\t\ttext-align: left;\n\t\t\t}\n\n\t\t\t.glyph {\n\t\t\t\tfont-size: 1.1em;\n\t\t\t\tmargin-right: 3px;\n\t\t\t\tline-height: 1;\n\t\t\t}\n\n\t\t\t.planet-cell {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tgap: 4px;\n\t\t\t\twhite-space: nowrap;\n\t\t\t}\n\n\t\t\t.total-row td {\n\t\t\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t\t\t\tborder-top: 2px solid var(--roxy-border, #e4e4e7);\n\t\t\t\tborder-bottom: none;\n\t\t\t}\n\n\t\t\t/* Heat cells */\n\t\t\t.heat-cell {\n\t\t\t\tborder-radius: var(--roxy-radius-sm, 4px);\n\t\t\t\tfont-weight: var(--roxy-weight-bold, 600);\n\t\t\t\tmin-width: 2rem;\n\t\t\t\tfont-variant-numeric: tabular-nums;\n\t\t\t}\n\n\t\t\t.heat-1 { background: var(--roxy-heat-1, #f0fdf4); color: var(--roxy-fg, #0a0a0a); }\n\t\t\t.heat-2 { background: var(--roxy-heat-2, #d1fae5); color: var(--roxy-fg, #0a0a0a); }\n\t\t\t.heat-3 { background: var(--roxy-heat-3, #a7f3d0); color: var(--roxy-fg, #0a0a0a); }\n\t\t\t.heat-4 { background: var(--roxy-heat-4, #fde68a); color: var(--roxy-fg, #0a0a0a); }\n\t\t\t.heat-5 { background: var(--roxy-heat-5, #fdba74); color: var(--roxy-fg, #0a0a0a); }\n\t\t\t.heat-6 { background: var(--roxy-heat-6, #fb923c); color: var(--roxy-fg, #0a0a0a); }\n\t\t\t.heat-7 { background: var(--roxy-heat-7, #ef4444); color: var(--roxy-fg, #0a0a0a); }\n\n\t\t\t/* Bhinna grid: planet header column narrower */\n\t\t\t.bhinna-table th:first-child,\n\t\t\t.bhinna-table td:first-child {\n\t\t\t\tmin-width: 5rem;\n\t\t\t}\n\t\t`,\n\t];\n\n\t@property({ attribute: false })\n\tdata: AshtakavargaResponse | null = null;\n\n\t@state()\n\tactiveTab: Tab = 'sarva';\n\n\trender() {\n\t\tif (!this.data) {\n\t\t\treturn html`<div class=\"roxy-empty\" role=\"status\">No ashtakavarga data</div>`;\n\t\t}\n\n\t\tconst signs = this.data.signs ?? [];\n\n\t\treturn html`<div class=\"wrap\" aria-label=\"Ashtakavarga grid\">\n\t\t\t<div class=\"head\">\n\t\t\t\t<h2 class=\"title\">Ashtakavarga</h2>\n\t\t\t\t${\n\t\t\t\t\tsigns.length\n\t\t\t\t\t\t? html`<p class=\"subtitle\">${signs.length} signs</p>`\n\t\t\t\t\t\t: nothing\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<div\n\t\t\t\tclass=\"tablist\"\n\t\t\t\trole=\"tablist\"\n\t\t\t\taria-label=\"Ashtakavarga views\"\n\t\t\t\t@keydown=${this.onTabKeyDown}\n\t\t\t>\n\t\t\t\t${TABS.map(\n\t\t\t\t\t(tab) => html`<button\n\t\t\t\t\t\tclass=\"tab\"\n\t\t\t\t\t\trole=\"tab\"\n\t\t\t\t\t\tid=\"tab-${tab}\"\n\t\t\t\t\t\taria-selected=${this.activeTab === tab ? 'true' : 'false'}\n\t\t\t\t\t\taria-controls=\"panel-${tab}\"\n\t\t\t\t\t\ttabindex=${this.activeTab === tab ? '0' : '-1'}\n\t\t\t\t\t\t@click=${() => {\n\t\t\t\t\t\t\tthis.activeTab = tab;\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t${TAB_LABELS[tab]}\n\t\t\t\t\t</button>`,\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t<div\n\t\t\t\tid=\"panel-${this.activeTab}\"\n\t\t\t\trole=\"tabpanel\"\n\t\t\t\taria-labelledby=\"tab-${this.activeTab}\"\n\t\t\t>\n\t\t\t\t${\n\t\t\t\t\tthis.activeTab === 'sarva'\n\t\t\t\t\t\t? this.renderSarva(signs)\n\t\t\t\t\t\t: this.activeTab === 'bhinna'\n\t\t\t\t\t\t\t? this.renderBhinna(signs)\n\t\t\t\t\t\t\t: this.renderPinda()\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>`;\n\t}\n\n\tprivate onTabKeyDown(e: KeyboardEvent) {\n\t\tconst idx = TABS.indexOf(this.activeTab);\n\t\tif (e.key === 'ArrowRight') {\n\t\t\te.preventDefault();\n\t\t\tthis.activeTab = TABS[(idx + 1) % TABS.length];\n\t\t\tthis.focusActiveTab();\n\t\t} else if (e.key === 'ArrowLeft') {\n\t\t\te.preventDefault();\n\t\t\tthis.activeTab = TABS[(idx - 1 + TABS.length) % TABS.length];\n\t\t\tthis.focusActiveTab();\n\t\t}\n\t}\n\n\tprivate focusActiveTab() {\n\t\trequestAnimationFrame(() => {\n\t\t\tconst btn = this.shadowRoot?.querySelector<HTMLButtonElement>(\n\t\t\t\t`#tab-${this.activeTab}`,\n\t\t\t);\n\t\t\tbtn?.focus();\n\t\t});\n\t}\n\n\tprivate heatClass(count: number): string {\n\t\tif (count <= 1) return 'heat-1';\n\t\tif (count <= 2) return 'heat-2';\n\t\tif (count <= 3) return 'heat-3';\n\t\tif (count <= 4) return 'heat-4';\n\t\tif (count <= 5) return 'heat-5';\n\t\tif (count <= 6) return 'heat-6';\n\t\treturn 'heat-7';\n\t}\n\n\tprivate renderSarva(signs: AshtakavargaResponse['signs']) {\n\t\tconst sav = this.data!.sarvashtakavarga;\n\t\tif (!sav) return html`<p class=\"roxy-empty\">No sarvashtakavarga data</p>`;\n\n\t\treturn html`<div class=\"overflow-scroll\">\n\t\t\t<table aria-label=\"Sarvashtakavarga bindu counts per sign\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th scope=\"col\">Sign</th>\n\t\t\t\t\t\t<th scope=\"col\">Bindus</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t${signs.map((sign, i) => {\n\t\t\t\t\t\tconst count = sav.bindus[i] ?? 0;\n\t\t\t\t\t\tconst hc = this.heatClass(count);\n\t\t\t\t\t\treturn html`<tr>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<div class=\"planet-cell\">\n\t\t\t\t\t\t\t\t\t<span class=\"glyph\" aria-hidden=\"true\">${SIGN_GLYPH[sign] ?? ''}</span>\n\t\t\t\t\t\t\t\t\t${sign}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"${`heat-cell ${hc}`}\">${count}</td>\n\t\t\t\t\t\t</tr>`;\n\t\t\t\t\t})}\n\t\t\t\t</tbody>\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr class=\"total-row\">\n\t\t\t\t\t\t<td>Total</td>\n\t\t\t\t\t\t<td>${sav.total}</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\t\t</div>`;\n\t}\n\n\tprivate renderBhinna(signs: AshtakavargaResponse['signs']) {\n\t\tconst bhinna = this.data!.bhinnashtakavarga;\n\t\tif (!bhinna?.length)\n\t\t\treturn html`<p class=\"roxy-empty\">No bhinnashtakavarga data</p>`;\n\n\t\treturn html`<div class=\"overflow-scroll\">\n\t\t\t<table class=\"bhinna-table\" aria-label=\"Bhinnashtakavarga planet-by-sign grid\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th scope=\"col\">Planet</th>\n\t\t\t\t\t\t${signs.map(\n\t\t\t\t\t\t\t(s) =>\n\t\t\t\t\t\t\t\thtml`<th scope=\"col\" title=${s}>${SIGN_GLYPH[s] ?? s.slice(0, 2)}</th>`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<th scope=\"col\">Total</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t${bhinna.map(\n\t\t\t\t\t\t(row) => html`<tr>\n\t\t\t\t\t\t<td>${row.planet}</td>\n\t\t\t\t\t\t${row.bindus.map((count) => {\n\t\t\t\t\t\t\tconst hc = this.heatClass(count);\n\t\t\t\t\t\t\treturn html`<td class=\"${`heat-cell ${hc}`}\">${count}</td>`;\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t<td>${row.total}</td>\n\t\t\t\t\t</tr>`,\n\t\t\t\t\t)}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>`;\n\t}\n\n\tprivate renderPinda() {\n\t\tconst pinda = this.data!.shodhyaPinda;\n\t\tif (!pinda?.length)\n\t\t\treturn html`<p class=\"roxy-empty\">No shodhya pinda data</p>`;\n\n\t\treturn html`<div class=\"overflow-scroll\">\n\t\t\t<table aria-label=\"Shodhya Pinda planet strength scores\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th scope=\"col\">Planet</th>\n\t\t\t\t\t\t<th scope=\"col\">Rashi Pinda</th>\n\t\t\t\t\t\t<th scope=\"col\">Graha Pinda</th>\n\t\t\t\t\t\t<th scope=\"col\">Shodhya Pinda</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t${pinda.map(\n\t\t\t\t\t\t(row) => html`<tr>\n\t\t\t\t\t\t\t<td>${row.planet}</td>\n\t\t\t\t\t\t\t<td>${row.rashiPinda}</td>\n\t\t\t\t\t\t\t<td>${row.grahaPinda}</td>\n\t\t\t\t\t\t\t<td>${row.shodhyaPinda}</td>\n\t\t\t\t\t\t</tr>`,\n\t\t\t\t\t)}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>`;\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'roxy-ashtakavarga-grid': RoxyAshtakavargaGrid;\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"],
5
+ "mappings": "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",
6
+ "names": ["css", "css"]
7
+ }
@@ -0,0 +1,19 @@
1
+ import { LitElement } from 'lit';
2
+ import type { GetChoghadiyaResponse } from '../types/index.js';
3
+ /**
4
+ * Choghadiya muhurta grid. Accepts a GetChoghadiyaResponse and renders
5
+ * 8 daytime and 8 nighttime muhurta tiles in a two-column responsive layout.
6
+ * Good periods are highlighted in green, Bad periods in red.
7
+ */
8
+ export declare class RoxyChoghadiyaGrid extends LitElement {
9
+ static styles: import("lit").CSSResult[];
10
+ data: GetChoghadiyaResponse | null;
11
+ private renderTile;
12
+ render(): import("lit").TemplateResult<1>;
13
+ }
14
+ declare global {
15
+ interface HTMLElementTagNameMap {
16
+ 'roxy-choghadiya-grid': RoxyChoghadiyaGrid;
17
+ }
18
+ }
19
+ //# sourceMappingURL=choghadiya-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choghadiya-grid.d.ts","sourceRoot":"","sources":["../../src/components/choghadiya-grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAoB/D;;;;GAIG;AACH,qBACa,kBAAmB,SAAQ,UAAU;IACjD,MAAM,CAAC,MAAM,4BAuFX;IAGF,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAAQ;IAE1C,OAAO,CAAC,UAAU;IAmBlB,MAAM;CAqCN;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,sBAAsB,EAAE,kBAAkB,CAAC;KAC3C;CACD"}