@roxyapi/ui 0.3.1 → 0.4.1

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 (165) hide show
  1. package/AGENTS.md +34 -7
  2. package/README.md +145 -26
  3. package/dist/cdn/components/ashtakavarga-grid.js +74 -19
  4. package/dist/cdn/components/ashtakavarga-grid.js.map +2 -2
  5. package/dist/cdn/components/biorhythm-chart.js +18 -4
  6. package/dist/cdn/components/biorhythm-chart.js.map +2 -2
  7. package/dist/cdn/components/choghadiya-grid.js +47 -12
  8. package/dist/cdn/components/choghadiya-grid.js.map +3 -3
  9. package/dist/cdn/components/compatibility-card.js +21 -7
  10. package/dist/cdn/components/compatibility-card.js.map +2 -2
  11. package/dist/cdn/components/dasha-timeline.js +113 -28
  12. package/dist/cdn/components/dasha-timeline.js.map +3 -3
  13. package/dist/cdn/components/data.js +27 -13
  14. package/dist/cdn/components/data.js.map +2 -2
  15. package/dist/cdn/components/divisional-chart.js +225 -118
  16. package/dist/cdn/components/divisional-chart.js.map +4 -4
  17. package/dist/cdn/components/dosha-card.js +18 -4
  18. package/dist/cdn/components/dosha-card.js.map +2 -2
  19. package/dist/cdn/components/endpoint-form.js +25 -11
  20. package/dist/cdn/components/endpoint-form.js.map +2 -2
  21. package/dist/cdn/components/guna-milan.js +20 -6
  22. package/dist/cdn/components/guna-milan.js.map +2 -2
  23. package/dist/cdn/components/hexagram.js +22 -8
  24. package/dist/cdn/components/hexagram.js.map +2 -2
  25. package/dist/cdn/components/horoscope-card.js +20 -6
  26. package/dist/cdn/components/horoscope-card.js.map +2 -2
  27. package/dist/cdn/components/kp-chart.js +19 -5
  28. package/dist/cdn/components/kp-chart.js.map +2 -2
  29. package/dist/cdn/components/kp-planets-table.js +17 -3
  30. package/dist/cdn/components/kp-planets-table.js.map +2 -2
  31. package/dist/cdn/components/kp-ruling-planets.js +17 -3
  32. package/dist/cdn/components/kp-ruling-planets.js.map +2 -2
  33. package/dist/cdn/components/location-search.js +18 -4
  34. package/dist/cdn/components/location-search.js.map +2 -2
  35. package/dist/cdn/components/moon-phase.js +27 -13
  36. package/dist/cdn/components/moon-phase.js.map +2 -2
  37. package/dist/cdn/components/nakshatra-card.js +16 -2
  38. package/dist/cdn/components/nakshatra-card.js.map +2 -2
  39. package/dist/cdn/components/natal-chart.js +79 -40
  40. package/dist/cdn/components/natal-chart.js.map +3 -3
  41. package/dist/cdn/components/numerology-card.js +18 -4
  42. package/dist/cdn/components/numerology-card.js.map +2 -2
  43. package/dist/cdn/components/panchang-table.js +53 -25
  44. package/dist/cdn/components/panchang-table.js.map +3 -3
  45. package/dist/cdn/components/shadbala-table.js +24 -10
  46. package/dist/cdn/components/shadbala-table.js.map +2 -2
  47. package/dist/cdn/components/synastry-chart.js +96 -48
  48. package/dist/cdn/components/synastry-chart.js.map +3 -3
  49. package/dist/cdn/components/tarot-card.js +17 -3
  50. package/dist/cdn/components/tarot-card.js.map +2 -2
  51. package/dist/cdn/components/tarot-spread.js +39 -25
  52. package/dist/cdn/components/tarot-spread.js.map +2 -2
  53. package/dist/cdn/components/transits-table.js +18 -4
  54. package/dist/cdn/components/transits-table.js.map +2 -2
  55. package/dist/cdn/components/vedic-kundli.js +215 -105
  56. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  57. package/dist/cdn/components/vedic-planets-table.js +22 -8
  58. package/dist/cdn/components/vedic-planets-table.js.map +2 -2
  59. package/dist/cdn/components/western-planets-table.js +18 -4
  60. package/dist/cdn/components/western-planets-table.js.map +2 -2
  61. package/dist/cdn/components/yoga-list.js +17 -3
  62. package/dist/cdn/components/yoga-list.js.map +2 -2
  63. package/dist/cdn/roxy-ui.js +1082 -816
  64. package/dist/cdn/roxy-ui.js.map +4 -4
  65. package/dist/components/ashtakavarga-grid.d.ts +13 -1
  66. package/dist/components/ashtakavarga-grid.d.ts.map +1 -1
  67. package/dist/components/ashtakavarga-grid.js +86 -11
  68. package/dist/components/ashtakavarga-grid.js.map +2 -2
  69. package/dist/components/biorhythm-chart.js +14 -0
  70. package/dist/components/biorhythm-chart.js.map +2 -2
  71. package/dist/components/choghadiya-grid.d.ts +6 -0
  72. package/dist/components/choghadiya-grid.d.ts.map +1 -1
  73. package/dist/components/choghadiya-grid.js +50 -2
  74. package/dist/components/choghadiya-grid.js.map +2 -2
  75. package/dist/components/compatibility-card.js +14 -0
  76. package/dist/components/compatibility-card.js.map +2 -2
  77. package/dist/components/dasha-timeline.d.ts +10 -0
  78. package/dist/components/dasha-timeline.d.ts.map +1 -1
  79. package/dist/components/dasha-timeline.js +135 -4
  80. package/dist/components/dasha-timeline.js.map +2 -2
  81. package/dist/components/data.js +14 -0
  82. package/dist/components/data.js.map +2 -2
  83. package/dist/components/divisional-chart.d.ts +9 -6
  84. package/dist/components/divisional-chart.d.ts.map +1 -1
  85. package/dist/components/divisional-chart.js +546 -251
  86. package/dist/components/divisional-chart.js.map +4 -4
  87. package/dist/components/dosha-card.js +14 -0
  88. package/dist/components/dosha-card.js.map +2 -2
  89. package/dist/components/endpoint-form.js +14 -0
  90. package/dist/components/endpoint-form.js.map +2 -2
  91. package/dist/components/guna-milan.js +14 -0
  92. package/dist/components/guna-milan.js.map +2 -2
  93. package/dist/components/hexagram.js +14 -0
  94. package/dist/components/hexagram.js.map +2 -2
  95. package/dist/components/horoscope-card.js +14 -0
  96. package/dist/components/horoscope-card.js.map +2 -2
  97. package/dist/components/kp-chart.js +14 -0
  98. package/dist/components/kp-chart.js.map +2 -2
  99. package/dist/components/kp-planets-table.js +14 -0
  100. package/dist/components/kp-planets-table.js.map +2 -2
  101. package/dist/components/kp-ruling-planets.js +14 -0
  102. package/dist/components/kp-ruling-planets.js.map +2 -2
  103. package/dist/components/location-search.js +14 -0
  104. package/dist/components/location-search.js.map +2 -2
  105. package/dist/components/moon-phase.js +14 -0
  106. package/dist/components/moon-phase.js.map +2 -2
  107. package/dist/components/nakshatra-card.js +14 -0
  108. package/dist/components/nakshatra-card.js.map +2 -2
  109. package/dist/components/natal-chart.d.ts.map +1 -1
  110. package/dist/components/natal-chart.js +76 -6
  111. package/dist/components/natal-chart.js.map +2 -2
  112. package/dist/components/numerology-card.js +14 -0
  113. package/dist/components/numerology-card.js.map +2 -2
  114. package/dist/components/panchang-table.d.ts +1 -0
  115. package/dist/components/panchang-table.d.ts.map +1 -1
  116. package/dist/components/panchang-table.js +37 -1
  117. package/dist/components/panchang-table.js.map +2 -2
  118. package/dist/components/shadbala-table.js +14 -0
  119. package/dist/components/shadbala-table.js.map +2 -2
  120. package/dist/components/synastry-chart.d.ts +6 -0
  121. package/dist/components/synastry-chart.d.ts.map +1 -1
  122. package/dist/components/synastry-chart.js +106 -7
  123. package/dist/components/synastry-chart.js.map +2 -2
  124. package/dist/components/tarot-card.js +14 -0
  125. package/dist/components/tarot-card.js.map +2 -2
  126. package/dist/components/tarot-spread.js +14 -0
  127. package/dist/components/tarot-spread.js.map +2 -2
  128. package/dist/components/transits-table.js +14 -0
  129. package/dist/components/transits-table.js.map +2 -2
  130. package/dist/components/vedic-kundli.d.ts +14 -9
  131. package/dist/components/vedic-kundli.d.ts.map +1 -1
  132. package/dist/components/vedic-kundli.js +537 -245
  133. package/dist/components/vedic-kundli.js.map +4 -4
  134. package/dist/components/vedic-planets-table.js +14 -0
  135. package/dist/components/vedic-planets-table.js.map +2 -2
  136. package/dist/components/western-planets-table.js +14 -0
  137. package/dist/components/western-planets-table.js.map +2 -2
  138. package/dist/components/yoga-list.js +14 -0
  139. package/dist/components/yoga-list.js.map +2 -2
  140. package/dist/index.cjs +1397 -797
  141. package/dist/index.cjs.map +4 -4
  142. package/dist/index.js +1278 -678
  143. package/dist/index.js.map +4 -4
  144. package/dist/manifest.json +23 -23
  145. package/dist/styles/tokens.css +8 -23
  146. package/dist/utils/base-styles.d.ts.map +1 -1
  147. package/dist/utils/kundli-render.d.ts +43 -104
  148. package/dist/utils/kundli-render.d.ts.map +1 -1
  149. package/dist/utils/kundli-styles.d.ts +13 -0
  150. package/dist/utils/kundli-styles.d.ts.map +1 -0
  151. package/dist/version.d.ts +1 -1
  152. package/package.json +1 -1
  153. package/src/components/ashtakavarga-grid.ts +73 -11
  154. package/src/components/choghadiya-grid.ts +37 -2
  155. package/src/components/dasha-timeline.ts +135 -4
  156. package/src/components/divisional-chart.ts +40 -97
  157. package/src/components/natal-chart.ts +89 -6
  158. package/src/components/panchang-table.ts +34 -1
  159. package/src/components/synastry-chart.ts +84 -8
  160. package/src/components/vedic-kundli.ts +35 -95
  161. package/src/styles/tokens.css +8 -23
  162. package/src/utils/base-styles.ts +14 -0
  163. package/src/utils/kundli-render.ts +609 -270
  164. package/src/utils/kundli-styles.ts +124 -0
  165. package/src/version.ts +1 -1
package/dist/index.cjs CHANGED
@@ -276,6 +276,20 @@ var baseStyles = import_lit.css`
276
276
  outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
277
277
  outline-offset: 2px;
278
278
  }
279
+
280
+ /* Force the text-style variant on every Unicode glyph in the component.
281
+ * macOS and iOS substitute coloured emoji glyphs for the planetary and
282
+ * gender Unicode code points (Mars, Venus, Mercury, etc.) when the
283
+ * system colour-emoji font wins font selection. The text-style variant
284
+ * keeps glyphs monochrome so they inherit the surrounding fill colour
285
+ * and match the brand palette consistently across platforms.
286
+ *
287
+ * font-variant-emoji is part of CSS Fonts 4 (Safari 17+, Chrome 134+,
288
+ * Firefox 139+). On older browsers the rule is silently ignored.
289
+ */
290
+ :host {
291
+ font-variant-emoji: text;
292
+ }
279
293
  `;
280
294
 
281
295
  // packages/ui/src/components/ashtakavarga-grid.ts
@@ -354,7 +368,11 @@ var RoxyAshtakavargaGrid = class extends import_lit2.LitElement {
354
368
  btn?.focus();
355
369
  });
356
370
  }
357
- heatClass(count) {
371
+ /**
372
+ * Bhinna bindus per planet per sign run 0..8 (sum of 0/1 contributions
373
+ * from each of the 8 reference points). Bucket directly by raw count.
374
+ */
375
+ bhinnaHeat(count) {
358
376
  if (count <= 1) return "heat-1";
359
377
  if (count <= 2) return "heat-2";
360
378
  if (count <= 3) return "heat-3";
@@ -363,6 +381,22 @@ var RoxyAshtakavargaGrid = class extends import_lit2.LitElement {
363
381
  if (count <= 6) return "heat-6";
364
382
  return "heat-7";
365
383
  }
384
+ /**
385
+ * Sarva bindus per sign are the column total across all 7 planets, range
386
+ * roughly 0..56 with typical values 20..40. Bucketed per classical
387
+ * interpretation: 25 below par, 25..30 average, 30..40 strong, 40+ very
388
+ * strong. Bucket spans intentionally widen at the extremes so a single
389
+ * outlier sign reads as exceptional.
390
+ */
391
+ sarvaHeat(count) {
392
+ if (count <= 18) return "heat-1";
393
+ if (count <= 23) return "heat-2";
394
+ if (count <= 28) return "heat-3";
395
+ if (count <= 32) return "heat-4";
396
+ if (count <= 37) return "heat-5";
397
+ if (count <= 42) return "heat-6";
398
+ return "heat-7";
399
+ }
366
400
  renderSarva(signs) {
367
401
  const sav = this.data.sarvashtakavarga;
368
402
  if (!sav) return import_lit2.html`<p class="roxy-empty">No sarvashtakavarga data</p>`;
@@ -377,7 +411,7 @@ var RoxyAshtakavargaGrid = class extends import_lit2.LitElement {
377
411
  <tbody>
378
412
  ${signs.map((sign, i) => {
379
413
  const count = sav.bindus[i] ?? 0;
380
- const hc = this.heatClass(count);
414
+ const hc = this.sarvaHeat(count);
381
415
  return import_lit2.html`<tr>
382
416
  <td>
383
417
  <div class="planet-cell">
@@ -418,7 +452,7 @@ var RoxyAshtakavargaGrid = class extends import_lit2.LitElement {
418
452
  (row) => import_lit2.html`<tr>
419
453
  <td>${row.planet}</td>
420
454
  ${row.bindus.map((count) => {
421
- const hc = this.heatClass(count);
455
+ const hc = this.bhinnaHeat(count);
422
456
  return import_lit2.html`<td class="${`heat-cell ${hc}`}">${count}</td>`;
423
457
  })}
424
458
  <td>${row.total}</td>
@@ -565,27 +599,68 @@ RoxyAshtakavargaGrid.styles = [
565
599
  border-bottom: none;
566
600
  }
567
601
 
568
- /* Heat cells */
602
+ /* Heat cells. Single base hue (var --roxy-heat) mixed with
603
+ * transparent at increasing percentages produces seven readable
604
+ * tiers in both light and dark themes. Text colour stays
605
+ * var(--roxy-fg) so it inverts with the host theme without
606
+ * per-tier overrides. */
569
607
  .heat-cell {
570
608
  border-radius: var(--roxy-radius-sm, 4px);
571
609
  font-weight: var(--roxy-weight-bold, 600);
572
610
  min-width: 2rem;
573
611
  font-variant-numeric: tabular-nums;
612
+ color: var(--roxy-fg, currentColor);
574
613
  }
575
614
 
576
- .heat-1 { background: var(--roxy-heat-1, #f0fdf4); color: var(--roxy-fg, #0a0a0a); }
577
- .heat-2 { background: var(--roxy-heat-2, #d1fae5); color: var(--roxy-fg, #0a0a0a); }
578
- .heat-3 { background: var(--roxy-heat-3, #a7f3d0); color: var(--roxy-fg, #0a0a0a); }
579
- .heat-4 { background: var(--roxy-heat-4, #fde68a); color: var(--roxy-fg, #0a0a0a); }
580
- .heat-5 { background: var(--roxy-heat-5, #fdba74); color: var(--roxy-fg, #0a0a0a); }
581
- .heat-6 { background: var(--roxy-heat-6, #fb923c); color: var(--roxy-fg, #0a0a0a); }
582
- .heat-7 { background: var(--roxy-heat-7, #ef4444); color: var(--roxy-fg, #0a0a0a); }
615
+ .heat-1 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 6%, transparent); }
616
+ .heat-2 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 14%, transparent); }
617
+ .heat-3 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 26%, transparent); }
618
+ .heat-4 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 40%, transparent); }
619
+ .heat-5 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 55%, transparent); }
620
+ .heat-6 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 72%, transparent); }
621
+ .heat-7 { background: color-mix(in srgb, var(--roxy-heat, #ef4444) 90%, transparent); }
583
622
 
584
623
  /* Bhinna grid: planet header column narrower */
585
624
  .bhinna-table th:first-child,
586
625
  .bhinna-table td:first-child {
587
626
  min-width: 5rem;
588
627
  }
628
+
629
+ /* Tight cells below 480px so the 14-column bhinna grid stops
630
+ * overflowing the viewport. The wrapper keeps overflow-x:auto as
631
+ * a fallback for very long content. */
632
+ @container (max-width: 480px) {
633
+ .bhinna-table th,
634
+ .bhinna-table td {
635
+ padding: 0.3rem 0.35rem;
636
+ font-size: var(--roxy-text-xs, 0.75rem);
637
+ }
638
+ .bhinna-table th:first-child,
639
+ .bhinna-table td:first-child {
640
+ min-width: 3.5rem;
641
+ }
642
+ .heat-cell {
643
+ min-width: 1.5rem;
644
+ }
645
+ }
646
+ /* Visual cue that the bhinna table is scrollable below the breakpoint:
647
+ * a soft gradient at the right edge so users see there is more to scroll. */
648
+ .overflow-scroll {
649
+ mask-image: linear-gradient(
650
+ to right,
651
+ transparent 0,
652
+ black 0.5rem,
653
+ black calc(100% - 1rem),
654
+ transparent 100%
655
+ );
656
+ -webkit-mask-image: linear-gradient(
657
+ to right,
658
+ transparent 0,
659
+ black 0.5rem,
660
+ black calc(100% - 1rem),
661
+ transparent 100%
662
+ );
663
+ }
589
664
  `
590
665
  ];
591
666
  __decorateClass([
@@ -843,12 +918,31 @@ var RoxyChoghadiyaGrid = class extends import_lit4.LitElement {
843
918
  super(...arguments);
844
919
  this.data = null;
845
920
  }
921
+ /**
922
+ * True when the current wall-clock time falls inside this period. Both
923
+ * `start` and `end` are ISO 8601 with timezone, so the comparison is
924
+ * timezone-aware via the host's `Date` parsing.
925
+ */
926
+ isCurrent(period) {
927
+ const now = Date.now();
928
+ const start = Date.parse(period.start);
929
+ const end = Date.parse(period.end);
930
+ if (Number.isNaN(start) || Number.isNaN(end)) return false;
931
+ return now >= start && now < end;
932
+ }
846
933
  renderTile(period) {
847
934
  const effectClass = period.effect === "Good" ? "good" : period.effect === "Bad" ? "bad" : "neutral";
935
+ const current = this.isCurrent(period);
848
936
  const lordGlyph = PLANET_GLYPH[capitalize(period.lord)] ?? "";
849
937
  const timeRange = `${fmtTime(period.start)} - ${fmtTime(period.end)}`;
850
- return import_lit4.html`<div class="cho-tile ${effectClass}" role="listitem">
851
- <span class="tile-name">${period.name}</span>
938
+ return import_lit4.html`<div
939
+ class="cho-tile ${effectClass}${current ? " now" : ""}"
940
+ role="listitem"
941
+ aria-current=${current ? "time" : "false"}
942
+ >
943
+ <span class="tile-name">
944
+ ${period.name}${current ? import_lit4.html`<span class="now-badge">Now</span>` : import_lit4.nothing}
945
+ </span>
852
946
  <span class="tile-time" aria-label="Time range">${timeRange}</span>
853
947
  <span class="tile-lord">
854
948
  ${lordGlyph ? import_lit4.html`<span aria-hidden="true">${lordGlyph}</span>` : import_lit4.nothing}
@@ -948,6 +1042,21 @@ RoxyChoghadiyaGrid.styles = [
948
1042
  background: transparent;
949
1043
  color: var(--roxy-fg, #0a0a0a);
950
1044
  }
1045
+ .cho-tile.now {
1046
+ outline: 2px solid var(--roxy-accent, #f59e0b);
1047
+ outline-offset: 1px;
1048
+ box-shadow: 0 0 0 4px
1049
+ color-mix(in srgb, var(--roxy-accent, #f59e0b) 18%, transparent);
1050
+ }
1051
+ .now-badge {
1052
+ display: inline-block;
1053
+ margin-left: 0.4em;
1054
+ font-size: var(--roxy-text-xs, 0.75rem);
1055
+ font-weight: var(--roxy-weight-bold, 600);
1056
+ color: var(--roxy-accent-fg, #b45309);
1057
+ text-transform: uppercase;
1058
+ letter-spacing: 0.06em;
1059
+ }
951
1060
  .tile-name {
952
1061
  font-size: var(--roxy-text-base, 1rem);
953
1062
  font-weight: var(--roxy-weight-bold, 600);
@@ -1251,12 +1360,39 @@ var RoxyDashaTimeline = class extends import_lit6.LitElement {
1251
1360
  </div>` : import_lit6.nothing}
1252
1361
  </header>
1253
1362
 
1363
+ ${this.renderBirthBalance(d)}
1254
1364
  ${this.period === "current" ? this.renderCurrent(d) : import_lit6.nothing}
1255
1365
  ${periods.length > 0 ? import_lit6.html`<div class="timeline" role="list">
1256
1366
  ${periods.map((p) => this.renderBar(p, maxYears))}
1257
1367
  </div>` : import_lit6.nothing}
1368
+ ${this.renderActiveInterpretation(periods)}
1258
1369
  </div>`;
1259
1370
  }
1371
+ renderBirthBalance(d) {
1372
+ if (!("birthDashaBalance" in d) || !d.birthDashaBalance) return import_lit6.nothing;
1373
+ const b = d.birthDashaBalance;
1374
+ const lord = "nakshatraLord" in d && d.nakshatraLord ? d.nakshatraLord : "";
1375
+ const yrs = b.years ?? 0;
1376
+ const mo = b.months ?? 0;
1377
+ const da = b.days ?? 0;
1378
+ const parts = [];
1379
+ if (yrs) parts.push(`${yrs}y`);
1380
+ if (mo) parts.push(`${mo}m`);
1381
+ if (da) parts.push(`${da}d`);
1382
+ const remaining = parts.length ? parts.join(" ") : "0d";
1383
+ return import_lit6.html`<p class="balance">
1384
+ Birth dasha balance: ${remaining} of
1385
+ ${lord ? import_lit6.html`<strong>${lord}</strong>` : "the opening mahadasha"} remained at birth.
1386
+ </p>`;
1387
+ }
1388
+ renderActiveInterpretation(periods) {
1389
+ const active = periods.find((p) => this.isCurrent(p));
1390
+ if (!active?.interpretation) return import_lit6.nothing;
1391
+ return import_lit6.html`<details class="interp">
1392
+ <summary>${active.planet} mahadasha interpretation</summary>
1393
+ <p>${active.interpretation}</p>
1394
+ </details>`;
1395
+ }
1260
1396
  renderCurrent(d) {
1261
1397
  if (!("mahadasha" in d)) return import_lit6.nothing;
1262
1398
  return import_lit6.html`<div class="current">
@@ -1282,12 +1418,52 @@ var RoxyDashaTimeline = class extends import_lit6.LitElement {
1282
1418
  if ("antardashas" in d && d.antardashas?.length) return d.antardashas;
1283
1419
  return [];
1284
1420
  }
1421
+ /** True when the current wall-clock time falls between the period's start and end. */
1422
+ isCurrent(p) {
1423
+ if (!p.startDate || !p.endDate) return false;
1424
+ const now = Date.now();
1425
+ const start = Date.parse(p.startDate);
1426
+ const end = Date.parse(p.endDate);
1427
+ if (Number.isNaN(start) || Number.isNaN(end)) return false;
1428
+ return now >= start && now < end;
1429
+ }
1430
+ /**
1431
+ * Fractional progress (0..1) through a period at the current time. Used to
1432
+ * draw a vertical "now" marker inside the active bar. Returns -1 outside the
1433
+ * period so the caller can skip the marker.
1434
+ */
1435
+ progressIn(p) {
1436
+ if (!p.startDate || !p.endDate) return -1;
1437
+ const start = Date.parse(p.startDate);
1438
+ const end = Date.parse(p.endDate);
1439
+ const now = Date.now();
1440
+ if (Number.isNaN(start) || Number.isNaN(end) || now < start || now >= end || end <= start) {
1441
+ return -1;
1442
+ }
1443
+ return (now - start) / (end - start);
1444
+ }
1285
1445
  renderBar(p, max) {
1286
1446
  const years = p.durationYears;
1287
1447
  const width = max > 0 ? years / max * 100 : 0;
1288
- return import_lit6.html`<div class="bar" role="listitem">
1289
- <span>${p.planet}</span>
1290
- <span class="bar-track"><span style="width: ${width}%"></span></span>
1448
+ const current = this.isCurrent(p);
1449
+ const progress = current ? this.progressIn(p) : -1;
1450
+ const trackClass = current ? "bar-track bar-now" : "bar-track";
1451
+ return import_lit6.html`<div
1452
+ class=${current ? "bar now" : "bar"}
1453
+ role="listitem"
1454
+ aria-current=${current ? "time" : "false"}
1455
+ >
1456
+ <span>
1457
+ <strong>${p.planet}</strong>${current ? import_lit6.html`<span class="now-badge">Now</span>` : import_lit6.nothing}
1458
+ </span>
1459
+ <span class=${trackClass}>
1460
+ <span class="bar-fill" style="width: ${width}%"></span>
1461
+ ${progress >= 0 ? import_lit6.html`<span
1462
+ class="bar-progress"
1463
+ style="left: ${progress * width}%"
1464
+ aria-hidden="true"
1465
+ ></span>` : import_lit6.nothing}
1466
+ </span>
1291
1467
  <span class="dates">
1292
1468
  ${p.startDate ? formatYear(p.startDate) : ""}
1293
1469
  ${p.endDate ? import_lit6.html`- ${formatYear(p.endDate)}` : ""}
@@ -1341,6 +1517,13 @@ RoxyDashaTimeline.styles = [
1341
1517
  color: var(--roxy-fg, #0a0a0a);
1342
1518
  }
1343
1519
 
1520
+ .balance {
1521
+ font-size: var(--roxy-text-sm, 0.875rem);
1522
+ color: var(--roxy-muted, #71717a);
1523
+ border-left: 2px solid var(--roxy-border, #e4e4e7);
1524
+ padding-left: var(--roxy-space-sm, 0.5rem);
1525
+ margin: 0;
1526
+ }
1344
1527
  .timeline {
1345
1528
  display: grid;
1346
1529
  gap: var(--roxy-space-xs, 0.25rem);
@@ -1352,26 +1535,69 @@ RoxyDashaTimeline.styles = [
1352
1535
  align-items: center;
1353
1536
  font-size: var(--roxy-text-sm, 0.875rem);
1354
1537
  }
1538
+ .bar.now strong {
1539
+ color: var(--roxy-accent-fg, #b45309);
1540
+ }
1541
+ .now-badge {
1542
+ display: inline-block;
1543
+ margin-left: 0.4em;
1544
+ font-size: var(--roxy-text-xs, 0.75rem);
1545
+ font-weight: var(--roxy-weight-bold, 600);
1546
+ color: var(--roxy-accent-fg, #b45309);
1547
+ text-transform: uppercase;
1548
+ letter-spacing: 0.06em;
1549
+ }
1355
1550
  .bar-track {
1551
+ position: relative;
1356
1552
  height: 14px;
1357
1553
  background: var(--roxy-border, #e4e4e7);
1358
1554
  border-radius: var(--roxy-radius-full, 9999px);
1359
1555
  overflow: hidden;
1360
1556
  }
1361
- .bar-track > span {
1557
+ .bar-fill {
1362
1558
  display: block;
1363
1559
  height: 100%;
1364
1560
  background: var(--roxy-accent, #f59e0b);
1561
+ opacity: 0.45;
1365
1562
  transition:
1366
1563
  width var(--roxy-motion-duration, 200ms)
1367
1564
  var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1));
1368
1565
  }
1566
+ .bar-now .bar-fill {
1567
+ opacity: 1;
1568
+ }
1569
+ .bar-progress {
1570
+ position: absolute;
1571
+ top: -2px;
1572
+ bottom: -2px;
1573
+ width: 2px;
1574
+ background: var(--roxy-accent-fg, #b45309);
1575
+ border-radius: 2px;
1576
+ box-shadow: 0 0 0 2px
1577
+ color-mix(in srgb, var(--roxy-accent, #f59e0b) 35%, transparent);
1578
+ }
1369
1579
  .dates {
1370
1580
  color: var(--roxy-muted, #71717a);
1371
1581
  font-size: var(--roxy-text-xs, 0.75rem);
1372
1582
  font-variant-numeric: tabular-nums;
1373
1583
  text-align: right;
1374
1584
  }
1585
+ details.interp {
1586
+ border: 1px solid var(--roxy-border, #e4e4e7);
1587
+ border-radius: var(--roxy-radius-md, 8px);
1588
+ padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
1589
+ background: var(--roxy-bg, #fff);
1590
+ }
1591
+ details.interp summary {
1592
+ cursor: pointer;
1593
+ font-size: var(--roxy-text-sm, 0.875rem);
1594
+ font-weight: var(--roxy-weight-bold, 600);
1595
+ }
1596
+ details.interp p {
1597
+ margin: var(--roxy-space-sm, 0.5rem) 0 0;
1598
+ font-size: var(--roxy-text-sm, 0.875rem);
1599
+ color: var(--roxy-muted, #71717a);
1600
+ }
1375
1601
  `
1376
1602
  ];
1377
1603
  __decorateClass([
@@ -1631,7 +1857,7 @@ RoxyData = __decorateClass([
1631
1857
  ], RoxyData);
1632
1858
 
1633
1859
  // packages/ui/src/components/divisional-chart.ts
1634
- var import_lit9 = require("lit");
1860
+ var import_lit10 = require("lit");
1635
1861
  var import_decorators7 = require("lit/decorators.js");
1636
1862
 
1637
1863
  // packages/ui/src/utils/kundli-render.ts
@@ -1680,25 +1906,45 @@ function polarToCartesian(cx, cy, radius, angleDeg) {
1680
1906
  }
1681
1907
 
1682
1908
  // packages/ui/src/utils/kundli-render.ts
1909
+ var VIEW_BOX = 400;
1910
+ var MARGIN = 20;
1911
+ var INNER = VIEW_BOX - 2 * MARGIN;
1912
+ var CENTRE = VIEW_BOX / 2;
1683
1913
  var RASHI_TO_SIGN = Object.fromEntries(
1684
1914
  SIGNS_ORDER.map((s) => [s.toLowerCase(), s])
1685
1915
  );
1916
+ var CHART_STYLES = [
1917
+ { id: "north", label: "North" },
1918
+ { id: "south", label: "South" },
1919
+ { id: "east", label: "East" }
1920
+ ];
1686
1921
  var RETRO_MARK = "\u02B3";
1687
- function grahaLabel(p) {
1922
+ function isDivisionalPlacement(p, cellSign) {
1923
+ if (typeof p.longitude !== "number" || !Number.isFinite(p.longitude)) {
1924
+ return false;
1925
+ }
1926
+ return longitudeToSignPosition(p.longitude).sign.toLowerCase() !== cellSign.toLowerCase();
1927
+ }
1928
+ function grahaLabel(p, cellSign) {
1688
1929
  const abbr = PLANET_ABBR[capitalize(p.graha)] ?? p.graha.slice(0, 2);
1689
1930
  const retro = p.isRetrograde ? RETRO_MARK : "";
1690
- if (typeof p.longitude !== "number" || !Number.isFinite(p.longitude)) {
1931
+ if (typeof p.longitude !== "number" || !Number.isFinite(p.longitude) || isDivisionalPlacement(p, cellSign)) {
1691
1932
  return `${abbr}${retro}`;
1692
1933
  }
1693
1934
  const { degree } = longitudeToSignPosition(p.longitude);
1694
1935
  return `${abbr} ${degree}\xB0${retro}`;
1695
1936
  }
1696
- function grahaTitle(p) {
1937
+ function grahaTitle(p, cellSign) {
1697
1938
  const parts = [capitalize(p.graha)];
1939
+ const divisional = isDivisionalPlacement(p, cellSign);
1940
+ if (divisional) {
1941
+ parts.push(`in ${cellSign}`);
1942
+ }
1698
1943
  if (typeof p.longitude === "number" && Number.isFinite(p.longitude)) {
1699
1944
  const sp = longitudeToSignPosition(p.longitude);
1945
+ const minute = String(sp.minute).padStart(2, "0");
1700
1946
  parts.push(
1701
- `${sp.degree}\xB0${String(sp.minute).padStart(2, "0")}' ${sp.sign}`
1947
+ divisional ? `D1: ${sp.degree}\xB0${minute}' ${sp.sign}` : `${sp.degree}\xB0${minute}' ${sp.sign}`
1702
1948
  );
1703
1949
  }
1704
1950
  if (p.nakshatra?.name) {
@@ -1709,272 +1955,573 @@ function grahaTitle(p) {
1709
1955
  if (p.isRetrograde) parts.push("retrograde");
1710
1956
  return parts.join(" \xB7 ");
1711
1957
  }
1712
- function renderPlanetStack(planets, cx, baseY, lineHeight) {
1958
+ function renderPlanetStack(planets, cellSign, cx, baseY, lineHeight) {
1713
1959
  const startY = baseY - (planets.length - 1) * lineHeight / 2;
1714
1960
  return planets.map((p, j) => {
1715
1961
  const yPos = startY + j * lineHeight;
1716
1962
  return import_lit8.svg`<text class="planet-text" x=${cx} y=${yPos} text-anchor="middle" dominant-baseline="central">${grahaLabel(
1717
- p
1718
- )}<title>${grahaTitle(p)}</title></text>`;
1963
+ p,
1964
+ cellSign
1965
+ )}<title>${grahaTitle(p, cellSign)}</title></text>`;
1719
1966
  });
1720
1967
  }
1721
- var SOUTH_HOUSE_CENTERS = {
1722
- 1: { x: 150, y: 58 },
1723
- 2: { x: 205, y: 52 },
1724
- 3: { x: 253, y: 112 },
1725
- 4: { x: 243, y: 150 },
1726
- 5: { x: 253, y: 188 },
1727
- 6: { x: 205, y: 248 },
1728
- 7: { x: 150, y: 242 },
1729
- 8: { x: 95, y: 248 },
1730
- 9: { x: 47, y: 188 },
1731
- 10: { x: 57, y: 150 },
1732
- 11: { x: 47, y: 112 },
1733
- 12: { x: 95, y: 52 }
1734
- };
1735
- var SOUTH_SIGN_POSITIONS = {
1736
- 1: { x: 150, y: 35 },
1737
- 2: { x: 222, y: 40 },
1738
- 3: { x: 265, y: 100 },
1739
- 4: { x: 265, y: 150 },
1740
- 5: { x: 265, y: 200 },
1741
- 6: { x: 222, y: 260 },
1742
- 7: { x: 150, y: 265 },
1743
- 8: { x: 78, y: 260 },
1744
- 9: { x: 35, y: 200 },
1745
- 10: { x: 35, y: 150 },
1746
- 11: { x: 35, y: 100 },
1747
- 12: { x: 78, y: 40 }
1748
- };
1749
- var NORTH_HOUSE_CENTERS = {
1750
- 1: { x: 150, y: 60 },
1751
- 2: { x: 225, y: 100 },
1752
- 3: { x: 255, y: 150 },
1753
- 4: { x: 225, y: 200 },
1754
- 5: { x: 150, y: 240 },
1755
- 6: { x: 75, y: 200 },
1756
- 7: { x: 45, y: 150 },
1757
- 8: { x: 75, y: 100 },
1758
- 9: { x: 100, y: 80 },
1759
- 10: { x: 150, y: 108 },
1760
- 11: { x: 200, y: 80 },
1761
- 12: { x: 200, y: 220 }
1762
- };
1763
- var EAST_HOUSE_CENTERS = {
1764
- 1: { x: 150, y: 80 },
1765
- // inner diamond, top
1766
- 2: { x: 220, y: 33 },
1767
- // top-right corner, upper triangle
1768
- 3: { x: 267, y: 80 },
1769
- // top-right corner, right triangle
1770
- 4: { x: 220, y: 150 },
1771
- // inner diamond, right
1772
- 5: { x: 267, y: 220 },
1773
- // bottom-right corner, right triangle
1774
- 6: { x: 220, y: 267 },
1775
- // bottom-right corner, lower triangle
1776
- 7: { x: 150, y: 220 },
1777
- // inner diamond, bottom
1778
- 8: { x: 80, y: 267 },
1779
- // bottom-left corner, lower triangle
1780
- 9: { x: 33, y: 220 },
1781
- // bottom-left corner, left triangle
1782
- 10: { x: 80, y: 150 },
1783
- // inner diamond, left
1784
- 11: { x: 33, y: 80 },
1785
- // top-left corner, left triangle
1786
- 12: { x: 80, y: 33 }
1787
- // top-left corner, upper triangle
1788
- };
1789
- var EAST_SIGN_POSITIONS = {
1790
- 1: { x: 150, y: 55 },
1791
- 2: { x: 235, y: 24 },
1792
- 3: { x: 276, y: 62 },
1793
- 4: { x: 242, y: 150 },
1794
- 5: { x: 276, y: 238 },
1795
- 6: { x: 235, y: 276 },
1796
- 7: { x: 150, y: 245 },
1797
- 8: { x: 65, y: 276 },
1798
- 9: { x: 24, y: 238 },
1799
- 10: { x: 58, y: 150 },
1800
- 11: { x: 24, y: 62 },
1801
- 12: { x: 65, y: 24 }
1968
+ function toKundliViewModel(meta, divisionLabel) {
1969
+ const placements = {};
1970
+ for (const sign of SIGNS_ORDER) placements[sign.toLowerCase()] = [];
1971
+ let lagnaSign = "";
1972
+ for (const [name, pos] of Object.entries(meta ?? {})) {
1973
+ const rashiKey = (pos?.rashi ?? "").toLowerCase();
1974
+ if (name === "Lagna" || pos?.graha === "Lagna") {
1975
+ lagnaSign = RASHI_TO_SIGN[rashiKey] ?? "";
1976
+ continue;
1977
+ }
1978
+ if (!rashiKey || !(rashiKey in placements)) continue;
1979
+ placements[rashiKey]?.push({
1980
+ graha: pos.graha ?? name,
1981
+ longitude: pos.longitude,
1982
+ nakshatra: pos.nakshatra,
1983
+ isRetrograde: pos.isRetrograde,
1984
+ awastha: pos.awastha
1985
+ });
1986
+ }
1987
+ return { lagnaSign, placements, divisionLabel };
1988
+ }
1989
+ var SOUTH_CELL = INNER / 4;
1990
+ var SOUTH_CELL_GRID = {
1991
+ Pisces: { col: 0, row: 0 },
1992
+ Aries: { col: 1, row: 0 },
1993
+ Taurus: { col: 2, row: 0 },
1994
+ Gemini: { col: 3, row: 0 },
1995
+ Cancer: { col: 3, row: 1 },
1996
+ Leo: { col: 3, row: 2 },
1997
+ Virgo: { col: 3, row: 3 },
1998
+ Libra: { col: 2, row: 3 },
1999
+ Scorpio: { col: 1, row: 3 },
2000
+ Sagittarius: { col: 0, row: 3 },
2001
+ Capricorn: { col: 0, row: 2 },
2002
+ Aquarius: { col: 0, row: 1 }
1802
2003
  };
1803
- function renderSouthHouseGroup(h) {
1804
- const center = SOUTH_HOUSE_CENTERS[h.number];
1805
- const signPos = SOUTH_SIGN_POSITIONS[h.number];
1806
- if (!center || !signPos) return import_lit8.nothing;
1807
- const signAbbr = SIGN_ABBR[h.sign] ?? "";
1808
- const baseY = h.isLagna ? center.y + 8 : center.y;
2004
+ function southCellRect(sign) {
2005
+ const g = SOUTH_CELL_GRID[sign] ?? { col: 0, row: 0 };
2006
+ return {
2007
+ x: MARGIN + g.col * SOUTH_CELL,
2008
+ y: MARGIN + g.row * SOUTH_CELL,
2009
+ w: SOUTH_CELL,
2010
+ h: SOUTH_CELL
2011
+ };
2012
+ }
2013
+ function renderSouthFrame(divisionLabel) {
2014
+ const a = MARGIN;
2015
+ const b = MARGIN + SOUTH_CELL;
2016
+ const c = MARGIN + 2 * SOUTH_CELL;
2017
+ const d = MARGIN + 3 * SOUTH_CELL;
2018
+ const e = VIEW_BOX - MARGIN;
2019
+ return import_lit8.svg`
2020
+ <rect class="line" x=${a} y=${a} width=${INNER} height=${INNER} stroke-width="1.5" fill="none" />
2021
+ <line class="line" x1=${a} y1=${b} x2=${e} y2=${b} stroke-width="1" />
2022
+ <line class="line" x1=${a} y1=${d} x2=${e} y2=${d} stroke-width="1" />
2023
+ <line class="line" x1=${b} y1=${a} x2=${b} y2=${e} stroke-width="1" />
2024
+ <line class="line" x1=${d} y1=${a} x2=${d} y2=${e} stroke-width="1" />
2025
+ <line class="line" x1=${a} y1=${c} x2=${b} y2=${c} stroke-width="1" />
2026
+ <line class="line" x1=${d} y1=${c} x2=${e} y2=${c} stroke-width="1" />
2027
+ <line class="line" x1=${c} y1=${a} x2=${c} y2=${b} stroke-width="1" />
2028
+ <line class="line" x1=${c} y1=${d} x2=${c} y2=${e} stroke-width="1" />
2029
+ ${divisionLabel ? import_lit8.svg`<text class="centre-label" x=${CENTRE} y=${CENTRE} text-anchor="middle" dominant-baseline="central">${divisionLabel}</text>` : import_lit8.nothing}
2030
+ `;
2031
+ }
2032
+ function houseNumberInSign(sign, lagnaSign) {
2033
+ const lagnaIdx = SIGNS_ORDER.findIndex((s) => s === lagnaSign);
2034
+ const signIdx = SIGNS_ORDER.findIndex((s) => s === sign);
2035
+ if (lagnaIdx === -1 || signIdx === -1) return 0;
2036
+ return (signIdx - lagnaIdx + 12) % 12 + 1;
2037
+ }
2038
+ function renderSouthCell(sign, planets, isLagna, houseNum) {
2039
+ const r = southCellRect(sign);
2040
+ const cx = r.x + r.w / 2;
2041
+ const cy = r.y + r.h / 2;
2042
+ const signAbbr = SIGN_ABBR[sign] ?? sign.slice(0, 2);
2043
+ const slashInset = 14;
1809
2044
  return import_lit8.svg`
1810
- <g>
1811
- ${h.isLagna ? import_lit8.svg`<rect
1812
- class="lagna-bg"
1813
- x=${center.x - 30} y=${center.y - 28}
1814
- width="60" height="56" rx="6"
1815
- />` : import_lit8.nothing}
1816
- ${signAbbr ? import_lit8.svg`<text class="sign-text" x=${signPos.x} y=${signPos.y} text-anchor="middle" dominant-baseline="central">${signAbbr}</text>` : import_lit8.nothing}
1817
- ${h.isLagna ? import_lit8.svg`<text class="lagna-marker" x=${center.x} y=${center.y - 18} text-anchor="middle" dominant-baseline="central">LAGNA</text>` : import_lit8.nothing}
1818
- ${renderPlanetStack(h.planets, center.x, baseY, 13)}
2045
+ <g class=${isLagna ? "cell lagna" : "cell"}>
2046
+ ${isLagna ? import_lit8.svg`
2047
+ <rect class="lagna-bg" x=${r.x} y=${r.y} width=${r.w} height=${r.h} />
2048
+ <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" />
2049
+ ` : import_lit8.nothing}
2050
+ <text class="sign-text" x=${r.x + 6} y=${r.y + 12} text-anchor="start" dominant-baseline="central">${signAbbr}</text>
2051
+ ${houseNum > 0 ? import_lit8.svg`<text class="house-num" x=${r.x + r.w - 6} y=${r.y + 12} text-anchor="end" dominant-baseline="central">${houseNum}</text>` : import_lit8.nothing}
2052
+ ${planets.length ? renderPlanetStack(planets, sign, cx, cy + 4, 14) : import_lit8.nothing}
1819
2053
  </g>
1820
2054
  `;
1821
2055
  }
1822
- function renderNorthFrame() {
2056
+ function renderSouthSvg(vm) {
2057
+ const lagnaKey = vm.lagnaSign.toLowerCase();
2058
+ return import_lit8.svg`
2059
+ ${renderSouthFrame(vm.divisionLabel)}
2060
+ ${SIGNS_ORDER.map(
2061
+ (sign) => renderSouthCell(
2062
+ sign,
2063
+ vm.placements[sign.toLowerCase()] ?? [],
2064
+ sign.toLowerCase() === lagnaKey,
2065
+ houseNumberInSign(sign, vm.lagnaSign)
2066
+ )
2067
+ )}
2068
+ `;
2069
+ }
2070
+ var NORTH_VERTICES = {
2071
+ tl: { x: MARGIN, y: MARGIN },
2072
+ tr: { x: VIEW_BOX - MARGIN, y: MARGIN },
2073
+ br: { x: VIEW_BOX - MARGIN, y: VIEW_BOX - MARGIN },
2074
+ bl: { x: MARGIN, y: VIEW_BOX - MARGIN },
2075
+ top: { x: CENTRE, y: MARGIN },
2076
+ right: { x: VIEW_BOX - MARGIN, y: CENTRE },
2077
+ bottom: { x: CENTRE, y: VIEW_BOX - MARGIN },
2078
+ left: { x: MARGIN, y: CENTRE },
2079
+ tlMid: { x: CENTRE - INNER / 4, y: CENTRE - INNER / 4 },
2080
+ trMid: { x: CENTRE + INNER / 4, y: CENTRE - INNER / 4 },
2081
+ brMid: { x: CENTRE + INNER / 4, y: CENTRE + INNER / 4 },
2082
+ blMid: { x: CENTRE - INNER / 4, y: CENTRE + INNER / 4 }
2083
+ };
2084
+ function centroidOf(pts) {
2085
+ const x = pts.reduce((s, p) => s + p.x, 0) / pts.length;
2086
+ const y = pts.reduce((s, p) => s + p.y, 0) / pts.length;
2087
+ return { x, y };
2088
+ }
2089
+ var NORTH_HOUSE_CENTERS = {
2090
+ 1: { x: CENTRE, y: NORTH_VERTICES.tlMid.y },
2091
+ 2: centroidOf([NORTH_VERTICES.tl, NORTH_VERTICES.top, NORTH_VERTICES.tlMid]),
2092
+ 3: centroidOf([NORTH_VERTICES.tl, NORTH_VERTICES.left, NORTH_VERTICES.tlMid]),
2093
+ 4: { x: NORTH_VERTICES.tlMid.x, y: CENTRE },
2094
+ 5: centroidOf([NORTH_VERTICES.bl, NORTH_VERTICES.left, NORTH_VERTICES.blMid]),
2095
+ 6: centroidOf([
2096
+ NORTH_VERTICES.bl,
2097
+ NORTH_VERTICES.bottom,
2098
+ NORTH_VERTICES.blMid
2099
+ ]),
2100
+ 7: { x: CENTRE, y: NORTH_VERTICES.blMid.y },
2101
+ 8: centroidOf([
2102
+ NORTH_VERTICES.br,
2103
+ NORTH_VERTICES.bottom,
2104
+ NORTH_VERTICES.brMid
2105
+ ]),
2106
+ 9: centroidOf([
2107
+ NORTH_VERTICES.br,
2108
+ NORTH_VERTICES.right,
2109
+ NORTH_VERTICES.brMid
2110
+ ]),
2111
+ 10: { x: NORTH_VERTICES.brMid.x, y: CENTRE },
2112
+ 11: centroidOf([
2113
+ NORTH_VERTICES.tr,
2114
+ NORTH_VERTICES.right,
2115
+ NORTH_VERTICES.trMid
2116
+ ]),
2117
+ 12: centroidOf([NORTH_VERTICES.tr, NORTH_VERTICES.top, NORTH_VERTICES.trMid])
2118
+ };
2119
+ function rashiInHouse(houseNum, lagnaSign) {
2120
+ const lagnaIdx = SIGNS_ORDER.findIndex((s) => s === lagnaSign);
2121
+ if (lagnaIdx === -1) return houseNum;
2122
+ return (lagnaIdx + houseNum - 1) % 12 + 1;
2123
+ }
2124
+ function renderNorthFrame(divisionLabel) {
2125
+ const { tl, tr, br, bl, top, right, bottom, left } = NORTH_VERTICES;
1823
2126
  return import_lit8.svg`
1824
- <polygon class="line" points="150,10 290,150 150,290 10,150" stroke-width="1.5" />
1825
- <line class="line" x1="150" y1="10" x2="150" y2="290" stroke-width="1" />
1826
- <line class="line" x1="10" y1="150" x2="290" y2="150" stroke-width="1" />
1827
- <line class="line" x1="150" y1="10" x2="10" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
1828
- <line class="line" x1="150" y1="10" x2="290" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
1829
- <line class="line" x1="150" y1="290" x2="10" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
1830
- <line class="line" x1="150" y1="290" x2="290" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
2127
+ <rect class="line" x=${tl.x} y=${tl.y} width=${INNER} height=${INNER} stroke-width="1.5" fill="none" />
2128
+ <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" />
2129
+ <line class="line" x1=${tl.x} y1=${tl.y} x2=${br.x} y2=${br.y} stroke-width="1" />
2130
+ <line class="line" x1=${tr.x} y1=${tr.y} x2=${bl.x} y2=${bl.y} stroke-width="1" />
2131
+ ${divisionLabel ? import_lit8.svg`<text class="centre-label" x=${CENTRE} y=${CENTRE} text-anchor="middle" dominant-baseline="central">${divisionLabel}</text>` : import_lit8.nothing}
1831
2132
  `;
1832
2133
  }
1833
- function renderNorthHouseGroup(h) {
1834
- const center = NORTH_HOUSE_CENTERS[h.number];
1835
- if (!center) return import_lit8.nothing;
1836
- const signAbbr = SIGN_ABBR[h.sign] ?? "";
2134
+ function renderNorthCell(houseNum, rashiNum, sign, planets, isLagna) {
2135
+ const c = NORTH_HOUSE_CENTERS[houseNum];
2136
+ if (!c) return import_lit8.svg``;
2137
+ const rashiOffsetY = Math.min(14, Math.abs(c.y - CENTRE) * 0.45 + 6);
2138
+ const ascOffsetY = rashiOffsetY + 12;
1837
2139
  return import_lit8.svg`
1838
- <g>
1839
- ${h.isLagna ? import_lit8.svg`<circle class="lagna-bg" cx=${center.x} cy=${center.y} r="22" />` : import_lit8.nothing}
1840
- ${signAbbr ? import_lit8.svg`<text class="sign-text" x=${center.x} y=${center.y - 10} text-anchor="middle" dominant-baseline="central">${signAbbr}</text>` : import_lit8.nothing}
1841
- <text class="house-num" x=${center.x} y=${center.y + 2} text-anchor="middle" dominant-baseline="central">${h.number}</text>
1842
- ${renderPlanetStack(h.planets, center.x, center.y + 14, 11)}
2140
+ <g class=${isLagna ? "cell lagna" : "cell"}>
2141
+ <text class="rashi-num" x=${c.x} y=${c.y - rashiOffsetY} text-anchor="middle" dominant-baseline="central">${rashiNum}</text>
2142
+ ${isLagna ? import_lit8.svg`<text class="lagna-marker" x=${c.x} y=${c.y - ascOffsetY} text-anchor="middle" dominant-baseline="central">Asc</text>` : import_lit8.nothing}
2143
+ ${planets.length ? renderPlanetStack(planets, sign, c.x, c.y + 8, 12) : import_lit8.nothing}
1843
2144
  </g>
1844
2145
  `;
1845
2146
  }
1846
- function renderSouthFrame() {
2147
+ function renderNorthSvg(vm) {
2148
+ const lagnaSign = vm.lagnaSign || "Aries";
1847
2149
  return import_lit8.svg`
1848
- <polygon class="line" points="150,10 290,150 150,290 10,150" stroke-width="1.5" />
1849
- <polygon class="line" points="220,80 220,220 80,220 80,80" stroke-width="1" fill="none" />
1850
- <line class="line" x1="150" y1="10" x2="80" y2="80" stroke-width="1" />
1851
- <line class="line" x1="150" y1="10" x2="220" y2="80" stroke-width="1" />
1852
- <line class="line" x1="290" y1="150" x2="220" y2="80" stroke-width="1" />
1853
- <line class="line" x1="290" y1="150" x2="220" y2="220" stroke-width="1" />
1854
- <line class="line" x1="150" y1="290" x2="220" y2="220" stroke-width="1" />
1855
- <line class="line" x1="150" y1="290" x2="80" y2="220" stroke-width="1" />
1856
- <line class="line" x1="10" y1="150" x2="80" y2="220" stroke-width="1" />
1857
- <line class="line" x1="10" y1="150" x2="80" y2="80" stroke-width="1" />
2150
+ ${renderNorthFrame(vm.divisionLabel)}
2151
+ ${Array.from({ length: 12 }, (_, i) => {
2152
+ const houseNum = i + 1;
2153
+ const rashiNum = rashiInHouse(houseNum, lagnaSign);
2154
+ const sign = SIGNS_ORDER[rashiNum - 1] ?? "Aries";
2155
+ return renderNorthCell(
2156
+ houseNum,
2157
+ rashiNum,
2158
+ sign,
2159
+ vm.placements[sign.toLowerCase()] ?? [],
2160
+ houseNum === 1
2161
+ );
2162
+ })}
1858
2163
  `;
1859
2164
  }
1860
- function renderEastFrame() {
2165
+ var EAST_CELL = INNER / 3;
2166
+ function eastCells() {
2167
+ const a = MARGIN;
2168
+ const b = MARGIN + EAST_CELL;
2169
+ const c = MARGIN + 2 * EAST_CELL;
2170
+ const d = VIEW_BOX - MARGIN;
2171
+ const aries = [
2172
+ { x: b, y: a },
2173
+ { x: c, y: a },
2174
+ { x: c, y: b },
2175
+ { x: b, y: b }
2176
+ ];
2177
+ const cancer = [
2178
+ { x: a, y: b },
2179
+ { x: b, y: b },
2180
+ { x: b, y: c },
2181
+ { x: a, y: c }
2182
+ ];
2183
+ const libra = [
2184
+ { x: b, y: c },
2185
+ { x: c, y: c },
2186
+ { x: c, y: d },
2187
+ { x: b, y: d }
2188
+ ];
2189
+ const capricorn = [
2190
+ { x: c, y: b },
2191
+ { x: d, y: b },
2192
+ { x: d, y: c },
2193
+ { x: c, y: c }
2194
+ ];
2195
+ const taurus = [
2196
+ { x: a, y: a },
2197
+ { x: b, y: a },
2198
+ { x: b, y: b }
2199
+ ];
2200
+ const gemini = [
2201
+ { x: a, y: a },
2202
+ { x: b, y: b },
2203
+ { x: a, y: b }
2204
+ ];
2205
+ const leo = [
2206
+ { x: a, y: c },
2207
+ { x: b, y: c },
2208
+ { x: a, y: d }
2209
+ ];
2210
+ const virgo = [
2211
+ { x: b, y: c },
2212
+ { x: b, y: d },
2213
+ { x: a, y: d }
2214
+ ];
2215
+ const scorpio = [
2216
+ { x: c, y: c },
2217
+ { x: c, y: d },
2218
+ { x: d, y: d }
2219
+ ];
2220
+ const sagittarius = [
2221
+ { x: c, y: c },
2222
+ { x: d, y: d },
2223
+ { x: d, y: c }
2224
+ ];
2225
+ const aquarius = [
2226
+ { x: d, y: a },
2227
+ { x: d, y: b },
2228
+ { x: c, y: b }
2229
+ ];
2230
+ const pisces = [
2231
+ { x: c, y: a },
2232
+ { x: d, y: a },
2233
+ { x: c, y: b }
2234
+ ];
2235
+ const polys = {
2236
+ Aries: aries,
2237
+ Taurus: taurus,
2238
+ Gemini: gemini,
2239
+ Cancer: cancer,
2240
+ Leo: leo,
2241
+ Virgo: virgo,
2242
+ Libra: libra,
2243
+ Scorpio: scorpio,
2244
+ Sagittarius: sagittarius,
2245
+ Capricorn: capricorn,
2246
+ Aquarius: aquarius,
2247
+ Pisces: pisces
2248
+ };
2249
+ const out = {};
2250
+ for (const [sign, points] of Object.entries(polys)) {
2251
+ out[sign] = { points: [...points], centroid: centroidOf(points) };
2252
+ }
2253
+ return out;
2254
+ }
2255
+ var EAST_CELLS = eastCells();
2256
+ function renderEastFrame(divisionLabel) {
2257
+ const a = MARGIN;
2258
+ const b = MARGIN + EAST_CELL;
2259
+ const c = MARGIN + 2 * EAST_CELL;
2260
+ const d = VIEW_BOX - MARGIN;
1861
2261
  return import_lit8.svg`
1862
- <rect class="line" x="10" y="10" width="280" height="280" stroke-width="1.5" fill="none" />
1863
- <line class="line" x1="10" y1="10" x2="290" y2="290" stroke-width="1" />
1864
- <line class="line" x1="290" y1="10" x2="10" y2="290" stroke-width="1" />
1865
- <polygon class="line" points="150,10 290,150 150,290 10,150" stroke-width="1" fill="none" />
2262
+ <rect class="line" x=${a} y=${a} width=${INNER} height=${INNER} stroke-width="1.5" fill="none" />
2263
+ <line class="line" x1=${a} y1=${b} x2=${b} y2=${b} stroke-width="1" />
2264
+ <line class="line" x1=${c} y1=${b} x2=${d} y2=${b} stroke-width="1" />
2265
+ <line class="line" x1=${a} y1=${c} x2=${b} y2=${c} stroke-width="1" />
2266
+ <line class="line" x1=${c} y1=${c} x2=${d} y2=${c} stroke-width="1" />
2267
+ <line class="line" x1=${b} y1=${a} x2=${b} y2=${b} stroke-width="1" />
2268
+ <line class="line" x1=${b} y1=${c} x2=${b} y2=${d} stroke-width="1" />
2269
+ <line class="line" x1=${c} y1=${a} x2=${c} y2=${b} stroke-width="1" />
2270
+ <line class="line" x1=${c} y1=${c} x2=${c} y2=${d} stroke-width="1" />
2271
+ <line class="line" x1=${a} y1=${a} x2=${b} y2=${b} stroke-width="1" />
2272
+ <line class="line" x1=${d} y1=${a} x2=${c} y2=${b} stroke-width="1" />
2273
+ <line class="line" x1=${d} y1=${d} x2=${c} y2=${c} stroke-width="1" />
2274
+ <line class="line" x1=${a} y1=${d} x2=${b} y2=${c} stroke-width="1" />
2275
+ ${divisionLabel ? import_lit8.svg`<text class="centre-label" x=${CENTRE} y=${CENTRE} text-anchor="middle" dominant-baseline="central">${divisionLabel}</text>` : import_lit8.nothing}
1866
2276
  `;
1867
2277
  }
1868
- function renderEastHouseGroup(h) {
1869
- const center = EAST_HOUSE_CENTERS[h.number];
1870
- const signPos = EAST_SIGN_POSITIONS[h.number];
1871
- if (!center || !signPos) return import_lit8.nothing;
1872
- const signAbbr = SIGN_ABBR[h.sign] ?? "";
2278
+ function renderEastCell(sign, planets, isLagna, houseNum) {
2279
+ const cell = EAST_CELLS[sign];
2280
+ if (!cell) return import_lit8.svg``;
2281
+ const { centroid: cen, points } = cell;
2282
+ const signAbbr = SIGN_ABBR[sign] ?? sign.slice(0, 2);
2283
+ const polyPoints = points.map((p) => `${p.x},${p.y}`).join(" ");
1873
2284
  return import_lit8.svg`
1874
- <g>
1875
- ${h.isLagna ? import_lit8.svg`<circle class="lagna-bg" cx=${center.x} cy=${center.y} r="20" />` : import_lit8.nothing}
1876
- ${signAbbr ? import_lit8.svg`<text class="sign-text" x=${signPos.x} y=${signPos.y} text-anchor="middle" dominant-baseline="central">${signAbbr}</text>` : import_lit8.nothing}
1877
- ${h.isLagna ? import_lit8.svg`<text class="lagna-marker" x=${center.x} y=${center.y - 14} text-anchor="middle" dominant-baseline="central">LAGNA</text>` : import_lit8.nothing}
1878
- ${renderPlanetStack(h.planets, center.x, center.y + 2, 11)}
2285
+ <g class=${isLagna ? "cell lagna" : "cell"}>
2286
+ ${isLagna ? import_lit8.svg`<polygon class="lagna-bg" points=${polyPoints} />` : import_lit8.nothing}
2287
+ <text class="sign-text" x=${cen.x} y=${cen.y - 16} text-anchor="middle" dominant-baseline="central">${signAbbr}</text>
2288
+ ${houseNum > 0 ? import_lit8.svg`<text class="house-num" x=${cen.x + 18} y=${cen.y - 16} text-anchor="start" dominant-baseline="central">${houseNum}</text>` : import_lit8.nothing}
2289
+ ${isLagna ? import_lit8.svg`<text class="lagna-marker" x=${cen.x} y=${cen.y - 30} text-anchor="middle" dominant-baseline="central">Asc</text>` : import_lit8.nothing}
2290
+ ${planets.length ? renderPlanetStack(planets, sign, cen.x, cen.y + 4, 12) : import_lit8.nothing}
1879
2291
  </g>
1880
2292
  `;
1881
2293
  }
1882
- function buildHousesFromMeta(meta) {
1883
- const byRashi = /* @__PURE__ */ new Map();
1884
- let lagnaKey = "";
1885
- for (const [name, pos] of Object.entries(meta)) {
1886
- const rashiKey = (pos?.rashi ?? "").toLowerCase();
1887
- if (name === "Lagna" || pos?.graha === "Lagna") {
1888
- lagnaKey = rashiKey;
1889
- continue;
1890
- }
1891
- if (!rashiKey) continue;
1892
- const list = byRashi.get(rashiKey) ?? [];
1893
- list.push({
1894
- graha: pos.graha ?? name,
1895
- longitude: pos.longitude,
1896
- nakshatra: pos.nakshatra,
1897
- isRetrograde: pos.isRetrograde,
1898
- awastha: pos.awastha
1899
- });
1900
- byRashi.set(rashiKey, list);
1901
- }
1902
- return SIGNS_ORDER.map((sign, i) => {
1903
- const key = sign.toLowerCase();
1904
- return {
1905
- number: i + 1,
2294
+ function renderEastSvg(vm) {
2295
+ const lagnaKey = vm.lagnaSign.toLowerCase();
2296
+ return import_lit8.svg`
2297
+ ${renderEastFrame(vm.divisionLabel)}
2298
+ ${SIGNS_ORDER.map(
2299
+ (sign) => renderEastCell(
1906
2300
  sign,
1907
- planets: byRashi.get(key) ?? [],
1908
- isLagna: lagnaKey === key
1909
- };
1910
- });
2301
+ vm.placements[sign.toLowerCase()] ?? [],
2302
+ sign.toLowerCase() === lagnaKey,
2303
+ houseNumberInSign(sign, vm.lagnaSign)
2304
+ )
2305
+ )}
2306
+ `;
2307
+ }
2308
+ function renderKundliSvg(vm, style) {
2309
+ switch (style) {
2310
+ case "north":
2311
+ return renderNorthSvg(vm);
2312
+ case "east":
2313
+ return renderEastSvg(vm);
2314
+ default:
2315
+ return renderSouthSvg(vm);
2316
+ }
2317
+ }
2318
+ function renderKundliStyleTablist(active, setStyle) {
2319
+ const onKeyDown = (e) => {
2320
+ const idx = CHART_STYLES.findIndex((s) => s.id === active);
2321
+ if (e.key === "ArrowRight") {
2322
+ e.preventDefault();
2323
+ const next = CHART_STYLES[(idx + 1) % CHART_STYLES.length];
2324
+ if (next) setStyle(next.id);
2325
+ } else if (e.key === "ArrowLeft") {
2326
+ e.preventDefault();
2327
+ const next = CHART_STYLES[(idx - 1 + CHART_STYLES.length) % CHART_STYLES.length];
2328
+ if (next) setStyle(next.id);
2329
+ }
2330
+ };
2331
+ return import_lit8.html`<div
2332
+ class="kundli-tablist"
2333
+ role="tablist"
2334
+ aria-label="Kundli style"
2335
+ @keydown=${onKeyDown}
2336
+ >
2337
+ ${CHART_STYLES.map(
2338
+ (s) => import_lit8.html`<button
2339
+ type="button"
2340
+ class="kundli-tab"
2341
+ role="tab"
2342
+ id="kundli-tab-${s.id}"
2343
+ aria-selected=${active === s.id ? "true" : "false"}
2344
+ tabindex=${active === s.id ? "0" : "-1"}
2345
+ @click=${() => setStyle(s.id)}
2346
+ >
2347
+ ${s.label}
2348
+ </button>`
2349
+ )}
2350
+ </div>`;
1911
2351
  }
1912
2352
 
2353
+ // packages/ui/src/utils/kundli-styles.ts
2354
+ var import_lit9 = require("lit");
2355
+ var kundliStyles = import_lit9.css`
2356
+ .wrap {
2357
+ display: grid;
2358
+ gap: var(--roxy-space-md, 1rem);
2359
+ }
2360
+ .header {
2361
+ display: flex;
2362
+ flex-wrap: wrap;
2363
+ align-items: center;
2364
+ justify-content: space-between;
2365
+ gap: var(--roxy-space-sm, 0.5rem);
2366
+ }
2367
+ .title {
2368
+ font-size: var(--roxy-text-lg, 1.125rem);
2369
+ font-weight: var(--roxy-weight-bold, 600);
2370
+ margin: 0;
2371
+ }
2372
+ .kundli-tablist {
2373
+ display: inline-flex;
2374
+ gap: 2px;
2375
+ border-bottom: 2px solid var(--roxy-border, #e4e4e7);
2376
+ }
2377
+ .kundli-tab {
2378
+ padding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);
2379
+ font-size: var(--roxy-text-sm, 0.875rem);
2380
+ background: none;
2381
+ border: none;
2382
+ border-bottom: 2px solid transparent;
2383
+ margin-bottom: -2px;
2384
+ cursor: pointer;
2385
+ color: var(--roxy-muted, #71717a);
2386
+ font-family: inherit;
2387
+ transition: color var(--roxy-motion-duration, 200ms)
2388
+ var(--roxy-motion-easing, ease);
2389
+ }
2390
+ .kundli-tab[aria-selected='true'] {
2391
+ color: var(--roxy-accent-fg, #b45309);
2392
+ border-bottom-color: var(--roxy-accent, #f59e0b);
2393
+ font-weight: var(--roxy-weight-bold, 600);
2394
+ }
2395
+ .kundli-tab:hover:not([aria-selected='true']) {
2396
+ color: var(--roxy-fg, #0a0a0a);
2397
+ }
2398
+ .kundli-tab:focus-visible {
2399
+ outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
2400
+ outline-offset: 2px;
2401
+ border-radius: 4px;
2402
+ }
2403
+ svg {
2404
+ display: block;
2405
+ width: 100%;
2406
+ max-width: 560px;
2407
+ aspect-ratio: 1 / 1;
2408
+ height: auto;
2409
+ margin: 0 auto;
2410
+ }
2411
+ .line {
2412
+ fill: transparent;
2413
+ stroke: var(--roxy-border, #d4d4d8);
2414
+ }
2415
+ .sign-text {
2416
+ fill: var(--roxy-muted, #71717a);
2417
+ font-size: 11px;
2418
+ font-weight: 500;
2419
+ font-family: var(--roxy-font-sans);
2420
+ text-transform: uppercase;
2421
+ letter-spacing: 0.04em;
2422
+ }
2423
+ .rashi-num {
2424
+ fill: var(--roxy-muted, #71717a);
2425
+ font-size: 12px;
2426
+ font-weight: 500;
2427
+ font-family: var(--roxy-font-sans);
2428
+ }
2429
+ .house-num {
2430
+ fill: var(--roxy-accent-fg, #b45309);
2431
+ font-size: 11px;
2432
+ font-weight: 600;
2433
+ font-family: var(--roxy-font-sans);
2434
+ opacity: 0.85;
2435
+ }
2436
+ .planet-text {
2437
+ fill: var(--roxy-fg, #0a0a0a);
2438
+ font-size: 13px;
2439
+ font-weight: 600;
2440
+ font-family: var(--roxy-font-sans);
2441
+ }
2442
+ .centre-label {
2443
+ fill: var(--roxy-muted, #71717a);
2444
+ font-size: 14px;
2445
+ font-weight: 600;
2446
+ font-family: var(--roxy-font-sans);
2447
+ letter-spacing: 0.02em;
2448
+ }
2449
+ .lagna-marker {
2450
+ fill: var(--roxy-accent-fg, #b45309);
2451
+ font-size: 10px;
2452
+ font-weight: 700;
2453
+ font-family: var(--roxy-font-sans);
2454
+ letter-spacing: 0.08em;
2455
+ text-transform: uppercase;
2456
+ }
2457
+ .lagna-bg {
2458
+ fill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 14%, transparent);
2459
+ }
2460
+ .lagna-slash {
2461
+ stroke: var(--roxy-accent, #f59e0b);
2462
+ stroke-linecap: round;
2463
+ opacity: 0.7;
2464
+ }
2465
+ `;
2466
+
1913
2467
  // packages/ui/src/components/divisional-chart.ts
1914
- var RoxyDivisionalChart = class extends import_lit9.LitElement {
2468
+ var RoxyDivisionalChart = class extends import_lit10.LitElement {
1915
2469
  constructor() {
1916
2470
  super(...arguments);
1917
2471
  this.data = null;
1918
- this.chartStyle = "south";
2472
+ this.chartStyle = "north";
2473
+ this.setStyle = (next) => {
2474
+ this.chartStyle = next;
2475
+ };
1919
2476
  }
1920
- buildHouses() {
1921
- if (!this.data?.chart?.meta) return [];
1922
- return buildHousesFromMeta(this.data.chart.meta);
2477
+ viewModel() {
2478
+ if (!this.data?.chart?.meta) return null;
2479
+ const { division } = this.data;
2480
+ const label = `D${division.number} ${division.name}`;
2481
+ return toKundliViewModel(this.data.chart.meta, label);
1923
2482
  }
1924
2483
  render() {
1925
- if (!this.data)
1926
- return import_lit9.html`<div class="roxy-empty" role="status">No divisional chart data</div>`;
2484
+ const vm = this.viewModel();
2485
+ if (!this.data || !vm)
2486
+ return import_lit10.html`<div class="roxy-empty" role="status">No divisional chart data</div>`;
1927
2487
  const { division, vargottama } = this.data;
1928
- const houses = this.buildHouses();
1929
- const style = this.chartStyle;
1930
- const frame = style === "north" ? renderNorthFrame() : style === "east" ? renderEastFrame() : renderSouthFrame();
1931
- const houseGroup = style === "north" ? renderNorthHouseGroup : style === "east" ? renderEastHouseGroup : renderSouthHouseGroup;
1932
- return import_lit9.html`<div class="wrap">
2488
+ return import_lit10.html`<div class="wrap">
1933
2489
  <div class="header">
1934
- <h2 class="title">
1935
- D${division.number} ${division.name}
1936
- ${division.sanskritName && division.sanskritName !== division.name ? import_lit9.html`<span class="division-meta"> · ${division.sanskritName}</span>` : import_lit9.nothing}
1937
- </h2>
1938
- ${division.significance ? import_lit9.html`<p class="significance">${division.significance}</p>` : import_lit9.nothing}
2490
+ <div>
2491
+ <h2 class="title">
2492
+ D${division.number} ${division.name}
2493
+ ${division.sanskritName && division.sanskritName !== division.name ? import_lit10.html`<span class="division-meta"> · ${division.sanskritName}</span>` : import_lit10.nothing}
2494
+ </h2>
2495
+ ${division.significance ? import_lit10.html`<p class="significance">${division.significance}</p>` : import_lit10.nothing}
2496
+ </div>
2497
+ ${renderKundliStyleTablist(this.chartStyle, this.setStyle)}
1939
2498
  </div>
1940
2499
 
1941
2500
  <svg
1942
- viewBox="0 0 300 300"
2501
+ viewBox="0 0 400 400"
2502
+ preserveAspectRatio="xMidYMid meet"
1943
2503
  role="img"
1944
2504
  aria-label="D${division.number} ${division.name} divisional chart with twelve sign houses"
1945
2505
  >
1946
2506
  <title>D${division.number} ${division.name}</title>
1947
- ${frame}
1948
- ${houses.map((h) => houseGroup(h))}
2507
+ ${renderKundliSvg(vm, this.chartStyle)}
1949
2508
  </svg>
1950
2509
 
1951
- ${vargottama && vargottama.length > 0 ? import_lit9.html`<div class="vargottama-row" role="list" aria-label="Vargottama planets">
2510
+ ${vargottama && vargottama.length > 0 ? import_lit10.html`<div class="vargottama-row" role="list" aria-label="Vargottama planets">
1952
2511
  <span class="vargottama-label">Vargottama:</span>
1953
2512
  ${vargottama.map(
1954
- (planet) => import_lit9.html`<span class="vargottama-pill" role="listitem">
2513
+ (planet) => import_lit10.html`<span class="vargottama-pill" role="listitem">
1955
2514
  ${PLANET_GLYPH[planet] ?? ""} ${planet}
1956
2515
  </span>`
1957
2516
  )}
1958
- </div>` : import_lit9.nothing}
2517
+ </div>` : import_lit10.nothing}
1959
2518
  </div>`;
1960
2519
  }
1961
2520
  };
1962
2521
  RoxyDivisionalChart.styles = [
1963
2522
  baseStyles,
1964
- import_lit9.css`
1965
- .wrap {
1966
- display: grid;
1967
- gap: var(--roxy-space-md, 1rem);
1968
- }
1969
- .header {
1970
- display: grid;
1971
- gap: var(--roxy-space-xs, 0.25rem);
1972
- }
1973
- .title {
1974
- font-size: var(--roxy-text-lg, 1.125rem);
1975
- font-weight: var(--roxy-weight-bold, 600);
1976
- margin: 0;
1977
- }
2523
+ kundliStyles,
2524
+ import_lit10.css`
1978
2525
  .division-meta {
1979
2526
  font-size: var(--roxy-text-sm, 0.875rem);
1980
2527
  color: var(--roxy-muted, #71717a);
@@ -1987,46 +2534,6 @@ RoxyDivisionalChart.styles = [
1987
2534
  padding-left: var(--roxy-space-sm, 0.5rem);
1988
2535
  margin: 0;
1989
2536
  }
1990
- svg {
1991
- display: block;
1992
- width: 100%;
1993
- max-width: 360px;
1994
- margin: 0 auto;
1995
- }
1996
- .line {
1997
- fill: transparent;
1998
- stroke: var(--roxy-border, #e4e4e7);
1999
- }
2000
- .sign-text {
2001
- fill: var(--roxy-muted, #71717a);
2002
- font-size: 9px;
2003
- font-weight: 500;
2004
- font-family: var(--roxy-font-sans);
2005
- }
2006
- .planet-text {
2007
- fill: var(--roxy-fg, #0a0a0a);
2008
- font-size: 11px;
2009
- font-weight: 600;
2010
- font-family: var(--roxy-font-sans);
2011
- }
2012
- .house-num {
2013
- fill: var(--roxy-muted, #71717a);
2014
- font-size: 9px;
2015
- font-weight: 400;
2016
- font-family: var(--roxy-font-sans);
2017
- }
2018
- .lagna-marker {
2019
- fill: var(--roxy-accent-fg, #b45309);
2020
- font-size: 8px;
2021
- font-weight: 700;
2022
- font-family: var(--roxy-font-sans);
2023
- letter-spacing: 0.05em;
2024
- }
2025
- .lagna-bg {
2026
- fill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 12%, transparent);
2027
- stroke: color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);
2028
- stroke-width: 0.8;
2029
- }
2030
2537
  .vargottama-row {
2031
2538
  display: flex;
2032
2539
  flex-wrap: wrap;
@@ -2064,14 +2571,14 @@ RoxyDivisionalChart = __decorateClass([
2064
2571
  ], RoxyDivisionalChart);
2065
2572
 
2066
2573
  // packages/ui/src/components/dosha-card.ts
2067
- var import_lit10 = require("lit");
2574
+ var import_lit11 = require("lit");
2068
2575
  var import_decorators8 = require("lit/decorators.js");
2069
2576
  var DOSHA_LABELS = {
2070
2577
  manglik: "Mangal Dosha",
2071
2578
  kalsarpa: "Kaal Sarp Dosha",
2072
2579
  sadhesati: "Sade Sati"
2073
2580
  };
2074
- var RoxyDoshaCard = class extends import_lit10.LitElement {
2581
+ var RoxyDoshaCard = class extends import_lit11.LitElement {
2075
2582
  constructor() {
2076
2583
  super(...arguments);
2077
2584
  this.data = null;
@@ -2080,14 +2587,14 @@ var RoxyDoshaCard = class extends import_lit10.LitElement {
2080
2587
  render() {
2081
2588
  const d = this.data;
2082
2589
  if (!d)
2083
- return import_lit10.html`<div class="roxy-empty" role="status">No dosha data</div>`;
2590
+ return import_lit11.html`<div class="roxy-empty" role="status">No dosha data</div>`;
2084
2591
  const present = !!d.present;
2085
2592
  const label = DOSHA_LABELS[this.type] ?? this.type;
2086
2593
  const sevLower = (d.severity ?? "").toLowerCase();
2087
2594
  const tier = sevLower === "severe" ? 3 : sevLower === "moderate" ? 2 : sevLower === "mild" ? 1 : 0;
2088
2595
  const pct = tier * 33;
2089
2596
  const barColor = tier === 3 ? "var(--roxy-danger)" : tier === 2 ? "var(--roxy-warning)" : tier === 1 ? "var(--roxy-success)" : "transparent";
2090
- return import_lit10.html`<article
2597
+ return import_lit11.html`<article
2091
2598
  class="card"
2092
2599
  aria-label=${label}
2093
2600
  >
@@ -2097,7 +2604,7 @@ var RoxyDoshaCard = class extends import_lit10.LitElement {
2097
2604
  ${present ? "Present" : "Absent"}
2098
2605
  </span>
2099
2606
  </header>
2100
- ${d.severity ? import_lit10.html`<div
2607
+ ${d.severity ? import_lit11.html`<div
2101
2608
  class="severity-bar"
2102
2609
  role="meter"
2103
2610
  aria-valuemin="0"
@@ -2106,32 +2613,32 @@ var RoxyDoshaCard = class extends import_lit10.LitElement {
2106
2613
  aria-label="Severity ${d.severity}"
2107
2614
  >
2108
2615
  <span class="severity-fill" style="width: ${pct}%; background: ${barColor};"></span>
2109
- </div>` : import_lit10.nothing}
2110
- ${d.description ? import_lit10.html`<p class="description">${d.description}</p>` : import_lit10.nothing}
2616
+ </div>` : import_lit11.nothing}
2617
+ ${d.description ? import_lit11.html`<p class="description">${d.description}</p>` : import_lit11.nothing}
2111
2618
  ${this.renderEffects(d)}
2112
- ${d.remedies && d.remedies.length > 0 ? import_lit10.html`<div>
2619
+ ${d.remedies && d.remedies.length > 0 ? import_lit11.html`<div>
2113
2620
  <h3>Remedies</h3>
2114
2621
  <ul>
2115
- ${d.remedies.map((r) => import_lit10.html`<li>${r}</li>`)}
2622
+ ${d.remedies.map((r) => import_lit11.html`<li>${r}</li>`)}
2116
2623
  </ul>
2117
- </div>` : import_lit10.nothing}
2118
- ${"exceptions" in d && d.exceptions && d.exceptions.length > 0 ? import_lit10.html`<div>
2624
+ </div>` : import_lit11.nothing}
2625
+ ${"exceptions" in d && d.exceptions && d.exceptions.length > 0 ? import_lit11.html`<div>
2119
2626
  <h3>Exceptions</h3>
2120
2627
  <ul>
2121
- ${d.exceptions.map((r) => import_lit10.html`<li>${r}</li>`)}
2628
+ ${d.exceptions.map((r) => import_lit11.html`<li>${r}</li>`)}
2122
2629
  </ul>
2123
- </div>` : import_lit10.nothing}
2630
+ </div>` : import_lit11.nothing}
2124
2631
  </article>`;
2125
2632
  }
2126
2633
  renderEffects(d) {
2127
- if (!d.effects) return import_lit10.nothing;
2634
+ if (!d.effects) return import_lit11.nothing;
2128
2635
  const entries = Object.entries(d.effects).filter(
2129
2636
  ([, v]) => typeof v === "string" && v.length > 0
2130
2637
  );
2131
- if (entries.length === 0) return import_lit10.nothing;
2132
- return import_lit10.html`<div class="effects">
2638
+ if (entries.length === 0) return import_lit11.nothing;
2639
+ return import_lit11.html`<div class="effects">
2133
2640
  ${entries.map(
2134
- ([k, v]) => import_lit10.html`<div>
2641
+ ([k, v]) => import_lit11.html`<div>
2135
2642
  <h3>${k}</h3>
2136
2643
  <p>${v}</p>
2137
2644
  </div>`
@@ -2141,7 +2648,7 @@ var RoxyDoshaCard = class extends import_lit10.LitElement {
2141
2648
  };
2142
2649
  RoxyDoshaCard.styles = [
2143
2650
  baseStyles,
2144
- import_lit10.css`
2651
+ import_lit11.css`
2145
2652
  .card {
2146
2653
  background: var(--roxy-bg, #fff);
2147
2654
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -2242,7 +2749,7 @@ RoxyDoshaCard = __decorateClass([
2242
2749
  ], RoxyDoshaCard);
2243
2750
 
2244
2751
  // packages/ui/src/components/endpoint-form.ts
2245
- var import_lit11 = require("lit");
2752
+ var import_lit12 = require("lit");
2246
2753
  var import_decorators9 = require("lit/decorators.js");
2247
2754
  var specCache = /* @__PURE__ */ new Map();
2248
2755
  async function loadSpec(url) {
@@ -2259,7 +2766,7 @@ async function loadSpec(url) {
2259
2766
  }
2260
2767
  return pending;
2261
2768
  }
2262
- var RoxyEndpointForm = class extends import_lit11.LitElement {
2769
+ var RoxyEndpointForm = class extends import_lit12.LitElement {
2263
2770
  constructor() {
2264
2771
  super(...arguments);
2265
2772
  this.endpoint = "vedic-astrology/birth-chart";
@@ -2404,35 +2911,35 @@ var RoxyEndpointForm = class extends import_lit11.LitElement {
2404
2911
  }
2405
2912
  render() {
2406
2913
  if (!this.loaded) {
2407
- return import_lit11.html`<form><div class="roxy-skeleton" style="height: 8rem"></div></form>`;
2914
+ return import_lit12.html`<form><div class="roxy-skeleton" style="height: 8rem"></div></form>`;
2408
2915
  }
2409
2916
  if (this.specError) {
2410
- return import_lit11.html`<div class="spec-error" role="alert">
2917
+ return import_lit12.html`<div class="spec-error" role="alert">
2411
2918
  Schema load failed: ${this.specError}
2412
2919
  <button type="button" class="submit" @click=${this.retryLoadSchema}>Retry</button>
2413
2920
  </div>`;
2414
2921
  }
2415
2922
  const renderField = (f) => {
2416
2923
  if (this.hasLocation && (f.name === "latitude" || f.name === "longitude" || f.name === "timezone")) {
2417
- return import_lit11.nothing;
2924
+ return import_lit12.nothing;
2418
2925
  }
2419
2926
  const inputId = `roxy-form-${f.name}`;
2420
- return import_lit11.html`<div class="field">
2927
+ return import_lit12.html`<div class="field">
2421
2928
  <label for=${inputId}>
2422
- ${humanize(f.name)}${f.required ? import_lit11.html`<span class="req" aria-hidden="true">*</span>` : import_lit11.nothing}
2929
+ ${humanize(f.name)}${f.required ? import_lit12.html`<span class="req" aria-hidden="true">*</span>` : import_lit12.nothing}
2423
2930
  </label>
2424
- ${f.enum ? import_lit11.html`<select
2931
+ ${f.enum ? import_lit12.html`<select
2425
2932
  id=${inputId}
2426
2933
  ?required=${f.required}
2427
2934
  @change=${(e) => this.setValue(f.name, e.target.value)}
2428
2935
  >
2429
2936
  <option value="">Choose</option>
2430
2937
  ${f.enum.map(
2431
- (opt) => import_lit11.html`<option value=${opt} ?selected=${this.values[f.name] === opt}>
2938
+ (opt) => import_lit12.html`<option value=${opt} ?selected=${this.values[f.name] === opt}>
2432
2939
  ${opt}
2433
2940
  </option>`
2434
2941
  )}
2435
- </select>` : import_lit11.html`<input
2942
+ </select>` : import_lit12.html`<input
2436
2943
  id=${inputId}
2437
2944
  type=${this.htmlType(f.type)}
2438
2945
  ?required=${f.required}
@@ -2445,12 +2952,12 @@ var RoxyEndpointForm = class extends import_lit11.LitElement {
2445
2952
  this.coerce(f.type, e.target.value)
2446
2953
  )}
2447
2954
  />`}
2448
- ${f.description ? import_lit11.html`<small class="help">${f.description}</small>` : import_lit11.nothing}
2955
+ ${f.description ? import_lit12.html`<small class="help">${f.description}</small>` : import_lit12.nothing}
2449
2956
  </div>`;
2450
2957
  };
2451
- return import_lit11.html`<form @submit=${this.onSubmit}>
2958
+ return import_lit12.html`<form @submit=${this.onSubmit}>
2452
2959
  <h2 class="title">${humanize(this.endpoint.split("/").pop() ?? "")}</h2>
2453
- ${this.hasLocation ? import_lit11.html`<div class="location-block">
2960
+ ${this.hasLocation ? import_lit12.html`<div class="location-block">
2454
2961
  <label>Birth location</label>
2455
2962
  <roxy-location-search
2456
2963
  @roxy-location-select=${this.onLocation}
@@ -2459,7 +2966,7 @@ var RoxyEndpointForm = class extends import_lit11.LitElement {
2459
2966
  <small class="help">
2460
2967
  Required: latitude, longitude, timezone. Pick a city to autofill.
2461
2968
  </small>
2462
- </div>` : import_lit11.nothing}
2969
+ </div>` : import_lit12.nothing}
2463
2970
  <div class="fields">
2464
2971
  ${this.fields.map((f) => renderField(f))}
2465
2972
  </div>
@@ -2491,7 +2998,7 @@ var RoxyEndpointForm = class extends import_lit11.LitElement {
2491
2998
  };
2492
2999
  RoxyEndpointForm.styles = [
2493
3000
  baseStyles,
2494
- import_lit11.css`
3001
+ import_lit12.css`
2495
3002
  form {
2496
3003
  display: grid;
2497
3004
  gap: var(--roxy-space-md, 1rem);
@@ -2627,9 +3134,9 @@ RoxyEndpointForm = __decorateClass([
2627
3134
  ], RoxyEndpointForm);
2628
3135
 
2629
3136
  // packages/ui/src/components/guna-milan.ts
2630
- var import_lit12 = require("lit");
3137
+ var import_lit13 = require("lit");
2631
3138
  var import_decorators10 = require("lit/decorators.js");
2632
- var RoxyGunaMilan = class extends import_lit12.LitElement {
3139
+ var RoxyGunaMilan = class extends import_lit13.LitElement {
2633
3140
  constructor() {
2634
3141
  super(...arguments);
2635
3142
  this.data = null;
@@ -2637,7 +3144,7 @@ var RoxyGunaMilan = class extends import_lit12.LitElement {
2637
3144
  render() {
2638
3145
  const d = this.data;
2639
3146
  if (!d)
2640
- return import_lit12.html`<div class="roxy-empty" role="status">No Guna Milan data</div>`;
3147
+ return import_lit13.html`<div class="roxy-empty" role="status">No Guna Milan data</div>`;
2641
3148
  const breakdown = (d.breakdown ?? []).filter(
2642
3149
  (b) => b?.category !== void 0
2643
3150
  );
@@ -2648,18 +3155,18 @@ var RoxyGunaMilan = class extends import_lit12.LitElement {
2648
3155
  const fillColor = pct >= 70 ? "var(--roxy-success)" : pct >= 50 ? "var(--roxy-warning)" : "var(--roxy-danger)";
2649
3156
  const dashFill = pct * 2.827;
2650
3157
  const dashGap = (100 - pct) * 2.827;
2651
- return import_lit12.html`<article class="card" aria-label="Guna Milan score">
3158
+ return import_lit13.html`<article class="card" aria-label="Guna Milan score">
2652
3159
  <div class="score-header">
2653
3160
  <div class="score-info">
2654
3161
  <div class="score-bar">
2655
3162
  <div>
2656
3163
  <span class="total">${formatNumber(d.total, 1)}</span>
2657
3164
  <span class="over"> / ${d.maxScore}</span>
2658
- ${typeof d.percentage === "number" ? import_lit12.html`<small style="margin-left: 0.5rem; color: var(--roxy-muted)">
3165
+ ${typeof d.percentage === "number" ? import_lit13.html`<small style="margin-left: 0.5rem; color: var(--roxy-muted)">
2659
3166
  ${formatPercent(d.percentage, 1)}
2660
- </small>` : import_lit12.nothing}
3167
+ </small>` : import_lit13.nothing}
2661
3168
  </div>
2662
- ${d.recommendation ? import_lit12.html`<span class="recommendation">${d.recommendation}</span>` : import_lit12.nothing}
3169
+ ${d.recommendation ? import_lit13.html`<span class="recommendation">${d.recommendation}</span>` : import_lit13.nothing}
2663
3170
  </div>
2664
3171
  </div>
2665
3172
  <div class="score-ring" role="meter" aria-label="Guna milan score" aria-valuemin="0" aria-valuemax="36" aria-valuenow="${score}">
@@ -2674,7 +3181,7 @@ var RoxyGunaMilan = class extends import_lit12.LitElement {
2674
3181
  </div>
2675
3182
  </div>
2676
3183
 
2677
- ${breakdown.length > 0 ? import_lit12.html`<table>
3184
+ ${breakdown.length > 0 ? import_lit13.html`<table>
2678
3185
  <thead>
2679
3186
  <tr>
2680
3187
  <th>Category</th>
@@ -2687,7 +3194,7 @@ var RoxyGunaMilan = class extends import_lit12.LitElement {
2687
3194
  const score2 = b.score ?? 0;
2688
3195
  const maxScore = b.maxScore ?? defaultMax(b.category);
2689
3196
  const pct2 = maxScore ? score2 / maxScore * 100 : 0;
2690
- return import_lit12.html`<tr>
3197
+ return import_lit13.html`<tr>
2691
3198
  <td>${b.category}</td>
2692
3199
  <td class="bar-cell">
2693
3200
  <div class="mini-bar">
@@ -2698,19 +3205,19 @@ var RoxyGunaMilan = class extends import_lit12.LitElement {
2698
3205
  </tr>`;
2699
3206
  })}
2700
3207
  </tbody>
2701
- </table>` : import_lit12.nothing}
2702
- ${(d.doshas?.length ?? 0) > 0 || (d.doshaCancellations?.length ?? 0) > 0 ? import_lit12.html`<div class="tags">
2703
- ${d.doshas?.map((x) => import_lit12.html`<span class="dosha">${x}</span>`)}
3208
+ </table>` : import_lit13.nothing}
3209
+ ${(d.doshas?.length ?? 0) > 0 || (d.doshaCancellations?.length ?? 0) > 0 ? import_lit13.html`<div class="tags">
3210
+ ${d.doshas?.map((x) => import_lit13.html`<span class="dosha">${x}</span>`)}
2704
3211
  ${d.doshaCancellations?.map(
2705
- (x) => import_lit12.html`<span class="cancel" title=${x.reason}>${x.dosha} cancelled</span>`
3212
+ (x) => import_lit13.html`<span class="cancel" title=${x.reason}>${x.dosha} cancelled</span>`
2706
3213
  )}
2707
- </div>` : import_lit12.nothing}
3214
+ </div>` : import_lit13.nothing}
2708
3215
  </article>`;
2709
3216
  }
2710
3217
  };
2711
3218
  RoxyGunaMilan.styles = [
2712
3219
  baseStyles,
2713
- import_lit12.css`
3220
+ import_lit13.css`
2714
3221
  .card {
2715
3222
  background: var(--roxy-bg, #fff);
2716
3223
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -2864,9 +3371,9 @@ function defaultMax(name) {
2864
3371
  }
2865
3372
 
2866
3373
  // packages/ui/src/components/hexagram.ts
2867
- var import_lit13 = require("lit");
3374
+ var import_lit14 = require("lit");
2868
3375
  var import_decorators11 = require("lit/decorators.js");
2869
- var RoxyHexagram = class extends import_lit13.LitElement {
3376
+ var RoxyHexagram = class extends import_lit14.LitElement {
2870
3377
  constructor() {
2871
3378
  super(...arguments);
2872
3379
  this.data = null;
@@ -2896,7 +3403,7 @@ var RoxyHexagram = class extends import_lit13.LitElement {
2896
3403
  render() {
2897
3404
  const resolved = this.resolveHexagram();
2898
3405
  if (!resolved)
2899
- return import_lit13.html`<div class="roxy-empty" role="status">No hexagram data</div>`;
3406
+ return import_lit14.html`<div class="roxy-empty" role="status">No hexagram data</div>`;
2900
3407
  const {
2901
3408
  hex: h,
2902
3409
  lines: castLines,
@@ -2906,52 +3413,52 @@ var RoxyHexagram = class extends import_lit13.LitElement {
2906
3413
  } = resolved;
2907
3414
  const lines = castLines ?? this.derivedLines(h);
2908
3415
  const changing = new Set(changingLinePositions ?? []);
2909
- return import_lit13.html`<article class="card" aria-label="I Ching hexagram">
3416
+ return import_lit14.html`<article class="card" aria-label="I Ching hexagram">
2910
3417
  <div class="glyphs">
2911
- ${h.symbol ? import_lit13.html`<div class="symbol">${h.symbol}</div>` : import_lit13.nothing}
3418
+ ${h.symbol ? import_lit14.html`<div class="symbol">${h.symbol}</div>` : import_lit14.nothing}
2912
3419
  <div class="lines" aria-hidden="true">
2913
3420
  ${lines.slice().reverse().map((l, idx) => {
2914
3421
  const realIdx = lines.length - 1 - idx + 1;
2915
3422
  const isChanging = changing.has(realIdx);
2916
3423
  const broken = l === 6 || l === 8;
2917
3424
  const cls = `${broken ? "broken" : "solid"}${isChanging ? " changing" : ""}`;
2918
- return import_lit13.html`<div class="line ${cls}">
2919
- ${broken ? import_lit13.svg`<span class="seg"></span><span class="seg"></span>` : import_lit13.svg`<span class="seg"></span>`}
3425
+ return import_lit14.html`<div class="line ${cls}">
3426
+ ${broken ? import_lit14.svg`<span class="seg"></span><span class="seg"></span>` : import_lit14.svg`<span class="seg"></span>`}
2920
3427
  </div>`;
2921
3428
  })}
2922
3429
  </div>
2923
3430
  </div>
2924
3431
  <div>
2925
3432
  <h2 class="title">
2926
- ${h.number ? import_lit13.html`${h.number}. ` : import_lit13.nothing}${h.english ?? h.chinese ?? "Hexagram"}
3433
+ ${h.number ? import_lit14.html`${h.number}. ` : import_lit14.nothing}${h.english ?? h.chinese ?? "Hexagram"}
2927
3434
  </h2>
2928
3435
  <p class="subtitle">
2929
- ${h.chinese ? import_lit13.html`${h.chinese}` : import_lit13.nothing}
2930
- ${h.pinyin ? import_lit13.html` · ${h.pinyin}` : import_lit13.nothing}
3436
+ ${h.chinese ? import_lit14.html`${h.chinese}` : import_lit14.nothing}
3437
+ ${h.pinyin ? import_lit14.html` · ${h.pinyin}` : import_lit14.nothing}
2931
3438
  </p>
2932
3439
  <div class="trigrams">
2933
- ${h.upperTrigram ? import_lit13.html`<div>
3440
+ ${h.upperTrigram ? import_lit14.html`<div>
2934
3441
  Upper
2935
3442
  <span class="tri-glyph"
2936
3443
  >${TRIGRAM_GLYPH[h.upperTrigram] ?? ""}</span
2937
3444
  >${h.upperTrigram}
2938
- </div>` : import_lit13.nothing}
2939
- ${h.lowerTrigram ? import_lit13.html`<div>
3445
+ </div>` : import_lit14.nothing}
3446
+ ${h.lowerTrigram ? import_lit14.html`<div>
2940
3447
  Lower
2941
3448
  <span class="tri-glyph"
2942
3449
  >${TRIGRAM_GLYPH[h.lowerTrigram] ?? ""}</span
2943
3450
  >${h.lowerTrigram}
2944
- </div>` : import_lit13.nothing}
3451
+ </div>` : import_lit14.nothing}
2945
3452
  </div>
2946
- ${h.judgment ? import_lit13.html`<p class="judgment">${h.judgment}</p>` : import_lit13.nothing}
2947
- ${h.image ? import_lit13.html`<p class="image">${h.image}</p>` : import_lit13.nothing}
2948
- ${dailyMessage ? import_lit13.html`<p class="message">${dailyMessage}</p>` : import_lit13.nothing}
2949
- ${h.interpretation?.general ? import_lit13.html`<p>${h.interpretation.general}</p>` : import_lit13.nothing}
2950
- ${changing.size > 0 ? import_lit13.html`<div class="changing">
3453
+ ${h.judgment ? import_lit14.html`<p class="judgment">${h.judgment}</p>` : import_lit14.nothing}
3454
+ ${h.image ? import_lit14.html`<p class="image">${h.image}</p>` : import_lit14.nothing}
3455
+ ${dailyMessage ? import_lit14.html`<p class="message">${dailyMessage}</p>` : import_lit14.nothing}
3456
+ ${h.interpretation?.general ? import_lit14.html`<p>${h.interpretation.general}</p>` : import_lit14.nothing}
3457
+ ${changing.size > 0 ? import_lit14.html`<div class="changing">
2951
3458
  Changing lines: ${Array.from(changing).sort((a, b) => a - b).join(", ")}.
2952
- ${resultingHexagram?.english ? import_lit13.html` Becomes hexagram ${resultingHexagram.number}
2953
- ${resultingHexagram.english}.` : import_lit13.nothing}
2954
- </div>` : import_lit13.nothing}
3459
+ ${resultingHexagram?.english ? import_lit14.html` Becomes hexagram ${resultingHexagram.number}
3460
+ ${resultingHexagram.english}.` : import_lit14.nothing}
3461
+ </div>` : import_lit14.nothing}
2955
3462
  </div>
2956
3463
  </article>`;
2957
3464
  }
@@ -2972,7 +3479,7 @@ var RoxyHexagram = class extends import_lit13.LitElement {
2972
3479
  };
2973
3480
  RoxyHexagram.styles = [
2974
3481
  baseStyles,
2975
- import_lit13.css`
3482
+ import_lit14.css`
2976
3483
  .card {
2977
3484
  background: var(--roxy-bg, #fff);
2978
3485
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -3092,9 +3599,9 @@ RoxyHexagram = __decorateClass([
3092
3599
  ], RoxyHexagram);
3093
3600
 
3094
3601
  // packages/ui/src/components/horoscope-card.ts
3095
- var import_lit14 = require("lit");
3602
+ var import_lit15 = require("lit");
3096
3603
  var import_decorators12 = require("lit/decorators.js");
3097
- var RoxyHoroscopeCard = class extends import_lit14.LitElement {
3604
+ var RoxyHoroscopeCard = class extends import_lit15.LitElement {
3098
3605
  constructor() {
3099
3606
  super(...arguments);
3100
3607
  this.data = null;
@@ -3103,12 +3610,12 @@ var RoxyHoroscopeCard = class extends import_lit14.LitElement {
3103
3610
  render() {
3104
3611
  const d = this.data;
3105
3612
  if (!d)
3106
- return import_lit14.html`<div class="roxy-empty" role="status">No horoscope data</div>`;
3613
+ return import_lit15.html`<div class="roxy-empty" role="status">No horoscope data</div>`;
3107
3614
  const sign = d.sign ?? "";
3108
3615
  const glyph = sign ? SIGN_GLYPH[capitalize(sign)] ?? "" : "";
3109
3616
  const energy = "energyRating" in d && typeof d.energyRating === "number" ? d.energyRating : null;
3110
3617
  const dateLabel = "date" in d && d.date || "week" in d && d.week || "month" in d && d.month || "";
3111
- return import_lit14.html`<article
3618
+ return import_lit15.html`<article
3112
3619
  class="card"
3113
3620
  aria-label=${`${this.period} horoscope for ${sign}`}
3114
3621
  >
@@ -3116,39 +3623,39 @@ var RoxyHoroscopeCard = class extends import_lit14.LitElement {
3116
3623
  <span class="glyph" aria-hidden="true">${glyph}</span>
3117
3624
  <div>
3118
3625
  <h2 class="title">${sign} ${this.period}</h2>
3119
- ${dateLabel ? import_lit14.html`<div class="date">${dateLabel}</div>` : import_lit14.nothing}
3626
+ ${dateLabel ? import_lit15.html`<div class="date">${dateLabel}</div>` : import_lit15.nothing}
3120
3627
  </div>
3121
- ${energy !== null ? import_lit14.html`<span class="energy" aria-label=${`Energy ${energy} of 10`}>
3628
+ ${energy !== null ? import_lit15.html`<span class="energy" aria-label=${`Energy ${energy} of 10`}>
3122
3629
  Energy ${energy}/10
3123
3630
  <span class="energy-bar"
3124
3631
  ><span style="width: ${energy / 10 * 100}%"></span
3125
3632
  ></span>
3126
- </span>` : import_lit14.nothing}
3633
+ </span>` : import_lit15.nothing}
3127
3634
  </header>
3128
3635
 
3129
- ${d.overview ? import_lit14.html`<p class="overview">${d.overview}</p>` : import_lit14.nothing}
3636
+ ${d.overview ? import_lit15.html`<p class="overview">${d.overview}</p>` : import_lit15.nothing}
3130
3637
 
3131
3638
  <div class="sections">
3132
- ${d.love ? import_lit14.html`<div class="section">
3639
+ ${d.love ? import_lit15.html`<div class="section">
3133
3640
  <h3>Love</h3>
3134
3641
  <p>${d.love}</p>
3135
- </div>` : import_lit14.nothing}
3136
- ${d.career ? import_lit14.html`<div class="section">
3642
+ </div>` : import_lit15.nothing}
3643
+ ${d.career ? import_lit15.html`<div class="section">
3137
3644
  <h3>Career</h3>
3138
3645
  <p>${d.career}</p>
3139
- </div>` : import_lit14.nothing}
3140
- ${d.health ? import_lit14.html`<div class="section">
3646
+ </div>` : import_lit15.nothing}
3647
+ ${d.health ? import_lit15.html`<div class="section">
3141
3648
  <h3>Health</h3>
3142
3649
  <p>${d.health}</p>
3143
- </div>` : import_lit14.nothing}
3144
- ${d.finance ? import_lit14.html`<div class="section">
3650
+ </div>` : import_lit15.nothing}
3651
+ ${d.finance ? import_lit15.html`<div class="section">
3145
3652
  <h3>Finance</h3>
3146
3653
  <p>${d.finance}</p>
3147
- </div>` : import_lit14.nothing}
3148
- ${"advice" in d && d.advice ? import_lit14.html`<div class="section">
3654
+ </div>` : import_lit15.nothing}
3655
+ ${"advice" in d && d.advice ? import_lit15.html`<div class="section">
3149
3656
  <h3>Advice</h3>
3150
3657
  <p>${d.advice}</p>
3151
- </div>` : import_lit14.nothing}
3658
+ </div>` : import_lit15.nothing}
3152
3659
  </div>
3153
3660
 
3154
3661
  ${(() => {
@@ -3158,25 +3665,25 @@ var RoxyHoroscopeCard = class extends import_lit14.LitElement {
3158
3665
  const luckyDays = "luckyDays" in d && d.luckyDays ? d.luckyDays : [];
3159
3666
  const compatibleSigns = d.compatibleSigns ?? [];
3160
3667
  if (luckyNumber === void 0 && !luckyColor && luckyNumbers.length === 0 && luckyDays.length === 0 && compatibleSigns.length === 0)
3161
- return import_lit14.nothing;
3162
- return import_lit14.html`<div class="lucky">
3163
- ${luckyNumber !== void 0 ? import_lit14.html`<span>Lucky number <strong>${luckyNumber}</strong></span>` : import_lit14.nothing}
3164
- ${luckyColor ? import_lit14.html`<span>Lucky color <strong>${luckyColor}</strong></span>` : import_lit14.nothing}
3165
- ${luckyNumbers.length ? import_lit14.html`<span
3668
+ return import_lit15.nothing;
3669
+ return import_lit15.html`<div class="lucky">
3670
+ ${luckyNumber !== void 0 ? import_lit15.html`<span>Lucky number <strong>${luckyNumber}</strong></span>` : import_lit15.nothing}
3671
+ ${luckyColor ? import_lit15.html`<span>Lucky color <strong>${luckyColor}</strong></span>` : import_lit15.nothing}
3672
+ ${luckyNumbers.length ? import_lit15.html`<span
3166
3673
  >Lucky numbers
3167
3674
  <strong>${luckyNumbers.join(", ")}</strong></span
3168
- >` : import_lit14.nothing}
3169
- ${luckyDays.length ? import_lit14.html`<span
3675
+ >` : import_lit15.nothing}
3676
+ ${luckyDays.length ? import_lit15.html`<span
3170
3677
  >Lucky days <strong>${luckyDays.join(", ")}</strong></span
3171
- >` : import_lit14.nothing}
3172
- ${compatibleSigns.length ? import_lit14.html`<span class="compat-wrap">
3678
+ >` : import_lit15.nothing}
3679
+ ${compatibleSigns.length ? import_lit15.html`<span class="compat-wrap">
3173
3680
  Best with
3174
3681
  <span class="compat"
3175
3682
  >${compatibleSigns.map(
3176
- (s) => import_lit14.html`<span>${s}</span>`
3683
+ (s) => import_lit15.html`<span>${s}</span>`
3177
3684
  )}</span
3178
3685
  >
3179
- </span>` : import_lit14.nothing}
3686
+ </span>` : import_lit15.nothing}
3180
3687
  </div>`;
3181
3688
  })()}
3182
3689
  </article>`;
@@ -3184,7 +3691,7 @@ var RoxyHoroscopeCard = class extends import_lit14.LitElement {
3184
3691
  };
3185
3692
  RoxyHoroscopeCard.styles = [
3186
3693
  baseStyles,
3187
- import_lit14.css`
3694
+ import_lit15.css`
3188
3695
  .card {
3189
3696
  background: var(--roxy-bg, #fff);
3190
3697
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -3319,9 +3826,9 @@ RoxyHoroscopeCard = __decorateClass([
3319
3826
  ], RoxyHoroscopeCard);
3320
3827
 
3321
3828
  // packages/ui/src/components/kp-chart.ts
3322
- var import_lit15 = require("lit");
3829
+ var import_lit16 = require("lit");
3323
3830
  var import_decorators13 = require("lit/decorators.js");
3324
- var RoxyKpChart = class extends import_lit15.LitElement {
3831
+ var RoxyKpChart = class extends import_lit16.LitElement {
3325
3832
  constructor() {
3326
3833
  super(...arguments);
3327
3834
  this.data = null;
@@ -3373,22 +3880,22 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3373
3880
  }
3374
3881
  render() {
3375
3882
  if (!this.data)
3376
- return import_lit15.html`<div class="roxy-empty" role="status">No KP chart data</div>`;
3883
+ return import_lit16.html`<div class="roxy-empty" role="status">No KP chart data</div>`;
3377
3884
  const d = this.data;
3378
3885
  const asc = d.ascendant;
3379
- return import_lit15.html`<div class="wrap" aria-label="KP chart" tabindex="0">
3886
+ return import_lit16.html`<div class="wrap" aria-label="KP chart" tabindex="0">
3380
3887
  <header class="head">
3381
3888
  <h2 class="title">KP chart</h2>
3382
- ${asc ? import_lit15.html`<div class="asc">
3889
+ ${asc ? import_lit16.html`<div class="asc">
3383
3890
  Ascendant: <strong>${asc.sign ?? ""}</strong>
3384
- ${asc.nakshatra ? import_lit15.html`· ${asc.nakshatra}` : import_lit15.nothing}
3385
- ${asc.subLord ? import_lit15.html`· sub lord ${asc.subLord}` : import_lit15.nothing}
3386
- ${typeof asc.kpNumber === "number" ? import_lit15.html`· KP ${asc.kpNumber}` : import_lit15.nothing}
3387
- </div>` : import_lit15.nothing}
3388
- ${typeof d.meta?.ayanamsa === "number" ? import_lit15.html`<div class="ayan">
3891
+ ${asc.nakshatra ? import_lit16.html`· ${asc.nakshatra}` : import_lit16.nothing}
3892
+ ${asc.subLord ? import_lit16.html`· sub lord ${asc.subLord}` : import_lit16.nothing}
3893
+ ${typeof asc.kpNumber === "number" ? import_lit16.html`· KP ${asc.kpNumber}` : import_lit16.nothing}
3894
+ </div>` : import_lit16.nothing}
3895
+ ${typeof d.meta?.ayanamsa === "number" ? import_lit16.html`<div class="ayan">
3389
3896
  ${d.meta.ayanamsaType ?? "Ayanamsa"}: ${formatNumber(d.meta.ayanamsa, 4)}°
3390
- ${d.meta.houseSystem ? import_lit15.html`· ${d.meta.houseSystem} houses` : import_lit15.nothing}
3391
- </div>` : import_lit15.nothing}
3897
+ ${d.meta.houseSystem ? import_lit16.html`· ${d.meta.houseSystem} houses` : import_lit16.nothing}
3898
+ </div>` : import_lit16.nothing}
3392
3899
  </header>
3393
3900
 
3394
3901
  <div
@@ -3398,7 +3905,7 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3398
3905
  @keydown=${this.onTabKeyDown}
3399
3906
  >
3400
3907
  ${["planets", "cusps"].map(
3401
- (t) => import_lit15.html`<button
3908
+ (t) => import_lit16.html`<button
3402
3909
  class="tab"
3403
3910
  role="tab"
3404
3911
  id="tab-${t}"
@@ -3422,8 +3929,8 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3422
3929
  renderPlanets() {
3423
3930
  const bodies = this.bodies();
3424
3931
  if (!bodies.length)
3425
- return import_lit15.html`<p class="roxy-empty" role="status">No planets</p>`;
3426
- return import_lit15.html`<table role="table" aria-label="KP planets and nodes">
3932
+ return import_lit16.html`<p class="roxy-empty" role="status">No planets</p>`;
3933
+ return import_lit16.html`<table role="table" aria-label="KP planets and nodes">
3427
3934
  <thead>
3428
3935
  <tr>
3429
3936
  <th scope="col">Body</th>
@@ -3438,9 +3945,9 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3438
3945
  </thead>
3439
3946
  <tbody>
3440
3947
  ${bodies.map(
3441
- (b) => import_lit15.html`<tr>
3948
+ (b) => import_lit16.html`<tr>
3442
3949
  <td class="body">
3443
- ${b.name}${b.retrograde ? import_lit15.html`<span class="retro">R</span>` : import_lit15.nothing}
3950
+ ${b.name}${b.retrograde ? import_lit16.html`<span class="retro">R</span>` : import_lit16.nothing}
3444
3951
  </td>
3445
3952
  <td>${b.sign ?? ""}</td>
3446
3953
  <td class="num">${typeof b.house === "number" ? b.house : ""}</td>
@@ -3457,8 +3964,8 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3457
3964
  renderCusps() {
3458
3965
  const cusps = this.data?.cusps ?? [];
3459
3966
  if (!cusps.length)
3460
- return import_lit15.html`<p class="roxy-empty" role="status">No cusps</p>`;
3461
- return import_lit15.html`<table role="table" aria-label="KP Placidus cusps">
3967
+ return import_lit16.html`<p class="roxy-empty" role="status">No cusps</p>`;
3968
+ return import_lit16.html`<table role="table" aria-label="KP Placidus cusps">
3462
3969
  <thead>
3463
3970
  <tr>
3464
3971
  <th scope="col">House</th>
@@ -3473,7 +3980,7 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3473
3980
  </thead>
3474
3981
  <tbody>
3475
3982
  ${cusps.map(
3476
- (c) => import_lit15.html`<tr>
3983
+ (c) => import_lit16.html`<tr>
3477
3984
  <td class="body num">${c.house}</td>
3478
3985
  <td>${c.sign ?? ""}</td>
3479
3986
  <td>${c.signLord ?? ""}</td>
@@ -3490,7 +3997,7 @@ var RoxyKpChart = class extends import_lit15.LitElement {
3490
3997
  };
3491
3998
  RoxyKpChart.styles = [
3492
3999
  baseStyles,
3493
- import_lit15.css`
4000
+ import_lit16.css`
3494
4001
  .wrap {
3495
4002
  border: 1px solid var(--roxy-border, #e4e4e7);
3496
4003
  border-radius: var(--roxy-radius-md, 8px);
@@ -3593,25 +4100,25 @@ RoxyKpChart = __decorateClass([
3593
4100
  ], RoxyKpChart);
3594
4101
 
3595
4102
  // packages/ui/src/components/kp-planets-table.ts
3596
- var import_lit16 = require("lit");
4103
+ var import_lit17 = require("lit");
3597
4104
  var import_decorators14 = require("lit/decorators.js");
3598
- var RoxyKpPlanetsTable = class extends import_lit16.LitElement {
4105
+ var RoxyKpPlanetsTable = class extends import_lit17.LitElement {
3599
4106
  constructor() {
3600
4107
  super(...arguments);
3601
4108
  this.data = null;
3602
4109
  }
3603
4110
  render() {
3604
4111
  if (!this.data)
3605
- return import_lit16.html`<div class="roxy-empty" role="status">No KP data</div>`;
4112
+ return import_lit17.html`<div class="roxy-empty" role="status">No KP data</div>`;
3606
4113
  const planets = this.data.planets ?? [];
3607
- return import_lit16.html`<div
4114
+ return import_lit17.html`<div
3608
4115
  class="wrap"
3609
4116
  aria-label="KP planets table"
3610
4117
  tabindex="0"
3611
4118
  >
3612
4119
  <header class="head">
3613
4120
  <h2 class="title">KP planets</h2>
3614
- ${typeof this.data.ayanamsa === "number" ? import_lit16.html`<span class="ayanamsa">Ayanamsa: ${formatNumber(this.data.ayanamsa, 2)}°</span>` : import_lit16.nothing}
4121
+ ${typeof this.data.ayanamsa === "number" ? import_lit17.html`<span class="ayanamsa">Ayanamsa: ${formatNumber(this.data.ayanamsa, 2)}°</span>` : import_lit17.nothing}
3615
4122
  </header>
3616
4123
  <table role="table">
3617
4124
  <thead>
@@ -3628,10 +4135,10 @@ var RoxyKpPlanetsTable = class extends import_lit16.LitElement {
3628
4135
  </thead>
3629
4136
  <tbody>
3630
4137
  ${planets.map(
3631
- (p) => import_lit16.html`<tr>
4138
+ (p) => import_lit17.html`<tr>
3632
4139
  <td class="planet">
3633
4140
  ${p.planet}
3634
- ${p.retrograde ? import_lit16.html`<span class="retro">R</span>` : import_lit16.nothing}
4141
+ ${p.retrograde ? import_lit17.html`<span class="retro">R</span>` : import_lit17.nothing}
3635
4142
  </td>
3636
4143
  <td>${p.sign ?? ""}</td>
3637
4144
  <td>${p.signLord ?? ""}</td>
@@ -3649,7 +4156,7 @@ var RoxyKpPlanetsTable = class extends import_lit16.LitElement {
3649
4156
  };
3650
4157
  RoxyKpPlanetsTable.styles = [
3651
4158
  baseStyles,
3652
- import_lit16.css`
4159
+ import_lit17.css`
3653
4160
  .wrap {
3654
4161
  border: 1px solid var(--roxy-border, #e4e4e7);
3655
4162
  border-radius: var(--roxy-radius-md, 8px);
@@ -3718,22 +4225,22 @@ RoxyKpPlanetsTable = __decorateClass([
3718
4225
  ], RoxyKpPlanetsTable);
3719
4226
 
3720
4227
  // packages/ui/src/components/kp-ruling-planets.ts
3721
- var import_lit17 = require("lit");
4228
+ var import_lit18 = require("lit");
3722
4229
  var import_decorators15 = require("lit/decorators.js");
3723
- var RoxyKpRulingPlanets = class extends import_lit17.LitElement {
4230
+ var RoxyKpRulingPlanets = class extends import_lit18.LitElement {
3724
4231
  constructor() {
3725
4232
  super(...arguments);
3726
4233
  this.data = null;
3727
4234
  }
3728
4235
  render() {
3729
4236
  if (!this.data)
3730
- return import_lit17.html`<div class="roxy-empty" role="status">No ruling planets data</div>`;
4237
+ return import_lit18.html`<div class="roxy-empty" role="status">No ruling planets data</div>`;
3731
4238
  const d = this.data;
3732
4239
  const significators = d.significators ?? [];
3733
- return import_lit17.html`<div class="wrap" aria-label="KP ruling planets">
4240
+ return import_lit18.html`<div class="wrap" aria-label="KP ruling planets">
3734
4241
  <header>
3735
4242
  <h2 class="title">KP ruling planets</h2>
3736
- ${d.dayLord ? import_lit17.html`<div class="day-lord">Day lord: <strong>${d.dayLord}</strong></div>` : import_lit17.nothing}
4243
+ ${d.dayLord ? import_lit18.html`<div class="day-lord">Day lord: <strong>${d.dayLord}</strong></div>` : import_lit18.nothing}
3737
4244
  </header>
3738
4245
 
3739
4246
  <div class="groups">
@@ -3757,14 +4264,14 @@ var RoxyKpRulingPlanets = class extends import_lit17.LitElement {
3757
4264
  </div>
3758
4265
  </div>
3759
4266
 
3760
- ${d.rulingPlanets?.length ? import_lit17.html`<div class="rp-list" role="list" aria-label="Ruling planets by strength">
4267
+ ${d.rulingPlanets?.length ? import_lit18.html`<div class="rp-list" role="list" aria-label="Ruling planets by strength">
3761
4268
  <span class="rp-label">Ruling planets</span>
3762
4269
  ${d.rulingPlanets.map(
3763
- (p, i) => import_lit17.html`<span class="rp" role="listitem"><span class="rank">${i + 1}</span> ${p}</span>`
4270
+ (p, i) => import_lit18.html`<span class="rp" role="listitem"><span class="rank">${i + 1}</span> ${p}</span>`
3764
4271
  )}
3765
- </div>` : import_lit17.nothing}
4272
+ </div>` : import_lit18.nothing}
3766
4273
 
3767
- ${significators.length ? import_lit17.html`<table aria-label="House significators">
4274
+ ${significators.length ? import_lit18.html`<table aria-label="House significators">
3768
4275
  <thead>
3769
4276
  <tr>
3770
4277
  <th scope="col">Planet</th>
@@ -3773,19 +4280,19 @@ var RoxyKpRulingPlanets = class extends import_lit17.LitElement {
3773
4280
  </thead>
3774
4281
  <tbody>
3775
4282
  ${significators.map(
3776
- (s) => import_lit17.html`<tr>
4283
+ (s) => import_lit18.html`<tr>
3777
4284
  <td>${s.planet}</td>
3778
4285
  <td>${(s.signifies ?? []).join(", ")}</td>
3779
4286
  </tr>`
3780
4287
  )}
3781
4288
  </tbody>
3782
- </table>` : import_lit17.nothing}
4289
+ </table>` : import_lit18.nothing}
3783
4290
  </div>`;
3784
4291
  }
3785
4292
  };
3786
4293
  RoxyKpRulingPlanets.styles = [
3787
4294
  baseStyles,
3788
- import_lit17.css`
4295
+ import_lit18.css`
3789
4296
  .wrap {
3790
4297
  border: 1px solid var(--roxy-border, #e4e4e7);
3791
4298
  border-radius: var(--roxy-radius-md, 8px);
@@ -3891,7 +4398,7 @@ RoxyKpRulingPlanets = __decorateClass([
3891
4398
  ], RoxyKpRulingPlanets);
3892
4399
 
3893
4400
  // packages/ui/src/components/location-search.ts
3894
- var import_lit18 = require("lit");
4401
+ var import_lit19 = require("lit");
3895
4402
  var import_decorators16 = require("lit/decorators.js");
3896
4403
 
3897
4404
  // packages/ui/src/utils/debounce.ts
@@ -3914,7 +4421,7 @@ function debounce(fn, wait) {
3914
4421
  }
3915
4422
 
3916
4423
  // packages/ui/src/components/location-search.ts
3917
- var RoxyLocationSearch = class extends import_lit18.LitElement {
4424
+ var RoxyLocationSearch = class extends import_lit19.LitElement {
3918
4425
  constructor() {
3919
4426
  super(...arguments);
3920
4427
  this.endpoint = "https://roxyapi.com/api/v2/location/search";
@@ -4049,7 +4556,7 @@ var RoxyLocationSearch = class extends import_lit18.LitElement {
4049
4556
  );
4050
4557
  }
4051
4558
  render() {
4052
- return import_lit18.html`<div class="field">
4559
+ return import_lit19.html`<div class="field">
4053
4560
  <input
4054
4561
  type="text"
4055
4562
  role="combobox"
@@ -4066,14 +4573,14 @@ var RoxyLocationSearch = class extends import_lit18.LitElement {
4066
4573
  if (this.results.length > 0) this.isOpen = true;
4067
4574
  }}
4068
4575
  />
4069
- ${this.isLoading ? import_lit18.html`<span class="spinner" role="status" aria-label="Loading"></span>` : import_lit18.nothing}
4070
- ${this.isOpen ? import_lit18.html`<ul
4576
+ ${this.isLoading ? import_lit19.html`<span class="spinner" role="status" aria-label="Loading"></span>` : import_lit19.nothing}
4577
+ ${this.isOpen ? import_lit19.html`<ul
4071
4578
  id="roxy-location-listbox"
4072
4579
  class="results"
4073
4580
  role="listbox"
4074
4581
  >
4075
- ${this.results.length === 0 ? import_lit18.html`<li class="empty" role="status">No cities found</li>` : this.results.map(
4076
- (city, idx) => import_lit18.html`<li role="presentation">
4582
+ ${this.results.length === 0 ? import_lit19.html`<li class="empty" role="status">No cities found</li>` : this.results.map(
4583
+ (city, idx) => import_lit19.html`<li role="presentation">
4077
4584
  <button
4078
4585
  type="button"
4079
4586
  class="option"
@@ -4087,7 +4594,7 @@ var RoxyLocationSearch = class extends import_lit18.LitElement {
4087
4594
  >
4088
4595
  <span class="city">${city.city}</span>
4089
4596
  <span class="where"
4090
- >${city.province ? import_lit18.html`${city.province}, ` : ""}${city.country}</span
4597
+ >${city.province ? import_lit19.html`${city.province}, ` : ""}${city.country}</span
4091
4598
  >
4092
4599
  <span class="tz"
4093
4600
  >UTC${city.utcOffset >= 0 ? "+" : ""}${city.utcOffset}</span
@@ -4095,13 +4602,13 @@ var RoxyLocationSearch = class extends import_lit18.LitElement {
4095
4602
  </button>
4096
4603
  </li>`
4097
4604
  )}
4098
- </ul>` : import_lit18.nothing}
4605
+ </ul>` : import_lit19.nothing}
4099
4606
  </div>`;
4100
4607
  }
4101
4608
  };
4102
4609
  RoxyLocationSearch.styles = [
4103
4610
  baseStyles,
4104
- import_lit18.css`
4611
+ import_lit19.css`
4105
4612
  :host {
4106
4613
  display: block;
4107
4614
  position: relative;
@@ -4239,9 +4746,9 @@ RoxyLocationSearch = __decorateClass([
4239
4746
  ], RoxyLocationSearch);
4240
4747
 
4241
4748
  // packages/ui/src/components/moon-phase.ts
4242
- var import_lit19 = require("lit");
4749
+ var import_lit20 = require("lit");
4243
4750
  var import_decorators17 = require("lit/decorators.js");
4244
- var RoxyMoonPhase = class extends import_lit19.LitElement {
4751
+ var RoxyMoonPhase = class extends import_lit20.LitElement {
4245
4752
  constructor() {
4246
4753
  super(...arguments);
4247
4754
  this.data = null;
@@ -4250,12 +4757,12 @@ var RoxyMoonPhase = class extends import_lit19.LitElement {
4250
4757
  render() {
4251
4758
  const d = this.data;
4252
4759
  if (!d)
4253
- return import_lit19.html`<div class="roxy-empty" role="status">No moon phase data</div>`;
4760
+ return import_lit20.html`<div class="roxy-empty" role="status">No moon phase data</div>`;
4254
4761
  const list = "phases" in d ? d.phases : "calendar" in d ? d.calendar : [];
4255
4762
  if (this.mode !== "current" && list.length > 0) {
4256
4763
  const month = "month" in d ? d.month : void 0;
4257
4764
  const year = "year" in d ? d.year : void 0;
4258
- return import_lit19.html`<article
4765
+ return import_lit20.html`<article
4259
4766
  class="card"
4260
4767
  aria-label="Moon phase calendar"
4261
4768
  >
@@ -4265,46 +4772,46 @@ var RoxyMoonPhase = class extends import_lit19.LitElement {
4265
4772
  </div>
4266
4773
  </article>`;
4267
4774
  }
4268
- if (!("phase" in d)) return import_lit19.nothing;
4775
+ if (!("phase" in d)) return import_lit20.nothing;
4269
4776
  return this.renderSingle(d);
4270
4777
  }
4271
4778
  renderSingle(d) {
4272
4779
  const emoji = phaseEmoji(d.phase);
4273
- return import_lit19.html`<article class="card" aria-label="Current moon phase">
4780
+ return import_lit20.html`<article class="card" aria-label="Current moon phase">
4274
4781
  <div class="hero">
4275
4782
  <span class="emoji" aria-hidden="true">${emoji}</span>
4276
4783
  <div>
4277
4784
  <h2 class="label">${d.phase ?? "Moon"}</h2>
4278
- ${d.date ? import_lit19.html`<div class="date">${d.date}</div>` : import_lit19.nothing}
4785
+ ${d.date ? import_lit20.html`<div class="date">${d.date}</div>` : import_lit20.nothing}
4279
4786
  </div>
4280
4787
  </div>
4281
4788
  <div class="stats">
4282
- ${typeof d.illumination === "number" ? import_lit19.html`<div>
4789
+ ${typeof d.illumination === "number" ? import_lit20.html`<div>
4283
4790
  <span>Illumination</span>
4284
4791
  <strong>${formatIllumination(d.illumination)}</strong>
4285
- </div>` : import_lit19.nothing}
4286
- ${typeof d.age === "number" ? import_lit19.html`<div>
4792
+ </div>` : import_lit20.nothing}
4793
+ ${typeof d.age === "number" ? import_lit20.html`<div>
4287
4794
  <span>Age</span>
4288
4795
  <strong>${formatNumber(d.age, 1)} days</strong>
4289
- </div>` : import_lit19.nothing}
4290
- ${d.sign ? import_lit19.html`<div>
4796
+ </div>` : import_lit20.nothing}
4797
+ ${d.sign ? import_lit20.html`<div>
4291
4798
  <span>Sign</span>
4292
4799
  <strong>${d.sign}</strong>
4293
- </div>` : import_lit19.nothing}
4294
- ${typeof d.distance === "number" ? import_lit19.html`<div>
4800
+ </div>` : import_lit20.nothing}
4801
+ ${typeof d.distance === "number" ? import_lit20.html`<div>
4295
4802
  <span>Distance</span>
4296
4803
  <strong>${(d.distance / 1e3).toFixed(0)}k km</strong>
4297
- </div>` : import_lit19.nothing}
4804
+ </div>` : import_lit20.nothing}
4298
4805
  </div>
4299
- ${d.meaning?.description ? import_lit19.html`<p class="meaning">${d.meaning.description}</p>` : import_lit19.nothing}
4300
- ${d.meaning?.keywords?.length ? import_lit19.html`<div class="keywords">
4301
- ${d.meaning.keywords.map((k) => import_lit19.html`<span>${k}</span>`)}
4302
- </div>` : import_lit19.nothing}
4806
+ ${d.meaning?.description ? import_lit20.html`<p class="meaning">${d.meaning.description}</p>` : import_lit20.nothing}
4807
+ ${d.meaning?.keywords?.length ? import_lit20.html`<div class="keywords">
4808
+ ${d.meaning.keywords.map((k) => import_lit20.html`<span>${k}</span>`)}
4809
+ </div>` : import_lit20.nothing}
4303
4810
  </article>`;
4304
4811
  }
4305
4812
  renderListItem(p) {
4306
4813
  const emoji = phaseEmoji(p.phase);
4307
- return import_lit19.html`<div class="list-item" role="listitem">
4814
+ return import_lit20.html`<div class="list-item" role="listitem">
4308
4815
  <span aria-hidden="true">${emoji}</span>
4309
4816
  <span>${p.phase}</span>
4310
4817
  <span>${p.date ?? ""}</span>
@@ -4313,7 +4820,7 @@ var RoxyMoonPhase = class extends import_lit19.LitElement {
4313
4820
  };
4314
4821
  RoxyMoonPhase.styles = [
4315
4822
  baseStyles,
4316
- import_lit19.css`
4823
+ import_lit20.css`
4317
4824
  .card {
4318
4825
  background: var(--roxy-bg, #fff);
4319
4826
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -4416,50 +4923,50 @@ function formatIllumination(v) {
4416
4923
  }
4417
4924
 
4418
4925
  // packages/ui/src/components/nakshatra-card.ts
4419
- var import_lit20 = require("lit");
4926
+ var import_lit21 = require("lit");
4420
4927
  var import_decorators18 = require("lit/decorators.js");
4421
- var RoxyNakshatraCard = class extends import_lit20.LitElement {
4928
+ var RoxyNakshatraCard = class extends import_lit21.LitElement {
4422
4929
  constructor() {
4423
4930
  super(...arguments);
4424
4931
  this.data = null;
4425
4932
  }
4426
4933
  render() {
4427
4934
  if (!this.data)
4428
- return import_lit20.html`<div class="roxy-empty" role="status">No nakshatra data</div>`;
4935
+ return import_lit21.html`<div class="roxy-empty" role="status">No nakshatra data</div>`;
4429
4936
  const n = this.data;
4430
4937
  const remedies = n.remedies;
4431
- return import_lit20.html`<article class="wrap" aria-label=${`Nakshatra ${n.name}`}>
4938
+ return import_lit21.html`<article class="wrap" aria-label=${`Nakshatra ${n.name}`}>
4432
4939
  <header class="head">
4433
4940
  <h2 class="name">${n.name}</h2>
4434
- ${typeof n.number === "number" ? import_lit20.html`<span class="number">Nakshatra ${n.number} of 27</span>` : import_lit20.nothing}
4435
- ${n.range ? import_lit20.html`<span class="range">${n.range}</span>` : import_lit20.nothing}
4941
+ ${typeof n.number === "number" ? import_lit21.html`<span class="number">Nakshatra ${n.number} of 27</span>` : import_lit21.nothing}
4942
+ ${n.range ? import_lit21.html`<span class="range">${n.range}</span>` : import_lit21.nothing}
4436
4943
  </header>
4437
4944
 
4438
4945
  <dl class="facts">
4439
- ${n.lord ? import_lit20.html`<div class="fact"><dt>Lord</dt><dd>${n.lord}</dd></div>` : import_lit20.nothing}
4440
- ${n.deity ? import_lit20.html`<div class="fact"><dt>Deity</dt><dd>${n.deity}</dd></div>` : import_lit20.nothing}
4441
- ${n.symbol ? import_lit20.html`<div class="fact"><dt>Symbol</dt><dd>${n.symbol}</dd></div>` : import_lit20.nothing}
4946
+ ${n.lord ? import_lit21.html`<div class="fact"><dt>Lord</dt><dd>${n.lord}</dd></div>` : import_lit21.nothing}
4947
+ ${n.deity ? import_lit21.html`<div class="fact"><dt>Deity</dt><dd>${n.deity}</dd></div>` : import_lit21.nothing}
4948
+ ${n.symbol ? import_lit21.html`<div class="fact"><dt>Symbol</dt><dd>${n.symbol}</dd></div>` : import_lit21.nothing}
4442
4949
  </dl>
4443
4950
 
4444
- ${n.characteristics ? import_lit20.html`<div class="section">
4951
+ ${n.characteristics ? import_lit21.html`<div class="section">
4445
4952
  <h3>Characteristics</h3>
4446
4953
  <p>${n.characteristics}</p>
4447
- </div>` : import_lit20.nothing}
4954
+ </div>` : import_lit21.nothing}
4448
4955
 
4449
- ${remedies ? import_lit20.html`<div class="section">
4956
+ ${remedies ? import_lit21.html`<div class="section">
4450
4957
  <h3>Remedies</h3>
4451
4958
  <div class="remedies">
4452
- ${remedies.mantras ? import_lit20.html`<div class="remedy"><strong>Mantras:</strong> ${remedies.mantras}</div>` : import_lit20.nothing}
4453
- ${remedies.gemstones ? import_lit20.html`<div class="remedy"><strong>Gemstones:</strong> ${remedies.gemstones}</div>` : import_lit20.nothing}
4454
- ${remedies.rituals ? import_lit20.html`<div class="remedy"><strong>Rituals:</strong> ${remedies.rituals}</div>` : import_lit20.nothing}
4959
+ ${remedies.mantras ? import_lit21.html`<div class="remedy"><strong>Mantras:</strong> ${remedies.mantras}</div>` : import_lit21.nothing}
4960
+ ${remedies.gemstones ? import_lit21.html`<div class="remedy"><strong>Gemstones:</strong> ${remedies.gemstones}</div>` : import_lit21.nothing}
4961
+ ${remedies.rituals ? import_lit21.html`<div class="remedy"><strong>Rituals:</strong> ${remedies.rituals}</div>` : import_lit21.nothing}
4455
4962
  </div>
4456
- </div>` : import_lit20.nothing}
4963
+ </div>` : import_lit21.nothing}
4457
4964
  </article>`;
4458
4965
  }
4459
4966
  };
4460
4967
  RoxyNakshatraCard.styles = [
4461
4968
  baseStyles,
4462
- import_lit20.css`
4969
+ import_lit21.css`
4463
4970
  .wrap {
4464
4971
  border: 1px solid var(--roxy-border, #e4e4e7);
4465
4972
  border-radius: var(--roxy-radius-md, 8px);
@@ -4545,7 +5052,7 @@ RoxyNakshatraCard = __decorateClass([
4545
5052
  ], RoxyNakshatraCard);
4546
5053
 
4547
5054
  // packages/ui/src/components/natal-chart.ts
4548
- var import_lit21 = require("lit");
5055
+ var import_lit22 = require("lit");
4549
5056
  var import_decorators19 = require("lit/decorators.js");
4550
5057
  var SIZE = 420;
4551
5058
  var CENTER = SIZE / 2;
@@ -4555,7 +5062,7 @@ var HOUSE_R = 120;
4555
5062
  var PLANET_R = 96;
4556
5063
  var ANGLE_TICK_R = 178;
4557
5064
  var ANGLE_LABEL_R = 196;
4558
- var RoxyNatalChart = class extends import_lit21.LitElement {
5065
+ var RoxyNatalChart = class extends import_lit22.LitElement {
4559
5066
  constructor() {
4560
5067
  super(...arguments);
4561
5068
  this.data = null;
@@ -4577,16 +5084,16 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4577
5084
  }
4578
5085
  render() {
4579
5086
  if (!this.data)
4580
- return import_lit21.html`<div class="roxy-empty" role="status">No chart data</div>`;
5087
+ return import_lit22.html`<div class="roxy-empty" role="status">No chart data</div>`;
4581
5088
  const planets = this.getPlanets();
4582
5089
  const aspects = this.data.aspects ?? [];
4583
5090
  const view = this.view;
4584
- return import_lit21.html`<div class="wrap">
5091
+ return import_lit22.html`<div class="wrap">
4585
5092
  <header>
4586
5093
  <h2 class="title">Natal chart</h2>
4587
- ${this.data.birthDetails ? import_lit21.html`<div class="meta">
5094
+ ${this.data.birthDetails ? import_lit22.html`<div class="meta">
4588
5095
  ${[this.data.birthDetails.date, this.data.birthDetails.time].filter(Boolean).join(" \xB7 ")}
4589
- </div>` : import_lit21.nothing}
5096
+ </div>` : import_lit22.nothing}
4590
5097
  </header>
4591
5098
  <div
4592
5099
  class="tablist"
@@ -4595,7 +5102,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4595
5102
  @keydown=${this.onTabKeyDown}
4596
5103
  >
4597
5104
  ${["wheel", "grid"].map(
4598
- (t) => import_lit21.html`<button
5105
+ (t) => import_lit22.html`<button
4599
5106
  class="tab"
4600
5107
  role="tab"
4601
5108
  id="tab-${t}"
@@ -4616,7 +5123,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4616
5123
  <div class="legend">
4617
5124
  <span>${planets.length} planets</span>
4618
5125
  <span>${aspects.length} aspects</span>
4619
- ${this.data.houseSystem ? import_lit21.html`<span>${this.data.houseSystem} houses</span>` : import_lit21.nothing}
5126
+ ${this.data.houseSystem ? import_lit22.html`<span>${this.data.houseSystem} houses</span>` : import_lit22.nothing}
4620
5127
  <span><span class="legend-swatch" style="background: var(--roxy-success)"></span>harmonious</span>
4621
5128
  <span><span class="legend-swatch" style="background: var(--roxy-danger)"></span>challenging</span>
4622
5129
  </div>
@@ -4634,7 +5141,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4634
5141
  });
4635
5142
  }
4636
5143
  renderWheel(planets, aspects) {
4637
- return import_lit21.html`<svg
5144
+ return import_lit22.html`<svg
4638
5145
  viewBox="0 0 ${SIZE} ${SIZE}"
4639
5146
  role="img"
4640
5147
  aria-label="Natal chart wheel with twelve houses, planets, and aspects"
@@ -4667,35 +5174,35 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4667
5174
  byPair.set(k, a);
4668
5175
  }
4669
5176
  if (names.length === 0)
4670
- return import_lit21.html`<p class="roxy-empty" role="status">No planets to grid</p>`;
4671
- return import_lit21.html`<div class="grid-scroll">
5177
+ return import_lit22.html`<p class="roxy-empty" role="status">No planets to grid</p>`;
5178
+ return import_lit22.html`<div class="grid-scroll">
4672
5179
  <table class="aspect-grid" aria-label="Planet by planet aspect grid">
4673
5180
  <thead>
4674
5181
  <tr>
4675
5182
  <th></th>
4676
5183
  ${names.slice(0, -1).map((n) => {
4677
5184
  const g = PLANET_GLYPH[n] ?? n.slice(0, 2);
4678
- return import_lit21.html`<th scope="col" title=${n}>${g}</th>`;
5185
+ return import_lit22.html`<th scope="col" title=${n}>${g}</th>`;
4679
5186
  })}
4680
5187
  </tr>
4681
5188
  </thead>
4682
5189
  <tbody>
4683
5190
  ${names.slice(1).map((rowName, ri) => {
4684
5191
  const rowGlyph = PLANET_GLYPH[rowName] ?? rowName.slice(0, 2);
4685
- return import_lit21.html`<tr>
5192
+ return import_lit22.html`<tr>
4686
5193
  <th scope="row" title=${rowName}>${rowGlyph}</th>
4687
5194
  ${names.slice(0, ri + 1).map((colName) => {
4688
5195
  const a = byPair.get([rowName, colName].sort().join("|"));
4689
- if (!a) return import_lit21.html`<td class="empty"></td>`;
5196
+ if (!a) return import_lit22.html`<td class="empty"></td>`;
4690
5197
  const name = normalizeAspect(a);
4691
5198
  const sym = ASPECT_SYMBOL[name] ?? ASPECT_SYMBOL[name.replace(/-/g, "")] ?? name.slice(0, 3);
4692
5199
  const cls = ASPECT_CLASS[name] ?? "aspect-other";
4693
5200
  const orb = formatNumber(a.orb, 1);
4694
- return import_lit21.html`<td class=${`cell ${cls}`} title=${`${rowName} ${name} ${colName}${orb ? ` (orb ${orb}\xB0)` : ""}`}>
5201
+ return import_lit22.html`<td class=${`cell ${cls}`} title=${`${rowName} ${name} ${colName}${orb ? ` (orb ${orb}\xB0)` : ""}`}>
4695
5202
  <span class="asp">${sym}</span>
4696
5203
  </td>`;
4697
5204
  })}
4698
- ${names.slice(ri + 1, -1).map(() => import_lit21.html`<td class="empty"></td>`)}
5205
+ ${names.slice(ri + 1, -1).map(() => import_lit22.html`<td class="empty"></td>`)}
4699
5206
  </tr>`;
4700
5207
  })}
4701
5208
  </tbody>
@@ -4728,7 +5235,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4728
5235
  const tickInner = polarToCartesian(CENTER, CENTER, OUTER_R, angle);
4729
5236
  const tickOuter = polarToCartesian(CENTER, CENTER, ANGLE_TICK_R, angle);
4730
5237
  const labelPos = polarToCartesian(CENTER, CENTER, ANGLE_LABEL_R, angle);
4731
- return import_lit21.svg`
5238
+ return import_lit22.svg`
4732
5239
  <g>
4733
5240
  <line class="angle-tick" x1=${tickInner.x} y1=${tickInner.y} x2=${tickOuter.x} y2=${tickOuter.y} />
4734
5241
  <text class="angle-marker" x=${labelPos.x} y=${labelPos.y} text-anchor="middle" dominant-baseline="central">${label}</text>
@@ -4742,14 +5249,14 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4742
5249
  const angle = this.toAngle(lon);
4743
5250
  const start = polarToCartesian(CENTER, CENTER, HOUSE_R, angle);
4744
5251
  const end = polarToCartesian(CENTER, CENTER, OUTER_R, angle);
4745
- return import_lit21.svg`<line class="wheel-line" x1=${start.x} y1=${start.y} x2=${end.x} y2=${end.y} stroke-width="0.8" />`;
5252
+ return import_lit22.svg`<line class="wheel-line" x1=${start.x} y1=${start.y} x2=${end.x} y2=${end.y} stroke-width="0.8" />`;
4746
5253
  });
4747
5254
  }
4748
5255
  renderSigns() {
4749
5256
  return SIGNS_ORDER.map((sign, i) => {
4750
5257
  const angle = this.toAngle(i * 30 + 15);
4751
5258
  const pos = polarToCartesian(CENTER, CENTER, SIGN_R, angle);
4752
- return import_lit21.svg`<text class="sign-glyph" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${SIGN_GLYPH[sign]}</text>`;
5259
+ return import_lit22.svg`<text class="sign-glyph" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${SIGN_GLYPH[sign]}</text>`;
4753
5260
  });
4754
5261
  }
4755
5262
  renderHouseNumbers() {
@@ -4767,7 +5274,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4767
5274
  HOUSE_R - 12,
4768
5275
  this.toAngle(mid)
4769
5276
  );
4770
- return import_lit21.svg`<text class="house-num" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${house.number}</text>`;
5277
+ return import_lit22.svg`<text class="house-num" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${house.number}</text>`;
4771
5278
  });
4772
5279
  }
4773
5280
  const ascSignIndex = Math.floor(this.getAscendant() / 30);
@@ -4775,7 +5282,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4775
5282
  const angle = this.toAngle(i * 30 + 15);
4776
5283
  const pos = polarToCartesian(CENTER, CENTER, HOUSE_R - 12, angle);
4777
5284
  const houseNum = (i - ascSignIndex + 12) % 12 + 1;
4778
- return import_lit21.svg`<text class="house-num" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${houseNum}</text>`;
5285
+ return import_lit22.svg`<text class="house-num" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${houseNum}</text>`;
4779
5286
  });
4780
5287
  }
4781
5288
  /**
@@ -4792,7 +5299,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4792
5299
  const a = polarToCartesian(CENTER, CENTER, inner, angle);
4793
5300
  const b = polarToCartesian(CENTER, CENTER, OUTER_R, angle);
4794
5301
  ticks.push(
4795
- import_lit21.svg`<line class=${isMajor ? "tick tick-major" : "tick"} x1=${a.x} y1=${a.y} x2=${b.x} y2=${b.y} stroke-width=${isMajor ? 1 : 0.5} />`
5302
+ import_lit22.svg`<line class=${isMajor ? "tick tick-major" : "tick"} x1=${a.x} y1=${a.y} x2=${b.x} y2=${b.y} stroke-width=${isMajor ? 1 : 0.5} />`
4796
5303
  );
4797
5304
  }
4798
5305
  return ticks;
@@ -4803,52 +5310,84 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4803
5310
  */
4804
5311
  renderCuspDegrees() {
4805
5312
  const houses = this.data?.houses ?? [];
4806
- if (houses.length !== 12) return import_lit21.nothing;
5313
+ if (houses.length !== 12) return import_lit22.nothing;
4807
5314
  return houses.map((house) => {
4808
5315
  const angle = this.toAngle(house.longitude);
4809
5316
  const pos = polarToCartesian(CENTER, CENTER, HOUSE_R + 9, angle);
4810
5317
  const sp = longitudeToSignPosition(house.longitude);
4811
- return import_lit21.svg`<text class="cusp-deg" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${sp.degree}°${String(sp.minute).padStart(2, "0")}'</text>`;
5318
+ return import_lit22.svg`<text class="cusp-deg" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${sp.degree}°${String(sp.minute).padStart(2, "0")}'</text>`;
4812
5319
  });
4813
5320
  }
4814
5321
  renderPlanets(planets) {
4815
- return planets.map((p) => {
4816
- if (!Number.isFinite(p.longitude)) return import_lit21.nothing;
4817
- const angle = this.toAngle(p.longitude);
4818
- const glyphPos = polarToCartesian(CENTER, CENTER, PLANET_R, angle);
4819
- const degPos = polarToCartesian(CENTER, CENTER, PLANET_R - 13, angle);
5322
+ const MIN_SEPARATION = 7;
5323
+ const sorted = planets.filter((p) => Number.isFinite(p.longitude)).map((p) => ({
5324
+ p,
5325
+ trueLon: normalizeLongitude(p.longitude),
5326
+ displayLon: normalizeLongitude(p.longitude)
5327
+ })).sort((a, b) => a.trueLon - b.trueLon);
5328
+ for (let i = 1; i < sorted.length; i++) {
5329
+ const prev = sorted[i - 1];
5330
+ const cur = sorted[i];
5331
+ if (!prev || !cur) continue;
5332
+ const wanted = prev.displayLon + MIN_SEPARATION;
5333
+ if (cur.displayLon < wanted) cur.displayLon = wanted;
5334
+ }
5335
+ const last = sorted[sorted.length - 1];
5336
+ if (last && last.displayLon > 360) {
5337
+ const shift = last.displayLon - 360;
5338
+ for (const s of sorted) s.displayLon -= shift;
5339
+ }
5340
+ return sorted.map(({ p, trueLon, displayLon }) => {
5341
+ const trueAngle = this.toAngle(trueLon);
5342
+ const displayAngle = this.toAngle(displayLon);
5343
+ const glyphPos = polarToCartesian(CENTER, CENTER, PLANET_R, displayAngle);
5344
+ const degPos = polarToCartesian(
5345
+ CENTER,
5346
+ CENTER,
5347
+ PLANET_R - 13,
5348
+ displayAngle
5349
+ );
5350
+ const rimPos = polarToCartesian(CENTER, CENTER, OUTER_R - 4, trueAngle);
5351
+ const leaderInner = polarToCartesian(
5352
+ CENTER,
5353
+ CENTER,
5354
+ PLANET_R + 8,
5355
+ displayAngle
5356
+ );
4820
5357
  const glyph = PLANET_GLYPH[capitalize(p.name)] ?? p.name.slice(0, 2);
4821
5358
  const sp = longitudeToSignPosition(p.longitude);
4822
5359
  const retro = p.isRetrograde === true;
4823
5360
  const degLabel = `${sp.degree}\xB0${String(sp.minute).padStart(2, "0")}'`;
4824
- return import_lit21.svg`<g>
5361
+ const offset = Math.abs(displayLon - trueLon) > 0.5;
5362
+ return import_lit22.svg`<g>
5363
+ ${offset ? import_lit22.svg`<line class="planet-leader" x1=${rimPos.x} y1=${rimPos.y} x2=${leaderInner.x} y2=${leaderInner.y} />` : import_lit22.nothing}
4825
5364
  <text class="planet-glyph" x=${glyphPos.x} y=${glyphPos.y} text-anchor="middle" dominant-baseline="central"><title>${p.name}${retro ? " retrograde" : ""} - ${degLabel} ${p.sign ?? ""}</title>${glyph}</text>
4826
- <text class="planet-deg" x=${degPos.x} y=${degPos.y} text-anchor="middle" dominant-baseline="central">${degLabel}${retro ? import_lit21.svg`<tspan class="retro"> ℞</tspan>` : import_lit21.nothing}</text>
5365
+ <text class="planet-deg" x=${degPos.x} y=${degPos.y} text-anchor="middle" dominant-baseline="central">${degLabel}${retro ? import_lit22.svg`<tspan class="retro"> ℞</tspan>` : import_lit22.nothing}</text>
4827
5366
  </g>`;
4828
5367
  });
4829
5368
  }
4830
5369
  renderDetails() {
4831
5370
  const summary = this.data?.summary;
4832
5371
  const ai = this.data?.aspectsInterpretation;
4833
- if (!summary && !ai) return import_lit21.nothing;
5372
+ if (!summary && !ai) return import_lit22.nothing;
4834
5373
  const retrogrades = summary?.retrogradePlanets ?? [];
4835
- return import_lit21.html`<div class="details">
4836
- ${summary?.dominantElement || summary?.dominantModality ? import_lit21.html`<div class="pill-row">
4837
- ${summary.dominantElement ? import_lit21.html`<span class="pill">Dominant element: ${summary.dominantElement}</span>` : import_lit21.nothing}
4838
- ${summary.dominantModality ? import_lit21.html`<span class="pill">Dominant modality: ${summary.dominantModality}</span>` : import_lit21.nothing}
4839
- </div>` : import_lit21.nothing}
4840
- ${ai ? import_lit21.html`<div class="pill-row">
5374
+ return import_lit22.html`<div class="details">
5375
+ ${summary?.dominantElement || summary?.dominantModality ? import_lit22.html`<div class="pill-row">
5376
+ ${summary.dominantElement ? import_lit22.html`<span class="pill">Dominant element: ${summary.dominantElement}</span>` : import_lit22.nothing}
5377
+ ${summary.dominantModality ? import_lit22.html`<span class="pill">Dominant modality: ${summary.dominantModality}</span>` : import_lit22.nothing}
5378
+ </div>` : import_lit22.nothing}
5379
+ ${ai ? import_lit22.html`<div class="pill-row">
4841
5380
  <span class="pill pill--success">Harmonious ${ai.harmonious}</span>
4842
5381
  <span class="pill pill--danger">Challenging ${ai.challenging}</span>
4843
5382
  <span class="pill pill--muted">Neutral ${ai.neutral}</span>
4844
- </div>` : import_lit21.nothing}
4845
- ${retrogrades.length > 0 ? import_lit21.html`<div class="pill-row">
5383
+ </div>` : import_lit22.nothing}
5384
+ ${retrogrades.length > 0 ? import_lit22.html`<div class="pill-row">
4846
5385
  ${retrogrades.map((p) => {
4847
5386
  const glyph = PLANET_GLYPH[p] ?? p.slice(0, 2);
4848
- return import_lit21.html`<span class="pill pill--muted">${glyph} ${p} R</span>`;
5387
+ return import_lit22.html`<span class="pill pill--muted">${glyph} ${p} R</span>`;
4849
5388
  })}
4850
- </div>` : import_lit21.nothing}
4851
- ${ai?.summary ? import_lit21.html`<p class="summary">${ai.summary}</p>` : import_lit21.nothing}
5389
+ </div>` : import_lit22.nothing}
5390
+ ${ai?.summary ? import_lit22.html`<p class="summary">${ai.summary}</p>` : import_lit22.nothing}
4852
5391
  ${this.renderElementModalityGrid()}
4853
5392
  </div>`;
4854
5393
  }
@@ -4860,7 +5399,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4860
5399
  */
4861
5400
  renderElementModalityGrid() {
4862
5401
  const planets = this.getPlanets();
4863
- if (planets.length === 0) return import_lit21.nothing;
5402
+ if (planets.length === 0) return import_lit22.nothing;
4864
5403
  const ELEMENTS = ["Fire", "Earth", "Air", "Water"];
4865
5404
  const MODALITIES = ["Cardinal", "Fixed", "Mutable"];
4866
5405
  const order = SIGNS_ORDER;
@@ -4875,11 +5414,11 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4875
5414
  const glyph = PLANET_GLYPH[capitalize(p.name)] ?? capitalize(p.name).slice(0, 2);
4876
5415
  cells[el]?.[mod]?.push(glyph);
4877
5416
  }
4878
- return import_lit21.html`<table class="em-grid" aria-label="Element and modality distribution">
5417
+ return import_lit22.html`<table class="em-grid" aria-label="Element and modality distribution">
4879
5418
  <thead>
4880
5419
  <tr>
4881
5420
  <th></th>
4882
- ${MODALITIES.map((m) => import_lit21.html`<th scope="col">${m.slice(0, 3)}</th>`)}
5421
+ ${MODALITIES.map((m) => import_lit22.html`<th scope="col">${m.slice(0, 3)}</th>`)}
4883
5422
  <th scope="col">Total</th>
4884
5423
  </tr>
4885
5424
  </thead>
@@ -4889,10 +5428,10 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4889
5428
  (s, m) => s + (cells[el]?.[m]?.length ?? 0),
4890
5429
  0
4891
5430
  );
4892
- return import_lit21.html`<tr>
5431
+ return import_lit22.html`<tr>
4893
5432
  <th scope="row">${el}</th>
4894
5433
  ${MODALITIES.map(
4895
- (m) => import_lit21.html`<td>${(cells[el]?.[m] ?? []).join(" ")}</td>`
5434
+ (m) => import_lit22.html`<td>${(cells[el]?.[m] ?? []).join(" ")}</td>`
4896
5435
  )}
4897
5436
  <td class="em-total">${rowTotal}</td>
4898
5437
  </tr>`;
@@ -4900,7 +5439,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4900
5439
  <tr>
4901
5440
  <th scope="row">Total</th>
4902
5441
  ${MODALITIES.map(
4903
- (m) => import_lit21.html`<td class="em-total">${ELEMENTS.reduce((s, el) => s + (cells[el]?.[m]?.length ?? 0), 0)}</td>`
5442
+ (m) => import_lit22.html`<td class="em-total">${ELEMENTS.reduce((s, el) => s + (cells[el]?.[m]?.length ?? 0), 0)}</td>`
4904
5443
  )}
4905
5444
  <td class="em-total">${planets.length}</td>
4906
5445
  </tr>
@@ -4909,19 +5448,19 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4909
5448
  }
4910
5449
  renderInterpretations() {
4911
5450
  const planets = this.getPlanets().filter((p) => p.interpretation);
4912
- if (planets.length === 0) return import_lit21.nothing;
4913
- return import_lit21.html`<section class="interpretations">
5451
+ if (planets.length === 0) return import_lit22.nothing;
5452
+ return import_lit22.html`<section class="interpretations">
4914
5453
  <h3>Planet readings</h3>
4915
5454
  ${planets.map((p, idx) => {
4916
5455
  const interp = p.interpretation;
4917
5456
  const glyph = PLANET_GLYPH[capitalize(p.name)] ?? "";
4918
5457
  const deg = formatNumber(p.degree ?? 0, 1);
4919
- return import_lit21.html`<details class="interp-card" name="natal-planet-readings" ?open=${idx === 0}>
5458
+ return import_lit22.html`<details class="interp-card" name="natal-planet-readings" ?open=${idx === 0}>
4920
5459
  <summary>${glyph} ${p.name} <small>${p.sign ?? ""} ${deg}</small></summary>
4921
5460
  <div class="interp-body">
4922
- ${interp.summary ? import_lit21.html`<p class="interp-summary">${interp.summary}</p>` : import_lit21.nothing}
4923
- ${interp.detailed ? import_lit21.html`<p class="interp-detail">${interp.detailed}</p>` : import_lit21.nothing}
4924
- ${interp.keywords?.length ? import_lit21.html`<div class="interp-keywords">${interp.keywords.map((k) => import_lit21.html`<span class="kw">${k}</span>`)}</div>` : import_lit21.nothing}
5461
+ ${interp.summary ? import_lit22.html`<p class="interp-summary">${interp.summary}</p>` : import_lit22.nothing}
5462
+ ${interp.detailed ? import_lit22.html`<p class="interp-detail">${interp.detailed}</p>` : import_lit22.nothing}
5463
+ ${interp.keywords?.length ? import_lit22.html`<div class="interp-keywords">${interp.keywords.map((k) => import_lit22.html`<span class="kw">${k}</span>`)}</div>` : import_lit22.nothing}
4925
5464
  </div>
4926
5465
  </details>`;
4927
5466
  })}
@@ -4937,7 +5476,7 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4937
5476
  return aspects.map((a) => {
4938
5477
  const l1 = planetMap.get(capitalize(a.planet1));
4939
5478
  const l2 = planetMap.get(capitalize(a.planet2));
4940
- if (l1 === void 0 || l2 === void 0) return import_lit21.nothing;
5479
+ if (l1 === void 0 || l2 === void 0) return import_lit22.nothing;
4941
5480
  const p1 = polarToCartesian(
4942
5481
  CENTER,
4943
5482
  CENTER,
@@ -4953,13 +5492,13 @@ var RoxyNatalChart = class extends import_lit21.LitElement {
4953
5492
  const aspectName = normalizeAspect(a);
4954
5493
  const aspectClass = ASPECT_CLASS[aspectName] ?? "aspect-other";
4955
5494
  const orbLabel = formatNumber(a.orb, 1);
4956
- return import_lit21.svg`<line class=${`aspect ${aspectClass}`} x1=${p1.x} y1=${p1.y} x2=${p2.x} y2=${p2.y}><title>${a.planet1} ${aspectName || ""} ${a.planet2}${orbLabel ? ` (orb ${orbLabel}\xB0)` : ""}</title></line>`;
5495
+ return import_lit22.svg`<line class=${`aspect ${aspectClass}`} x1=${p1.x} y1=${p1.y} x2=${p2.x} y2=${p2.y}><title>${a.planet1} ${aspectName || ""} ${a.planet2}${orbLabel ? ` (orb ${orbLabel}\xB0)` : ""}</title></line>`;
4957
5496
  });
4958
5497
  }
4959
5498
  };
4960
5499
  RoxyNatalChart.styles = [
4961
5500
  baseStyles,
4962
- import_lit21.css`
5501
+ import_lit22.css`
4963
5502
  .wrap {
4964
5503
  width: 100%;
4965
5504
  display: grid;
@@ -4981,7 +5520,8 @@ RoxyNatalChart.styles = [
4981
5520
  svg {
4982
5521
  display: block;
4983
5522
  width: 100%;
4984
- max-width: 360px;
5523
+ max-width: 560px;
5524
+ aspect-ratio: 1 / 1;
4985
5525
  height: auto;
4986
5526
  margin: 0 auto;
4987
5527
  }
@@ -5010,10 +5550,33 @@ RoxyNatalChart.styles = [
5010
5550
  font-family: var(--roxy-font-sans);
5011
5551
  }
5012
5552
 
5553
+ /* Below 480px the chart container shrinks to ~320px on phones.
5554
+ * Bump in-SVG text up proportionally so the 7px degree band
5555
+ * does not collapse below ~6px on screen.
5556
+ */
5557
+ @container (max-width: 480px) {
5558
+ .sign-glyph,
5559
+ .planet-glyph {
5560
+ font-size: 18px;
5561
+ }
5562
+ .planet-deg {
5563
+ font-size: 10px;
5564
+ }
5565
+ .house-num {
5566
+ font-size: 12px;
5567
+ }
5568
+ }
5569
+
5013
5570
  .planet-deg .retro {
5014
5571
  fill: var(--roxy-danger, #dc2626);
5015
5572
  }
5016
5573
 
5574
+ .planet-leader {
5575
+ stroke: var(--roxy-accent, #f59e0b);
5576
+ stroke-width: 0.5;
5577
+ opacity: 0.55;
5578
+ }
5579
+
5017
5580
  .house-num {
5018
5581
  fill: var(--roxy-muted, #71717a);
5019
5582
  font-size: 9px;
@@ -5288,9 +5851,9 @@ RoxyNatalChart = __decorateClass([
5288
5851
  ], RoxyNatalChart);
5289
5852
 
5290
5853
  // packages/ui/src/components/numerology-card.ts
5291
- var import_lit22 = require("lit");
5854
+ var import_lit23 = require("lit");
5292
5855
  var import_decorators20 = require("lit/decorators.js");
5293
- var RoxyNumerologyCard = class extends import_lit22.LitElement {
5856
+ var RoxyNumerologyCard = class extends import_lit23.LitElement {
5294
5857
  constructor() {
5295
5858
  super(...arguments);
5296
5859
  this.data = null;
@@ -5299,7 +5862,7 @@ var RoxyNumerologyCard = class extends import_lit22.LitElement {
5299
5862
  render() {
5300
5863
  const d = this.data;
5301
5864
  if (!d)
5302
- return import_lit22.html`<div class="roxy-empty" role="status">No numerology data</div>`;
5865
+ return import_lit23.html`<div class="roxy-empty" role="status">No numerology data</div>`;
5303
5866
  const headerLabel = LABELS[this.type] ?? this.type;
5304
5867
  if ("coreNumbers" in d) return this.renderChart(d, headerLabel);
5305
5868
  if ("personalYear" in d) return this.renderPersonalYear(d, headerLabel);
@@ -5310,61 +5873,61 @@ var RoxyNumerologyCard = class extends import_lit22.LitElement {
5310
5873
  }
5311
5874
  renderNumberCard(d, headerLabel) {
5312
5875
  const keywords = d.meaning?.keywords ?? [];
5313
- return import_lit22.html`<article class="card" aria-label=${headerLabel}>
5876
+ return import_lit23.html`<article class="card" aria-label=${headerLabel}>
5314
5877
  <div class="hero">
5315
- ${typeof d.number === "number" ? import_lit22.html`<div class="numeral">${d.number}</div>` : import_lit22.nothing}
5878
+ ${typeof d.number === "number" ? import_lit23.html`<div class="numeral">${d.number}</div>` : import_lit23.nothing}
5316
5879
  <div>
5317
5880
  <p class="label">${headerLabel}</p>
5318
- ${d.meaning?.title ? import_lit22.html`<h2 class="title">${d.meaning.title}</h2>` : import_lit22.nothing}
5881
+ ${d.meaning?.title ? import_lit23.html`<h2 class="title">${d.meaning.title}</h2>` : import_lit23.nothing}
5319
5882
  </div>
5320
5883
  </div>
5321
- ${d.meaning?.description ? import_lit22.html`<p class="meaning">${d.meaning.description}</p>` : import_lit22.nothing}
5322
- ${d.calculation ? import_lit22.html`<pre class="calc">${d.calculation}</pre>` : import_lit22.nothing}
5323
- ${keywords.length > 0 ? import_lit22.html`<div class="chips">
5324
- ${keywords.map((k) => import_lit22.html`<span>${k}</span>`)}
5325
- </div>` : import_lit22.nothing}
5326
- ${d.hasKarmicDebt && d.karmicDebtNumber ? import_lit22.html`<div class="karmic">
5884
+ ${d.meaning?.description ? import_lit23.html`<p class="meaning">${d.meaning.description}</p>` : import_lit23.nothing}
5885
+ ${d.calculation ? import_lit23.html`<pre class="calc">${d.calculation}</pre>` : import_lit23.nothing}
5886
+ ${keywords.length > 0 ? import_lit23.html`<div class="chips">
5887
+ ${keywords.map((k) => import_lit23.html`<span>${k}</span>`)}
5888
+ </div>` : import_lit23.nothing}
5889
+ ${d.hasKarmicDebt && d.karmicDebtNumber ? import_lit23.html`<div class="karmic">
5327
5890
  Karmic debt ${d.karmicDebtNumber}.
5328
5891
  ${karmicDebtText(d.karmicDebtMeaning)}
5329
- </div>` : import_lit22.nothing}
5892
+ </div>` : import_lit23.nothing}
5330
5893
  </article>`;
5331
5894
  }
5332
5895
  renderPersonalYear(d, headerLabel) {
5333
- return import_lit22.html`<article class="card" aria-label=${headerLabel}>
5896
+ return import_lit23.html`<article class="card" aria-label=${headerLabel}>
5334
5897
  <div class="hero">
5335
- ${typeof d.personalYear === "number" ? import_lit22.html`<div class="numeral">${d.personalYear}</div>` : import_lit22.nothing}
5898
+ ${typeof d.personalYear === "number" ? import_lit23.html`<div class="numeral">${d.personalYear}</div>` : import_lit23.nothing}
5336
5899
  <div>
5337
5900
  <p class="label">${headerLabel}</p>
5338
- ${d.theme ? import_lit22.html`<h2 class="title">${d.theme}</h2>` : import_lit22.nothing}
5901
+ ${d.theme ? import_lit23.html`<h2 class="title">${d.theme}</h2>` : import_lit23.nothing}
5339
5902
  </div>
5340
5903
  </div>
5341
- ${d.forecast ? import_lit22.html`<p class="meaning">${d.forecast}</p>` : import_lit22.nothing}
5342
- ${d.advice ? import_lit22.html`<p>${d.advice}</p>` : import_lit22.nothing}
5904
+ ${d.forecast ? import_lit23.html`<p class="meaning">${d.forecast}</p>` : import_lit23.nothing}
5905
+ ${d.advice ? import_lit23.html`<p>${d.advice}</p>` : import_lit23.nothing}
5343
5906
  </article>`;
5344
5907
  }
5345
5908
  renderChart(d, headerLabel) {
5346
5909
  const cores = Object.entries(d.coreNumbers).filter(
5347
5910
  ([, v]) => v !== null && v !== void 0
5348
5911
  );
5349
- return import_lit22.html`<article class="card" aria-label=${headerLabel}>
5912
+ return import_lit23.html`<article class="card" aria-label=${headerLabel}>
5350
5913
  <div>
5351
5914
  <p class="label">${headerLabel}</p>
5352
- ${d.profile?.name ? import_lit22.html`<h2 class="title">${d.profile.name}</h2>` : import_lit22.nothing}
5915
+ ${d.profile?.name ? import_lit23.html`<h2 class="title">${d.profile.name}</h2>` : import_lit23.nothing}
5353
5916
  </div>
5354
- ${cores.length > 0 ? import_lit22.html`<div class="cores">
5917
+ ${cores.length > 0 ? import_lit23.html`<div class="cores">
5355
5918
  ${cores.map(
5356
- ([k, v]) => import_lit22.html`<div class="item">
5919
+ ([k, v]) => import_lit23.html`<div class="item">
5357
5920
  <span>${humanize(k)}</span>
5358
5921
  <strong>${v.number ?? ""}</strong>
5359
5922
  </div>`
5360
5923
  )}
5361
- </div>` : import_lit22.nothing}
5924
+ </div>` : import_lit23.nothing}
5362
5925
  </article>`;
5363
5926
  }
5364
5927
  };
5365
5928
  RoxyNumerologyCard.styles = [
5366
5929
  baseStyles,
5367
- import_lit22.css`
5930
+ import_lit23.css`
5368
5931
  .card {
5369
5932
  background: var(--roxy-bg, #fff);
5370
5933
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -5483,9 +6046,9 @@ function karmicDebtText(value) {
5483
6046
  }
5484
6047
 
5485
6048
  // packages/ui/src/components/panchang-table.ts
5486
- var import_lit23 = require("lit");
6049
+ var import_lit24 = require("lit");
5487
6050
  var import_decorators21 = require("lit/decorators.js");
5488
- var RoxyPanchangTable = class extends import_lit23.LitElement {
6051
+ var RoxyPanchangTable = class extends import_lit24.LitElement {
5489
6052
  constructor() {
5490
6053
  super(...arguments);
5491
6054
  this.data = null;
@@ -5494,7 +6057,7 @@ var RoxyPanchangTable = class extends import_lit23.LitElement {
5494
6057
  render() {
5495
6058
  const d = this.data;
5496
6059
  if (!d)
5497
- return import_lit23.html`<div class="roxy-empty" role="status">No panchang data</div>`;
6060
+ return import_lit24.html`<div class="roxy-empty" role="status">No panchang data</div>`;
5498
6061
  const detailed = "sunrise" in d ? d : null;
5499
6062
  const fivefold = [
5500
6063
  ["Tithi", this.formatPart(d.tithi)],
@@ -5517,7 +6080,8 @@ var RoxyPanchangTable = class extends import_lit23.LitElement {
5517
6080
  ["Yamaganda", detailed.yamaganda],
5518
6081
  ["Gulika", detailed.gulika]
5519
6082
  ] : [];
5520
- return import_lit23.html`<div class="wrap" aria-label="Panchang">
6083
+ const transitions = detailed && "transitions" in detailed ? detailed.transitions : void 0;
6084
+ return import_lit24.html`<div class="wrap" aria-label="Panchang">
5521
6085
  <header class="head">
5522
6086
  <h2 class="title">Panchang</h2>
5523
6087
  <span class="date">${detailed ? formatDate(detailed.date) : ""}</span>
@@ -5525,35 +6089,46 @@ var RoxyPanchangTable = class extends import_lit23.LitElement {
5525
6089
  <table>
5526
6090
  <tbody>
5527
6091
  ${fivefold.map(
5528
- ([k, v]) => import_lit23.html`<tr>
6092
+ ([k, v]) => import_lit24.html`<tr>
5529
6093
  <th>${k}</th>
5530
6094
  <td>${v}</td>
5531
6095
  </tr>`
5532
6096
  )}
5533
- ${detailed?.sunrise ? import_lit23.html`<tr>
6097
+ ${detailed?.sunrise ? import_lit24.html`<tr>
5534
6098
  <th>Sunrise</th>
5535
6099
  <td>${formatTime(detailed.sunrise)}</td>
5536
- </tr>` : import_lit23.nothing}
5537
- ${detailed?.sunset ? import_lit23.html`<tr>
6100
+ </tr>` : import_lit24.nothing}
6101
+ ${detailed?.sunset ? import_lit24.html`<tr>
5538
6102
  <th>Sunset</th>
5539
6103
  <td>${formatTime(detailed.sunset)}</td>
5540
- </tr>` : import_lit23.nothing}
5541
- ${detailed?.moonrise ? import_lit23.html`<tr>
6104
+ </tr>` : import_lit24.nothing}
6105
+ ${detailed?.moonrise ? import_lit24.html`<tr>
5542
6106
  <th>Moonrise</th>
5543
6107
  <td>${formatTime(detailed.moonrise)}</td>
5544
- </tr>` : import_lit23.nothing}
5545
- ${detailed?.moonset ? import_lit23.html`<tr>
6108
+ </tr>` : import_lit24.nothing}
6109
+ ${detailed?.moonset ? import_lit24.html`<tr>
5546
6110
  <th>Moonset</th>
5547
6111
  <td>${formatTime(detailed.moonset)}</td>
5548
- </tr>` : import_lit23.nothing}
6112
+ </tr>` : import_lit24.nothing}
5549
6113
  </tbody>
5550
6114
  </table>
5551
- ${this.detail === "detailed" && (muhurtas.some((m) => !!m[1]) || inauspicious.some((m) => !!m[1])) ? import_lit23.html`
6115
+ ${transitions ? import_lit24.html`
6116
+ <div class="section">Next transitions</div>
6117
+ <table>
6118
+ <tbody>
6119
+ ${this.renderTransitionRow("Tithi", transitions.tithi)}
6120
+ ${this.renderTransitionRow("Nakshatra", transitions.nakshatra)}
6121
+ ${this.renderTransitionRow("Yoga", transitions.yoga)}
6122
+ ${this.renderTransitionRow("Karana", transitions.karana)}
6123
+ </tbody>
6124
+ </table>
6125
+ ` : import_lit24.nothing}
6126
+ ${this.detail === "detailed" && (muhurtas.some((m) => !!m[1]) || inauspicious.some((m) => !!m[1])) ? import_lit24.html`
5552
6127
  <div class="section">Auspicious muhurtas</div>
5553
6128
  <table>
5554
6129
  <tbody>
5555
6130
  ${muhurtas.filter(([, v]) => !!v).map(
5556
- ([k, v]) => import_lit23.html`<tr>
6131
+ ([k, v]) => import_lit24.html`<tr>
5557
6132
  <th>${k}</th>
5558
6133
  <td>${formatTimeRange(v)}</td>
5559
6134
  </tr>`
@@ -5564,16 +6139,25 @@ var RoxyPanchangTable = class extends import_lit23.LitElement {
5564
6139
  <table>
5565
6140
  <tbody>
5566
6141
  ${inauspicious.filter(([, v]) => !!v).map(
5567
- ([k, v]) => import_lit23.html`<tr>
6142
+ ([k, v]) => import_lit24.html`<tr>
5568
6143
  <th>${k}</th>
5569
6144
  <td>${formatTimeRange(v)}</td>
5570
6145
  </tr>`
5571
6146
  )}
5572
6147
  </tbody>
5573
6148
  </table>
5574
- ` : import_lit23.nothing}
6149
+ ` : import_lit24.nothing}
5575
6150
  </div>`;
5576
6151
  }
6152
+ renderTransitionRow(label, t) {
6153
+ if (!t?.endsAt) return import_lit24.nothing;
6154
+ const when = formatTime(t.endsAt);
6155
+ const next = t.next ? ` \u2192 ${t.next}` : "";
6156
+ return import_lit24.html`<tr>
6157
+ <th>${label}</th>
6158
+ <td>ends ${when}${next}</td>
6159
+ </tr>`;
6160
+ }
5577
6161
  formatPart(v) {
5578
6162
  if (!v) return "";
5579
6163
  if (typeof v === "string") return v;
@@ -5581,7 +6165,8 @@ var RoxyPanchangTable = class extends import_lit23.LitElement {
5581
6165
  const obj = v;
5582
6166
  const parts = [
5583
6167
  obj.name,
5584
- obj.lord ? `(${obj.lord})` : "",
6168
+ obj.paksha ? `(${obj.paksha} paksha)` : "",
6169
+ obj.lord ? `\xB7 ${obj.lord}` : "",
5585
6170
  obj.phase
5586
6171
  ].filter(Boolean);
5587
6172
  return parts.join(" ");
@@ -5591,7 +6176,7 @@ var RoxyPanchangTable = class extends import_lit23.LitElement {
5591
6176
  };
5592
6177
  RoxyPanchangTable.styles = [
5593
6178
  baseStyles,
5594
- import_lit23.css`
6179
+ import_lit24.css`
5595
6180
  .wrap {
5596
6181
  border: 1px solid var(--roxy-border, #e4e4e7);
5597
6182
  border-radius: var(--roxy-radius-md, 8px);
@@ -5662,7 +6247,7 @@ RoxyPanchangTable = __decorateClass([
5662
6247
  ], RoxyPanchangTable);
5663
6248
 
5664
6249
  // packages/ui/src/components/shadbala-table.ts
5665
- var import_lit24 = require("lit");
6250
+ var import_lit25 = require("lit");
5666
6251
  var import_decorators22 = require("lit/decorators.js");
5667
6252
  var BALA_COMPONENTS = [
5668
6253
  { key: "sthanaBala", label: "Sthana", color: "var(--roxy-info, #0284c7)" },
@@ -5676,19 +6261,19 @@ var BALA_COMPONENTS = [
5676
6261
  },
5677
6262
  { key: "drikBala", label: "Drik", color: "var(--roxy-danger, #dc2626)" }
5678
6263
  ];
5679
- var RoxyShadbalaTable = class extends import_lit24.LitElement {
6264
+ var RoxyShadbalaTable = class extends import_lit25.LitElement {
5680
6265
  constructor() {
5681
6266
  super(...arguments);
5682
6267
  this.data = null;
5683
6268
  }
5684
6269
  render() {
5685
6270
  if (!this.data?.planets?.length) {
5686
- return import_lit24.html`<div class="roxy-empty" role="status">No shadbala data</div>`;
6271
+ return import_lit25.html`<div class="roxy-empty" role="status">No shadbala data</div>`;
5687
6272
  }
5688
6273
  const sorted = [...this.data.planets].sort(
5689
6274
  (a, b) => a.relativeRank - b.relativeRank
5690
6275
  );
5691
- return import_lit24.html`<div class="wrap" aria-label="Shadbala planetary strength">
6276
+ return import_lit25.html`<div class="wrap" aria-label="Shadbala planetary strength">
5692
6277
  <div class="head">
5693
6278
  <h2 class="title">Shadbala</h2>
5694
6279
  <p class="subtitle">${sorted.length} planets ranked by strength</p>
@@ -5700,7 +6285,7 @@ var RoxyShadbalaTable = class extends import_lit24.LitElement {
5700
6285
 
5701
6286
  <div class="legend" aria-label="Strength component legend">
5702
6287
  ${BALA_COMPONENTS.map(
5703
- (b) => import_lit24.html`<div class="legend-row">
6288
+ (b) => import_lit25.html`<div class="legend-row">
5704
6289
  <span
5705
6290
  class="legend-swatch"
5706
6291
  style="background: ${b.color}"
@@ -5720,7 +6305,7 @@ var RoxyShadbalaTable = class extends import_lit24.LitElement {
5720
6305
  const badgeClass = isAdequate ? "adequacy-badge--adequate" : "adequacy-badge--weak";
5721
6306
  const badgeLabel = isAdequate ? "adequate" : "weak";
5722
6307
  const rupasStr = formatNumber(p.totalRupas, 2) && formatNumber(p.minRequired, 2) ? `${formatNumber(p.totalRupas, 2)} / ${formatNumber(p.minRequired, 2)} R` : "";
5723
- return import_lit24.html`<div class="planet-row" role="listitem" aria-label="${p.planet} shadbala">
6308
+ return import_lit25.html`<div class="planet-row" role="listitem" aria-label="${p.planet} shadbala">
5724
6309
  <div class="planet-label">
5725
6310
  <span class="glyph" aria-hidden="true">${glyph}</span>
5726
6311
  ${p.planet}
@@ -5730,18 +6315,18 @@ var RoxyShadbalaTable = class extends import_lit24.LitElement {
5730
6315
  <div class="bar" role="img" aria-label="Strength components for ${p.planet}">
5731
6316
  ${total > 0 ? BALA_COMPONENTS.map((b, i) => {
5732
6317
  const v = values[i];
5733
- if (v <= 0) return import_lit24.nothing;
6318
+ if (v <= 0) return import_lit25.nothing;
5734
6319
  const grow = v / total * 100;
5735
- return import_lit24.html`<div
6320
+ return import_lit25.html`<div
5736
6321
  class="bar-segment"
5737
6322
  style="flex-grow: ${grow}; background: ${b.color};"
5738
6323
  title="${b.label}: ${formatNumber(v, 1)}"
5739
6324
  ></div>`;
5740
- }) : import_lit24.nothing}
6325
+ }) : import_lit25.nothing}
5741
6326
  </div>
5742
6327
  </div>
5743
6328
  <div class="pills">
5744
- ${rupasStr ? import_lit24.html`<span class="rupas-label">${rupasStr}</span>` : import_lit24.nothing}
6329
+ ${rupasStr ? import_lit25.html`<span class="rupas-label">${rupasStr}</span>` : import_lit25.nothing}
5745
6330
  <span class="${`adequacy-badge ${badgeClass}`}">${badgeLabel}</span>
5746
6331
  </div>
5747
6332
  </div>`;
@@ -5749,7 +6334,7 @@ var RoxyShadbalaTable = class extends import_lit24.LitElement {
5749
6334
  };
5750
6335
  RoxyShadbalaTable.styles = [
5751
6336
  baseStyles,
5752
- import_lit24.css`
6337
+ import_lit25.css`
5753
6338
  .wrap {
5754
6339
  display: grid;
5755
6340
  gap: var(--roxy-space-md, 1rem);
@@ -5905,7 +6490,7 @@ RoxyShadbalaTable = __decorateClass([
5905
6490
  ], RoxyShadbalaTable);
5906
6491
 
5907
6492
  // packages/ui/src/components/synastry-chart.ts
5908
- var import_lit25 = require("lit");
6493
+ var import_lit26 = require("lit");
5909
6494
  var import_decorators23 = require("lit/decorators.js");
5910
6495
  var SIZE2 = 360;
5911
6496
  var CENTER2 = SIZE2 / 2;
@@ -5913,14 +6498,14 @@ var OUTER_R2 = 170;
5913
6498
  var SIGN_R2 = 154;
5914
6499
  var P1_R = 124;
5915
6500
  var P2_R = 96;
5916
- var RoxySynastryChart = class extends import_lit25.LitElement {
6501
+ var RoxySynastryChart = class extends import_lit26.LitElement {
5917
6502
  constructor() {
5918
6503
  super(...arguments);
5919
6504
  this.data = null;
5920
6505
  }
5921
6506
  render() {
5922
6507
  if (!this.data)
5923
- return import_lit25.html`<div class="roxy-empty" role="status">No synastry data</div>`;
6508
+ return import_lit26.html`<div class="roxy-empty" role="status">No synastry data</div>`;
5924
6509
  const { person1, person2, compatibilityScore, analysis } = this.data;
5925
6510
  const interAspects = this.data.interAspects ?? [];
5926
6511
  const p1Planets = person1?.planets ?? [];
@@ -5931,15 +6516,15 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
5931
6516
  const challenges = analysis?.challenges ?? [];
5932
6517
  const hasPlanets = p1Planets.length > 0 && p2Planets.length > 0;
5933
6518
  if (!hasPlanets) {
5934
- return import_lit25.html`<div
6519
+ return import_lit26.html`<div
5935
6520
  class="wrap"
5936
6521
  aria-label="Synastry compatibility chart"
5937
6522
  >
5938
6523
  <div class="head">
5939
6524
  <h2 class="title">Synastry</h2>
5940
- ${typeof score === "number" ? import_lit25.html`<span class="score" aria-label=${`Score ${score} of 100`}
6525
+ ${typeof score === "number" ? import_lit26.html`<span class="score" aria-label=${`Score ${score} of 100`}
5941
6526
  >${score} / 100</span
5942
- >` : import_lit25.nothing}
6527
+ >` : import_lit26.nothing}
5943
6528
  </div>
5944
6529
  <div class="missing-planets" role="status">
5945
6530
  Synastry response missing planet positions. Pass
@@ -5947,33 +6532,33 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
5947
6532
  <code>person2.planets</code> arrays from the natal-chart endpoint, or
5948
6533
  use the <code>&lt;roxy-data&gt;</code> fallback.
5949
6534
  </div>
5950
- ${summaryText ? import_lit25.html`<p class="summary">${summaryText}</p>` : import_lit25.nothing}
5951
- ${interAspects.length > 0 ? this.renderAspects(interAspects) : import_lit25.nothing}
5952
- ${strengths.length > 0 || challenges.length > 0 ? import_lit25.html`<div class="lists">
5953
- ${strengths.length ? import_lit25.html`<div>
6535
+ ${summaryText ? import_lit26.html`<p class="summary">${summaryText}</p>` : import_lit26.nothing}
6536
+ ${interAspects.length > 0 ? this.renderAspects(interAspects) : import_lit26.nothing}
6537
+ ${strengths.length > 0 || challenges.length > 0 ? import_lit26.html`<div class="lists">
6538
+ ${strengths.length ? import_lit26.html`<div>
5954
6539
  <h3>Strengths</h3>
5955
6540
  <ul>
5956
- ${strengths.map((s) => import_lit25.html`<li>${s}</li>`)}
6541
+ ${strengths.map((s) => import_lit26.html`<li>${s}</li>`)}
5957
6542
  </ul>
5958
- </div>` : import_lit25.nothing}
5959
- ${challenges.length ? import_lit25.html`<div>
6543
+ </div>` : import_lit26.nothing}
6544
+ ${challenges.length ? import_lit26.html`<div>
5960
6545
  <h3>Challenges</h3>
5961
6546
  <ul>
5962
- ${challenges.map((s) => import_lit25.html`<li>${s}</li>`)}
6547
+ ${challenges.map((s) => import_lit26.html`<li>${s}</li>`)}
5963
6548
  </ul>
5964
- </div>` : import_lit25.nothing}
5965
- </div>` : import_lit25.nothing}
6549
+ </div>` : import_lit26.nothing}
6550
+ </div>` : import_lit26.nothing}
5966
6551
  </div>`;
5967
6552
  }
5968
- return import_lit25.html`<div
6553
+ return import_lit26.html`<div
5969
6554
  class="wrap"
5970
6555
  aria-label="Synastry compatibility chart"
5971
6556
  >
5972
6557
  <div class="head">
5973
6558
  <h2 class="title">Synastry</h2>
5974
- ${typeof score === "number" ? import_lit25.html`<span class="score" aria-label=${`Score ${score} of 100`}
6559
+ ${typeof score === "number" ? import_lit26.html`<span class="score" aria-label=${`Score ${score} of 100`}
5975
6560
  >${score} / 100</span
5976
- >` : import_lit25.nothing}
6561
+ >` : import_lit26.nothing}
5977
6562
  </div>
5978
6563
  <svg
5979
6564
  viewBox="0 0 ${SIZE2} ${SIZE2}"
@@ -6004,7 +6589,8 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
6004
6589
  />
6005
6590
  ${this.renderSpokes()} ${this.renderSigns()}
6006
6591
  ${this.renderInterAspectLines(p1Planets, p2Planets, interAspects)}
6007
- ${this.renderRing(p1Planets, P1_R, "p1")} ${this.renderRing(p2Planets, P2_R, "p2")}
6592
+ ${this.renderRing(p1Planets, P1_R, "p1", 1)} ${this.renderRing(p2Planets, P2_R, "p2", 2)}
6593
+ ${this.renderAscendants(this.data)}
6008
6594
  </svg>
6009
6595
  <div class="legend-row">
6010
6596
  <span><span class="swatch" style="background: var(--roxy-accent)"></span>Person 1</span>
@@ -6012,22 +6598,22 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
6012
6598
  <span><span class="swatch" style="background: var(--roxy-success)"></span>harmonious</span>
6013
6599
  <span><span class="swatch" style="background: var(--roxy-danger)"></span>challenging</span>
6014
6600
  </div>
6015
- ${summaryText ? import_lit25.html`<p class="summary">${summaryText}</p>` : import_lit25.nothing}
6016
- ${interAspects.length > 0 ? this.renderAspects(interAspects) : import_lit25.nothing}
6017
- ${strengths.length > 0 || challenges.length > 0 ? import_lit25.html`<div class="lists">
6018
- ${strengths.length ? import_lit25.html`<div>
6601
+ ${summaryText ? import_lit26.html`<p class="summary">${summaryText}</p>` : import_lit26.nothing}
6602
+ ${interAspects.length > 0 ? this.renderAspects(interAspects) : import_lit26.nothing}
6603
+ ${strengths.length > 0 || challenges.length > 0 ? import_lit26.html`<div class="lists">
6604
+ ${strengths.length ? import_lit26.html`<div>
6019
6605
  <h3>Strengths</h3>
6020
6606
  <ul>
6021
- ${strengths.map((s) => import_lit25.html`<li>${s}</li>`)}
6607
+ ${strengths.map((s) => import_lit26.html`<li>${s}</li>`)}
6022
6608
  </ul>
6023
- </div>` : import_lit25.nothing}
6024
- ${challenges.length ? import_lit25.html`<div>
6609
+ </div>` : import_lit26.nothing}
6610
+ ${challenges.length ? import_lit26.html`<div>
6025
6611
  <h3>Challenges</h3>
6026
6612
  <ul>
6027
- ${challenges.map((s) => import_lit25.html`<li>${s}</li>`)}
6613
+ ${challenges.map((s) => import_lit26.html`<li>${s}</li>`)}
6028
6614
  </ul>
6029
- </div>` : import_lit25.nothing}
6030
- </div>` : import_lit25.nothing}
6615
+ </div>` : import_lit26.nothing}
6616
+ </div>` : import_lit26.nothing}
6031
6617
  </div>`;
6032
6618
  }
6033
6619
  toAngle(longitude) {
@@ -6038,29 +6624,66 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
6038
6624
  const angle = this.toAngle(i * 30);
6039
6625
  const start = polarToCartesian(CENTER2, CENTER2, P2_R - 14, angle);
6040
6626
  const end = polarToCartesian(CENTER2, CENTER2, OUTER_R2, angle);
6041
- return import_lit25.svg`<line class="wheel-line" x1=${start.x} y1=${start.y} x2=${end.x} y2=${end.y} stroke-width="0.6" />`;
6627
+ return import_lit26.svg`<line class="wheel-line" x1=${start.x} y1=${start.y} x2=${end.x} y2=${end.y} stroke-width="0.6" />`;
6042
6628
  });
6043
6629
  }
6044
6630
  renderSigns() {
6045
6631
  return SIGNS_ORDER.map((s, i) => {
6046
6632
  const angle = this.toAngle(i * 30 + 15);
6047
6633
  const pos = polarToCartesian(CENTER2, CENTER2, SIGN_R2, angle);
6048
- return import_lit25.svg`<text class="sign" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${SIGN_GLYPH[s]}</text>`;
6634
+ return import_lit26.svg`<text class="sign" x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central">${SIGN_GLYPH[s]}</text>`;
6049
6635
  });
6050
6636
  }
6051
- renderRing(planets, radius, cls) {
6637
+ renderRing(planets, radius, cls, personIndex) {
6052
6638
  return planets.map((p) => {
6053
- if (!Number.isFinite(p.longitude)) return import_lit25.nothing;
6054
- const pos = polarToCartesian(
6639
+ if (!Number.isFinite(p.longitude)) return import_lit26.nothing;
6640
+ const angle = this.toAngle(p.longitude);
6641
+ const pos = polarToCartesian(CENTER2, CENTER2, radius, angle);
6642
+ const degOffset = personIndex === 1 ? -12 : -10;
6643
+ const degPos = polarToCartesian(
6055
6644
  CENTER2,
6056
6645
  CENTER2,
6057
- radius,
6058
- this.toAngle(p.longitude)
6646
+ radius + degOffset,
6647
+ angle
6059
6648
  );
6060
6649
  const glyph = PLANET_GLYPH[capitalize(p.name)] ?? p.name.slice(0, 2);
6061
- return import_lit25.svg`<text class=${cls} x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central"><title>${p.name}</title>${glyph}</text>`;
6650
+ const sp = longitudeToSignPosition(p.longitude);
6651
+ const retro = p.isRetrograde === true;
6652
+ const degLabel = `${sp.degree}\xB0${String(sp.minute).padStart(2, "0")}'`;
6653
+ const tooltip = `${p.name}${retro ? " retrograde" : ""} - ${degLabel} ${sp.sign}`;
6654
+ return import_lit26.svg`<g>
6655
+ <text class=${cls} x=${pos.x} y=${pos.y} text-anchor="middle" dominant-baseline="central"><title>${tooltip}</title>${glyph}<tspan class="person-tag" dy="-0.55em" dx="0.15em">${personIndex}</tspan></text>
6656
+ <text class="planet-deg" x=${degPos.x} y=${degPos.y} text-anchor="middle" dominant-baseline="central">${sp.degree}°${retro ? import_lit26.svg`<tspan class="retro"> ℞</tspan>` : import_lit26.nothing}</text>
6657
+ </g>`;
6062
6658
  });
6063
6659
  }
6660
+ /**
6661
+ * Ascendant markers for both people. Drawn as small spokes at the inner
6662
+ * rim with the label outside, so the two rising signs are immediately
6663
+ * scannable on the wheel without depending on tooltips.
6664
+ */
6665
+ renderAscendants(data) {
6666
+ const items = [];
6667
+ const make = (asc, personIndex) => {
6668
+ if (!asc) return;
6669
+ const signIdx = SIGNS_ORDER.findIndex(
6670
+ (s) => s.toLowerCase() === asc.sign.toLowerCase()
6671
+ );
6672
+ if (signIdx === -1) return;
6673
+ const longitude = signIdx * 30 + asc.degree;
6674
+ const angle = this.toAngle(longitude);
6675
+ const innerR = personIndex === 1 ? P1_R + 14 : P2_R + 14;
6676
+ const tickPos = polarToCartesian(CENTER2, CENTER2, innerR, angle);
6677
+ const labelPos = polarToCartesian(CENTER2, CENTER2, OUTER_R2 + 14, angle);
6678
+ items.push(import_lit26.svg`<g>
6679
+ <line class="asc-tick" x1=${tickPos.x} y1=${tickPos.y} x2=${labelPos.x} y2=${labelPos.y} />
6680
+ <text class="asc-label" x=${labelPos.x} y=${labelPos.y} text-anchor="middle" dominant-baseline="central">Asc${personIndex}</text>
6681
+ </g>`);
6682
+ };
6683
+ make(data.person1?.ascendant, 1);
6684
+ make(data.person2?.ascendant, 2);
6685
+ return items;
6686
+ }
6064
6687
  renderInterAspectLines(p1, p2, aspects) {
6065
6688
  const longitudeOf = (list, name) => {
6066
6689
  const target = capitalize(name);
@@ -6073,17 +6696,17 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
6073
6696
  return aspects.map((a) => {
6074
6697
  const l1 = longitudeOf(p1, a.planet1);
6075
6698
  const l2 = longitudeOf(p2, a.planet2);
6076
- if (l1 === void 0 || l2 === void 0) return import_lit25.nothing;
6699
+ if (l1 === void 0 || l2 === void 0) return import_lit26.nothing;
6077
6700
  const out = polarToCartesian(CENTER2, CENTER2, P1_R - 12, this.toAngle(l1));
6078
6701
  const inn = polarToCartesian(CENTER2, CENTER2, P2_R + 8, this.toAngle(l2));
6079
6702
  const aspectName = normalizeAspect(a);
6080
6703
  const cls = ASPECT_CLASS[aspectName] ?? "aspect-other";
6081
6704
  const orbLabel = formatNumber(a.orb, 1);
6082
- return import_lit25.svg`<line class=${`aspect ${cls}`} x1=${out.x} y1=${out.y} x2=${inn.x} y2=${inn.y}><title>${a.planet1} ${aspectName} ${a.planet2}${orbLabel ? ` (orb ${orbLabel}\xB0)` : ""}</title></line>`;
6705
+ return import_lit26.svg`<line class=${`aspect ${cls}`} x1=${out.x} y1=${out.y} x2=${inn.x} y2=${inn.y}><title>${a.planet1} ${aspectName} ${a.planet2}${orbLabel ? ` (orb ${orbLabel}\xB0)` : ""}</title></line>`;
6083
6706
  });
6084
6707
  }
6085
6708
  renderAspects(aspects) {
6086
- return import_lit25.html`<table>
6709
+ return import_lit26.html`<table>
6087
6710
  <thead>
6088
6711
  <tr>
6089
6712
  <th>Planet 1</th>
@@ -6095,7 +6718,7 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
6095
6718
  </thead>
6096
6719
  <tbody>
6097
6720
  ${aspects.slice(0, 12).map(
6098
- (a) => import_lit25.html`<tr>
6721
+ (a) => import_lit26.html`<tr>
6099
6722
  <td>${a.planet1}</td>
6100
6723
  <td>${a.planet2}</td>
6101
6724
  <td>${normalizeAspect(a) || ""}</td>
@@ -6109,7 +6732,7 @@ var RoxySynastryChart = class extends import_lit25.LitElement {
6109
6732
  };
6110
6733
  RoxySynastryChart.styles = [
6111
6734
  baseStyles,
6112
- import_lit25.css`
6735
+ import_lit26.css`
6113
6736
  .wrap {
6114
6737
  display: grid;
6115
6738
  gap: var(--roxy-space-md, 1rem);
@@ -6139,7 +6762,9 @@ RoxySynastryChart.styles = [
6139
6762
  svg {
6140
6763
  display: block;
6141
6764
  width: 100%;
6142
- max-width: 400px;
6765
+ max-width: 560px;
6766
+ aspect-ratio: 1 / 1;
6767
+ height: auto;
6143
6768
  margin: 0 auto;
6144
6769
  }
6145
6770
 
@@ -6161,6 +6786,31 @@ RoxySynastryChart.styles = [
6161
6786
  font-weight: 600;
6162
6787
  font-size: 13px;
6163
6788
  }
6789
+ .person-tag {
6790
+ font-size: 7px;
6791
+ font-weight: 700;
6792
+ opacity: 0.85;
6793
+ }
6794
+ .planet-deg {
6795
+ fill: var(--roxy-muted, #71717a);
6796
+ font-size: 7px;
6797
+ font-family: var(--roxy-font-sans);
6798
+ }
6799
+ .planet-deg .retro {
6800
+ fill: var(--roxy-danger, #dc2626);
6801
+ }
6802
+ .asc-tick {
6803
+ stroke: var(--roxy-accent-fg, #b45309);
6804
+ stroke-width: 1;
6805
+ opacity: 0.75;
6806
+ }
6807
+ .asc-label {
6808
+ fill: var(--roxy-accent-fg, #b45309);
6809
+ font-size: 9px;
6810
+ font-weight: 700;
6811
+ font-family: var(--roxy-font-sans);
6812
+ letter-spacing: 0.04em;
6813
+ }
6164
6814
  .aspect {
6165
6815
  stroke-width: 0.8;
6166
6816
  fill: none;
@@ -6275,9 +6925,9 @@ function formatStrength(s) {
6275
6925
  }
6276
6926
 
6277
6927
  // packages/ui/src/components/tarot-card.ts
6278
- var import_lit26 = require("lit");
6928
+ var import_lit27 = require("lit");
6279
6929
  var import_decorators24 = require("lit/decorators.js");
6280
- var RoxyTarotCard = class extends import_lit26.LitElement {
6930
+ var RoxyTarotCard = class extends import_lit27.LitElement {
6281
6931
  constructor() {
6282
6932
  super(...arguments);
6283
6933
  this.data = null;
@@ -6289,7 +6939,7 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6289
6939
  render() {
6290
6940
  const d = this.data;
6291
6941
  if (!d)
6292
- return import_lit26.html`<div class="roxy-empty" role="status">No tarot data</div>`;
6942
+ return import_lit27.html`<div class="roxy-empty" role="status">No tarot data</div>`;
6293
6943
  if ("card" in d) return this.renderDailyCard(d);
6294
6944
  return this.renderFullCard(d);
6295
6945
  }
@@ -6297,9 +6947,9 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6297
6947
  const card = d.card;
6298
6948
  const isReversed = this.flipped !== Boolean(card.reversed);
6299
6949
  const keywords = card.keywords ?? [];
6300
- return import_lit26.html`<article class="card" aria-label=${card.name ?? "Tarot card"}>
6950
+ return import_lit27.html`<article class="card" aria-label=${card.name ?? "Tarot card"}>
6301
6951
  <div class="image-wrap">
6302
- ${card.imageUrl ? import_lit26.html`<img
6952
+ ${card.imageUrl ? import_lit27.html`<img
6303
6953
  class=${`image ${isReversed ? "reversed" : ""}`}
6304
6954
  src=${card.imageUrl}
6305
6955
  alt=${card.name ?? "Tarot card"}
@@ -6311,7 +6961,7 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6311
6961
  this.toggleFlip();
6312
6962
  }
6313
6963
  }}
6314
- />` : import_lit26.html`<div
6964
+ />` : import_lit27.html`<div
6315
6965
  class=${`image ${isReversed ? "reversed" : ""}`}
6316
6966
  style="aspect-ratio: 0.6; display: flex; align-items: center; justify-content: center; color: var(--roxy-muted)"
6317
6967
  >
@@ -6320,15 +6970,15 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6320
6970
  </div>
6321
6971
  <div>
6322
6972
  <div class="meta">
6323
- ${card.arcana ? import_lit26.html`${card.arcana} arcana` : import_lit26.nothing}
6324
- ${isReversed ? import_lit26.html` · reversed` : import_lit26.nothing}
6973
+ ${card.arcana ? import_lit27.html`${card.arcana} arcana` : import_lit27.nothing}
6974
+ ${isReversed ? import_lit27.html` · reversed` : import_lit27.nothing}
6325
6975
  </div>
6326
6976
  <h2 class="title">${card.name ?? "Tarot card"}</h2>
6327
- ${d.dailyMessage ? import_lit26.html`<p class="message">${d.dailyMessage}</p>` : import_lit26.nothing}
6328
- ${card.meaning ? import_lit26.html`<p>${card.meaning}</p>` : import_lit26.nothing}
6329
- ${keywords.length > 0 ? import_lit26.html`<div class="chips">
6330
- ${keywords.map((k) => import_lit26.html`<span>${k}</span>`)}
6331
- </div>` : import_lit26.nothing}
6977
+ ${d.dailyMessage ? import_lit27.html`<p class="message">${d.dailyMessage}</p>` : import_lit27.nothing}
6978
+ ${card.meaning ? import_lit27.html`<p>${card.meaning}</p>` : import_lit27.nothing}
6979
+ ${keywords.length > 0 ? import_lit27.html`<div class="chips">
6980
+ ${keywords.map((k) => import_lit27.html`<span>${k}</span>`)}
6981
+ </div>` : import_lit27.nothing}
6332
6982
  <button
6333
6983
  class="flip"
6334
6984
  type="button"
@@ -6344,9 +6994,9 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6344
6994
  const isReversed = this.flipped;
6345
6995
  const orientedMeaning = isReversed ? d.reversed : d.upright;
6346
6996
  const keywords = isReversed ? d.keywords?.reversed ?? [] : d.keywords?.upright ?? [];
6347
- return import_lit26.html`<article class="card" aria-label=${d.name ?? "Tarot card"}>
6997
+ return import_lit27.html`<article class="card" aria-label=${d.name ?? "Tarot card"}>
6348
6998
  <div class="image-wrap">
6349
- ${d.imageUrl ? import_lit26.html`<img
6999
+ ${d.imageUrl ? import_lit27.html`<img
6350
7000
  class=${`image ${isReversed ? "reversed" : ""}`}
6351
7001
  src=${d.imageUrl}
6352
7002
  alt=${d.name ?? "Tarot card"}
@@ -6358,7 +7008,7 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6358
7008
  this.toggleFlip();
6359
7009
  }
6360
7010
  }}
6361
- />` : import_lit26.html`<div
7011
+ />` : import_lit27.html`<div
6362
7012
  class=${`image ${isReversed ? "reversed" : ""}`}
6363
7013
  style="aspect-ratio: 0.6; display: flex; align-items: center; justify-content: center; color: var(--roxy-muted)"
6364
7014
  >
@@ -6367,15 +7017,15 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6367
7017
  </div>
6368
7018
  <div>
6369
7019
  <div class="meta">
6370
- ${d.arcana ? import_lit26.html`${d.arcana} arcana` : import_lit26.nothing}
6371
- ${d.number !== void 0 && d.number !== null ? import_lit26.html` · ${d.number}` : import_lit26.nothing}
6372
- ${isReversed ? import_lit26.html` · reversed` : import_lit26.nothing}
7020
+ ${d.arcana ? import_lit27.html`${d.arcana} arcana` : import_lit27.nothing}
7021
+ ${d.number !== void 0 && d.number !== null ? import_lit27.html` · ${d.number}` : import_lit27.nothing}
7022
+ ${isReversed ? import_lit27.html` · reversed` : import_lit27.nothing}
6373
7023
  </div>
6374
7024
  <h2 class="title">${d.name ?? "Tarot card"}</h2>
6375
- ${orientedMeaning?.description ? import_lit26.html`<p>${orientedMeaning.description}</p>` : import_lit26.nothing}
6376
- ${keywords.length > 0 ? import_lit26.html`<div class="chips">
6377
- ${keywords.map((k) => import_lit26.html`<span>${k}</span>`)}
6378
- </div>` : import_lit26.nothing}
7025
+ ${orientedMeaning?.description ? import_lit27.html`<p>${orientedMeaning.description}</p>` : import_lit27.nothing}
7026
+ ${keywords.length > 0 ? import_lit27.html`<div class="chips">
7027
+ ${keywords.map((k) => import_lit27.html`<span>${k}</span>`)}
7028
+ </div>` : import_lit27.nothing}
6379
7029
  <button
6380
7030
  class="flip"
6381
7031
  type="button"
@@ -6390,7 +7040,7 @@ var RoxyTarotCard = class extends import_lit26.LitElement {
6390
7040
  };
6391
7041
  RoxyTarotCard.styles = [
6392
7042
  baseStyles,
6393
- import_lit26.css`
7043
+ import_lit27.css`
6394
7044
  .card {
6395
7045
  background: var(--roxy-bg, #fff);
6396
7046
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -6493,9 +7143,9 @@ RoxyTarotCard = __decorateClass([
6493
7143
  ], RoxyTarotCard);
6494
7144
 
6495
7145
  // packages/ui/src/components/tarot-spread.ts
6496
- var import_lit27 = require("lit");
7146
+ var import_lit28 = require("lit");
6497
7147
  var import_decorators25 = require("lit/decorators.js");
6498
- var RoxyTarotSpread = class extends import_lit27.LitElement {
7148
+ var RoxyTarotSpread = class extends import_lit28.LitElement {
6499
7149
  constructor() {
6500
7150
  super(...arguments);
6501
7151
  this.data = null;
@@ -6504,7 +7154,7 @@ var RoxyTarotSpread = class extends import_lit27.LitElement {
6504
7154
  render() {
6505
7155
  const d = this.data;
6506
7156
  if (!d)
6507
- return import_lit27.html`<div class="roxy-empty" role="status">No tarot spread</div>`;
7157
+ return import_lit28.html`<div class="roxy-empty" role="status">No tarot spread</div>`;
6508
7158
  const isYesNo = "answer" in d;
6509
7159
  const isDrawn = "cards" in d && !("spread" in d);
6510
7160
  const positions = isDrawn ? [] : "positions" in d ? d.positions ?? [] : [];
@@ -6516,60 +7166,60 @@ var RoxyTarotSpread = class extends import_lit27.LitElement {
6516
7166
  const summary = "summary" in d ? d.summary : void 0;
6517
7167
  const yesNoInterp = isYesNo ? d.interpretation : void 0;
6518
7168
  const answerClass = answer ? answer.toLowerCase().replace(/[^a-z]/g, "") : "";
6519
- return import_lit27.html`<article class="wrap" aria-label="Tarot spread">
7169
+ return import_lit28.html`<article class="wrap" aria-label="Tarot spread">
6520
7170
  <header class="head">
6521
7171
  <h2 class="title">${spreadLabel}</h2>
6522
- ${question ? import_lit27.html`<span class="question">"${question}"</span>` : import_lit27.nothing}
7172
+ ${question ? import_lit28.html`<span class="question">"${question}"</span>` : import_lit28.nothing}
6523
7173
  </header>
6524
- ${isYesNo ? import_lit27.html`<div>
7174
+ ${isYesNo ? import_lit28.html`<div>
6525
7175
  <span class=${`answer ${answerClass}`}>${answer}</span>
6526
- ${strength ? import_lit27.html`<small> · ${strength}</small>` : import_lit27.nothing}
6527
- </div>` : import_lit27.nothing}
6528
- ${positions.length > 0 ? import_lit27.html`<div class="grid">
7176
+ ${strength ? import_lit28.html`<small> · ${strength}</small>` : import_lit28.nothing}
7177
+ </div>` : import_lit28.nothing}
7178
+ ${positions.length > 0 ? import_lit28.html`<div class="grid">
6529
7179
  ${positions.map(
6530
- (p) => import_lit27.html`<div class="card">
7180
+ (p) => import_lit28.html`<div class="card">
6531
7181
  <p class="label">${p.name ?? ""}</p>
6532
7182
  <div class="image">
6533
- ${p.card?.imageUrl ? import_lit27.html`<img
7183
+ ${p.card?.imageUrl ? import_lit28.html`<img
6534
7184
  src=${p.card.imageUrl}
6535
7185
  alt=${p.card.name ?? "tarot card"}
6536
7186
  class=${p.card.reversed ? "reversed" : ""}
6537
- />` : import_lit27.html`${p.card?.name ?? "?"}`}
7187
+ />` : import_lit28.html`${p.card?.name ?? "?"}`}
6538
7188
  </div>
6539
7189
  <p class="name">
6540
7190
  ${p.card?.name ?? ""}
6541
- ${p.card?.reversed ? import_lit27.html`<small>(reversed)</small>` : import_lit27.nothing}
7191
+ ${p.card?.reversed ? import_lit28.html`<small>(reversed)</small>` : import_lit28.nothing}
6542
7192
  </p>
6543
- ${p.interpretation ? import_lit27.html`<p class="interp">${p.interpretation}</p>` : import_lit27.nothing}
7193
+ ${p.interpretation ? import_lit28.html`<p class="interp">${p.interpretation}</p>` : import_lit28.nothing}
6544
7194
  </div>`
6545
7195
  )}
6546
- </div>` : import_lit27.nothing}
6547
- ${cards.length > 0 ? import_lit27.html`<div class="grid">
7196
+ </div>` : import_lit28.nothing}
7197
+ ${cards.length > 0 ? import_lit28.html`<div class="grid">
6548
7198
  ${cards.map(
6549
- (c) => import_lit27.html`<div class="card">
7199
+ (c) => import_lit28.html`<div class="card">
6550
7200
  <div class="image">
6551
- ${c.imageUrl ? import_lit27.html`<img
7201
+ ${c.imageUrl ? import_lit28.html`<img
6552
7202
  src=${c.imageUrl}
6553
7203
  alt=${c.name ?? "tarot card"}
6554
7204
  class=${c.reversed ? "reversed" : ""}
6555
- />` : import_lit27.html`${c.name ?? "?"}`}
7205
+ />` : import_lit28.html`${c.name ?? "?"}`}
6556
7206
  </div>
6557
7207
  <p class="name">
6558
7208
  ${c.name ?? ""}
6559
- ${c.reversed ? import_lit27.html`<small>(reversed)</small>` : import_lit27.nothing}
7209
+ ${c.reversed ? import_lit28.html`<small>(reversed)</small>` : import_lit28.nothing}
6560
7210
  </p>
6561
- ${c.meaning ? import_lit27.html`<p class="interp">${c.meaning}</p>` : import_lit27.nothing}
7211
+ ${c.meaning ? import_lit28.html`<p class="interp">${c.meaning}</p>` : import_lit28.nothing}
6562
7212
  </div>`
6563
7213
  )}
6564
- </div>` : import_lit27.nothing}
6565
- ${summary ? import_lit27.html`<p class="reading">${summary}</p>` : import_lit27.nothing}
6566
- ${yesNoInterp ? import_lit27.html`<p class="reading">${yesNoInterp}</p>` : import_lit27.nothing}
7214
+ </div>` : import_lit28.nothing}
7215
+ ${summary ? import_lit28.html`<p class="reading">${summary}</p>` : import_lit28.nothing}
7216
+ ${yesNoInterp ? import_lit28.html`<p class="reading">${yesNoInterp}</p>` : import_lit28.nothing}
6567
7217
  </article>`;
6568
7218
  }
6569
7219
  };
6570
7220
  RoxyTarotSpread.styles = [
6571
7221
  baseStyles,
6572
- import_lit27.css`
7222
+ import_lit28.css`
6573
7223
  .wrap {
6574
7224
  display: grid;
6575
7225
  gap: var(--roxy-space-md, 1rem);
@@ -6688,16 +7338,16 @@ RoxyTarotSpread = __decorateClass([
6688
7338
  ], RoxyTarotSpread);
6689
7339
 
6690
7340
  // packages/ui/src/components/transits-table.ts
6691
- var import_lit28 = require("lit");
7341
+ var import_lit29 = require("lit");
6692
7342
  var import_decorators26 = require("lit/decorators.js");
6693
- var RoxyTransitsTable = class extends import_lit28.LitElement {
7343
+ var RoxyTransitsTable = class extends import_lit29.LitElement {
6694
7344
  constructor() {
6695
7345
  super(...arguments);
6696
7346
  this.data = null;
6697
7347
  }
6698
7348
  render() {
6699
7349
  if (!this.data?.transitPlanets?.length) {
6700
- return import_lit28.html`<div class="roxy-empty" role="status">No transits data</div>`;
7350
+ return import_lit29.html`<div class="roxy-empty" role="status">No transits data</div>`;
6701
7351
  }
6702
7352
  const {
6703
7353
  transitDate,
@@ -6707,13 +7357,13 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6707
7357
  summary
6708
7358
  } = this.data;
6709
7359
  const dateStr = [formatDate(transitDate), formatTime(transitTime)].filter(Boolean).join(" ");
6710
- return import_lit28.html`<div class="wrap" aria-label="Transit positions table">
7360
+ return import_lit29.html`<div class="wrap" aria-label="Transit positions table">
6711
7361
  <div class="head">
6712
7362
  <h2 class="title">Transits</h2>
6713
- ${dateStr ? import_lit28.html`<p class="subtitle">${dateStr}</p>` : import_lit28.nothing}
7363
+ ${dateStr ? import_lit29.html`<p class="subtitle">${dateStr}</p>` : import_lit29.nothing}
6714
7364
  </div>
6715
7365
 
6716
- ${summary ? this.renderSummaryPills(summary) : import_lit28.nothing}
7366
+ ${summary ? this.renderSummaryPills(summary) : import_lit29.nothing}
6717
7367
 
6718
7368
  <div>
6719
7369
  <p class="section-label">Planet positions</p>
@@ -6722,16 +7372,16 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6722
7372
  </div>
6723
7373
  </div>
6724
7374
 
6725
- ${transitAspects?.length ? import_lit28.html`<div>
7375
+ ${transitAspects?.length ? import_lit29.html`<div>
6726
7376
  <p class="section-label">Transit aspects</p>
6727
7377
  <div class="overflow-scroll">
6728
7378
  ${this.renderAspectsList(transitAspects)}
6729
7379
  </div>
6730
- </div>` : import_lit28.nothing}
7380
+ </div>` : import_lit29.nothing}
6731
7381
  </div>`;
6732
7382
  }
6733
7383
  renderSummaryPills(summary) {
6734
- return import_lit28.html`<div class="summary-pills" role="region" aria-label="Aspect summary">
7384
+ return import_lit29.html`<div class="summary-pills" role="region" aria-label="Aspect summary">
6735
7385
  <span class="pill pill--muted">
6736
7386
  Total: ${summary.totalAspects}
6737
7387
  </span>
@@ -6747,7 +7397,7 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6747
7397
  </div>`;
6748
7398
  }
6749
7399
  renderPlanetsTable(planets) {
6750
- return import_lit28.html`<table class="planets-table">
7400
+ return import_lit29.html`<table class="planets-table">
6751
7401
  <thead>
6752
7402
  <tr>
6753
7403
  <th scope="col">Planet</th>
@@ -6761,12 +7411,12 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6761
7411
  const pGlyph = PLANET_GLYPH[capitalize(p.name)] ?? "";
6762
7412
  const sGlyph = SIGN_GLYPH[capitalize(p.sign)] ?? "";
6763
7413
  const speedArrow = p.speed >= 0 ? "\u2191" : "\u2193";
6764
- return import_lit28.html`<tr>
7414
+ return import_lit29.html`<tr>
6765
7415
  <td>
6766
7416
  <div class="planet-cell">
6767
7417
  <span class="glyph" aria-hidden="true">${pGlyph}</span>
6768
7418
  ${p.name}
6769
- ${p.isRetrograde ? import_lit28.html`<span class="retro-badge" aria-label="retrograde">R</span>` : import_lit28.nothing}
7419
+ ${p.isRetrograde ? import_lit29.html`<span class="retro-badge" aria-label="retrograde">R</span>` : import_lit29.nothing}
6770
7420
  </div>
6771
7421
  </td>
6772
7422
  <td>
@@ -6786,7 +7436,7 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6786
7436
  </table>`;
6787
7437
  }
6788
7438
  renderAspectsList(aspects) {
6789
- return import_lit28.html`<div role="list" aria-label="Transit aspects">
7439
+ return import_lit29.html`<div role="list" aria-label="Transit aspects">
6790
7440
  ${aspects.map((a, idx) => {
6791
7441
  const tGlyph = PLANET_GLYPH[capitalize(a.transitPlanet)] ?? "";
6792
7442
  const nGlyph = PLANET_GLYPH[capitalize(a.natalPlanet)] ?? "";
@@ -6794,7 +7444,7 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6794
7444
  const interp = a.interpretation;
6795
7445
  const type = (a.type ?? "").toLowerCase();
6796
7446
  const status = a.isApplying ? "Applying" : "Separating";
6797
- return import_lit28.html`<details class="aspect-card" role="listitem" name="transit-aspects" ?open=${idx === 0}>
7447
+ return import_lit29.html`<details class="aspect-card" role="listitem" name="transit-aspects" ?open=${idx === 0}>
6798
7448
  <summary>
6799
7449
  <span aria-hidden="true">${tGlyph}</span>
6800
7450
  ${a.transitPlanet}
@@ -6806,13 +7456,13 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6806
7456
  </span>
6807
7457
  </summary>
6808
7458
  <div class="interp-body">
6809
- ${interp?.summary ? import_lit28.html`<p>${interp.summary}</p>` : import_lit28.nothing}
6810
- ${interp?.impact ? import_lit28.html`<p><strong>Impact:</strong> ${interp.impact}</p>` : import_lit28.nothing}
6811
- ${interp?.timing ? import_lit28.html`<p><strong>Timing:</strong> ${interp.timing}</p>` : import_lit28.nothing}
6812
- ${interp?.guidance ? import_lit28.html`<p><strong>Guidance:</strong> ${interp.guidance}</p>` : import_lit28.nothing}
6813
- ${interp?.keywords?.length ? import_lit28.html`<div class="interp-keywords">
6814
- ${interp.keywords.map((k) => import_lit28.html`<span class="kw">${k}</span>`)}
6815
- </div>` : import_lit28.nothing}
7459
+ ${interp?.summary ? import_lit29.html`<p>${interp.summary}</p>` : import_lit29.nothing}
7460
+ ${interp?.impact ? import_lit29.html`<p><strong>Impact:</strong> ${interp.impact}</p>` : import_lit29.nothing}
7461
+ ${interp?.timing ? import_lit29.html`<p><strong>Timing:</strong> ${interp.timing}</p>` : import_lit29.nothing}
7462
+ ${interp?.guidance ? import_lit29.html`<p><strong>Guidance:</strong> ${interp.guidance}</p>` : import_lit29.nothing}
7463
+ ${interp?.keywords?.length ? import_lit29.html`<div class="interp-keywords">
7464
+ ${interp.keywords.map((k) => import_lit29.html`<span class="kw">${k}</span>`)}
7465
+ </div>` : import_lit29.nothing}
6816
7466
  </div>
6817
7467
  </details>`;
6818
7468
  })}
@@ -6821,7 +7471,7 @@ var RoxyTransitsTable = class extends import_lit28.LitElement {
6821
7471
  };
6822
7472
  RoxyTransitsTable.styles = [
6823
7473
  baseStyles,
6824
- import_lit28.css`
7474
+ import_lit29.css`
6825
7475
  .wrap {
6826
7476
  display: grid;
6827
7477
  gap: var(--roxy-space-md, 1rem);
@@ -7027,93 +7677,43 @@ RoxyTransitsTable = __decorateClass([
7027
7677
  ], RoxyTransitsTable);
7028
7678
 
7029
7679
  // packages/ui/src/components/vedic-kundli.ts
7030
- var import_lit29 = require("lit");
7680
+ var import_lit30 = require("lit");
7031
7681
  var import_decorators27 = require("lit/decorators.js");
7032
- var RoxyVedicKundli = class extends import_lit29.LitElement {
7682
+ var RoxyVedicKundli = class extends import_lit30.LitElement {
7033
7683
  constructor() {
7034
7684
  super(...arguments);
7035
7685
  this.data = null;
7036
- this.chartStyle = "south";
7686
+ this.chartStyle = "north";
7687
+ this.setStyle = (next) => {
7688
+ this.chartStyle = next;
7689
+ };
7037
7690
  }
7038
- buildHouses() {
7039
- if (!this.data?.meta) return [];
7040
- return buildHousesFromMeta(this.data.meta);
7691
+ viewModel() {
7692
+ if (!this.data?.meta) return null;
7693
+ return toKundliViewModel(this.data.meta, "D1 Rashi");
7041
7694
  }
7042
7695
  render() {
7043
- if (!this.data)
7044
- return import_lit29.html`<div class="roxy-empty" role="status">No kundli data</div>`;
7045
- const houses = this.buildHouses();
7046
- const style = this.chartStyle;
7047
- const frame = style === "north" ? renderNorthFrame() : style === "east" ? renderEastFrame() : renderSouthFrame();
7048
- const houseGroup = style === "north" ? renderNorthHouseGroup : style === "east" ? renderEastHouseGroup : renderSouthHouseGroup;
7049
- return import_lit29.html`<div class="wrap">
7050
- <h2 class="title">Vedic kundli</h2>
7696
+ const vm = this.viewModel();
7697
+ if (!vm)
7698
+ return import_lit30.html`<div class="roxy-empty" role="status">No kundli data</div>`;
7699
+ return import_lit30.html`<div class="wrap">
7700
+ <div class="header">
7701
+ <h2 class="title">Vedic kundli</h2>
7702
+ ${renderKundliStyleTablist(this.chartStyle, this.setStyle)}
7703
+ </div>
7051
7704
  <svg
7052
- viewBox="0 0 300 300"
7705
+ viewBox="0 0 400 400"
7706
+ preserveAspectRatio="xMidYMid meet"
7053
7707
  role="img"
7054
7708
  aria-label="Vedic birth chart with twelve sign houses"
7055
7709
  >
7056
7710
  <title>Vedic kundli</title>
7057
- ${frame}
7058
- ${houses.map((h) => houseGroup(h))}
7711
+ ${renderKundliSvg(vm, this.chartStyle)}
7059
7712
  </svg>
7060
7713
  </div>`;
7061
7714
  }
7062
7715
  };
7063
- RoxyVedicKundli.styles = [
7064
- baseStyles,
7065
- import_lit29.css`
7066
- .wrap {
7067
- display: grid;
7068
- gap: var(--roxy-space-md, 1rem);
7069
- }
7070
- .title {
7071
- font-size: var(--roxy-text-lg, 1.125rem);
7072
- font-weight: var(--roxy-weight-bold, 600);
7073
- margin: 0;
7074
- }
7075
- svg {
7076
- display: block;
7077
- width: 100%;
7078
- max-width: 360px;
7079
- margin: 0 auto;
7080
- }
7081
- .line {
7082
- fill: transparent;
7083
- stroke: var(--roxy-border, #e4e4e7);
7084
- }
7085
- .sign-text {
7086
- fill: var(--roxy-muted, #71717a);
7087
- font-size: 9px;
7088
- font-weight: 500;
7089
- font-family: var(--roxy-font-sans);
7090
- }
7091
- .planet-text {
7092
- fill: var(--roxy-fg, #0a0a0a);
7093
- font-size: 10px;
7094
- font-weight: 600;
7095
- font-family: var(--roxy-font-sans);
7096
- }
7097
- .house-num {
7098
- fill: var(--roxy-muted, #71717a);
7099
- font-size: 9px;
7100
- font-weight: 400;
7101
- font-family: var(--roxy-font-sans);
7102
- }
7103
- .lagna-marker {
7104
- fill: var(--roxy-accent-fg, #b45309);
7105
- font-size: 8px;
7106
- font-weight: 700;
7107
- font-family: var(--roxy-font-sans);
7108
- letter-spacing: 0.05em;
7109
- }
7110
- .lagna-bg {
7111
- fill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 12%, transparent);
7112
- stroke: color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);
7113
- stroke-width: 0.8;
7114
- }
7115
- `
7116
- ];
7716
+ RoxyVedicKundli.styles = [baseStyles, kundliStyles];
7117
7717
  __decorateClass([
7118
7718
  (0, import_decorators27.property)({ attribute: false })
7119
7719
  ], RoxyVedicKundli.prototype, "data", 2);
@@ -7125,7 +7725,7 @@ RoxyVedicKundli = __decorateClass([
7125
7725
  ], RoxyVedicKundli);
7126
7726
 
7127
7727
  // packages/ui/src/components/vedic-planets-table.ts
7128
- var import_lit30 = require("lit");
7728
+ var import_lit31 = require("lit");
7129
7729
  var import_decorators28 = require("lit/decorators.js");
7130
7730
  var GRAHA_ORDER = [
7131
7731
  "Lagna",
@@ -7139,7 +7739,7 @@ var GRAHA_ORDER = [
7139
7739
  "Rahu",
7140
7740
  "Ketu"
7141
7741
  ];
7142
- var RoxyVedicPlanetsTable = class extends import_lit30.LitElement {
7742
+ var RoxyVedicPlanetsTable = class extends import_lit31.LitElement {
7143
7743
  constructor() {
7144
7744
  super(...arguments);
7145
7745
  this.data = null;
@@ -7163,9 +7763,9 @@ var RoxyVedicPlanetsTable = class extends import_lit30.LitElement {
7163
7763
  }
7164
7764
  render() {
7165
7765
  if (!this.data?.meta)
7166
- return import_lit30.html`<div class="roxy-empty" role="status">No chart data</div>`;
7766
+ return import_lit31.html`<div class="roxy-empty" role="status">No chart data</div>`;
7167
7767
  const rows = this.orderedRows();
7168
- return import_lit30.html`<div class="wrap" aria-label="Vedic planetary positions" tabindex="0">
7768
+ return import_lit31.html`<div class="wrap" aria-label="Vedic planetary positions" tabindex="0">
7169
7769
  <header class="head">
7170
7770
  <h2 class="title">Planetary positions</h2>
7171
7771
  </header>
@@ -7188,12 +7788,12 @@ var RoxyVedicPlanetsTable = class extends import_lit30.LitElement {
7188
7788
  const isLagna = (p.graha ?? name) === "Lagna";
7189
7789
  const glyph = PLANET_GLYPH[capitalize(p.graha ?? name)] ?? "";
7190
7790
  const signGlyph = SIGN_GLYPH[capitalize(p.rashi ?? "")] ?? "";
7191
- return import_lit30.html`<tr class=${isLagna ? "lagna" : ""}>
7791
+ return import_lit31.html`<tr class=${isLagna ? "lagna" : ""}>
7192
7792
  <td class="graha">
7193
- ${glyph ? import_lit30.html`<span class="glyph">${glyph}</span>` : import_lit30.nothing}${p.graha ?? name}
7793
+ ${glyph ? import_lit31.html`<span class="glyph">${glyph}</span>` : import_lit31.nothing}${p.graha ?? name}
7194
7794
  </td>
7195
7795
  <td>
7196
- ${signGlyph ? import_lit30.html`<span class="glyph">${signGlyph}</span>` : import_lit30.nothing}${p.rashi ?? ""}
7796
+ ${signGlyph ? import_lit31.html`<span class="glyph">${signGlyph}</span>` : import_lit31.nothing}${p.rashi ?? ""}
7197
7797
  </td>
7198
7798
  <td class="num">
7199
7799
  ${typeof p.longitude === "number" ? formatSignPosition(p.longitude) : ""}
@@ -7203,7 +7803,7 @@ var RoxyVedicPlanetsTable = class extends import_lit30.LitElement {
7203
7803
  <td>${p.nakshatra?.lord ?? ""}</td>
7204
7804
  <td class="num">${typeof p.house === "number" ? p.house : ""}</td>
7205
7805
  <td>${p.awastha ?? ""}</td>
7206
- <td>${p.isRetrograde ? import_lit30.html`<span class="retro">R</span>` : import_lit30.nothing}</td>
7806
+ <td>${p.isRetrograde ? import_lit31.html`<span class="retro">R</span>` : import_lit31.nothing}</td>
7207
7807
  </tr>`;
7208
7808
  })}
7209
7809
  </tbody>
@@ -7213,7 +7813,7 @@ var RoxyVedicPlanetsTable = class extends import_lit30.LitElement {
7213
7813
  };
7214
7814
  RoxyVedicPlanetsTable.styles = [
7215
7815
  baseStyles,
7216
- import_lit30.css`
7816
+ import_lit31.css`
7217
7817
  .wrap {
7218
7818
  border: 1px solid var(--roxy-border, #e4e4e7);
7219
7819
  border-radius: var(--roxy-radius-md, 8px);
@@ -7289,9 +7889,9 @@ RoxyVedicPlanetsTable = __decorateClass([
7289
7889
  ], RoxyVedicPlanetsTable);
7290
7890
 
7291
7891
  // packages/ui/src/components/western-planets-table.ts
7292
- var import_lit31 = require("lit");
7892
+ var import_lit32 = require("lit");
7293
7893
  var import_decorators29 = require("lit/decorators.js");
7294
- var RoxyWesternPlanetsTable = class extends import_lit31.LitElement {
7894
+ var RoxyWesternPlanetsTable = class extends import_lit32.LitElement {
7295
7895
  constructor() {
7296
7896
  super(...arguments);
7297
7897
  this.data = null;
@@ -7327,9 +7927,9 @@ var RoxyWesternPlanetsTable = class extends import_lit31.LitElement {
7327
7927
  }
7328
7928
  render() {
7329
7929
  if (!this.data?.planets)
7330
- return import_lit31.html`<div class="roxy-empty" role="status">No chart data</div>`;
7930
+ return import_lit32.html`<div class="roxy-empty" role="status">No chart data</div>`;
7331
7931
  const rows = this.rows();
7332
- return import_lit31.html`<div class="wrap" aria-label="Western planetary positions" tabindex="0">
7932
+ return import_lit32.html`<div class="wrap" aria-label="Western planetary positions" tabindex="0">
7333
7933
  <header class="head">
7334
7934
  <h2 class="title">Planetary positions</h2>
7335
7935
  </header>
@@ -7348,20 +7948,20 @@ var RoxyWesternPlanetsTable = class extends import_lit31.LitElement {
7348
7948
  const glyph = PLANET_GLYPH[capitalize(r.name)] ?? "";
7349
7949
  const signGlyph = SIGN_GLYPH[capitalize(r.sign ?? "")] ?? "";
7350
7950
  const speed = typeof r.speed === "number" ? formatNumber(r.speed, 3) : "";
7351
- return import_lit31.html`<tr class=${r.isPoint ? "point" : ""}>
7951
+ return import_lit32.html`<tr class=${r.isPoint ? "point" : ""}>
7352
7952
  <td class="body">
7353
- ${glyph ? import_lit31.html`<span class="glyph">${glyph}</span>` : import_lit31.nothing}${r.name}
7953
+ ${glyph ? import_lit32.html`<span class="glyph">${glyph}</span>` : import_lit32.nothing}${r.name}
7354
7954
  </td>
7355
7955
  <td>
7356
- ${signGlyph ? import_lit31.html`<span class="glyph">${signGlyph}</span>` : import_lit31.nothing}${r.sign ?? ""}
7956
+ ${signGlyph ? import_lit32.html`<span class="glyph">${signGlyph}</span>` : import_lit32.nothing}${r.sign ?? ""}
7357
7957
  </td>
7358
7958
  <td class="num">
7359
7959
  ${typeof r.longitude === "number" ? formatSignPosition(r.longitude) : ""}
7360
7960
  </td>
7361
7961
  <td class="num">${typeof r.house === "number" ? r.house : ""}</td>
7362
7962
  <td class="num">
7363
- ${speed ? import_lit31.html`${speed}°/day` : import_lit31.nothing}
7364
- ${r.isRetrograde ? import_lit31.html`<span class="retro"> ℞</span>` : import_lit31.nothing}
7963
+ ${speed ? import_lit32.html`${speed}°/day` : import_lit32.nothing}
7964
+ ${r.isRetrograde ? import_lit32.html`<span class="retro"> ℞</span>` : import_lit32.nothing}
7365
7965
  </td>
7366
7966
  </tr>`;
7367
7967
  })}
@@ -7372,7 +7972,7 @@ var RoxyWesternPlanetsTable = class extends import_lit31.LitElement {
7372
7972
  };
7373
7973
  RoxyWesternPlanetsTable.styles = [
7374
7974
  baseStyles,
7375
- import_lit31.css`
7975
+ import_lit32.css`
7376
7976
  .wrap {
7377
7977
  border: 1px solid var(--roxy-border, #e4e4e7);
7378
7978
  border-radius: var(--roxy-radius-md, 8px);
@@ -7442,9 +8042,9 @@ RoxyWesternPlanetsTable = __decorateClass([
7442
8042
  ], RoxyWesternPlanetsTable);
7443
8043
 
7444
8044
  // packages/ui/src/components/yoga-list.ts
7445
- var import_lit32 = require("lit");
8045
+ var import_lit33 = require("lit");
7446
8046
  var import_decorators30 = require("lit/decorators.js");
7447
- var RoxyYogaList = class extends import_lit32.LitElement {
8047
+ var RoxyYogaList = class extends import_lit33.LitElement {
7448
8048
  constructor() {
7449
8049
  super(...arguments);
7450
8050
  this.data = null;
@@ -7455,29 +8055,29 @@ var RoxyYogaList = class extends import_lit32.LitElement {
7455
8055
  }
7456
8056
  renderQualityChip(quality) {
7457
8057
  const cls = `quality-chip quality-${quality}`;
7458
- return import_lit32.html`<span class=${cls}>${quality}</span>`;
8058
+ return import_lit33.html`<span class=${cls}>${quality}</span>`;
7459
8059
  }
7460
8060
  renderDetailCard(yoga) {
7461
- return import_lit32.html`<div class="detail-card">
8061
+ return import_lit33.html`<div class="detail-card">
7462
8062
  <p class="detail-name">
7463
8063
  ${yoga.name}
7464
- ${yoga.quality ? this.renderQualityChip(yoga.quality) : import_lit32.nothing}
8064
+ ${yoga.quality ? this.renderQualityChip(yoga.quality) : import_lit33.nothing}
7465
8065
  </p>
7466
- ${yoga.description ? import_lit32.html`<p class="description">${yoga.description}</p>` : import_lit32.nothing}
7467
- ${yoga.result ? import_lit32.html`<details>
8066
+ ${yoga.description ? import_lit33.html`<p class="description">${yoga.description}</p>` : import_lit33.nothing}
8067
+ ${yoga.result ? import_lit33.html`<details>
7468
8068
  <summary>Effects</summary>
7469
8069
  <div class="result-body">${yoga.result}</div>
7470
- </details>` : import_lit32.nothing}
8070
+ </details>` : import_lit33.nothing}
7471
8071
  </div>`;
7472
8072
  }
7473
8073
  render() {
7474
8074
  if (!this.data)
7475
- return import_lit32.html`<div class="roxy-empty" role="status">No yoga data</div>`;
8075
+ return import_lit33.html`<div class="roxy-empty" role="status">No yoga data</div>`;
7476
8076
  const d = this.data;
7477
8077
  const lc = this.filter.toLowerCase();
7478
8078
  if ("description" in d && typeof d.description === "string") {
7479
8079
  const yoga = d;
7480
- return import_lit32.html`<div class="wrap">${this.renderDetailCard(yoga)}</div>`;
8080
+ return import_lit33.html`<div class="wrap">${this.renderDetailCard(yoga)}</div>`;
7481
8081
  }
7482
8082
  if ("yogas" in d && Array.isArray(d.yogas)) {
7483
8083
  const allYogas = d.yogas;
@@ -7486,10 +8086,10 @@ var RoxyYogaList = class extends import_lit32.LitElement {
7486
8086
  const detailYogas = allYogas;
7487
8087
  const filtered2 = lc ? detailYogas.filter((y) => y.name.toLowerCase().includes(lc)) : detailYogas;
7488
8088
  const total2 = d.total;
7489
- return import_lit32.html`<div class="wrap">
8089
+ return import_lit33.html`<div class="wrap">
7490
8090
  <div class="head">
7491
8091
  <h2 class="title">Yoga catalog</h2>
7492
- ${total2 !== void 0 ? import_lit32.html`<span class="count">${total2} total</span>` : import_lit32.nothing}
8092
+ ${total2 !== void 0 ? import_lit33.html`<span class="count">${total2} total</span>` : import_lit33.nothing}
7493
8093
  </div>
7494
8094
  <div class="search-wrap">
7495
8095
  <input
@@ -7507,17 +8107,17 @@ var RoxyYogaList = class extends import_lit32.LitElement {
7507
8107
  aria-live="polite"
7508
8108
  aria-label="Yoga results"
7509
8109
  >
7510
- ${filtered2.length > 0 ? filtered2.map((y) => this.renderDetailCard(y)) : import_lit32.html`<p class="no-results">No yogas match your search.</p>`}
8110
+ ${filtered2.length > 0 ? filtered2.map((y) => this.renderDetailCard(y)) : import_lit33.html`<p class="no-results">No yogas match your search.</p>`}
7511
8111
  </div>
7512
8112
  </div>`;
7513
8113
  }
7514
8114
  const catalogYogas = allYogas;
7515
8115
  const filtered = lc ? catalogYogas.filter((y) => y.name.toLowerCase().includes(lc)) : catalogYogas;
7516
8116
  const total = d.total;
7517
- return import_lit32.html`<div class="wrap">
8117
+ return import_lit33.html`<div class="wrap">
7518
8118
  <div class="head">
7519
8119
  <h2 class="title">Yoga catalog</h2>
7520
- ${total !== void 0 ? import_lit32.html`<span class="count">${total} total</span>` : import_lit32.nothing}
8120
+ ${total !== void 0 ? import_lit33.html`<span class="count">${total} total</span>` : import_lit33.nothing}
7521
8121
  </div>
7522
8122
  <div class="search-wrap">
7523
8123
  <input
@@ -7536,20 +8136,20 @@ var RoxyYogaList = class extends import_lit32.LitElement {
7536
8136
  aria-label="Yoga results"
7537
8137
  >
7538
8138
  ${filtered.length > 0 ? filtered.map(
7539
- (y) => import_lit32.html`<div class="yoga-chip">
8139
+ (y) => import_lit33.html`<div class="yoga-chip">
7540
8140
  ${y.name}
7541
8141
  <span class="yoga-id">${y.id}</span>
7542
8142
  </div>`
7543
- ) : import_lit32.html`<p class="no-results">No yogas match your search.</p>`}
8143
+ ) : import_lit33.html`<p class="no-results">No yogas match your search.</p>`}
7544
8144
  </div>
7545
8145
  </div>`;
7546
8146
  }
7547
- return import_lit32.html`<div class="roxy-empty" role="status">No yoga data</div>`;
8147
+ return import_lit33.html`<div class="roxy-empty" role="status">No yoga data</div>`;
7548
8148
  }
7549
8149
  };
7550
8150
  RoxyYogaList.styles = [
7551
8151
  baseStyles,
7552
- import_lit32.css`
8152
+ import_lit33.css`
7553
8153
  .wrap {
7554
8154
  display: grid;
7555
8155
  gap: var(--roxy-space-md, 1rem);
@@ -8047,7 +8647,7 @@ var ROXY_COMPONENTS = [
8047
8647
  ];
8048
8648
 
8049
8649
  // packages/ui/src/version.ts
8050
- var ROXY_UI_VERSION = "0.3.1";
8650
+ var ROXY_UI_VERSION = "0.4.1";
8051
8651
 
8052
8652
  // packages/ui/src/index.ts
8053
8653
  var ROXY_UI_COMPONENTS = ROXY_COMPONENTS.map((c) => c.slug);