@roxyapi/ui 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/AGENTS.md +6 -0
  2. package/README.md +327 -14
  3. package/THEMING.md +24 -7
  4. package/dist/cdn/components/ashtakavarga-grid.js +349 -0
  5. package/dist/cdn/components/ashtakavarga-grid.js.map +7 -0
  6. package/dist/cdn/components/biorhythm-chart.js +15 -22
  7. package/dist/cdn/components/biorhythm-chart.js.map +3 -3
  8. package/dist/cdn/components/choghadiya-grid.js +239 -0
  9. package/dist/cdn/components/choghadiya-grid.js.map +7 -0
  10. package/dist/cdn/components/compatibility-card.js +36 -34
  11. package/dist/cdn/components/compatibility-card.js.map +4 -4
  12. package/dist/cdn/components/dasha-timeline.js +35 -39
  13. package/dist/cdn/components/dasha-timeline.js.map +4 -4
  14. package/dist/cdn/components/data.js +9 -9
  15. package/dist/cdn/components/data.js.map +4 -4
  16. package/dist/cdn/components/divisional-chart.js +279 -0
  17. package/dist/cdn/components/divisional-chart.js.map +7 -0
  18. package/dist/cdn/components/dosha-card.js +49 -49
  19. package/dist/cdn/components/dosha-card.js.map +3 -3
  20. package/dist/cdn/components/endpoint-form.js +47 -28
  21. package/dist/cdn/components/endpoint-form.js.map +4 -4
  22. package/dist/cdn/components/guna-milan.js +66 -24
  23. package/dist/cdn/components/guna-milan.js.map +4 -4
  24. package/dist/cdn/components/hexagram.js +26 -26
  25. package/dist/cdn/components/hexagram.js.map +3 -3
  26. package/dist/cdn/components/horoscope-card.js +47 -40
  27. package/dist/cdn/components/horoscope-card.js.map +4 -4
  28. package/dist/cdn/components/kp-planets-table.js +10 -10
  29. package/dist/cdn/components/kp-planets-table.js.map +4 -4
  30. package/dist/cdn/components/location-search.js +6 -6
  31. package/dist/cdn/components/location-search.js.map +3 -3
  32. package/dist/cdn/components/moon-phase.js +18 -18
  33. package/dist/cdn/components/moon-phase.js.map +4 -4
  34. package/dist/cdn/components/natal-chart.js +240 -24
  35. package/dist/cdn/components/natal-chart.js.map +4 -4
  36. package/dist/cdn/components/numerology-card.js +40 -31
  37. package/dist/cdn/components/numerology-card.js.map +4 -4
  38. package/dist/cdn/components/panchang-table.js +30 -30
  39. package/dist/cdn/components/panchang-table.js.map +4 -4
  40. package/dist/cdn/components/shadbala-table.js +312 -0
  41. package/dist/cdn/components/shadbala-table.js.map +7 -0
  42. package/dist/cdn/components/synastry-chart.js +129 -39
  43. package/dist/cdn/components/synastry-chart.js.map +4 -4
  44. package/dist/cdn/components/tarot-card.js +49 -20
  45. package/dist/cdn/components/tarot-card.js.map +3 -3
  46. package/dist/cdn/components/tarot-spread.js +43 -27
  47. package/dist/cdn/components/tarot-spread.js.map +3 -3
  48. package/dist/cdn/components/transits-table.js +391 -0
  49. package/dist/cdn/components/transits-table.js.map +7 -0
  50. package/dist/cdn/components/vedic-kundli.js +63 -27
  51. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  52. package/dist/cdn/components/yoga-list.js +334 -0
  53. package/dist/cdn/components/yoga-list.js.map +7 -0
  54. package/dist/cdn/roxy-ui.js +2104 -544
  55. package/dist/cdn/roxy-ui.js.map +4 -4
  56. package/dist/components/ashtakavarga-grid.d.ts +26 -0
  57. package/dist/components/ashtakavarga-grid.d.ts.map +1 -0
  58. package/dist/components/ashtakavarga-grid.js +457 -0
  59. package/dist/components/ashtakavarga-grid.js.map +7 -0
  60. package/dist/components/biorhythm-chart.d.ts +2 -46
  61. package/dist/components/biorhythm-chart.d.ts.map +1 -1
  62. package/dist/components/biorhythm-chart.js +24 -23
  63. package/dist/components/biorhythm-chart.js.map +2 -2
  64. package/dist/components/choghadiya-grid.d.ts +19 -0
  65. package/dist/components/choghadiya-grid.d.ts.map +1 -0
  66. package/dist/components/choghadiya-grid.js +304 -0
  67. package/dist/components/choghadiya-grid.js.map +7 -0
  68. package/dist/components/compatibility-card.d.ts +2 -27
  69. package/dist/components/compatibility-card.d.ts.map +1 -1
  70. package/dist/components/compatibility-card.js +50 -29
  71. package/dist/components/compatibility-card.js.map +3 -3
  72. package/dist/components/dasha-timeline.d.ts +2 -31
  73. package/dist/components/dasha-timeline.d.ts.map +1 -1
  74. package/dist/components/dasha-timeline.js +32 -30
  75. package/dist/components/dasha-timeline.js.map +3 -3
  76. package/dist/components/data.d.ts +11 -7
  77. package/dist/components/data.d.ts.map +1 -1
  78. package/dist/components/data.js +16 -6
  79. package/dist/components/data.js.map +3 -3
  80. package/dist/components/divisional-chart.d.ts +20 -0
  81. package/dist/components/divisional-chart.d.ts.map +1 -0
  82. package/dist/components/divisional-chart.js +471 -0
  83. package/dist/components/divisional-chart.js.map +7 -0
  84. package/dist/components/dosha-card.d.ts +2 -16
  85. package/dist/components/dosha-card.d.ts.map +1 -1
  86. package/dist/components/dosha-card.js +45 -43
  87. package/dist/components/dosha-card.js.map +2 -2
  88. package/dist/components/endpoint-form.d.ts +2 -0
  89. package/dist/components/endpoint-form.d.ts.map +1 -1
  90. package/dist/components/endpoint-form.js +71 -11
  91. package/dist/components/endpoint-form.js.map +3 -3
  92. package/dist/components/guna-milan.d.ts +2 -20
  93. package/dist/components/guna-milan.d.ts.map +1 -1
  94. package/dist/components/guna-milan.js +79 -20
  95. package/dist/components/guna-milan.js.map +4 -4
  96. package/dist/components/hexagram.d.ts +3 -27
  97. package/dist/components/hexagram.d.ts.map +1 -1
  98. package/dist/components/hexagram.js +48 -15
  99. package/dist/components/hexagram.js.map +2 -2
  100. package/dist/components/horoscope-card.d.ts +2 -20
  101. package/dist/components/horoscope-card.d.ts.map +1 -1
  102. package/dist/components/horoscope-card.js +54 -18
  103. package/dist/components/horoscope-card.js.map +3 -3
  104. package/dist/components/kp-planets-table.d.ts +2 -21
  105. package/dist/components/kp-planets-table.d.ts.map +1 -1
  106. package/dist/components/kp-planets-table.js +10 -4
  107. package/dist/components/kp-planets-table.js.map +3 -3
  108. package/dist/components/location-search.d.ts +5 -14
  109. package/dist/components/location-search.d.ts.map +1 -1
  110. package/dist/components/location-search.js +45 -5
  111. package/dist/components/location-search.js.map +2 -2
  112. package/dist/components/moon-phase.d.ts +4 -21
  113. package/dist/components/moon-phase.d.ts.map +1 -1
  114. package/dist/components/moon-phase.js +34 -4
  115. package/dist/components/moon-phase.js.map +3 -3
  116. package/dist/components/natal-chart.d.ts +9 -43
  117. package/dist/components/natal-chart.d.ts.map +1 -1
  118. package/dist/components/natal-chart.js +346 -79
  119. package/dist/components/natal-chart.js.map +3 -3
  120. package/dist/components/numerology-card.d.ts +5 -37
  121. package/dist/components/numerology-card.d.ts.map +1 -1
  122. package/dist/components/numerology-card.js +58 -30
  123. package/dist/components/numerology-card.js.map +3 -3
  124. package/dist/components/panchang-table.d.ts +3 -62
  125. package/dist/components/panchang-table.d.ts.map +1 -1
  126. package/dist/components/panchang-table.js +62 -32
  127. package/dist/components/panchang-table.js.map +3 -3
  128. package/dist/components/shadbala-table.d.ts +18 -0
  129. package/dist/components/shadbala-table.d.ts.map +1 -0
  130. package/dist/components/shadbala-table.js +400 -0
  131. package/dist/components/shadbala-table.js.map +7 -0
  132. package/dist/components/synastry-chart.d.ts +9 -28
  133. package/dist/components/synastry-chart.d.ts.map +1 -1
  134. package/dist/components/synastry-chart.js +201 -56
  135. package/dist/components/synastry-chart.js.map +3 -3
  136. package/dist/components/tarot-card.d.ts +5 -29
  137. package/dist/components/tarot-card.d.ts.map +1 -1
  138. package/dist/components/tarot-card.js +59 -20
  139. package/dist/components/tarot-card.js.map +2 -2
  140. package/dist/components/tarot-spread.d.ts +2 -24
  141. package/dist/components/tarot-spread.d.ts.map +1 -1
  142. package/dist/components/tarot-spread.js +39 -13
  143. package/dist/components/tarot-spread.js.map +2 -2
  144. package/dist/components/transits-table.d.ts +21 -0
  145. package/dist/components/transits-table.d.ts.map +1 -0
  146. package/dist/components/transits-table.js +515 -0
  147. package/dist/components/transits-table.js.map +7 -0
  148. package/dist/components/vedic-kundli.d.ts +5 -28
  149. package/dist/components/vedic-kundli.d.ts.map +1 -1
  150. package/dist/components/vedic-kundli.js +147 -83
  151. package/dist/components/vedic-kundli.js.map +3 -3
  152. package/dist/components/yoga-list.d.ts +29 -0
  153. package/dist/components/yoga-list.d.ts.map +1 -0
  154. package/dist/components/yoga-list.js +389 -0
  155. package/dist/components/yoga-list.js.map +7 -0
  156. package/dist/index.cjs +3693 -1180
  157. package/dist/index.cjs.map +4 -4
  158. package/dist/index.d.ts +11 -4
  159. package/dist/index.d.ts.map +1 -1
  160. package/dist/index.js +3709 -1196
  161. package/dist/index.js.map +4 -4
  162. package/dist/manifest.d.ts +43 -0
  163. package/dist/manifest.d.ts.map +1 -0
  164. package/dist/manifest.json +7 -2
  165. package/dist/styles/tokens.css +73 -1
  166. package/dist/tokens/index.d.ts +6 -0
  167. package/dist/tokens/index.d.ts.map +1 -1
  168. package/dist/types/index.d.ts +2 -0
  169. package/dist/types/index.d.ts.map +1 -0
  170. package/dist/types/types.gen.d.ts +27811 -0
  171. package/dist/types/types.gen.d.ts.map +1 -0
  172. package/dist/utils/debounce.d.ts +9 -1
  173. package/dist/utils/debounce.d.ts.map +1 -1
  174. package/dist/utils/format.d.ts +29 -0
  175. package/dist/utils/format.d.ts.map +1 -0
  176. package/dist/utils/kundli-render.d.ts +63 -0
  177. package/dist/utils/kundli-render.d.ts.map +1 -0
  178. package/dist/utils/string.d.ts +14 -0
  179. package/dist/utils/string.d.ts.map +1 -0
  180. package/dist/version.d.ts +2 -0
  181. package/dist/version.d.ts.map +1 -0
  182. package/package.json +7 -1
  183. package/src/components/ashtakavarga-grid.ts +354 -0
  184. package/src/components/biorhythm-chart.ts +39 -84
  185. package/src/components/choghadiya-grid.ts +185 -0
  186. package/src/components/compatibility-card.ts +85 -52
  187. package/src/components/dasha-timeline.ts +55 -73
  188. package/src/components/data.ts +28 -16
  189. package/src/components/divisional-chart.ts +214 -0
  190. package/src/components/dosha-card.ts +72 -68
  191. package/src/components/endpoint-form.ts +80 -18
  192. package/src/components/guna-milan.ts +87 -47
  193. package/src/components/hexagram.ts +53 -43
  194. package/src/components/horoscope-card.ts +59 -43
  195. package/src/components/kp-planets-table.ts +8 -27
  196. package/src/components/location-search.ts +47 -23
  197. package/src/components/moon-phase.ts +28 -25
  198. package/src/components/natal-chart.ts +364 -110
  199. package/src/components/numerology-card.ts +86 -84
  200. package/src/components/panchang-table.ts +40 -78
  201. package/src/components/shadbala-table.ts +286 -0
  202. package/src/components/synastry-chart.ts +213 -97
  203. package/src/components/tarot-card.ts +76 -62
  204. package/src/components/tarot-spread.ts +72 -45
  205. package/src/components/transits-table.ts +350 -0
  206. package/src/components/vedic-kundli.ts +59 -173
  207. package/src/components/yoga-list.ts +328 -0
  208. package/src/index.ts +18 -26
  209. package/src/manifest.ts +340 -0
  210. package/src/styles/tokens.css +73 -1
  211. package/src/tokens/index.ts +14 -0
  212. package/src/types/types.gen.ts +3 -3
  213. package/src/utils/debounce.ts +23 -4
  214. package/src/utils/format.ts +75 -0
  215. package/src/utils/kundli-render.ts +197 -0
  216. package/src/utils/string.ts +23 -0
  217. package/src/version.ts +2 -0
  218. package/dist/utils/motion.d.ts +0 -13
  219. package/dist/utils/motion.d.ts.map +0 -1
  220. package/src/utils/motion.ts +0 -18
@@ -1,6 +1,6 @@
1
- "use strict";var RoxyUI=(()=>{var de=Object.defineProperty;var He=Object.getOwnPropertyDescriptor;var gr=Object.getOwnPropertyNames;var ur=Object.prototype.hasOwnProperty;var hr=(o,t)=>{for(var e in t)de(o,e,{get:t[e],enumerable:!0})},yr=(o,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of gr(t))!ur.call(o,a)&&a!==e&&de(o,a,{get:()=>t[a],enumerable:!(r=He(t,a))||r.enumerable});return o};var xr=o=>yr(de({},"__esModule",{value:!0}),o),d=(o,t,e,r)=>{for(var a=r>1?void 0:r?He(t,e):t,i=o.length-1,n;i>=0;i--)(n=o[i])&&(a=(r?n(t,e,a):n(a))||a);return r&&a&&de(t,e,a),a};var Xr={};hr(Xr,{ROXY_UI_COMPONENTS:()=>Zr,ROXY_UI_VERSION:()=>Wr,RoxyBiorhythmChart:()=>T,RoxyCompatibilityCard:()=>M,RoxyDashaTimeline:()=>L,RoxyData:()=>K,RoxyDoshaCard:()=>N,RoxyEndpointForm:()=>A,RoxyGunaMilan:()=>G,RoxyHexagram:()=>C,RoxyHoroscopeCard:()=>D,RoxyKpPlanetsTable:()=>Y,RoxyLocationSearch:()=>k,RoxyMoonPhase:()=>O,RoxyNatalChart:()=>H,RoxyNumerologyCard:()=>j,RoxyPanchangTable:()=>U,RoxySynastryChart:()=>F,RoxyTarotCard:()=>R,RoxyTarotSpread:()=>I,RoxyVedicKundli:()=>q});var me=globalThis,pe=me.ShadowRoot&&(me.ShadyCSS===void 0||me.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,$e=Symbol(),je=new WeakMap,te=class{constructor(t,e,r){if(this._$cssResult$=!0,r!==$e)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o,e=this.t;if(pe&&t===void 0){let r=e!==void 0&&e.length===1;r&&(t=je.get(e)),t===void 0&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),r&&je.set(e,t))}return t}toString(){return this.cssText}},Ue=o=>new te(typeof o=="string"?o:o+"",void 0,$e),y=(o,...t)=>{let e=o.length===1?o[0]:t.reduce((r,a,i)=>r+(n=>{if(n._$cssResult$===!0)return n.cssText;if(typeof n=="number")return n;throw Error("Value passed to 'css' function must be a 'css' function result: "+n+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(a)+o[i+1],o[0]);return new te(e,o,$e)},Re=(o,t)=>{if(pe)o.adoptedStyleSheets=t.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let e of t){let r=document.createElement("style"),a=me.litNonce;a!==void 0&&r.setAttribute("nonce",a),r.textContent=e.cssText,o.appendChild(r)}},we=pe?o=>o:o=>o instanceof CSSStyleSheet?(t=>{let e="";for(let r of t.cssRules)e+=r.cssText;return Ue(e)})(o):o;var{is:fr,defineProperty:vr,getOwnPropertyDescriptor:br,getOwnPropertyNames:$r,getOwnPropertySymbols:wr,getPrototypeOf:kr}=Object,ge=globalThis,Ie=ge.trustedTypes,Sr=Ie?Ie.emptyScript:"",Ar=ge.reactiveElementPolyfillSupport,ae=(o,t)=>o,se={toAttribute(o,t){switch(t){case Boolean:o=o?Sr:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o)}return o},fromAttribute(o,t){let e=o;switch(t){case Boolean:e=o!==null;break;case Number:e=o===null?null:Number(o);break;case Object:case Array:try{e=JSON.parse(o)}catch{e=null}}return e}},ue=(o,t)=>!fr(o,t),qe={attribute:!0,type:String,converter:se,reflect:!1,useDefault:!1,hasChanged:ue};Symbol.metadata??=Symbol("metadata"),ge.litPropertyMetadata??=new WeakMap;var z=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=qe){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){let r=Symbol(),a=this.getPropertyDescriptor(t,r,e);a!==void 0&&vr(this.prototype,t,a)}}static getPropertyDescriptor(t,e,r){let{get:a,set:i}=br(this.prototype,t)??{get(){return this[e]},set(n){this[e]=n}};return{get:a,set(n){let c=a?.call(this);i?.call(this,n),this.requestUpdate(t,c,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??qe}static _$Ei(){if(this.hasOwnProperty(ae("elementProperties")))return;let t=kr(this);t.finalize(),t.l!==void 0&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(ae("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(ae("properties"))){let e=this.properties,r=[...$r(e),...wr(e)];for(let a of r)this.createProperty(a,e[a])}let t=this[Symbol.metadata];if(t!==null){let e=litPropertyMetadata.get(t);if(e!==void 0)for(let[r,a]of e)this.elementProperties.set(r,a)}this._$Eh=new Map;for(let[e,r]of this.elementProperties){let a=this._$Eu(e,r);a!==void 0&&this._$Eh.set(a,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){let e=[];if(Array.isArray(t)){let r=new Set(t.flat(1/0).reverse());for(let a of r)e.unshift(we(a))}else t!==void 0&&e.push(we(t));return e}static _$Eu(t,e){let r=e.attribute;return r===!1?void 0:typeof r=="string"?r:typeof t=="string"?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),this.renderRoot!==void 0&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){let t=new Map,e=this.constructor.elementProperties;for(let r of e.keys())this.hasOwnProperty(r)&&(t.set(r,this[r]),delete this[r]);t.size>0&&(this._$Ep=t)}createRenderRoot(){let t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return Re(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,r){this._$AK(t,r)}_$ET(t,e){let r=this.constructor.elementProperties.get(t),a=this.constructor._$Eu(t,r);if(a!==void 0&&r.reflect===!0){let i=(r.converter?.toAttribute!==void 0?r.converter:se).toAttribute(e,r.type);this._$Em=t,i==null?this.removeAttribute(a):this.setAttribute(a,i),this._$Em=null}}_$AK(t,e){let r=this.constructor,a=r._$Eh.get(t);if(a!==void 0&&this._$Em!==a){let i=r.getPropertyOptions(a),n=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:se;this._$Em=a;let c=n.fromAttribute(e,i.type);this[a]=c??this._$Ej?.get(a)??c,this._$Em=null}}requestUpdate(t,e,r,a=!1,i){if(t!==void 0){let n=this.constructor;if(a===!1&&(i=this[t]),r??=n.getPropertyOptions(t),!((r.hasChanged??ue)(i,e)||r.useDefault&&r.reflect&&i===this._$Ej?.get(t)&&!this.hasAttribute(n._$Eu(t,r))))return;this.C(t,e,r)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(t,e,{useDefault:r,reflect:a,wrapped:i},n){r&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,n??e??this[t]),i!==!0||n!==void 0)||(this._$AL.has(t)||(this.hasUpdated||r||(e=void 0),this._$AL.set(t,e)),a===!0&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let t=this.scheduleUpdate();return t!=null&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[a,i]of this._$Ep)this[a]=i;this._$Ep=void 0}let r=this.constructor.elementProperties;if(r.size>0)for(let[a,i]of r){let{wrapped:n}=i,c=this[a];n!==!0||this._$AL.has(a)||c===void 0||this.C(a,void 0,i,c)}}let t=!1,e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(r=>r.hostUpdate?.()),this.update(e)):this._$EM()}catch(r){throw t=!1,this._$EM(),r}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(t){}firstUpdated(t){}};z.elementStyles=[],z.shadowRootOptions={mode:"open"},z[ae("elementProperties")]=new Map,z[ae("finalized")]=new Map,Ar?.({ReactiveElement:z}),(ge.reactiveElementVersions??=[]).push("2.1.2");var ze=globalThis,Be=o=>o,he=ze.trustedTypes,Ke=he?he.createPolicy("lit-html",{createHTML:o=>o}):void 0,We="$lit$",B=`lit$${Math.random().toFixed(9).slice(2)}$`,Ze="?"+B,Er=`<${Ze}>`,W=document,ne=()=>W.createComment(""),oe=o=>o===null||typeof o!="object"&&typeof o!="function",Te=Array.isArray,_r=o=>Te(o)||typeof o?.[Symbol.iterator]=="function",ke=`[
2
- \f\r]`,ie=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Ge=/-->/g,Ye=/>/g,V=RegExp(`>|${ke}(?:([^\\s"'>=/]+)(${ke}*=${ke}*(?:[^
3
- \f\r"'\`<>=]|("|')|))|$)`,"g"),Fe=/'/g,Ve=/"/g,Xe=/^(?:script|style|textarea|title)$/i,Me=o=>(t,...e)=>({_$litType$:o,strings:t,values:e}),s=Me(1),$=Me(2),st=Me(3),Z=Symbol.for("lit-noChange"),l=Symbol.for("lit-nothing"),Je=new WeakMap,J=W.createTreeWalker(W,129);function Qe(o,t){if(!Te(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return Ke!==void 0?Ke.createHTML(t):t}var Pr=(o,t)=>{let e=o.length-1,r=[],a,i=t===2?"<svg>":t===3?"<math>":"",n=ie;for(let c=0;c<e;c++){let m=o[c],u,h,v=-1,S=0;for(;S<m.length&&(n.lastIndex=S,h=n.exec(m),h!==null);)S=n.lastIndex,n===ie?h[1]==="!--"?n=Ge:h[1]!==void 0?n=Ye:h[2]!==void 0?(Xe.test(h[2])&&(a=RegExp("</"+h[2],"g")),n=V):h[3]!==void 0&&(n=V):n===V?h[0]===">"?(n=a??ie,v=-1):h[1]===void 0?v=-2:(v=n.lastIndex-h[2].length,u=h[1],n=h[3]===void 0?V:h[3]==='"'?Ve:Fe):n===Ve||n===Fe?n=V:n===Ge||n===Ye?n=ie:(n=V,a=void 0);let w=n===V&&o[c+1].startsWith("/>")?" ":"";i+=n===ie?m+Er:v>=0?(r.push(u),m.slice(0,v)+We+m.slice(v)+B+w):m+B+(v===-2?c:w)}return[Qe(o,i+(o[e]||"<?>")+(t===2?"</svg>":t===3?"</math>":"")),r]},le=class o{constructor({strings:t,_$litType$:e},r){let a;this.parts=[];let i=0,n=0,c=t.length-1,m=this.parts,[u,h]=Pr(t,e);if(this.el=o.createElement(u,r),J.currentNode=this.el.content,e===2||e===3){let v=this.el.content.firstChild;v.replaceWith(...v.childNodes)}for(;(a=J.nextNode())!==null&&m.length<c;){if(a.nodeType===1){if(a.hasAttributes())for(let v of a.getAttributeNames())if(v.endsWith(We)){let S=h[n++],w=a.getAttribute(v).split(B),X=/([.?@])?(.*)/.exec(S);m.push({type:1,index:i,name:X[2],strings:w,ctor:X[1]==="."?Ae:X[1]==="?"?Ee:X[1]==="@"?_e:ee}),a.removeAttribute(v)}else v.startsWith(B)&&(m.push({type:6,index:i}),a.removeAttribute(v));if(Xe.test(a.tagName)){let v=a.textContent.split(B),S=v.length-1;if(S>0){a.textContent=he?he.emptyScript:"";for(let w=0;w<S;w++)a.append(v[w],ne()),J.nextNode(),m.push({type:2,index:++i});a.append(v[S],ne())}}}else if(a.nodeType===8)if(a.data===Ze)m.push({type:2,index:i});else{let v=-1;for(;(v=a.data.indexOf(B,v+1))!==-1;)m.push({type:7,index:i}),v+=B.length-1}i++}}static createElement(t,e){let r=W.createElement("template");return r.innerHTML=t,r}};function Q(o,t,e=o,r){if(t===Z)return t;let a=r!==void 0?e._$Co?.[r]:e._$Cl,i=oe(t)?void 0:t._$litDirective$;return a?.constructor!==i&&(a?._$AO?.(!1),i===void 0?a=void 0:(a=new i(o),a._$AT(o,e,r)),r!==void 0?(e._$Co??=[])[r]=a:e._$Cl=a),a!==void 0&&(t=Q(o,a._$AS(o,t.values),a,r)),t}var Se=class{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){let{el:{content:e},parts:r}=this._$AD,a=(t?.creationScope??W).importNode(e,!0);J.currentNode=a;let i=J.nextNode(),n=0,c=0,m=r[0];for(;m!==void 0;){if(n===m.index){let u;m.type===2?u=new ce(i,i.nextSibling,this,t):m.type===1?u=new m.ctor(i,m.name,m.strings,this,t):m.type===6&&(u=new Pe(i,this,t)),this._$AV.push(u),m=r[++c]}n!==m?.index&&(i=J.nextNode(),n++)}return J.currentNode=W,a}p(t){let e=0;for(let r of this._$AV)r!==void 0&&(r.strings!==void 0?(r._$AI(t,r,e),e+=r.strings.length-2):r._$AI(t[e])),e++}},ce=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,r,a){this.type=2,this._$AH=l,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=r,this.options=a,this._$Cv=a?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode,e=this._$AM;return e!==void 0&&t?.nodeType===11&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=Q(this,t,e),oe(t)?t===l||t==null||t===""?(this._$AH!==l&&this._$AR(),this._$AH=l):t!==this._$AH&&t!==Z&&this._(t):t._$litType$!==void 0?this.$(t):t.nodeType!==void 0?this.T(t):_r(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==l&&oe(this._$AH)?this._$AA.nextSibling.data=t:this.T(W.createTextNode(t)),this._$AH=t}$(t){let{values:e,_$litType$:r}=t,a=typeof r=="number"?this._$AC(t):(r.el===void 0&&(r.el=le.createElement(Qe(r.h,r.h[0]),this.options)),r);if(this._$AH?._$AD===a)this._$AH.p(e);else{let i=new Se(a,this),n=i.u(this.options);i.p(e),this.T(n),this._$AH=i}}_$AC(t){let e=Je.get(t.strings);return e===void 0&&Je.set(t.strings,e=new le(t)),e}k(t){Te(this._$AH)||(this._$AH=[],this._$AR());let e=this._$AH,r,a=0;for(let i of t)a===e.length?e.push(r=new o(this.O(ne()),this.O(ne()),this,this.options)):r=e[a],r._$AI(i),a++;a<e.length&&(this._$AR(r&&r._$AB.nextSibling,a),e.length=a)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t!==this._$AB;){let r=Be(t).nextSibling;Be(t).remove(),t=r}}setConnected(t){this._$AM===void 0&&(this._$Cv=t,this._$AP?.(t))}},ee=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,r,a,i){this.type=1,this._$AH=l,this._$AN=void 0,this.element=t,this.name=e,this._$AM=a,this.options=i,r.length>2||r[0]!==""||r[1]!==""?(this._$AH=Array(r.length-1).fill(new String),this.strings=r):this._$AH=l}_$AI(t,e=this,r,a){let i=this.strings,n=!1;if(i===void 0)t=Q(this,t,e,0),n=!oe(t)||t!==this._$AH&&t!==Z,n&&(this._$AH=t);else{let c=t,m,u;for(t=i[0],m=0;m<i.length-1;m++)u=Q(this,c[r+m],e,m),u===Z&&(u=this._$AH[m]),n||=!oe(u)||u!==this._$AH[m],u===l?t=l:t!==l&&(t+=(u??"")+i[m+1]),this._$AH[m]=u}n&&!a&&this.j(t)}j(t){t===l?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}},Ae=class extends ee{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===l?void 0:t}},Ee=class extends ee{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==l)}},_e=class extends ee{constructor(t,e,r,a,i){super(t,e,r,a,i),this.type=5}_$AI(t,e=this){if((t=Q(this,t,e,0)??l)===Z)return;let r=this._$AH,a=t===l&&r!==l||t.capture!==r.capture||t.once!==r.once||t.passive!==r.passive,i=t!==l&&(r===l||a);a&&this.element.removeEventListener(this.name,this,r),i&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}},Pe=class{constructor(t,e,r){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=r}get _$AU(){return this._$AM._$AU}_$AI(t){Q(this,t)}};var zr=ze.litHtmlPolyfillSupport;zr?.(le,ce),(ze.litHtmlVersions??=[]).push("3.3.2");var er=(o,t,e)=>{let r=e?.renderBefore??t,a=r._$litPart$;if(a===void 0){let i=e?.renderBefore??null;r._$litPart$=a=new ce(t.insertBefore(ne(),i),i,void 0,e??{})}return a._$AI(o),a};var Le=globalThis,g=class extends z{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=er(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return Z}};g._$litElement$=!0,g.finalized=!0,Le.litElementHydrateSupport?.({LitElement:g});var Tr=Le.litElementPolyfillSupport;Tr?.({LitElement:g});(Le.litElementVersions??=[]).push("4.2.2");var x=o=>(t,e)=>{e!==void 0?e.addInitializer(()=>{customElements.define(o,t)}):customElements.define(o,t)};var Mr={attribute:!0,type:String,converter:se,reflect:!1,hasChanged:ue},Lr=(o=Mr,t,e)=>{let{kind:r,metadata:a}=e,i=globalThis.litPropertyMetadata.get(a);if(i===void 0&&globalThis.litPropertyMetadata.set(a,i=new Map),r==="setter"&&((o=Object.create(o)).wrapped=!0),i.set(e.name,o),r==="accessor"){let{name:n}=e;return{set(c){let m=t.get.call(this);t.set.call(this,c),this.requestUpdate(n,m,o,!0,c)},init(c){return c!==void 0&&this.C(n,void 0,o,c),c}}}if(r==="setter"){let{name:n}=e;return function(c){let m=this[n];t.call(this,c),this.requestUpdate(n,m,o,!0,c)}}throw Error("Unsupported decorator location: "+r)};function p(o){return(t,e)=>typeof e=="object"?Lr(o,t,e):((r,a,i)=>{let n=a.hasOwnProperty(i);return a.constructor.createProperty(i,r),n?Object.getOwnPropertyDescriptor(a,i):void 0})(o,t,e)}function _(o){return p({...o,state:!0,attribute:!1})}var f=y`
1
+ "use strict";var RoxyUI=(()=>{var Ae=Object.defineProperty;var mt=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var jt=Object.prototype.hasOwnProperty;var It=(i,r)=>{for(var e in r)Ae(i,e,{get:r[e],enumerable:!0})},Bt=(i,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of Gt(r))!jt.call(i,s)&&s!==e&&Ae(i,s,{get:()=>r[s],enumerable:!(t=mt(r,s))||t.enumerable});return i};var qt=i=>Bt(Ae({},"__esModule",{value:!0}),i),c=(i,r,e,t)=>{for(var s=t>1?void 0:t?mt(r,e):r,o=i.length-1,l;o>=0;o--)(l=i[o])&&(s=(t?l(r,e,s):l(s))||s);return t&&s&&Ae(r,e,s),s};var Cr={};It(Cr,{ROXY_COMPONENTS:()=>Be,ROXY_UI_COMPONENTS:()=>Ar,ROXY_UI_VERSION:()=>Ht,RoxyAshtakavargaGrid:()=>M,RoxyBiorhythmChart:()=>D,RoxyChoghadiyaGrid:()=>te,RoxyCompatibilityCard:()=>H,RoxyDashaTimeline:()=>G,RoxyData:()=>j,RoxyDivisionalChart:()=>I,RoxyDoshaCard:()=>B,RoxyEndpointForm:()=>_,RoxyGunaMilan:()=>re,RoxyHexagram:()=>q,RoxyHoroscopeCard:()=>U,RoxyKpPlanetsTable:()=>ae,RoxyLocationSearch:()=>T,RoxyMoonPhase:()=>Y,RoxyNatalChart:()=>K,RoxyNumerologyCard:()=>V,RoxyPanchangTable:()=>F,RoxyShadbalaTable:()=>se,RoxySynastryChart:()=>oe,RoxyTarotCard:()=>W,RoxyTarotSpread:()=>J,RoxyTransitsTable:()=>ie,RoxyVedicKundli:()=>X,RoxyYogaList:()=>Z});var Ce=globalThis,Ee=Ce.ShadowRoot&&(Ce.ShadyCSS===void 0||Ce.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,qe=Symbol(),ht=new WeakMap,ye=class{constructor(r,e,t){if(this._$cssResult$=!0,t!==qe)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=r,this.t=e}get styleSheet(){let r=this.o,e=this.t;if(Ee&&r===void 0){let t=e!==void 0&&e.length===1;t&&(r=ht.get(e)),r===void 0&&((this.o=r=new CSSStyleSheet).replaceSync(this.cssText),t&&ht.set(e,r))}return r}toString(){return this.cssText}},gt=i=>new ye(typeof i=="string"?i:i+"",void 0,qe),x=(i,...r)=>{let e=i.length===1?i[0]:r.reduce((t,s,o)=>t+(l=>{if(l._$cssResult$===!0)return l.cssText;if(typeof l=="number")return l;throw Error("Value passed to 'css' function must be a 'css' function result: "+l+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+i[o+1],i[0]);return new ye(e,i,qe)},yt=(i,r)=>{if(Ee)i.adoptedStyleSheets=r.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let e of r){let t=document.createElement("style"),s=Ce.litNonce;s!==void 0&&t.setAttribute("nonce",s),t.textContent=e.cssText,i.appendChild(t)}},Ue=Ee?i=>i:i=>i instanceof CSSStyleSheet?(r=>{let e="";for(let t of r.cssRules)e+=t.cssText;return gt(e)})(i):i;var{is:Ut,defineProperty:Yt,getOwnPropertyDescriptor:Kt,getOwnPropertyNames:Vt,getOwnPropertySymbols:Ft,getPrototypeOf:Wt}=Object,Re=globalThis,ut=Re.trustedTypes,Jt=ut?ut.emptyScript:"",Xt=Re.reactiveElementPolyfillSupport,ue=(i,r)=>i,xe={toAttribute(i,r){switch(r){case Boolean:i=i?Jt:null;break;case Object:case Array:i=i==null?i:JSON.stringify(i)}return i},fromAttribute(i,r){let e=i;switch(r){case Boolean:e=i!==null;break;case Number:e=i===null?null:Number(i);break;case Object:case Array:try{e=JSON.parse(i)}catch{e=null}}return e}},Pe=(i,r)=>!Ut(i,r),xt={attribute:!0,type:String,converter:xe,reflect:!1,useDefault:!1,hasChanged:Pe};Symbol.metadata??=Symbol("metadata"),Re.litPropertyMetadata??=new WeakMap;var z=class extends HTMLElement{static addInitializer(r){this._$Ei(),(this.l??=[]).push(r)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(r,e=xt){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(r)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(r,e),!e.noAccessor){let t=Symbol(),s=this.getPropertyDescriptor(r,t,e);s!==void 0&&Yt(this.prototype,r,s)}}static getPropertyDescriptor(r,e,t){let{get:s,set:o}=Kt(this.prototype,r)??{get(){return this[e]},set(l){this[e]=l}};return{get:s,set(l){let d=s?.call(this);o?.call(this,l),this.requestUpdate(r,d,t)},configurable:!0,enumerable:!0}}static getPropertyOptions(r){return this.elementProperties.get(r)??xt}static _$Ei(){if(this.hasOwnProperty(ue("elementProperties")))return;let r=Wt(this);r.finalize(),r.l!==void 0&&(this.l=[...r.l]),this.elementProperties=new Map(r.elementProperties)}static finalize(){if(this.hasOwnProperty(ue("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(ue("properties"))){let e=this.properties,t=[...Vt(e),...Ft(e)];for(let s of t)this.createProperty(s,e[s])}let r=this[Symbol.metadata];if(r!==null){let e=litPropertyMetadata.get(r);if(e!==void 0)for(let[t,s]of e)this.elementProperties.set(t,s)}this._$Eh=new Map;for(let[e,t]of this.elementProperties){let s=this._$Eu(e,t);s!==void 0&&this._$Eh.set(s,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(r){let e=[];if(Array.isArray(r)){let t=new Set(r.flat(1/0).reverse());for(let s of t)e.unshift(Ue(s))}else r!==void 0&&e.push(Ue(r));return e}static _$Eu(r,e){let t=e.attribute;return t===!1?void 0:typeof t=="string"?t:typeof r=="string"?r.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(r=>this.enableUpdating=r),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(r=>r(this))}addController(r){(this._$EO??=new Set).add(r),this.renderRoot!==void 0&&this.isConnected&&r.hostConnected?.()}removeController(r){this._$EO?.delete(r)}_$E_(){let r=new Map,e=this.constructor.elementProperties;for(let t of e.keys())this.hasOwnProperty(t)&&(r.set(t,this[t]),delete this[t]);r.size>0&&(this._$Ep=r)}createRenderRoot(){let r=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return yt(r,this.constructor.elementStyles),r}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(r=>r.hostConnected?.())}enableUpdating(r){}disconnectedCallback(){this._$EO?.forEach(r=>r.hostDisconnected?.())}attributeChangedCallback(r,e,t){this._$AK(r,t)}_$ET(r,e){let t=this.constructor.elementProperties.get(r),s=this.constructor._$Eu(r,t);if(s!==void 0&&t.reflect===!0){let o=(t.converter?.toAttribute!==void 0?t.converter:xe).toAttribute(e,t.type);this._$Em=r,o==null?this.removeAttribute(s):this.setAttribute(s,o),this._$Em=null}}_$AK(r,e){let t=this.constructor,s=t._$Eh.get(r);if(s!==void 0&&this._$Em!==s){let o=t.getPropertyOptions(s),l=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:xe;this._$Em=s;let d=l.fromAttribute(e,o.type);this[s]=d??this._$Ej?.get(s)??d,this._$Em=null}}requestUpdate(r,e,t,s=!1,o){if(r!==void 0){let l=this.constructor;if(s===!1&&(o=this[r]),t??=l.getPropertyOptions(r),!((t.hasChanged??Pe)(o,e)||t.useDefault&&t.reflect&&o===this._$Ej?.get(r)&&!this.hasAttribute(l._$Eu(r,t))))return;this.C(r,e,t)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(r,e,{useDefault:t,reflect:s,wrapped:o},l){t&&!(this._$Ej??=new Map).has(r)&&(this._$Ej.set(r,l??e??this[r]),o!==!0||l!==void 0)||(this._$AL.has(r)||(this.hasUpdated||t||(e=void 0),this._$AL.set(r,e)),s===!0&&this._$Em!==r&&(this._$Eq??=new Set).add(r))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let r=this.scheduleUpdate();return r!=null&&await r,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[s,o]of this._$Ep)this[s]=o;this._$Ep=void 0}let t=this.constructor.elementProperties;if(t.size>0)for(let[s,o]of t){let{wrapped:l}=o,d=this[s];l!==!0||this._$AL.has(s)||d===void 0||this.C(s,void 0,o,d)}}let r=!1,e=this._$AL;try{r=this.shouldUpdate(e),r?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(t){throw r=!1,this._$EM(),t}r&&this._$AE(e)}willUpdate(r){}_$AE(r){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(r)),this.updated(r)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(r){return!0}update(r){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(r){}firstUpdated(r){}};z.elementStyles=[],z.shadowRootOptions={mode:"open"},z[ue("elementProperties")]=new Map,z[ue("finalized")]=new Map,Xt?.({ReactiveElement:z}),(Re.reactiveElementVersions??=[]).push("2.1.2");var Xe=globalThis,ft=i=>i,Te=Xe.trustedTypes,vt=Te?Te.createPolicy("lit-html",{createHTML:i=>i}):void 0,At="$lit$",Q=`lit$${Math.random().toFixed(9).slice(2)}$`,Ct="?"+Q,Zt=`<${Ct}>`,de=document,ve=()=>de.createComment(""),be=i=>i===null||typeof i!="object"&&typeof i!="function",Ze=Array.isArray,Qt=i=>Ze(i)||typeof i?.[Symbol.iterator]=="function",Ye=`[
2
+ \f\r]`,fe=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,bt=/-->/g,$t=/>/g,ne=RegExp(`>|${Ye}(?:([^\\s"'>=/]+)(${Ye}*=${Ye}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),wt=/'/g,kt=/"/g,Et=/^(?:script|style|textarea|title)$/i,Qe=i=>(r,...e)=>({_$litType$:i,strings:r,values:e}),a=Qe(1),S=Qe(2),_r=Qe(3),ce=Symbol.for("lit-noChange"),n=Symbol.for("lit-nothing"),St=new WeakMap,le=de.createTreeWalker(de,129);function Rt(i,r){if(!Ze(i)||!i.hasOwnProperty("raw"))throw Error("invalid template strings array");return vt!==void 0?vt.createHTML(r):r}var er=(i,r)=>{let e=i.length-1,t=[],s,o=r===2?"<svg>":r===3?"<math>":"",l=fe;for(let d=0;d<e;d++){let p=i[d],m,h,g=-1,f=0;for(;f<p.length&&(l.lastIndex=f,h=l.exec(p),h!==null);)f=l.lastIndex,l===fe?h[1]==="!--"?l=bt:h[1]!==void 0?l=$t:h[2]!==void 0?(Et.test(h[2])&&(s=RegExp("</"+h[2],"g")),l=ne):h[3]!==void 0&&(l=ne):l===ne?h[0]===">"?(l=s??fe,g=-1):h[1]===void 0?g=-2:(g=l.lastIndex-h[2].length,m=h[1],l=h[3]===void 0?ne:h[3]==='"'?kt:wt):l===kt||l===wt?l=ne:l===bt||l===$t?l=fe:(l=ne,s=void 0);let k=l===ne&&i[d+1].startsWith("/>")?" ":"";o+=l===fe?p+Zt:g>=0?(t.push(m),p.slice(0,g)+At+p.slice(g)+Q+k):p+Q+(g===-2?d:k)}return[Rt(i,o+(i[e]||"<?>")+(r===2?"</svg>":r===3?"</math>":"")),t]},$e=class i{constructor({strings:r,_$litType$:e},t){let s;this.parts=[];let o=0,l=0,d=r.length-1,p=this.parts,[m,h]=er(r,e);if(this.el=i.createElement(m,t),le.currentNode=this.el.content,e===2||e===3){let g=this.el.content.firstChild;g.replaceWith(...g.childNodes)}for(;(s=le.nextNode())!==null&&p.length<d;){if(s.nodeType===1){if(s.hasAttributes())for(let g of s.getAttributeNames())if(g.endsWith(At)){let f=h[l++],k=s.getAttribute(g).split(Q),$=/([.?@])?(.*)/.exec(f);p.push({type:1,index:o,name:$[2],strings:k,ctor:$[1]==="."?Ve:$[1]==="?"?Fe:$[1]==="@"?We:ge}),s.removeAttribute(g)}else g.startsWith(Q)&&(p.push({type:6,index:o}),s.removeAttribute(g));if(Et.test(s.tagName)){let g=s.textContent.split(Q),f=g.length-1;if(f>0){s.textContent=Te?Te.emptyScript:"";for(let k=0;k<f;k++)s.append(g[k],ve()),le.nextNode(),p.push({type:2,index:++o});s.append(g[f],ve())}}}else if(s.nodeType===8)if(s.data===Ct)p.push({type:2,index:o});else{let g=-1;for(;(g=s.data.indexOf(Q,g+1))!==-1;)p.push({type:7,index:o}),g+=Q.length-1}o++}}static createElement(r,e){let t=de.createElement("template");return t.innerHTML=r,t}};function he(i,r,e=i,t){if(r===ce)return r;let s=t!==void 0?e._$Co?.[t]:e._$Cl,o=be(r)?void 0:r._$litDirective$;return s?.constructor!==o&&(s?._$AO?.(!1),o===void 0?s=void 0:(s=new o(i),s._$AT(i,e,t)),t!==void 0?(e._$Co??=[])[t]=s:e._$Cl=s),s!==void 0&&(r=he(i,s._$AS(i,r.values),s,t)),r}var Ke=class{constructor(r,e){this._$AV=[],this._$AN=void 0,this._$AD=r,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(r){let{el:{content:e},parts:t}=this._$AD,s=(r?.creationScope??de).importNode(e,!0);le.currentNode=s;let o=le.nextNode(),l=0,d=0,p=t[0];for(;p!==void 0;){if(l===p.index){let m;p.type===2?m=new we(o,o.nextSibling,this,r):p.type===1?m=new p.ctor(o,p.name,p.strings,this,r):p.type===6&&(m=new Je(o,this,r)),this._$AV.push(m),p=t[++d]}l!==p?.index&&(o=le.nextNode(),l++)}return le.currentNode=de,s}p(r){let e=0;for(let t of this._$AV)t!==void 0&&(t.strings!==void 0?(t._$AI(r,t,e),e+=t.strings.length-2):t._$AI(r[e])),e++}},we=class i{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(r,e,t,s){this.type=2,this._$AH=n,this._$AN=void 0,this._$AA=r,this._$AB=e,this._$AM=t,this.options=s,this._$Cv=s?.isConnected??!0}get parentNode(){let r=this._$AA.parentNode,e=this._$AM;return e!==void 0&&r?.nodeType===11&&(r=e.parentNode),r}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(r,e=this){r=he(this,r,e),be(r)?r===n||r==null||r===""?(this._$AH!==n&&this._$AR(),this._$AH=n):r!==this._$AH&&r!==ce&&this._(r):r._$litType$!==void 0?this.$(r):r.nodeType!==void 0?this.T(r):Qt(r)?this.k(r):this._(r)}O(r){return this._$AA.parentNode.insertBefore(r,this._$AB)}T(r){this._$AH!==r&&(this._$AR(),this._$AH=this.O(r))}_(r){this._$AH!==n&&be(this._$AH)?this._$AA.nextSibling.data=r:this.T(de.createTextNode(r)),this._$AH=r}$(r){let{values:e,_$litType$:t}=r,s=typeof t=="number"?this._$AC(r):(t.el===void 0&&(t.el=$e.createElement(Rt(t.h,t.h[0]),this.options)),t);if(this._$AH?._$AD===s)this._$AH.p(e);else{let o=new Ke(s,this),l=o.u(this.options);o.p(e),this.T(l),this._$AH=o}}_$AC(r){let e=St.get(r.strings);return e===void 0&&St.set(r.strings,e=new $e(r)),e}k(r){Ze(this._$AH)||(this._$AH=[],this._$AR());let e=this._$AH,t,s=0;for(let o of r)s===e.length?e.push(t=new i(this.O(ve()),this.O(ve()),this,this.options)):t=e[s],t._$AI(o),s++;s<e.length&&(this._$AR(t&&t._$AB.nextSibling,s),e.length=s)}_$AR(r=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);r!==this._$AB;){let t=ft(r).nextSibling;ft(r).remove(),r=t}}setConnected(r){this._$AM===void 0&&(this._$Cv=r,this._$AP?.(r))}},ge=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(r,e,t,s,o){this.type=1,this._$AH=n,this._$AN=void 0,this.element=r,this.name=e,this._$AM=s,this.options=o,t.length>2||t[0]!==""||t[1]!==""?(this._$AH=Array(t.length-1).fill(new String),this.strings=t):this._$AH=n}_$AI(r,e=this,t,s){let o=this.strings,l=!1;if(o===void 0)r=he(this,r,e,0),l=!be(r)||r!==this._$AH&&r!==ce,l&&(this._$AH=r);else{let d=r,p,m;for(r=o[0],p=0;p<o.length-1;p++)m=he(this,d[t+p],e,p),m===ce&&(m=this._$AH[p]),l||=!be(m)||m!==this._$AH[p],m===n?r=n:r!==n&&(r+=(m??"")+o[p+1]),this._$AH[p]=m}l&&!s&&this.j(r)}j(r){r===n?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,r??"")}},Ve=class extends ge{constructor(){super(...arguments),this.type=3}j(r){this.element[this.name]=r===n?void 0:r}},Fe=class extends ge{constructor(){super(...arguments),this.type=4}j(r){this.element.toggleAttribute(this.name,!!r&&r!==n)}},We=class extends ge{constructor(r,e,t,s,o){super(r,e,t,s,o),this.type=5}_$AI(r,e=this){if((r=he(this,r,e,0)??n)===ce)return;let t=this._$AH,s=r===n&&t!==n||r.capture!==t.capture||r.once!==t.once||r.passive!==t.passive,o=r!==n&&(t===n||s);s&&this.element.removeEventListener(this.name,this,t),o&&this.element.addEventListener(this.name,this,r),this._$AH=r}handleEvent(r){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,r):this._$AH.handleEvent(r)}},Je=class{constructor(r,e,t){this.element=r,this.type=6,this._$AN=void 0,this._$AM=e,this.options=t}get _$AU(){return this._$AM._$AU}_$AI(r){he(this,r)}};var tr=Xe.litHtmlPolyfillSupport;tr?.($e,we),(Xe.litHtmlVersions??=[]).push("3.3.2");var Pt=(i,r,e)=>{let t=e?.renderBefore??r,s=t._$litPart$;if(s===void 0){let o=e?.renderBefore??null;t._$litPart$=s=new we(r.insertBefore(ve(),o),o,void 0,e??{})}return s._$AI(i),s};var et=globalThis,u=class extends z{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let r=super.createRenderRoot();return this.renderOptions.renderBefore??=r.firstChild,r}update(r){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(r),this._$Do=Pt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return ce}};u._$litElement$=!0,u.finalized=!0,et.litElementHydrateSupport?.({LitElement:u});var rr=et.litElementPolyfillSupport;rr?.({LitElement:u});(et.litElementVersions??=[]).push("4.2.2");var v=i=>(r,e)=>{e!==void 0?e.addInitializer(()=>{customElements.define(i,r)}):customElements.define(i,r)};var ar={attribute:!0,type:String,converter:xe,reflect:!1,hasChanged:Pe},sr=(i=ar,r,e)=>{let{kind:t,metadata:s}=e,o=globalThis.litPropertyMetadata.get(s);if(o===void 0&&globalThis.litPropertyMetadata.set(s,o=new Map),t==="setter"&&((i=Object.create(i)).wrapped=!0),o.set(e.name,i),t==="accessor"){let{name:l}=e;return{set(d){let p=r.get.call(this);r.set.call(this,d),this.requestUpdate(l,p,i,!0,d)},init(d){return d!==void 0&&this.C(l,void 0,i,d),d}}}if(t==="setter"){let{name:l}=e;return function(d){let p=this[l];r.call(this,d),this.requestUpdate(l,p,i,!0,d)}}throw Error("Unsupported decorator location: "+t)};function y(i){return(r,e)=>typeof e=="object"?sr(i,r,e):((t,s,o)=>{let l=s.hasOwnProperty(o);return s.constructor.createProperty(o,t),l?Object.getOwnPropertyDescriptor(s,o):void 0})(i,r,e)}function E(i){return y({...i,state:!0,attribute:!1})}var L={Sun:"\u2609",Moon:"\u263D",Mercury:"\u263F",Venus:"\u2640",Earth:"\u2641",Mars:"\u2642",Jupiter:"\u2643",Saturn:"\u2644",Uranus:"\u2645",Neptune:"\u2646",Pluto:"\u2647",Rahu:"\u260A",Ketu:"\u260B",Ascendant:"Asc",Lagna:"La",NorthNode:"\u260A",SouthNode:"\u260B","North node":"\u260A","South node":"\u260B",Chiron:"\u26B7",Lilith:"\u26B8","Black moon lilith":"\u26B8"},tt={Sun:"Su",Moon:"Mo",Mercury:"Me",Venus:"Ve",Mars:"Ma",Jupiter:"Ju",Saturn:"Sa",Uranus:"Ur",Neptune:"Ne",Pluto:"Pl",Rahu:"Ra",Ketu:"Ke",Ascendant:"Asc",Lagna:"La"},N={Aries:"\u2648",Taurus:"\u2649",Gemini:"\u264A",Cancer:"\u264B",Leo:"\u264C",Virgo:"\u264D",Libra:"\u264E",Scorpio:"\u264F",Sagittarius:"\u2650",Capricorn:"\u2651",Aquarius:"\u2652",Pisces:"\u2653"},rt={Aries:"Ar",Taurus:"Ta",Gemini:"Ge",Cancer:"Cn",Leo:"Le",Virgo:"Vi",Libra:"Li",Scorpio:"Sc",Sagittarius:"Sg",Capricorn:"Cp",Aquarius:"Aq",Pisces:"Pi"},pe=["Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius","Pisces"],_e=pe.map(i=>i.toLowerCase());var at={heaven:"\u2630",lake:"\u2631",fire:"\u2632",thunder:"\u2633",wind:"\u2634",water:"\u2635",mountain:"\u2636",earth:"\u2637",Heaven:"\u2630",Lake:"\u2631",Fire:"\u2632",Thunder:"\u2633",Wind:"\u2634",Water:"\u2635",Mountain:"\u2636",Earth:"\u2637"},Tt={"new moon":"\u{1F311}","waxing crescent":"\u{1F312}","first quarter":"\u{1F313}","waxing gibbous":"\u{1F314}","full moon":"\u{1F315}","waning gibbous":"\u{1F316}","last quarter":"\u{1F317}","waning crescent":"\u{1F318}"};var b=x`
4
4
  :host {
5
5
  display: block;
6
6
  container-type: inline-size;
@@ -82,65 +82,280 @@
82
82
  outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
83
83
  outline-offset: 2px;
84
84
  }
85
- `;var rr={physical:"#dc2626",emotional:"#0284c7",intellectual:"#16a34a",intuitive:"#a855f7",aesthetic:"#f59e0b",awareness:"#ec4899",spiritual:"#14b8a6",passion:"#ef4444",mastery:"#6366f1",wisdom:"#475569"},T=class extends g{constructor(){super(...arguments);this.data=null;this.mode="daily"}render(){let e=this.data;return e?this.mode==="critical-days"&&e.criticalDays?.length?this.renderCritical(e):this.mode==="forecast"&&e.days?.length?this.renderForecast(e):this.renderDaily(e):s`<div class="roxy-empty" role="status">No biorhythm data</div>`}renderDaily(e){let r=e.cycles??{},a=Object.entries(r);return s`<section class="wrap" aria-label="Daily biorhythm">
85
+ `;var or={sarva:"Sarvashtakavarga",bhinna:"Bhinnashtakavarga",pinda:"Shodhya Pinda"},me=["sarva","bhinna","pinda"],M=class extends u{constructor(){super(...arguments);this.data=null;this.activeTab="sarva"}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No ashtakavarga data</div>`;let e=this.data.signs??[];return a`<div class="wrap" aria-label="Ashtakavarga grid">
86
+ <div class="head">
87
+ <h2 class="title">Ashtakavarga</h2>
88
+ ${e.length?a`<p class="subtitle">${e.length} signs</p>`:n}
89
+ </div>
90
+
91
+ <div
92
+ class="tablist"
93
+ role="tablist"
94
+ aria-label="Ashtakavarga views"
95
+ @keydown=${this.onTabKeyDown}
96
+ >
97
+ ${me.map(t=>a`<button
98
+ class="tab"
99
+ role="tab"
100
+ id="tab-${t}"
101
+ aria-selected=${this.activeTab===t?"true":"false"}
102
+ aria-controls="panel-${t}"
103
+ tabindex=${this.activeTab===t?"0":"-1"}
104
+ @click=${()=>{this.activeTab=t}}
105
+ >
106
+ ${or[t]}
107
+ </button>`)}
108
+ </div>
109
+
110
+ <div
111
+ id="panel-${this.activeTab}"
112
+ role="tabpanel"
113
+ aria-labelledby="tab-${this.activeTab}"
114
+ >
115
+ ${this.activeTab==="sarva"?this.renderSarva(e):this.activeTab==="bhinna"?this.renderBhinna(e):this.renderPinda()}
116
+ </div>
117
+ </div>`}onTabKeyDown(e){let t=me.indexOf(this.activeTab);e.key==="ArrowRight"?(e.preventDefault(),this.activeTab=me[(t+1)%me.length],this.focusActiveTab()):e.key==="ArrowLeft"&&(e.preventDefault(),this.activeTab=me[(t-1+me.length)%me.length],this.focusActiveTab())}focusActiveTab(){requestAnimationFrame(()=>{this.shadowRoot?.querySelector(`#tab-${this.activeTab}`)?.focus()})}heatClass(e){return e<=1?"heat-1":e<=2?"heat-2":e<=3?"heat-3":e<=4?"heat-4":e<=5?"heat-5":e<=6?"heat-6":"heat-7"}renderSarva(e){let t=this.data.sarvashtakavarga;return t?a`<div class="overflow-scroll">
118
+ <table aria-label="Sarvashtakavarga bindu counts per sign">
119
+ <thead>
120
+ <tr>
121
+ <th scope="col">Sign</th>
122
+ <th scope="col">Bindus</th>
123
+ </tr>
124
+ </thead>
125
+ <tbody>
126
+ ${e.map((s,o)=>{let l=t.bindus[o]??0,d=this.heatClass(l);return a`<tr>
127
+ <td>
128
+ <div class="planet-cell">
129
+ <span class="glyph" aria-hidden="true">${N[s]??""}</span>
130
+ ${s}
131
+ </div>
132
+ </td>
133
+ <td class="${`heat-cell ${d}`}">${l}</td>
134
+ </tr>`})}
135
+ </tbody>
136
+ <tfoot>
137
+ <tr class="total-row">
138
+ <td>Total</td>
139
+ <td>${t.total}</td>
140
+ </tr>
141
+ </tfoot>
142
+ </table>
143
+ </div>`:a`<p class="roxy-empty">No sarvashtakavarga data</p>`}renderBhinna(e){let t=this.data.bhinnashtakavarga;return t?.length?a`<div class="overflow-scroll">
144
+ <table class="bhinna-table" aria-label="Bhinnashtakavarga planet-by-sign grid">
145
+ <thead>
146
+ <tr>
147
+ <th scope="col">Planet</th>
148
+ ${e.map(s=>a`<th scope="col" title=${s}>${N[s]??s.slice(0,2)}</th>`)}
149
+ <th scope="col">Total</th>
150
+ </tr>
151
+ </thead>
152
+ <tbody>
153
+ ${t.map(s=>a`<tr>
154
+ <td>${s.planet}</td>
155
+ ${s.bindus.map(o=>{let l=this.heatClass(o);return a`<td class="${`heat-cell ${l}`}">${o}</td>`})}
156
+ <td>${s.total}</td>
157
+ </tr>`)}
158
+ </tbody>
159
+ </table>
160
+ </div>`:a`<p class="roxy-empty">No bhinnashtakavarga data</p>`}renderPinda(){let e=this.data.shodhyaPinda;return e?.length?a`<div class="overflow-scroll">
161
+ <table aria-label="Shodhya Pinda planet strength scores">
162
+ <thead>
163
+ <tr>
164
+ <th scope="col">Planet</th>
165
+ <th scope="col">Rashi Pinda</th>
166
+ <th scope="col">Graha Pinda</th>
167
+ <th scope="col">Shodhya Pinda</th>
168
+ </tr>
169
+ </thead>
170
+ <tbody>
171
+ ${e.map(t=>a`<tr>
172
+ <td>${t.planet}</td>
173
+ <td>${t.rashiPinda}</td>
174
+ <td>${t.grahaPinda}</td>
175
+ <td>${t.shodhyaPinda}</td>
176
+ </tr>`)}
177
+ </tbody>
178
+ </table>
179
+ </div>`:a`<p class="roxy-empty">No shodhya pinda data</p>`}};M.styles=[b,x`
180
+ .wrap {
181
+ display: grid;
182
+ gap: var(--roxy-space-md, 1rem);
183
+ }
184
+
185
+ .head {
186
+ display: flex;
187
+ justify-content: space-between;
188
+ align-items: baseline;
189
+ gap: var(--roxy-space-md, 1rem);
190
+ flex-wrap: wrap;
191
+ }
192
+
193
+ .title {
194
+ font-size: var(--roxy-text-lg, 1.125rem);
195
+ font-weight: var(--roxy-weight-bold, 600);
196
+ margin: 0;
197
+ }
198
+
199
+ .subtitle {
200
+ color: var(--roxy-muted, #71717a);
201
+ font-size: var(--roxy-text-sm, 0.875rem);
202
+ margin: 0;
203
+ }
204
+
205
+ /* Tabs */
206
+ .tablist {
207
+ display: flex;
208
+ gap: 2px;
209
+ border-bottom: 2px solid var(--roxy-border, #e4e4e7);
210
+ }
211
+
212
+ .tab {
213
+ padding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);
214
+ font-size: var(--roxy-text-sm, 0.875rem);
215
+ background: none;
216
+ border: none;
217
+ border-bottom: 2px solid transparent;
218
+ margin-bottom: -2px;
219
+ cursor: pointer;
220
+ color: var(--roxy-muted, #71717a);
221
+ font-family: inherit;
222
+ transition: color var(--roxy-motion-duration, 200ms) var(--roxy-motion-easing, ease);
223
+ }
224
+
225
+ .tab[aria-selected='true'] {
226
+ color: var(--roxy-accent-fg, #b45309);
227
+ border-bottom-color: var(--roxy-accent, #f59e0b);
228
+ font-weight: var(--roxy-weight-bold, 600);
229
+ }
230
+
231
+ .tab:hover:not([aria-selected='true']) {
232
+ color: var(--roxy-fg, #0a0a0a);
233
+ }
234
+
235
+ /* Tables */
236
+ .overflow-scroll {
237
+ overflow-x: auto;
238
+ -webkit-overflow-scrolling: touch;
239
+ }
240
+
241
+ table {
242
+ width: 100%;
243
+ border-collapse: collapse;
244
+ font-size: var(--roxy-text-sm, 0.875rem);
245
+ }
246
+
247
+ th,
248
+ td {
249
+ padding: var(--roxy-space-sm, 0.5rem);
250
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
251
+ text-align: center;
252
+ }
253
+
254
+ th {
255
+ color: var(--roxy-muted, #71717a);
256
+ font-weight: var(--roxy-weight-bold, 600);
257
+ text-transform: uppercase;
258
+ font-size: var(--roxy-text-xs, 0.75rem);
259
+ letter-spacing: 0.06em;
260
+ }
261
+
262
+ td:first-child,
263
+ th:first-child {
264
+ text-align: left;
265
+ }
266
+
267
+ .glyph {
268
+ font-size: 1.1em;
269
+ margin-right: 3px;
270
+ line-height: 1;
271
+ }
272
+
273
+ .planet-cell {
274
+ display: flex;
275
+ align-items: center;
276
+ gap: 4px;
277
+ white-space: nowrap;
278
+ }
279
+
280
+ .total-row td {
281
+ font-weight: var(--roxy-weight-bold, 600);
282
+ border-top: 2px solid var(--roxy-border, #e4e4e7);
283
+ border-bottom: none;
284
+ }
285
+
286
+ /* Heat cells */
287
+ .heat-cell {
288
+ border-radius: var(--roxy-radius-sm, 4px);
289
+ font-weight: var(--roxy-weight-bold, 600);
290
+ min-width: 2rem;
291
+ font-variant-numeric: tabular-nums;
292
+ }
293
+
294
+ .heat-1 { background: var(--roxy-heat-1, #f0fdf4); color: var(--roxy-fg, #0a0a0a); }
295
+ .heat-2 { background: var(--roxy-heat-2, #d1fae5); color: var(--roxy-fg, #0a0a0a); }
296
+ .heat-3 { background: var(--roxy-heat-3, #a7f3d0); color: var(--roxy-fg, #0a0a0a); }
297
+ .heat-4 { background: var(--roxy-heat-4, #fde68a); color: var(--roxy-fg, #0a0a0a); }
298
+ .heat-5 { background: var(--roxy-heat-5, #fdba74); color: var(--roxy-fg, #0a0a0a); }
299
+ .heat-6 { background: var(--roxy-heat-6, #fb923c); color: var(--roxy-fg, #0a0a0a); }
300
+ .heat-7 { background: var(--roxy-heat-7, #ef4444); color: var(--roxy-fg, #0a0a0a); }
301
+
302
+ /* Bhinna grid: planet header column narrower */
303
+ .bhinna-table th:first-child,
304
+ .bhinna-table td:first-child {
305
+ min-width: 5rem;
306
+ }
307
+ `],c([y({attribute:!1})],M.prototype,"data",2),c([E()],M.prototype,"activeTab",2),M=c([v("roxy-ashtakavarga-grid")],M);var Lt={physical:"#dc2626",emotional:"#0284c7",intellectual:"#16a34a",intuitive:"#a855f7",aesthetic:"#f59e0b",awareness:"#ec4899",spiritual:"#14b8a6",passion:"#ef4444",mastery:"#6366f1",wisdom:"#475569"},D=class extends u{constructor(){super(...arguments);this.data=null;this.mode="daily"}render(){let e=this.data;return e?this.mode==="critical-days"&&"criticalDays"in e?this.renderCritical(e):this.mode==="forecast"&&"days"in e?this.renderForecast(e):this.renderDaily(e):a`<div class="roxy-empty" role="status">No biorhythm data</div>`}renderDaily(e){let t=e.quickRead??{},s=Object.entries(t).map(([o,l])=>{let d=typeof l=="number"?l:0,p=Math.abs(d)>1?d/100:d;return[o,p]});return a`<section class="wrap" aria-label="Daily biorhythm">
86
308
  <header class="head">
87
309
  <h2 class="title">Biorhythm</h2>
88
- ${typeof e.energyRating=="number"?s`<span class="energy">Energy ${e.energyRating}/10</span>`:l}
310
+ ${typeof e.energyRating=="number"?a`<span class="energy">Energy ${e.energyRating}/10</span>`:n}
89
311
  </header>
90
312
  <div class="bars" role="list">
91
- ${a.map(([i,n])=>{let c=typeof n=="number"?n:0,m=(c+1)/2*100,u=rr[i]??"var(--roxy-accent, #f59e0b)";return s`<div class="bar" role="listitem">
92
- <span style="text-transform: capitalize">${i}</span>
313
+ ${s.map(([o,l])=>{let d=(l+1)/2*100,p=Lt[o]??"var(--roxy-accent, #f59e0b)";return a`<div class="bar" role="listitem">
314
+ <span style="text-transform: capitalize">${o}</span>
93
315
  <span class="track">
94
316
  <span
95
317
  class="fill"
96
- style="width: ${m}%; background: ${u}"
318
+ style="width: ${d}%; background: ${p}"
97
319
  ></span>
98
320
  </span>
99
- <span class="value">${(c*100).toFixed(0)}%</span>
321
+ <span class="value">${Math.round(l*100)}%</span>
100
322
  </div>`})}
101
323
  </div>
102
- ${e.interpretation?s`<p class="advice">${e.interpretation}</p>`:l}
103
- ${e.advice?s`<p class="advice">${e.advice}</p>`:l}
104
- ${e.criticalAlerts?.length?s`<div>
105
- ${e.criticalAlerts.map(i=>s`<p class="alert">${i}</p>`)}
106
- </div>`:l}
107
- </section>`}renderForecast(e){let r=e.days??[];if(r.length===0)return s`<div class="roxy-empty" role="status">No forecast</div>`;let a=600,i=160,n=a/Math.max(r.length-1,1),c=Object.keys(r[0]?.cycles??{});return s`<section class="wrap" aria-label="Biorhythm forecast">
324
+ ${e.dailyMessage?a`<p class="advice">${e.dailyMessage}</p>`:n}
325
+ ${e.advice?a`<p class="advice">${e.advice}</p>`:n}
326
+ </section>`}renderForecast(e){let t=e.days??[];if(t.length===0)return a`<div class="roxy-empty" role="status">No forecast</div>`;let s=600,o=160,l=s/Math.max(t.length-1,1),d=["physical","emotional","intellectual","intuitive"];return a`<section class="wrap" aria-label="Biorhythm forecast">
108
327
  <header class="head">
109
328
  <h2 class="title">Forecast</h2>
110
- <span class="energy"
111
- >${e.startDate??""} - ${e.endDate??""}</span
112
- >
329
+ <span class="energy">${e.startDate} - ${e.endDate}</span>
113
330
  </header>
114
331
  <svg
115
- viewBox="0 0 ${a} ${i}"
332
+ viewBox="0 0 ${s} ${o}"
116
333
  role="img"
117
334
  aria-label="Biorhythm cycle lines across the forecast window"
118
335
  >
119
336
  <title>Biorhythm forecast</title>
120
337
  <line
121
338
  x1="0"
122
- y1=${i/2}
123
- x2=${a}
124
- y2=${i/2}
339
+ y1=${o/2}
340
+ x2=${s}
341
+ y2=${o/2}
125
342
  stroke="var(--roxy-border, #e4e4e7)"
126
343
  stroke-width="1"
127
344
  />
128
- ${c.map(m=>{let u=r.map((v,S)=>{let w=v.cycles?.[m]??0,X=S*n,pr=i/2-w*(i/2-8);return`${X.toFixed(2)},${pr.toFixed(2)}`}).join(" "),h=rr[m]??"#475569";return $`<polyline points=${u} fill="none" stroke=${h} stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />`})}
345
+ ${d.map(p=>{let m=t.map((g,f)=>{let k=g[p]??0,$=f*l,pt=o/2-k/100*(o/2-8);return`${$.toFixed(2)},${pt.toFixed(2)}`}).join(" "),h=Lt[p]??"#475569";return S`<polyline points=${m} fill="none" stroke=${h} stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />`})}
129
346
  </svg>
130
- ${e.summary?.periodAdvice?s`<p class="advice">${e.summary.periodAdvice}</p>`:l}
131
- </section>`}renderCritical(e){return s`<section class="wrap" aria-label="Critical days">
347
+ ${e.summary?.periodAdvice?a`<p class="advice">${e.summary.periodAdvice}</p>`:n}
348
+ </section>`}renderCritical(e){return a`<section class="wrap" aria-label="Critical days">
132
349
  <header class="head">
133
350
  <h2 class="title">Critical days</h2>
134
- <span class="energy"
135
- >${e.totalCriticalDays??e.criticalDays?.length??0} total</span
136
- >
351
+ <span class="energy">${e.totalCriticalDays} total</span>
137
352
  </header>
138
353
  <div>
139
- ${(e.criticalDays??[]).map(r=>s`<span class="crit"
140
- >${r.date} · ${r.cycle??""} ${r.severity??""}</span
354
+ ${e.criticalDays.map(t=>a`<span class="crit"
355
+ >${t.date} · ${t.cycle} ${t.severity}</span
141
356
  >`)}
142
357
  </div>
143
- </section>`}};T.styles=[f,y`
358
+ </section>`}};D.styles=[b,x`
144
359
  .wrap {
145
360
  display: grid;
146
361
  gap: var(--roxy-space-md, 1rem);
@@ -216,53 +431,167 @@
216
431
  display: inline-block;
217
432
  margin: 2px;
218
433
  }
219
- `],d([p({attribute:!1})],T.prototype,"data",2),d([p({type:String,reflect:!0})],T.prototype,"mode",2),T=d([x("roxy-biorhythm-chart")],T);var M=class extends g{constructor(){super(...arguments);this.data=null;this.mode="astrology"}getBreakdown(){let e=this.data;if(!e)return{};if(e.categoryScores)return e.categoryScores;if(e.categoryBreakdown)return e.categoryBreakdown;let r={};return typeof e.emotional=="number"&&(r.emotional=e.emotional),typeof e.communication=="number"&&(r.communication=e.communication),typeof e.romance=="number"&&(r.romance=e.romance),e.elementBalance&&Object.assign(r,e.elementBalance),r}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No compatibility data</div>`;let r=e.overallScore??e.score,a=this.getBreakdown();return s`<article
434
+ `],c([y({attribute:!1})],D.prototype,"data",2),c([y({type:String,reflect:!0})],D.prototype,"mode",2),D=c([v("roxy-biorhythm-chart")],D);function C(i){return i?i.charAt(0).toUpperCase()+i.slice(1).toLowerCase():""}function ee(i){return i.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/^\w/,r=>r.toUpperCase())}function _t(i){try{let r=new Date(i);return Number.isNaN(r.getTime())?i:r.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return i}}var te=class extends u{constructor(){super(...arguments);this.data=null}renderTile(e){let t=e.effect==="Good"?"good":e.effect==="Bad"?"bad":"neutral",s=L[C(e.lord)]??"",o=`${_t(e.start)} - ${_t(e.end)}`;return a`<div class="cho-tile ${t}" role="listitem">
435
+ <span class="tile-name">${e.name}</span>
436
+ <span class="tile-time" aria-label="Time range">${o}</span>
437
+ <span class="tile-lord">
438
+ ${s?a`<span aria-hidden="true">${s}</span>`:n}
439
+ ${e.lord}
440
+ </span>
441
+ </div>`}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No choghadiya data</div>`;let{date:e,dayChoghadiya:t,nightChoghadiya:s}=this.data;return a`<div class="wrap">
442
+ <div class="header">
443
+ <h2 class="title">Choghadiya</h2>
444
+ ${e?a`<p class="subtitle">${e}</p>`:n}
445
+ </div>
446
+
447
+ <div class="cho-grid">
448
+ <section class="period-col" aria-label="Day muhurta periods">
449
+ <h3 class="period-heading">Day</h3>
450
+ <div role="list" aria-label="Daytime choghadiya">
451
+ ${t&&t.length>0?t.map(o=>this.renderTile(o)):a`<p class="roxy-empty" role="status">No daytime periods</p>`}
452
+ </div>
453
+ </section>
454
+
455
+ <section class="period-col" aria-label="Night muhurta periods">
456
+ <h3 class="period-heading">Night</h3>
457
+ <div role="list" aria-label="Nighttime choghadiya">
458
+ ${s&&s.length>0?s.map(o=>this.renderTile(o)):a`<p class="roxy-empty" role="status">No nighttime periods</p>`}
459
+ </div>
460
+ </section>
461
+ </div>
462
+ </div>`}};te.styles=[b,x`
463
+ .wrap {
464
+ display: grid;
465
+ gap: var(--roxy-space-md, 1rem);
466
+ }
467
+ .header {
468
+ display: grid;
469
+ gap: var(--roxy-space-xs, 0.25rem);
470
+ }
471
+ .title {
472
+ font-size: var(--roxy-text-lg, 1.125rem);
473
+ font-weight: var(--roxy-weight-bold, 600);
474
+ margin: 0;
475
+ }
476
+ .subtitle {
477
+ font-size: var(--roxy-text-sm, 0.875rem);
478
+ color: var(--roxy-muted, #71717a);
479
+ margin: 0;
480
+ }
481
+ .cho-grid {
482
+ display: grid;
483
+ grid-template-columns: 1fr;
484
+ gap: var(--roxy-space-md, 1rem);
485
+ }
486
+ @media (min-width: 720px) {
487
+ .cho-grid {
488
+ grid-template-columns: 1fr 1fr;
489
+ }
490
+ }
491
+ .period-col {
492
+ display: grid;
493
+ gap: var(--roxy-space-xs, 0.25rem);
494
+ }
495
+ .period-heading {
496
+ font-size: var(--roxy-text-base, 1rem);
497
+ font-weight: var(--roxy-weight-bold, 600);
498
+ margin: 0 0 var(--roxy-space-xs, 0.25rem);
499
+ color: var(--roxy-fg, #0a0a0a);
500
+ }
501
+ .cho-tile {
502
+ display: grid;
503
+ grid-template-columns: 1fr auto;
504
+ align-items: center;
505
+ gap: 0.25em 0.75em;
506
+ padding: 0.55em 0.85em;
507
+ border: 1px solid var(--roxy-border, #e4e4e7);
508
+ border-radius: var(--roxy-radius-md, 8px);
509
+ }
510
+ .cho-tile.good {
511
+ background: color-mix(in srgb, var(--roxy-success, #22c55e) 18%, transparent);
512
+ border-color: color-mix(in srgb, var(--roxy-success, #22c55e) 45%, transparent);
513
+ color: var(--roxy-fg, #0a0a0a);
514
+ }
515
+ .cho-tile.bad {
516
+ background: color-mix(in srgb, var(--roxy-danger, #ef4444) 18%, transparent);
517
+ border-color: color-mix(in srgb, var(--roxy-danger, #ef4444) 45%, transparent);
518
+ color: var(--roxy-fg, #0a0a0a);
519
+ }
520
+ .cho-tile.neutral {
521
+ background: transparent;
522
+ color: var(--roxy-fg, #0a0a0a);
523
+ }
524
+ .tile-name {
525
+ font-size: var(--roxy-text-base, 1rem);
526
+ font-weight: var(--roxy-weight-bold, 600);
527
+ grid-column: 1;
528
+ }
529
+ .tile-time {
530
+ font-size: var(--roxy-text-xs, 0.75rem);
531
+ opacity: 0.8;
532
+ white-space: nowrap;
533
+ grid-column: 2;
534
+ grid-row: 1 / 3;
535
+ text-align: right;
536
+ align-self: center;
537
+ }
538
+ .tile-lord {
539
+ font-size: var(--roxy-text-sm, 0.875rem);
540
+ opacity: 0.85;
541
+ grid-column: 1;
542
+ display: flex;
543
+ align-items: center;
544
+ gap: 0.25em;
545
+ }
546
+ `],c([y({attribute:!1})],te.prototype,"data",2),te=c([v("roxy-choghadiya-grid")],te);function O(i){if(typeof i!="string"||i.length===0||/^\d{4}-\d{2}-\d{2}$/.test(i))return"";let e=/^\d{2}:\d{2}(:\d{2})?$/.test(i)?`1970-01-01T${i}`:i,t=new Date(e);return Number.isNaN(t.getTime())?i:t.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",hour12:!0})}function Ne(i){if(typeof i!="string"||i.length===0)return"";let r=new Date(/^\d{4}-\d{2}-\d{2}$/.test(i)?`${i}T00:00:00`:i);return Number.isNaN(r.getTime())?i:r.toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}function st(i){if(!i)return"";let r=O(i.start),e=O(i.end);return r&&e?`${r} - ${e}`:r||e||""}function w(i,r=1){return typeof i!="number"||!Number.isFinite(i)?"":i.toFixed(r).replace(/\.?0+$/,"")}function Nt(i,r=1){let e=w(i,r);return e?`${e}%`:""}var ze={conjunction:"aspect-conjunction",sextile:"aspect-sextile",square:"aspect-square",trine:"aspect-trine",opposition:"aspect-opposition"};function ke(i){return(i.type??"").toLowerCase().replace(/_/g,"-")}var H=class extends u{constructor(){super(...arguments);this.data=null;this.mode="astrology"}getBreakdown(){let e=this.data;if(!e)return{};if("categories"in e&&e.categories){let t={};for(let[s,o]of Object.entries(e.categories))typeof o=="number"&&Number.isFinite(o)&&(t[s]=o);return t}return{}}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No compatibility data</div>`;let t=e.overallScore,s=this.getBreakdown(),o="rating"in e?e.rating:void 0,l="archetype"in e?e.archetype:void 0,d="advice"in e?e.advice:void 0,p="summary"in e?e.summary:void 0,m="interpretation"in e?e.interpretation:void 0,h="strengths"in e?e.strengths:void 0,g="challenges"in e?e.challenges:void 0,f="keyAspects"in e?e.keyAspects:void 0;return a`<article
220
547
  class="card"
221
548
  aria-label=${`Compatibility (${this.mode})`}
222
549
  >
223
550
  <div class="head">
224
551
  <h2>${this.mode} compatibility</h2>
225
552
  <div>
226
- ${typeof r=="number"?s`<div class="score">${r}</div>`:l}
227
- ${e.rating?s`<div class="rating">${e.rating}</div>`:l}
553
+ ${typeof t=="number"?a`<div class="score">${w(t,0)}</div>`:n}
554
+ ${o?a`<div class="rating">${o}</div>`:n}
228
555
  </div>
229
556
  </div>
230
557
 
231
- ${Object.keys(a).length>0?s`<div role="list">
232
- ${Object.entries(a).map(([i,n])=>s`<div class="bar-row" role="listitem">
233
- <span style="text-transform: capitalize">${i}</span>
558
+ ${Object.keys(s).length>0?a`<div role="list">
559
+ ${Object.entries(s).map(([k,$])=>a`<div class="bar-row" role="listitem">
560
+ <span style="text-transform: capitalize">${k}</span>
234
561
  <span class="bar"
235
- ><span style="width: ${Math.max(0,Math.min(100,n))}%"></span
562
+ ><span style="width: ${Math.max(0,Math.min(100,$))}%"></span
236
563
  ></span>
237
- <span>${n}</span>
564
+ <span>${w($,0)}</span>
238
565
  </div>`)}
239
- </div>`:l}
240
- ${e.relationshipArchetype?s`<p>
241
- <span class="archetype">${e.relationshipArchetype}</span>
242
- </p>`:l}
243
- ${e.summary?s`<p>${e.summary}</p>`:l}
244
- ${e.advice?s`<p>${e.advice}</p>`:l}
245
- ${(e.strengths?.length??0)>0||(e.challenges?.length??0)>0?s`<div class="lists">
246
- ${e.strengths?.length?s`<div>
566
+ </div>`:n}
567
+ ${l?a`<p>
568
+ <span class="archetype">${l.label}</span>
569
+ ${l.description?a` · ${l.description}`:n}
570
+ </p>`:n}
571
+ ${p?a`<p>${p}</p>`:n}
572
+ ${m&&!p?a`<p>${m}</p>`:n}
573
+ ${d?a`<p>${d}</p>`:n}
574
+ ${(h?.length??0)>0||(g?.length??0)>0?a`<div class="lists">
575
+ ${h?.length?a`<div>
247
576
  <h3>Strengths</h3>
248
577
  <ul>
249
- ${e.strengths.map(i=>s`<li>${i}</li>`)}
578
+ ${h.map(k=>a`<li>${k}</li>`)}
250
579
  </ul>
251
- </div>`:l}
252
- ${e.challenges?.length?s`<div>
580
+ </div>`:n}
581
+ ${g?.length?a`<div>
253
582
  <h3>Challenges</h3>
254
583
  <ul>
255
- ${e.challenges.map(i=>s`<li>${i}</li>`)}
256
- </ul>
257
- </div>`:l}
258
- ${e.keyAspects?.length?s`<div>
259
- <h3>Key aspects</h3>
260
- <ul>
261
- ${e.keyAspects.map(i=>s`<li>${i}</li>`)}
584
+ ${g.map(k=>a`<li>${k}</li>`)}
262
585
  </ul>
263
- </div>`:l}
264
- </div>`:l}
265
- </article>`}};M.styles=[f,y`
586
+ </div>`:n}
587
+ </div>`:n}
588
+ ${f?.length?a`<div>
589
+ <h3 style="margin: 0 0 0.25rem; font-size: var(--roxy-text-xs); color: var(--roxy-muted); text-transform: uppercase; letter-spacing: 0.06em;">Key aspects</h3>
590
+ <ul style="margin: 0; padding-left: 1rem; font-size: var(--roxy-text-sm);">
591
+ ${f.slice(0,6).map(k=>a`<li>${ir(k)}</li>`)}
592
+ </ul>
593
+ </div>`:n}
594
+ </article>`}};H.styles=[b,x`
266
595
  .card {
267
596
  background: var(--roxy-bg, #fff);
268
597
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -326,7 +655,7 @@
326
655
  }
327
656
 
328
657
  .archetype {
329
- color: var(--roxy-info, #0284c7);
658
+ color: var(--roxy-accent-fg, #b45309);
330
659
  font-weight: var(--roxy-weight-bold, 600);
331
660
  }
332
661
 
@@ -346,49 +675,45 @@
346
675
  margin: 0;
347
676
  padding-left: var(--roxy-space-md, 1rem);
348
677
  }
349
- `],d([p({attribute:!1})],M.prototype,"data",2),d([p({type:String,reflect:!0})],M.prototype,"mode",2),M=d([x("roxy-compatibility-card")],M);var L=class extends g{constructor(){super(...arguments);this.data=null;this.period="current"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No dasha data</div>`;let r=this.collectPeriods(e),a=r.length?Math.max(...r.map(i=>i.durationYears??i.years??1)):0;return s`<div class="wrap" aria-label="Dasha timeline">
678
+ `],c([y({attribute:!1})],H.prototype,"data",2),c([y({type:String,reflect:!0})],H.prototype,"mode",2),H=c([v("roxy-compatibility-card")],H);function ir(i){let r=i.type.toLowerCase().replace(/_/g,"-"),e=typeof i.orb=="number"?` (orb ${w(i.orb,1)}\xB0)`:"",t=[i.planet1,r,i.planet2].filter(Boolean).join(" ");return i.description?`${t}${e} \xB7 ${i.description}`:`${t}${e}`}var G=class extends u{constructor(){super(...arguments);this.data=null;this.period="current"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No dasha data</div>`;let t=this.collectPeriods(e),s=t.length?Math.max(...t.map(o=>o.durationYears)):0;return a`<div class="wrap" aria-label="Dasha timeline">
350
679
  <header class="head">
351
680
  <h2 class="title">
352
681
  ${this.period==="major"?"Vimshottari Mahadasha":this.period==="sub"?"Antardasha":"Active dashas"}
353
682
  </h2>
354
- ${e.nakshatraName||e.moonNakshatra?s`<div class="nakshatra">
355
- Moon nakshatra: ${e.nakshatraName??e.moonNakshatra}
356
- ${e.nakshatraLord?s`(lord ${e.nakshatraLord})`:l}
357
- </div>`:l}
683
+ ${"nakshatraName"in e&&e.nakshatraName?a`<div class="nakshatra">
684
+ Moon nakshatra: ${e.nakshatraName}
685
+ ${"nakshatraLord"in e&&e.nakshatraLord?a`(lord ${e.nakshatraLord})`:n}
686
+ </div>`:n}
358
687
  </header>
359
688
 
360
- ${this.period==="current"?this.renderCurrent(e):l}
361
- ${r.length>0?s`<div class="timeline" role="list">
362
- ${r.map(i=>this.renderBar(i,a))}
363
- </div>`:l}
364
- </div>`}renderCurrent(e){return s`<div class="current">
365
- ${e.mahadasha?s`<div>
366
- <span>Mahadasha</span>
367
- <strong>${e.mahadasha.lord??e.mahadasha.mahadashaLord}</strong>
368
- ${typeof e.remainingInMahadasha=="number"?s`<small>${e.remainingInMahadasha.toFixed(1)} years left</small>`:l}
369
- </div>`:l}
370
- ${e.antardasha?s`<div>
371
- <span>Antardasha</span>
372
- <strong>${e.antardasha.lord??e.antardasha.antardashaLord}</strong>
373
- ${typeof e.remainingInAntardasha=="number"?s`<small>${e.remainingInAntardasha.toFixed(1)} years left</small>`:l}
374
- </div>`:l}
375
- ${e.pratyantardasha?s`<div>
376
- <span>Pratyantardasha</span>
377
- <strong
378
- >${e.pratyantardasha.lord??e.pratyantardasha.pratyantardashaLord}</strong
379
- >
380
- ${typeof e.remainingInPratyantardasha=="number"?s`<small
381
- >${e.remainingInPratyantardasha.toFixed(2)} years left</small
382
- >`:l}
383
- </div>`:l}
384
- </div>`}collectPeriods(e){return this.period==="major"&&e.mahadashas?.length?e.mahadashas:this.period==="sub"&&e.antardashas?.length?e.antardashas:e.mahadashas??e.antardashas??[]}renderBar(e,r){let a=e.lord??e.mahadashaLord??e.antardashaLord??e.planet??"",i=e.durationYears??e.years??0,n=r>0?i/r*100:0;return s`<div class="bar" role="listitem">
385
- <span>${a}</span>
386
- <span class="bar-track"><span style="width: ${n}%"></span></span>
689
+ ${this.period==="current"?this.renderCurrent(e):n}
690
+ ${t.length>0?a`<div class="timeline" role="list">
691
+ ${t.map(o=>this.renderBar(o,s))}
692
+ </div>`:n}
693
+ </div>`}renderCurrent(e){return"mahadasha"in e?a`<div class="current">
694
+ ${"mahadasha"in e&&e.mahadasha?a`<div>
695
+ <span>Mahadasha</span>
696
+ <strong>${e.mahadasha.planet}</strong>
697
+ ${"remainingInMahadasha"in e&&e.remainingInMahadasha?a`<small>${w(e.remainingInMahadasha.years+e.remainingInMahadasha.months/12,1)} years left</small>`:n}
698
+ </div>`:n}
699
+ ${"antardasha"in e&&e.antardasha?a`<div>
700
+ <span>Antardasha</span>
701
+ <strong>${e.antardasha.planet}</strong>
702
+ ${"remainingInAntardasha"in e&&e.remainingInAntardasha?a`<small>${w(e.remainingInAntardasha.years+e.remainingInAntardasha.months/12,1)} years left</small>`:n}
703
+ </div>`:n}
704
+ ${"pratyantardasha"in e&&e.pratyantardasha?a`<div>
705
+ <span>Pratyantardasha</span>
706
+ <strong>${e.pratyantardasha.planet}</strong>
707
+ ${"remainingInPratyantardasha"in e&&e.remainingInPratyantardasha?a`<small>${w(e.remainingInPratyantardasha.years+e.remainingInPratyantardasha.months/12,1)} years left</small>`:n}
708
+ </div>`:n}
709
+ </div>`:n}collectPeriods(e){return"mahadashas"in e&&e.mahadashas?.length?e.mahadashas:"antardashas"in e&&e.antardashas?.length?e.antardashas:[]}renderBar(e,t){let s=e.durationYears,o=t>0?s/t*100:0;return a`<div class="bar" role="listitem">
710
+ <span>${e.planet}</span>
711
+ <span class="bar-track"><span style="width: ${o}%"></span></span>
387
712
  <span class="dates">
388
- ${e.startDate?tr(e.startDate):""}
389
- ${e.endDate?s`- ${tr(e.endDate)}`:""}
713
+ ${e.startDate?zt(e.startDate):""}
714
+ ${e.endDate?a`- ${zt(e.endDate)}`:""}
390
715
  </span>
391
- </div>`}};L.styles=[f,y`
716
+ </div>`}};G.styles=[b,x`
392
717
  .wrap {
393
718
  display: grid;
394
719
  gap: var(--roxy-space-md, 1rem);
@@ -463,44 +788,44 @@
463
788
  font-variant-numeric: tabular-nums;
464
789
  text-align: right;
465
790
  }
466
- `],d([p({attribute:!1})],L.prototype,"data",2),d([p({type:String,reflect:!0})],L.prototype,"period",2),L=d([x("roxy-dasha-timeline")],L);function tr(o){let t=o.match(/^(\d{4})/);return t?t[1]:o}var Nr=["title","name","label","heading","overview","summary"],Cr=["imageUrl","image","icon","symbol"],Dr=["imageUrl","image"],K=class extends g{constructor(){super(...arguments);this.data=null}render(){return this.data==null?s`<div class="roxy-empty" role="status">No data</div>`:s`<div
791
+ `],c([y({attribute:!1})],G.prototype,"data",2),c([y({type:String,reflect:!0})],G.prototype,"period",2),G=c([v("roxy-dasha-timeline")],G);function zt(i){let r=i.match(/^(\d{4})/);return r?r[1]:i}var nr=["title","name","label","heading","overview","summary"],lr=["imageUrl","image","icon","symbol"],dr=["imageUrl","image"],cr=6,j=class extends u{constructor(){super(...arguments);this.data=null;this.depth=0}render(){return this.data==null?a`<div class="roxy-empty" role="status">No data</div>`:this.depth>=cr?a`<div class="roxy-empty" role="status">…</div>`:a`<div
467
792
  class="roxy-card"
468
793
  aria-label="Generic data display"
469
794
  >
470
795
  ${this.renderValue(this.data)}
471
- </div>`}renderValue(e){return e==null?l:typeof e=="string"?s`<p>${e}</p>`:typeof e=="number"||typeof e=="boolean"?s`<p>${String(e)}</p>`:Array.isArray(e)?this.renderArray(e):this.renderObject(e)}renderArray(e){return e.length===0?s`<div class="roxy-empty" role="status">Empty list</div>`:e.every(i=>i===null||["string","number","boolean"].includes(typeof i))?s`<ul class="roxy-chips">
472
- ${e.map(i=>s`<li>${String(i)}</li>`)}
473
- </ul>`:e.every(i=>i!==null&&typeof i=="object"&&!Array.isArray(i))?this.renderTable(e):s`<ol>
474
- ${e.map(i=>s`<li>${this.renderValue(i)}</li>`)}
475
- </ol>`}renderTable(e){let r=this.collectKeys(e);return s`<table class="roxy-table" role="table">
796
+ </div>`}renderValue(e){return e==null?n:typeof e=="string"?a`<p>${e}</p>`:typeof e=="number"||typeof e=="boolean"?a`<p>${String(e)}</p>`:Array.isArray(e)?this.renderArray(e):this.renderObject(e)}renderArray(e){return e.length===0?a`<div class="roxy-empty" role="status">Empty list</div>`:e.every(o=>o===null||["string","number","boolean"].includes(typeof o))?a`<ul class="roxy-chips">
797
+ ${e.map(o=>a`<li>${String(o)}</li>`)}
798
+ </ul>`:e.every(o=>o!==null&&typeof o=="object"&&!Array.isArray(o))?this.renderTable(e):a`<ol>
799
+ ${e.map(o=>a`<li>${this.renderValue(o)}</li>`)}
800
+ </ol>`}renderTable(e){let t=this.collectKeys(e);return a`<table class="roxy-table" role="table">
476
801
  <thead>
477
802
  <tr>
478
- ${r.map(a=>s`<th>${this.humanize(a)}</th>`)}
803
+ ${t.map(s=>a`<th>${ee(s)}</th>`)}
479
804
  </tr>
480
805
  </thead>
481
806
  <tbody>
482
- ${e.map(a=>s`<tr>
483
- ${r.map(i=>s`<td>${this.formatPrimitive(a[i])}</td>`)}
807
+ ${e.map(s=>a`<tr>
808
+ ${t.map(o=>a`<td>${this.formatPrimitive(s[o])}</td>`)}
484
809
  </tr>`)}
485
810
  </tbody>
486
- </table>`}renderObject(e){let r=Nr.find(c=>typeof e[c]=="string"),a=Cr.find(c=>typeof e[c]=="string"&&e[c].startsWith("http")),i=r!=="summary"&&typeof e.summary=="string"?"summary":null,n=Object.entries(e).filter(([c,m])=>c!==r&&c!==i&&!Dr.includes(c)&&m!==null&&m!==void 0);return s`
487
- ${a?s`<img
811
+ </table>`}renderObject(e){let t=nr.find(d=>typeof e[d]=="string"),s=lr.find(d=>typeof e[d]=="string"&&e[d].startsWith("http")),o=t!=="summary"&&typeof e.summary=="string"?"summary":null,l=Object.entries(e).filter(([d,p])=>d!==t&&d!==o&&!dr.includes(d)&&p!==null&&p!==void 0);return a`
812
+ ${s?a`<img
488
813
  class="roxy-image"
489
- src=${String(e[a])}
490
- alt=${r?String(e[r]):"illustration"}
814
+ src=${String(e[s])}
815
+ alt=${t?String(e[t]):"illustration"}
491
816
  loading="lazy"
492
- />`:l}
493
- ${r?s`<h3 class="roxy-title">${e[r]}</h3>`:l}
494
- ${i?s`<p class="roxy-summary">${e[i]}</p>`:l}
495
- ${n.length>0?s`<dl class="roxy-rows">
496
- ${n.map(([c,m])=>s`
497
- <dt>${this.humanize(c)}</dt>
498
- <dd>${this.renderField(m)}</dd>
817
+ />`:n}
818
+ ${t?a`<h3 class="roxy-title">${e[t]}</h3>`:n}
819
+ ${o?a`<p class="roxy-summary">${e[o]}</p>`:n}
820
+ ${l.length>0?a`<dl class="roxy-rows">
821
+ ${l.map(([d,p])=>a`
822
+ <dt>${ee(d)}</dt>
823
+ <dd>${this.renderField(p)}</dd>
499
824
  `)}
500
- </dl>`:l}
501
- `}renderField(e){return e==null?"":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):Array.isArray(e)&&e.every(a=>["string","number","boolean"].includes(typeof a))?s`<ul class="roxy-chips">
502
- ${e.map(a=>s`<li>${String(a)}</li>`)}
503
- </ul>`:s`<roxy-data .data=${e}></roxy-data>`}formatPrimitive(e){return e==null?"":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):Array.isArray(e)?e.map(String).join(", "):JSON.stringify(e)}collectKeys(e){let r=new Set;for(let a of e)for(let i of Object.keys(a))r.add(i);return Array.from(r)}humanize(e){return e.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/^\w/,r=>r.toUpperCase())}};K.styles=[f,y`
825
+ </dl>`:n}
826
+ `}renderField(e){return e==null?"":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):Array.isArray(e)&&e.every(s=>["string","number","boolean"].includes(typeof s))?a`<ul class="roxy-chips">
827
+ ${e.map(s=>a`<li>${String(s)}</li>`)}
828
+ </ul>`:a`<roxy-data .data=${e} .depth=${this.depth+1}></roxy-data>`}formatPrimitive(e){return e==null?"":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):Array.isArray(e)?e.map(String).join(", "):JSON.stringify(e)}collectKeys(e){let t=new Set;for(let s of e)for(let o of Object.keys(s))t.add(o);return Array.from(t)}};j.styles=[b,x`
504
829
  .roxy-card {
505
830
  background: var(--roxy-bg, #fff);
506
831
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -594,105 +919,257 @@
594
919
  margin: 0 0 var(--roxy-space-xs, 0.25rem) 0;
595
920
  text-transform: capitalize;
596
921
  }
597
- `],d([p({attribute:!1})],K.prototype,"data",2),K=d([x("roxy-data")],K);var Or={manglik:"Mangal Dosha",kalsarpa:"Kaal Sarp Dosha",sadhesati:"Sade Sati"},N=class extends g{constructor(){super(...arguments);this.data=null;this.type="manglik"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No dosha data</div>`;let r=!!e.present,a=Or[this.type]??this.type,i=(e.severity??"").toLowerCase();return s`<article
598
- class="card"
599
- aria-label=${a}
600
- >
601
- <header class="head">
602
- <h2 class="title">${a}</h2>
603
- <div style="display:flex; gap:0.5rem; align-items:center;">
604
- <span class=${`badge ${r?"present":"absent"}`}>
605
- ${r?"Present":"Absent"}
606
- </span>
607
- ${e.severity?s`<span
608
- class=${`severity ${i}`}
609
- role="img"
610
- aria-label=${`Severity ${e.severity}`}
611
- >
612
- <span></span><span></span><span></span>
613
- </span>`:l}
614
- </div>
615
- </header>
616
- ${e.description?s`<p class="description">${e.description}</p>`:l}
617
- ${this.renderEffects(e.effects)}
618
- ${e.remedies&&e.remedies.length>0?s`<div>
619
- <h3>Remedies</h3>
620
- <ul>
621
- ${e.remedies.map(n=>s`<li>${n}</li>`)}
622
- </ul>
623
- </div>`:l}
624
- ${e.exceptions&&e.exceptions.length>0?s`<div>
625
- <h3>Exceptions</h3>
626
- <ul>
627
- ${e.exceptions.map(n=>s`<li>${n}</li>`)}
628
- </ul>
629
- </div>`:l}
630
- </article>`}renderEffects(e){if(!e)return l;if(typeof e=="string")return s`<p>${e}</p>`;let r=Object.entries(e).filter(([,a])=>typeof a=="string"&&a.length>0);return r.length===0?l:s`<div class="effects">
631
- ${r.map(([a,i])=>s`<div>
632
- <h3>${a}</h3>
633
- <p>${i}</p>
634
- </div>`)}
635
- </div>`}};N.styles=[f,y`
636
- .card {
637
- background: var(--roxy-bg, #fff);
638
- border: 1px solid var(--roxy-border, #e4e4e7);
639
- border-radius: var(--roxy-radius-md, 8px);
640
- padding: var(--roxy-space-lg, 1.5rem);
641
- box-shadow: var(--roxy-shadow-sm);
922
+ `],c([y({attribute:!1})],j.prototype,"data",2),c([y({attribute:!1})],j.prototype,"depth",2),j=c([v("roxy-data")],j);var Me=Object.fromEntries(pe.map(i=>[i.toLowerCase(),i])),pr={1:{x:150,y:58},2:{x:205,y:52},3:{x:253,y:112},4:{x:243,y:150},5:{x:253,y:188},6:{x:205,y:248},7:{x:150,y:242},8:{x:95,y:248},9:{x:47,y:188},10:{x:57,y:150},11:{x:47,y:112},12:{x:95,y:52}},mr={1:{x:150,y:35},2:{x:222,y:40},3:{x:265,y:100},4:{x:265,y:150},5:{x:265,y:200},6:{x:222,y:260},7:{x:150,y:265},8:{x:78,y:260},9:{x:35,y:200},10:{x:35,y:150},11:{x:35,y:100},12:{x:78,y:40}},hr={1:{x:150,y:60},2:{x:225,y:100},3:{x:255,y:150},4:{x:225,y:200},5:{x:150,y:240},6:{x:75,y:200},7:{x:45,y:150},8:{x:75,y:100},9:{x:100,y:80},10:{x:150,y:108},11:{x:200,y:80},12:{x:200,y:220}};function De(i){let r=pr[i.number],e=mr[i.number];if(!r||!e)return n;let t=rt[i.sign]??"",s=i.planets;return S`
923
+ <g>
924
+ ${i.isLagna?S`<rect
925
+ class="lagna-bg"
926
+ x=${r.x-30} y=${r.y-28}
927
+ width="60" height="56" rx="6"
928
+ />`:n}
929
+ ${t?S`<text class="sign-text" x=${e.x} y=${e.y} text-anchor="middle" dominant-baseline="central">${t}</text>`:n}
930
+ ${i.isLagna?S`<text class="lagna-marker" x=${r.x} y=${r.y-18} text-anchor="middle" dominant-baseline="central">LAGNA</text>`:n}
931
+ ${s.map((o,l)=>{let d=tt[C(o)]??o.slice(0,2),p=13,g=(i.isLagna?r.y+8:r.y)-(s.length-1)*p/2+l*p;return S`<text class="planet-text" x=${r.x} y=${g} text-anchor="middle" dominant-baseline="central">${d}</text>`})}
932
+ </g>
933
+ `}function Oe(){return S`
934
+ <polygon class="line" points="150,10 290,150 150,290 10,150" stroke-width="1.5" />
935
+ <line class="line" x1="150" y1="10" x2="150" y2="290" stroke-width="1" />
936
+ <line class="line" x1="10" y1="150" x2="290" y2="150" stroke-width="1" />
937
+ <line class="line" x1="150" y1="10" x2="10" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
938
+ <line class="line" x1="150" y1="10" x2="290" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
939
+ <line class="line" x1="150" y1="290" x2="10" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
940
+ <line class="line" x1="150" y1="290" x2="290" y2="150" stroke-width="0.6" stroke-dasharray="3,3" />
941
+ `}function He(i){let r=hr[i.number];if(!r)return n;let e=rt[i.sign]??"",t=i.planets;return S`
942
+ <g>
943
+ ${i.isLagna?S`<circle class="lagna-bg" cx=${r.x} cy=${r.y} r="22" />`:n}
944
+ ${e?S`<text class="sign-text" x=${r.x} y=${r.y-10} text-anchor="middle" dominant-baseline="central">${e}</text>`:n}
945
+ <text class="house-num" x=${r.x} y=${r.y+2} text-anchor="middle" dominant-baseline="central">${i.number}</text>
946
+ ${t.map((s,o)=>{let l=tt[C(s)]??s.slice(0,2),d=11,m=r.y+14-(t.length-1)*d/2+o*d;return S`<text class="planet-text" x=${r.x} y=${m} text-anchor="middle" dominant-baseline="central">${l}</text>`})}
947
+ </g>
948
+ `}function Ge(){return S`
949
+ <polygon class="line" points="150,10 290,150 150,290 10,150" stroke-width="1.5" />
950
+ <polygon class="line" points="220,80 220,220 80,220 80,80" stroke-width="1" fill="none" />
951
+ <line class="line" x1="150" y1="10" x2="80" y2="80" stroke-width="1" />
952
+ <line class="line" x1="150" y1="10" x2="220" y2="80" stroke-width="1" />
953
+ <line class="line" x1="290" y1="150" x2="220" y2="80" stroke-width="1" />
954
+ <line class="line" x1="290" y1="150" x2="220" y2="220" stroke-width="1" />
955
+ <line class="line" x1="150" y1="290" x2="220" y2="220" stroke-width="1" />
956
+ <line class="line" x1="150" y1="290" x2="80" y2="220" stroke-width="1" />
957
+ <line class="line" x1="10" y1="150" x2="80" y2="220" stroke-width="1" />
958
+ <line class="line" x1="10" y1="150" x2="80" y2="80" stroke-width="1" />
959
+ `}var I=class extends u{constructor(){super(...arguments);this.data=null;this.chartStyle="south"}buildHouses(){if(!this.data)return[];let e=this.data.chart,s=(this.data.chart.meta??{}).Lagna?.rashi??"",o=[];for(let l=0;l<12;l++){let d=_e[l],m=(e[d]?.signs??[]).map(g=>g.graha).filter(Boolean),h=Me[d]??"";o.push({number:l+1,sign:h,planets:m,isLagna:s?s.toLowerCase()===h.toLowerCase():!1})}return o}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No divisional chart data</div>`;let{division:e,vargottama:t}=this.data,s=this.buildHouses(),o=this.chartStyle==="north";return a`<div class="wrap">
960
+ <div class="header">
961
+ <h2 class="title">
962
+ D${e.number} ${e.name}
963
+ ${e.sanskritName&&e.sanskritName!==e.name?a`<span class="division-meta"> · ${e.sanskritName}</span>`:n}
964
+ </h2>
965
+ ${e.significance?a`<p class="significance">${e.significance}</p>`:n}
966
+ </div>
967
+
968
+ <svg
969
+ viewBox="0 0 300 300"
970
+ role="img"
971
+ aria-label="D${e.number} ${e.name} divisional chart with twelve sign houses"
972
+ >
973
+ <title>D${e.number} ${e.name}</title>
974
+ ${o?Oe():Ge()}
975
+ ${o?s.map(l=>He(l)):s.map(l=>De(l))}
976
+ </svg>
977
+
978
+ ${t&&t.length>0?a`<div class="vargottama-row" role="list" aria-label="Vargottama planets">
979
+ <span class="vargottama-label">Vargottama:</span>
980
+ ${t.map(l=>a`<span class="vargottama-pill" role="listitem">
981
+ ${L[l]??""} ${l}
982
+ </span>`)}
983
+ </div>`:n}
984
+ </div>`}};I.styles=[b,x`
985
+ .wrap {
642
986
  display: grid;
643
987
  gap: var(--roxy-space-md, 1rem);
644
988
  }
645
- .head {
646
- display: flex;
647
- align-items: center;
648
- justify-content: space-between;
649
- gap: var(--roxy-space-md, 1rem);
650
- flex-wrap: wrap;
989
+ .header {
990
+ display: grid;
991
+ gap: var(--roxy-space-xs, 0.25rem);
651
992
  }
652
993
  .title {
653
- margin: 0;
654
994
  font-size: var(--roxy-text-lg, 1.125rem);
655
995
  font-weight: var(--roxy-weight-bold, 600);
656
- text-transform: capitalize;
657
- }
658
- .badge {
659
- display: inline-flex;
660
- align-items: center;
661
- gap: var(--roxy-space-xs, 0.25rem);
662
- padding: 4px 10px;
663
- border-radius: var(--roxy-radius-full, 9999px);
664
- font-size: var(--roxy-text-xs, 0.75rem);
665
- font-weight: var(--roxy-weight-bold, 600);
666
- text-transform: uppercase;
667
- letter-spacing: 0.06em;
996
+ margin: 0;
668
997
  }
669
- .badge.absent {
670
- background: color-mix(in srgb, var(--roxy-success, #16a34a) 16%, transparent);
671
- color: var(--roxy-success, #16a34a);
998
+ .division-meta {
999
+ font-size: var(--roxy-text-sm, 0.875rem);
1000
+ color: var(--roxy-muted, #71717a);
1001
+ margin: 0;
672
1002
  }
673
- .badge.present {
674
- background: color-mix(in srgb, var(--roxy-danger, #dc2626) 16%, transparent);
675
- color: var(--roxy-danger, #dc2626);
1003
+ .significance {
1004
+ font-size: var(--roxy-text-sm, 0.875rem);
1005
+ color: var(--roxy-muted, #71717a);
1006
+ border-left: 2px solid var(--roxy-border, #e4e4e7);
1007
+ padding-left: var(--roxy-space-sm, 0.5rem);
1008
+ margin: 0;
676
1009
  }
677
- .severity {
678
- display: flex;
679
- align-items: center;
680
- gap: 4px;
1010
+ svg {
1011
+ display: block;
1012
+ width: 100%;
1013
+ max-width: 360px;
1014
+ margin: 0 auto;
681
1015
  }
682
- .severity span {
683
- width: 14px;
684
- height: 4px;
685
- border-radius: 2px;
686
- background: var(--roxy-border, #e4e4e7);
1016
+ .line {
1017
+ fill: transparent;
1018
+ stroke: var(--roxy-border, #e4e4e7);
1019
+ }
1020
+ .sign-text {
1021
+ fill: var(--roxy-muted, #71717a);
1022
+ font-size: 9px;
1023
+ font-weight: 500;
1024
+ font-family: var(--roxy-font-sans);
1025
+ }
1026
+ .planet-text {
1027
+ fill: var(--roxy-fg, #0a0a0a);
1028
+ font-size: 11px;
1029
+ font-weight: 600;
1030
+ font-family: var(--roxy-font-sans);
1031
+ }
1032
+ .house-num {
1033
+ fill: var(--roxy-muted, #71717a);
1034
+ font-size: 9px;
1035
+ font-weight: 400;
1036
+ font-family: var(--roxy-font-sans);
1037
+ }
1038
+ .lagna-marker {
1039
+ fill: var(--roxy-accent-fg, #b45309);
1040
+ font-size: 8px;
1041
+ font-weight: 700;
1042
+ font-family: var(--roxy-font-sans);
1043
+ letter-spacing: 0.05em;
1044
+ }
1045
+ .lagna-bg {
1046
+ fill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 12%, transparent);
1047
+ stroke: color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);
1048
+ stroke-width: 0.8;
1049
+ }
1050
+ .vargottama-row {
1051
+ display: flex;
1052
+ flex-wrap: wrap;
1053
+ gap: var(--roxy-space-xs, 0.25rem);
1054
+ align-items: center;
1055
+ }
1056
+ .vargottama-label {
1057
+ font-size: var(--roxy-text-sm, 0.875rem);
1058
+ color: var(--roxy-muted, #71717a);
1059
+ font-weight: 500;
1060
+ margin-right: var(--roxy-space-xs, 0.25rem);
1061
+ }
1062
+ .vargottama-pill {
1063
+ display: inline-flex;
1064
+ align-items: center;
1065
+ gap: 0.2em;
1066
+ font-size: var(--roxy-text-sm, 0.875rem);
1067
+ font-weight: 600;
1068
+ padding: 0.15em 0.6em;
1069
+ border-radius: 999px;
1070
+ background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 22%, transparent);
1071
+ color: var(--roxy-fg, #0a0a0a);
1072
+ border: 1px solid color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);
1073
+ }
1074
+ `],c([y({attribute:!1})],I.prototype,"data",2),c([y({type:String,reflect:!0,attribute:"chart-style"})],I.prototype,"chartStyle",2),I=c([v("roxy-divisional-chart")],I);var gr={manglik:"Mangal Dosha",kalsarpa:"Kaal Sarp Dosha",sadhesati:"Sade Sati"},B=class extends u{constructor(){super(...arguments);this.data=null;this.type="manglik"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No dosha data</div>`;let t=!!e.present,s=gr[this.type]??this.type,o=(e.severity??"").toLowerCase(),l=o==="severe"?3:o==="moderate"?2:o==="mild"?1:0,d=l*33,p=l===3?"var(--roxy-danger)":l===2?"var(--roxy-warning)":l===1?"var(--roxy-success)":"transparent";return a`<article
1075
+ class="card"
1076
+ aria-label=${s}
1077
+ >
1078
+ <header class="head">
1079
+ <h2 class="title">${s}</h2>
1080
+ <span class=${`badge ${t?"present":"absent"}`}>
1081
+ ${t?"Present":"Absent"}
1082
+ </span>
1083
+ </header>
1084
+ ${e.severity?a`<div
1085
+ class="severity-bar"
1086
+ role="meter"
1087
+ aria-valuemin="0"
1088
+ aria-valuemax="3"
1089
+ aria-valuenow="${l}"
1090
+ aria-label="Severity ${e.severity}"
1091
+ >
1092
+ <span class="severity-fill" style="width: ${d}%; background: ${p};"></span>
1093
+ </div>`:n}
1094
+ ${e.description?a`<p class="description">${e.description}</p>`:n}
1095
+ ${this.renderEffects(e)}
1096
+ ${e.remedies&&e.remedies.length>0?a`<div>
1097
+ <h3>Remedies</h3>
1098
+ <ul>
1099
+ ${e.remedies.map(m=>a`<li>${m}</li>`)}
1100
+ </ul>
1101
+ </div>`:n}
1102
+ ${"exceptions"in e&&e.exceptions&&e.exceptions.length>0?a`<div>
1103
+ <h3>Exceptions</h3>
1104
+ <ul>
1105
+ ${e.exceptions.map(m=>a`<li>${m}</li>`)}
1106
+ </ul>
1107
+ </div>`:n}
1108
+ </article>`}renderEffects(e){if(!e.effects)return n;let t=Object.entries(e.effects).filter(([,s])=>typeof s=="string"&&s.length>0);return t.length===0?n:a`<div class="effects">
1109
+ ${t.map(([s,o])=>a`<div>
1110
+ <h3>${s}</h3>
1111
+ <p>${o}</p>
1112
+ </div>`)}
1113
+ </div>`}};B.styles=[b,x`
1114
+ .card {
1115
+ background: var(--roxy-bg, #fff);
1116
+ border: 1px solid var(--roxy-border, #e4e4e7);
1117
+ border-radius: var(--roxy-radius-md, 8px);
1118
+ padding: var(--roxy-space-lg, 1.5rem);
1119
+ box-shadow: var(--roxy-shadow-sm);
1120
+ display: grid;
1121
+ gap: var(--roxy-space-md, 1rem);
1122
+ }
1123
+ .head {
1124
+ display: flex;
1125
+ align-items: center;
1126
+ justify-content: space-between;
1127
+ gap: var(--roxy-space-md, 1rem);
1128
+ flex-wrap: wrap;
1129
+ }
1130
+ .title {
1131
+ margin: 0;
1132
+ font-size: var(--roxy-text-lg, 1.125rem);
1133
+ font-weight: var(--roxy-weight-bold, 600);
1134
+ text-transform: capitalize;
1135
+ }
1136
+ .badge {
1137
+ display: inline-flex;
1138
+ align-items: center;
1139
+ gap: var(--roxy-space-xs, 0.25rem);
1140
+ padding: 4px 10px;
1141
+ border-radius: var(--roxy-radius-full, 9999px);
1142
+ font-size: var(--roxy-text-xs, 0.75rem);
1143
+ font-weight: var(--roxy-weight-bold, 600);
1144
+ text-transform: uppercase;
1145
+ letter-spacing: 0.06em;
1146
+ }
1147
+ .badge.absent {
1148
+ background: color-mix(in srgb, var(--roxy-success, #16a34a) 16%, transparent);
1149
+ color: var(--roxy-success-fg, #166534);
1150
+ }
1151
+ .badge.present {
1152
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 16%, transparent);
1153
+ color: var(--roxy-danger-fg, #991b1b);
687
1154
  }
688
- .severity.mild span:nth-child(1) {
689
- background: var(--roxy-warning, #ea580c);
1155
+ .severity-bar {
1156
+ position: relative;
1157
+ width: 100%;
1158
+ height: 8px;
1159
+ background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 30%, transparent);
1160
+ border-radius: 4px;
1161
+ overflow: hidden;
690
1162
  }
691
- .severity.moderate span:nth-child(-n + 2) {
692
- background: var(--roxy-warning, #ea580c);
1163
+ .severity-fill {
1164
+ display: block;
1165
+ height: 100%;
1166
+ transition: width var(--roxy-motion-duration, 200ms) ease-out;
1167
+ border-radius: 4px;
693
1168
  }
694
- .severity.severe span {
695
- background: var(--roxy-danger, #dc2626);
1169
+ @media (prefers-reduced-motion: reduce) {
1170
+ .severity-fill {
1171
+ transition: none;
1172
+ }
696
1173
  }
697
1174
 
698
1175
  .description {
@@ -721,33 +1198,36 @@
721
1198
  margin: 0;
722
1199
  font-size: var(--roxy-text-sm, 0.875rem);
723
1200
  }
724
- `],d([p({attribute:!1})],N.prototype,"data",2),d([p({type:String,reflect:!0})],N.prototype,"type",2),N=d([x("roxy-dosha-card")],N);var A=class extends g{constructor(){super(...arguments);this.endpoint="vedic-astrology/birth-chart";this.method="POST";this.specUrl="https://roxyapi.com/api/v2/openapi.json";this.submitLabel="Submit";this.fields=[];this.values={};this.hasLocation=!1;this.loaded=!1;this.onLocation=e=>{let r=e.detail;r&&(this.values={...this.values,latitude:r.latitude,longitude:r.longitude,timezone:r.timezone??r.utcOffset})};this.onSubmit=e=>{e.preventDefault();let r=this.fields.filter(a=>a.required).filter(a=>this.values[a.name]===void 0||this.values[a.name]==="");if(r.length>0){this.dispatchEvent(new CustomEvent("roxy-validation-error",{detail:{missing:r.map(a=>a.name)},bubbles:!0,composed:!0}));return}this.dispatchEvent(new CustomEvent("roxy-submit",{detail:{endpoint:this.endpoint,values:this.values},bubbles:!0,composed:!0}))}}connectedCallback(){super.connectedCallback(),this.loadSchema()}async loadSchema(){try{let e=await fetch(this.specUrl);if(!e.ok)throw new Error(`HTTP ${e.status}`);let r=await e.json(),a=`/${this.endpoint.replace(/^\//,"")}`,i=r.paths?.[a]?.[this.method.toLowerCase()];if(!i)return;let n=r.components?.schemas??{},c=[],m;if(i.requestBody){let h=i.requestBody.content?.["application/json"]?.schema;m=this.resolve(h,n)}if(m?.properties){let h=new Set(m.required??[]);for(let[v,S]of Object.entries(m.properties)){let w=this.resolve(S,n)??{};c.push({name:v,type:this.fieldType(w),required:h.has(v),description:w.description,enum:w.enum,min:w.minimum,max:w.maximum,default:w.default})}}for(let h of i.parameters??[])if(h.in==="path"||h.in==="query"){let v=this.resolve(h.schema,n)??{};c.push({name:h.name,type:this.fieldType(v),required:!!h.required,description:v.description,enum:v.enum,default:v.default})}this.fields=c,this.hasLocation=c.some(h=>h.name==="latitude")&&c.some(h=>h.name==="longitude")&&c.some(h=>h.name==="timezone");let u={};for(let h of c)h.default!==void 0&&(u[h.name]=h.default);this.values=u,this.loaded=!0}catch{this.loaded=!0}}resolve(e,r){if(e){if("$ref"in e&&e.$ref){let a=e.$ref.split("/").pop();return a?r[a]:void 0}return e}}fieldType(e){return e.enum?"enum":e.format==="date"?"date":e.format==="time"?"time":e.format==="date-time"?"datetime":e.type==="integer"||e.type==="number"?"number":"text"}setValue(e,r){this.values={...this.values,[e]:r}}render(){if(!this.loaded)return s`<form><div class="roxy-skeleton" style="height: 8rem"></div></form>`;let e=r=>{if(this.hasLocation&&(r.name==="latitude"||r.name==="longitude"||r.name==="timezone"))return l;let a=`roxy-form-${r.name}`;return s`<div class="field">
725
- <label for=${a}>
726
- ${ar(r.name)}${r.required?s`<span class="req" aria-hidden="true">*</span>`:l}
1201
+ `],c([y({attribute:!1})],B.prototype,"data",2),c([y({type:String,reflect:!0})],B.prototype,"type",2),B=c([v("roxy-dosha-card")],B);var ot=new Map;async function yr(i){let r=ot.get(i);return r||(r=fetch(i).then(async e=>{if(!e.ok)throw new Error(`HTTP ${e.status}`);return await e.json()}).catch(e=>{throw ot.delete(i),e}),ot.set(i,r)),r}var _=class extends u{constructor(){super(...arguments);this.endpoint="vedic-astrology/birth-chart";this.method="POST";this.specUrl="https://roxyapi.com/api/v2/openapi.json";this.submitLabel="Submit";this.fields=[];this.values={};this.hasLocation=!1;this.loaded=!1;this.specError=null;this.retryLoadSchema=()=>{this.loaded=!1,this.specError=null,this.loadSchema()};this.onLocation=e=>{let t=e.detail;t&&(this.values={...this.values,latitude:t.latitude,longitude:t.longitude,timezone:t.timezone??t.utcOffset})};this.onSubmit=e=>{e.preventDefault();let t=this.fields.filter(s=>s.required).filter(s=>this.values[s.name]===void 0||this.values[s.name]==="");if(t.length>0){this.dispatchEvent(new CustomEvent("roxy-validation-error",{detail:{missing:t.map(s=>s.name)},bubbles:!0,composed:!0}));return}this.dispatchEvent(new CustomEvent("roxy-submit",{detail:{endpoint:this.endpoint,values:this.values},bubbles:!0,composed:!0}))}}connectedCallback(){super.connectedCallback(),this.loadSchema()}async loadSchema(){this.specError=null;try{let e=await yr(this.specUrl),t=`/${this.endpoint.replace(/^\//,"")}`,s=e.paths?.[t]?.[this.method.toLowerCase()];if(!s)throw new Error(`Endpoint ${this.method} ${t} not found in OpenAPI spec`);let o=e.components?.schemas??{},l=[],d;if(s.requestBody){let m=s.requestBody.content?.["application/json"]?.schema;d=this.resolve(m,o)}if(d?.properties){let m=new Set(d.required??[]);for(let[h,g]of Object.entries(d.properties)){let f=this.resolve(g,o)??{};l.push({name:h,type:this.fieldType(f),required:m.has(h),description:f.description,enum:f.enum,min:f.minimum,max:f.maximum,default:f.default})}}for(let m of s.parameters??[])if(m.in==="path"||m.in==="query"){let h=this.resolve(m.schema,o)??{};l.push({name:m.name,type:this.fieldType(h),required:!!m.required,description:h.description,enum:h.enum,default:h.default})}this.fields=l,this.hasLocation=l.some(m=>m.name==="latitude")&&l.some(m=>m.name==="longitude")&&l.some(m=>m.name==="timezone");let p={};for(let m of l)m.default!==void 0&&(p[m.name]=m.default);this.values=p,this.loaded=!0}catch(e){let t=e instanceof Error?e.message:String(e);this.specError=t,this.loaded=!0,this.dispatchEvent(new CustomEvent("roxy-spec-error",{detail:{url:this.specUrl,message:t},bubbles:!0,composed:!0}))}}resolve(e,t){if(e){if("$ref"in e&&e.$ref){let s=e.$ref.split("/").pop();return s?t[s]:void 0}return e}}fieldType(e){return e.enum?"enum":e.format==="date"?"date":e.format==="time"?"time":e.format==="date-time"?"datetime":e.type==="integer"||e.type==="number"?"number":"text"}setValue(e,t){this.values={...this.values,[e]:t}}render(){if(!this.loaded)return a`<form><div class="roxy-skeleton" style="height: 8rem"></div></form>`;if(this.specError)return a`<div class="spec-error" role="alert">
1202
+ Schema load failed: ${this.specError}
1203
+ <button type="button" class="submit" @click=${this.retryLoadSchema}>Retry</button>
1204
+ </div>`;let e=t=>{if(this.hasLocation&&(t.name==="latitude"||t.name==="longitude"||t.name==="timezone"))return n;let s=`roxy-form-${t.name}`;return a`<div class="field">
1205
+ <label for=${s}>
1206
+ ${ee(t.name)}${t.required?a`<span class="req" aria-hidden="true">*</span>`:n}
727
1207
  </label>
728
- ${r.enum?s`<select
729
- id=${a}
730
- ?required=${r.required}
731
- @change=${i=>this.setValue(r.name,i.target.value)}
1208
+ ${t.enum?a`<select
1209
+ id=${s}
1210
+ ?required=${t.required}
1211
+ @change=${o=>this.setValue(t.name,o.target.value)}
732
1212
  >
733
1213
  <option value="">Choose</option>
734
- ${r.enum.map(i=>s`<option value=${i} ?selected=${this.values[r.name]===i}>
735
- ${i}
1214
+ ${t.enum.map(o=>a`<option value=${o} ?selected=${this.values[t.name]===o}>
1215
+ ${o}
736
1216
  </option>`)}
737
- </select>`:s`<input
738
- id=${a}
739
- type=${this.htmlType(r.type)}
740
- ?required=${r.required}
741
- min=${r.min??""}
742
- max=${r.max??""}
743
- step=${r.type==="number"?"any":""}
744
- .value=${this.values[r.name]??""}
745
- @input=${i=>this.setValue(r.name,this.coerce(r.type,i.target.value))}
1217
+ </select>`:a`<input
1218
+ id=${s}
1219
+ type=${this.htmlType(t.type)}
1220
+ ?required=${t.required}
1221
+ min=${t.min??""}
1222
+ max=${t.max??""}
1223
+ step=${t.type==="number"?"any":""}
1224
+ .value=${this.values[t.name]??""}
1225
+ @input=${o=>this.setValue(t.name,this.coerce(t.type,o.target.value))}
746
1226
  />`}
747
- ${r.description?s`<small class="help">${r.description}</small>`:l}
748
- </div>`};return s`<form @submit=${this.onSubmit}>
749
- <h2 class="title">${ar(this.endpoint.split("/").pop()??"")}</h2>
750
- ${this.hasLocation?s`<div class="location-block">
1227
+ ${t.description?a`<small class="help">${t.description}</small>`:n}
1228
+ </div>`};return a`<form @submit=${this.onSubmit}>
1229
+ <h2 class="title">${ee(this.endpoint.split("/").pop()??"")}</h2>
1230
+ ${this.hasLocation?a`<div class="location-block">
751
1231
  <label>Birth location</label>
752
1232
  <roxy-location-search
753
1233
  @roxy-location-select=${this.onLocation}
@@ -756,12 +1236,12 @@
756
1236
  <small class="help">
757
1237
  Required: latitude, longitude, timezone. Pick a city to autofill.
758
1238
  </small>
759
- </div>`:l}
1239
+ </div>`:n}
760
1240
  <div class="fields">
761
- ${this.fields.map(r=>e(r))}
1241
+ ${this.fields.map(t=>e(t))}
762
1242
  </div>
763
1243
  <button class="submit" type="submit">${this.submitLabel}</button>
764
- </form>`}htmlType(e){switch(e){case"date":return"date";case"time":return"time";case"datetime":return"datetime-local";case"number":return"number";default:return"text"}}coerce(e,r){if(r!==""){if(e==="number"){let a=Number(r);return Number.isFinite(a)?a:void 0}return r}}};A.styles=[f,y`
1244
+ </form>`}htmlType(e){switch(e){case"date":return"date";case"time":return"time";case"datetime":return"datetime-local";case"number":return"number";default:return"text"}}coerce(e,t){if(t!==""){if(e==="number"){let s=Number(t);return Number.isFinite(s)?s:void 0}return t}}};_.styles=[b,x`
765
1245
  form {
766
1246
  display: grid;
767
1247
  gap: var(--roxy-space-md, 1rem);
@@ -779,22 +1259,27 @@
779
1259
  .fields {
780
1260
  display: grid;
781
1261
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
1262
+ align-items: start;
782
1263
  gap: var(--roxy-space-md, 1rem);
783
1264
  }
784
1265
  .field {
785
- display: grid;
1266
+ display: flex;
1267
+ flex-direction: column;
786
1268
  gap: var(--roxy-space-xs, 0.25rem);
1269
+ min-width: 0;
787
1270
  }
788
1271
  label {
789
1272
  font-size: var(--roxy-text-sm, 0.875rem);
790
1273
  color: var(--roxy-secondary, #475569);
791
1274
  }
792
1275
  label .req {
793
- color: var(--roxy-danger, #dc2626);
1276
+ color: var(--roxy-danger-fg, #991b1b);
794
1277
  margin-left: 4px;
795
1278
  }
796
1279
  input,
797
1280
  select {
1281
+ width: 100%;
1282
+ box-sizing: border-box;
798
1283
  padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
799
1284
  font-size: var(--roxy-text-base, 1rem);
800
1285
  font-family: inherit;
@@ -829,7 +1314,7 @@
829
1314
  button.submit {
830
1315
  justify-self: start;
831
1316
  background: var(--roxy-accent-fg, #b45309);
832
- color: #fff;
1317
+ color: var(--roxy-bg, #fff);
833
1318
  border: 0;
834
1319
  border-radius: var(--roxy-radius-md, 8px);
835
1320
  padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-lg, 1.5rem);
@@ -847,19 +1332,44 @@
847
1332
  outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
848
1333
  outline-offset: 2px;
849
1334
  }
850
- `],d([p({type:String,attribute:"data-endpoint"})],A.prototype,"endpoint",2),d([p({type:String})],A.prototype,"method",2),d([p({type:String,attribute:"spec-url"})],A.prototype,"specUrl",2),d([p({type:String,attribute:"submit-label"})],A.prototype,"submitLabel",2),d([_()],A.prototype,"fields",2),d([_()],A.prototype,"values",2),d([_()],A.prototype,"hasLocation",2),d([_()],A.prototype,"loaded",2),A=d([x("roxy-endpoint-form")],A);function ar(o){return o.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/^\w/,t=>t.toUpperCase())}var G=class extends g{constructor(){super(...arguments);this.data=null}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No Guna Milan data</div>`;let r=e.total??e.totalScore??0,a=e.maxScore??36,i=(e.breakdown??[]).filter(n=>n&&(n.name||n.score!==void 0));return s`<article class="card" aria-label="Guna Milan score">
851
- <div class="score-bar">
852
- <div>
853
- <span class="total">${r}</span>
854
- <span class="over"> / ${a}</span>
855
- ${typeof e.percentage=="number"?s`<small style="margin-left: 0.5rem; color: var(--roxy-muted)">
856
- ${e.percentage}%
857
- </small>`:l}
1335
+ .spec-error {
1336
+ display: grid;
1337
+ gap: var(--roxy-space-md, 1rem);
1338
+ justify-items: start;
1339
+ background: var(--roxy-bg, #fff);
1340
+ border: 1px solid var(--roxy-danger, #dc2626);
1341
+ border-radius: var(--roxy-radius-md, 8px);
1342
+ padding: var(--roxy-space-lg, 1.5rem);
1343
+ color: var(--roxy-danger-fg, #991b1b);
1344
+ font-size: var(--roxy-text-sm, 0.875rem);
1345
+ }
1346
+ `],c([y({type:String,attribute:"data-endpoint"})],_.prototype,"endpoint",2),c([y({type:String})],_.prototype,"method",2),c([y({type:String,attribute:"spec-url"})],_.prototype,"specUrl",2),c([y({type:String,attribute:"submit-label"})],_.prototype,"submitLabel",2),c([E()],_.prototype,"fields",2),c([E()],_.prototype,"values",2),c([E()],_.prototype,"hasLocation",2),c([E()],_.prototype,"loaded",2),c([E()],_.prototype,"specError",2),_=c([v("roxy-endpoint-form")],_);var re=class extends u{constructor(){super(...arguments);this.data=null}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No Guna Milan data</div>`;let t=(e.breakdown??[]).filter(g=>g?.category!==void 0),s=e.total??0,o=e.maxScore??36,l=s/o*100,d="color-mix(in srgb, var(--roxy-border) 50%, transparent)",p=l>=70?"var(--roxy-success)":l>=50?"var(--roxy-warning)":"var(--roxy-danger)",m=l*2.827,h=(100-l)*2.827;return a`<article class="card" aria-label="Guna Milan score">
1347
+ <div class="score-header">
1348
+ <div class="score-info">
1349
+ <div class="score-bar">
1350
+ <div>
1351
+ <span class="total">${w(e.total,1)}</span>
1352
+ <span class="over"> / ${e.maxScore}</span>
1353
+ ${typeof e.percentage=="number"?a`<small style="margin-left: 0.5rem; color: var(--roxy-muted)">
1354
+ ${Nt(e.percentage,1)}
1355
+ </small>`:n}
1356
+ </div>
1357
+ ${e.recommendation?a`<span class="recommendation">${e.recommendation}</span>`:n}
1358
+ </div>
1359
+ </div>
1360
+ <div class="score-ring" role="meter" aria-label="Guna milan score" aria-valuemin="0" aria-valuemax="36" aria-valuenow="${s}">
1361
+ <svg viewBox="0 0 100 100" aria-hidden="true">
1362
+ <circle class="ring-track" cx="50" cy="50" r="45" fill="none" stroke="${d}" stroke-width="8"/>
1363
+ <circle class="ring-fill" cx="50" cy="50" r="45" fill="none" stroke="${p}" stroke-width="8"
1364
+ stroke-dasharray="${m},${h}" stroke-linecap="round"
1365
+ transform="rotate(-90 50 50)"/>
1366
+ <text x="50" y="50" text-anchor="middle" dominant-baseline="central" class="ring-text">${s}</text>
1367
+ <text x="50" y="64" text-anchor="middle" dominant-baseline="central" class="ring-max">/${o}</text>
1368
+ </svg>
858
1369
  </div>
859
- ${e.recommendation?s`<span class="recommendation">${e.recommendation}</span>`:l}
860
1370
  </div>
861
1371
 
862
- ${i.length>0?s`<table>
1372
+ ${t.length>0?a`<table>
863
1373
  <thead>
864
1374
  <tr>
865
1375
  <th>Category</th>
@@ -868,22 +1378,22 @@
868
1378
  </tr>
869
1379
  </thead>
870
1380
  <tbody>
871
- ${i.map(n=>{let c=n.score??0,m=n.max??n.maxScore??Hr(n.name),u=m?c/m*100:0;return s`<tr>
872
- <td>${n.name??""}</td>
1381
+ ${t.map(g=>{let f=g.score??0,k=g.maxScore??ur(g.category),$=k?f/k*100:0;return a`<tr>
1382
+ <td>${g.category}</td>
873
1383
  <td class="bar-cell">
874
1384
  <div class="mini-bar">
875
- <span style="width: ${u}%"></span>
1385
+ <span style="width: ${$}%"></span>
876
1386
  </div>
877
1387
  </td>
878
- <td class="score">${c} / ${m}</td>
1388
+ <td class="score">${w(f,1)} / ${k}</td>
879
1389
  </tr>`})}
880
1390
  </tbody>
881
- </table>`:l}
882
- ${(e.doshas?.length??0)>0||(e.doshaCancellations?.length??0)>0?s`<div class="tags">
883
- ${e.doshas?.map(n=>s`<span class="dosha">${n}</span>`)}
884
- ${e.doshaCancellations?.map(n=>s`<span class="cancel">${n}</span>`)}
885
- </div>`:l}
886
- </article>`}};G.styles=[f,y`
1391
+ </table>`:n}
1392
+ ${(e.doshas?.length??0)>0||(e.doshaCancellations?.length??0)>0?a`<div class="tags">
1393
+ ${e.doshas?.map(g=>a`<span class="dosha">${g}</span>`)}
1394
+ ${e.doshaCancellations?.map(g=>a`<span class="cancel" title=${g.reason}>${g.dosha} cancelled</span>`)}
1395
+ </div>`:n}
1396
+ </article>`}};re.styles=[b,x`
887
1397
  .card {
888
1398
  background: var(--roxy-bg, #fff);
889
1399
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -894,6 +1404,14 @@
894
1404
  gap: var(--roxy-space-md, 1rem);
895
1405
  }
896
1406
 
1407
+ .score-header {
1408
+ display: flex;
1409
+ align-items: center;
1410
+ gap: 1rem;
1411
+ }
1412
+ .score-info {
1413
+ flex: 1;
1414
+ }
897
1415
  .score-bar {
898
1416
  display: grid;
899
1417
  grid-template-columns: 1fr auto;
@@ -915,6 +1433,26 @@
915
1433
  font-size: var(--roxy-text-sm, 0.875rem);
916
1434
  color: var(--roxy-secondary, #475569);
917
1435
  }
1436
+ .score-ring {
1437
+ width: 120px;
1438
+ height: 120px;
1439
+ flex-shrink: 0;
1440
+ }
1441
+ .score-ring svg {
1442
+ width: 100%;
1443
+ height: 100%;
1444
+ }
1445
+ .score-ring .ring-text {
1446
+ font-size: 22px;
1447
+ font-weight: 700;
1448
+ fill: var(--roxy-fg, #0a0a0a);
1449
+ font-family: var(--roxy-font-sans);
1450
+ }
1451
+ .score-ring .ring-max {
1452
+ font-size: 10px;
1453
+ fill: var(--roxy-muted, #71717a);
1454
+ font-family: var(--roxy-font-sans);
1455
+ }
918
1456
 
919
1457
  table {
920
1458
  width: 100%;
@@ -970,54 +1508,54 @@
970
1508
  }
971
1509
  .tags .dosha {
972
1510
  background: color-mix(in srgb, var(--roxy-danger, #dc2626) 16%, transparent);
973
- color: var(--roxy-danger, #dc2626);
1511
+ color: var(--roxy-danger-fg, #991b1b);
974
1512
  }
975
1513
  .tags .cancel {
976
1514
  background: color-mix(in srgb, var(--roxy-success, #16a34a) 18%, transparent);
977
- color: var(--roxy-success, #16a34a);
1515
+ color: var(--roxy-success-fg, #166534);
978
1516
  }
979
- `],d([p({attribute:!1})],G.prototype,"data",2),G=d([x("roxy-guna-milan")],G);function Hr(o){if(!o)return 1;switch(o.toLowerCase()){case"varna":return 1;case"vasya":return 2;case"tara":return 3;case"yoni":return 4;case"maitri":return 5;case"gana":return 6;case"bhakoot":return 7;case"nadi":return 8;default:return 1}}var xe={Sun:"\u2609",Moon:"\u263D",Mercury:"\u263F",Venus:"\u2640",Earth:"\u2641",Mars:"\u2642",Jupiter:"\u2643",Saturn:"\u2644",Uranus:"\u2645",Neptune:"\u2646",Pluto:"\u2647",Rahu:"\u260A",Ketu:"\u260B",Ascendant:"Asc",Lagna:"La",NorthNode:"\u260A",SouthNode:"\u260B"},sr={Sun:"Su",Moon:"Mo",Mercury:"Me",Venus:"Ve",Mars:"Ma",Jupiter:"Ju",Saturn:"Sa",Uranus:"Ur",Neptune:"Ne",Pluto:"Pl",Rahu:"Ra",Ketu:"Ke",Ascendant:"Asc",Lagna:"La"},re={Aries:"\u2648",Taurus:"\u2649",Gemini:"\u264A",Cancer:"\u264B",Leo:"\u264C",Virgo:"\u264D",Libra:"\u264E",Scorpio:"\u264F",Sagittarius:"\u2650",Capricorn:"\u2651",Aquarius:"\u2652",Pisces:"\u2653"},ir={Aries:"Ar",Taurus:"Ta",Gemini:"Ge",Cancer:"Cn",Leo:"Le",Virgo:"Vi",Libra:"Li",Scorpio:"Sc",Sagittarius:"Sg",Capricorn:"Cp",Aquarius:"Aq",Pisces:"Pi"};var Ne={heaven:"\u2630",lake:"\u2631",fire:"\u2632",thunder:"\u2633",wind:"\u2634",water:"\u2635",mountain:"\u2636",earth:"\u2637",Heaven:"\u2630",Lake:"\u2631",Fire:"\u2632",Thunder:"\u2633",Wind:"\u2634",Water:"\u2635",Mountain:"\u2636",Earth:"\u2637"},nr={"new moon":"\u{1F311}","waxing crescent":"\u{1F312}","first quarter":"\u{1F313}","waxing gibbous":"\u{1F314}","full moon":"\u{1F315}","waning gibbous":"\u{1F316}","last quarter":"\u{1F317}","waning crescent":"\u{1F318}"};var C=class extends g{constructor(){super(...arguments);this.data=null;this.mode="lookup"}getHexagram(){return this.data?"hexagram"in this.data&&this.data.hexagram?{...this.data.hexagram,lines:this.data.lines,changingLinePositions:this.data.changingLinePositions}:this.data:null}render(){let e=this.getHexagram();if(!e)return s`<div class="roxy-empty" role="status">No hexagram data</div>`;let r=e.lines??this.derivedLines(e),a=new Set(e.changingLinePositions??[]);return s`<article class="card" aria-label="I Ching hexagram">
1517
+ `],c([y({attribute:!1})],re.prototype,"data",2),re=c([v("roxy-guna-milan")],re);function ur(i){if(!i)return 1;switch(i.toLowerCase()){case"varna":return 1;case"vasya":return 2;case"tara":return 3;case"yoni":return 4;case"maitri":return 5;case"gana":return 6;case"bhakoot":return 7;case"nadi":return 8;default:return 1}}var q=class extends u{constructor(){super(...arguments);this.data=null;this.mode="lookup"}resolveHexagram(){let e=this.data;if(!e)return null;if("hexagram"in e&&e.hexagram){if("lines"in e){let s=e;return{hex:s.hexagram,lines:s.lines,changingLinePositions:s.changingLinePositions,resultingHexagram:s.resultingHexagram}}let t=e;return{hex:t.hexagram,dailyMessage:t.dailyMessage}}return{hex:e}}render(){let e=this.resolveHexagram();if(!e)return a`<div class="roxy-empty" role="status">No hexagram data</div>`;let{hex:t,lines:s,changingLinePositions:o,dailyMessage:l,resultingHexagram:d}=e,p=s??this.derivedLines(t),m=new Set(o??[]);return a`<article class="card" aria-label="I Ching hexagram">
980
1518
  <div class="glyphs">
981
- ${e.symbol?s`<div class="symbol">${e.symbol}</div>`:l}
1519
+ ${t.symbol?a`<div class="symbol">${t.symbol}</div>`:n}
982
1520
  <div class="lines" aria-hidden="true">
983
- ${r.slice().reverse().map((i,n)=>{let c=r.length-1-n+1,m=a.has(c),u=i===6||i===8;return s`<div class="line ${`${u?"broken":"solid"}${m?" changing":""}`}">
984
- ${u?$`<span class="seg"></span><span class="seg"></span>`:$`<span class="seg"></span>`}
1521
+ ${p.slice().reverse().map((h,g)=>{let f=p.length-1-g+1,k=m.has(f),$=h===6||h===8;return a`<div class="line ${`${$?"broken":"solid"}${k?" changing":""}`}">
1522
+ ${$?S`<span class="seg"></span><span class="seg"></span>`:S`<span class="seg"></span>`}
985
1523
  </div>`})}
986
1524
  </div>
987
1525
  </div>
988
1526
  <div>
989
1527
  <h2 class="title">
990
- ${e.number?s`${e.number}. `:l}${e.english??e.chinese??"Hexagram"}
1528
+ ${t.number?a`${t.number}. `:n}${t.english??t.chinese??"Hexagram"}
991
1529
  </h2>
992
1530
  <p class="subtitle">
993
- ${e.chinese?s`${e.chinese}`:l}
994
- ${e.pinyin?s` · ${e.pinyin}`:l}
1531
+ ${t.chinese?a`${t.chinese}`:n}
1532
+ ${t.pinyin?a` · ${t.pinyin}`:n}
995
1533
  </p>
996
1534
  <div class="trigrams">
997
- ${e.upperTrigram?s`<div>
1535
+ ${t.upperTrigram?a`<div>
998
1536
  Upper
999
1537
  <span class="tri-glyph"
1000
- >${Ne[e.upperTrigram]??""}</span
1001
- >${e.upperTrigram}
1002
- </div>`:l}
1003
- ${e.lowerTrigram?s`<div>
1538
+ >${at[t.upperTrigram]??""}</span
1539
+ >${t.upperTrigram}
1540
+ </div>`:n}
1541
+ ${t.lowerTrigram?a`<div>
1004
1542
  Lower
1005
1543
  <span class="tri-glyph"
1006
- >${Ne[e.lowerTrigram]??""}</span
1007
- >${e.lowerTrigram}
1008
- </div>`:l}
1544
+ >${at[t.lowerTrigram]??""}</span
1545
+ >${t.lowerTrigram}
1546
+ </div>`:n}
1009
1547
  </div>
1010
- ${e.judgment?s`<p class="judgment">${e.judgment}</p>`:l}
1011
- ${e.image?s`<p class="image">${e.image}</p>`:l}
1012
- ${e.dailyMessage?s`<p class="message">${e.dailyMessage}</p>`:l}
1013
- ${e.interpretation?.general?s`<p>${e.interpretation.general}</p>`:l}
1014
- ${a.size>0?s`<div class="changing">
1015
- Changing lines: ${Array.from(a).sort((i,n)=>i-n).join(", ")}.
1016
- ${e.resultingHexagram?.english?s` Becomes hexagram ${e.resultingHexagram.number}
1017
- ${e.resultingHexagram.english}.`:l}
1018
- </div>`:l}
1548
+ ${t.judgment?a`<p class="judgment">${t.judgment}</p>`:n}
1549
+ ${t.image?a`<p class="image">${t.image}</p>`:n}
1550
+ ${l?a`<p class="message">${l}</p>`:n}
1551
+ ${t.interpretation?.general?a`<p>${t.interpretation.general}</p>`:n}
1552
+ ${m.size>0?a`<div class="changing">
1553
+ Changing lines: ${Array.from(m).sort((h,g)=>h-g).join(", ")}.
1554
+ ${d?.english?a` Becomes hexagram ${d.number}
1555
+ ${d.english}.`:n}
1556
+ </div>`:n}
1019
1557
  </div>
1020
- </article>`}derivedLines(e){if(!e.symbol)return Array.from({length:6},()=>7);let r=e.symbol.codePointAt(0)??0;if(r>=19904&&r<=19967){let a=r-19904,i=[];for(let n=0;n<6;n++){let c=a>>n&1;i.push(c?8:7)}return i}return Array.from({length:6},()=>7)}};C.styles=[f,y`
1558
+ </article>`}derivedLines(e){let t=e.symbol.codePointAt(0)??0;if(t>=19904&&t<=19967){let s=t-19904,o=[];for(let l=0;l<6;l++){let d=s>>l&1;o.push(d?8:7)}return o}return Array.from({length:6},()=>7)}};q.styles=[b,x`
1021
1559
  .card {
1022
1560
  background: var(--roxy-bg, #fff);
1023
1561
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -1124,67 +1662,67 @@
1124
1662
  color: var(--roxy-accent-fg, #b45309);
1125
1663
  font-size: var(--roxy-text-sm, 0.875rem);
1126
1664
  }
1127
- `],d([p({attribute:!1})],C.prototype,"data",2),d([p({type:String,reflect:!0})],C.prototype,"mode",2),C=d([x("roxy-hexagram")],C);var D=class extends g{constructor(){super(...arguments);this.data=null;this.period="daily"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No horoscope data</div>`;let r=e.sign??"",a=r?re[jr(r)]??"":"",i=typeof e.energyRating=="number"?e.energyRating:null,n=e.date??e.week??e.month??"";return s`<article
1665
+ `],c([y({attribute:!1})],q.prototype,"data",2),c([y({type:String,reflect:!0})],q.prototype,"mode",2),q=c([v("roxy-hexagram")],q);var U=class extends u{constructor(){super(...arguments);this.data=null;this.period="daily"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No horoscope data</div>`;let t=e.sign??"",s=t?N[C(t)]??"":"",o="energyRating"in e&&typeof e.energyRating=="number"?e.energyRating:null,l="date"in e&&e.date||"week"in e&&e.week||"month"in e&&e.month||"";return a`<article
1128
1666
  class="card"
1129
- aria-label=${`${this.period} horoscope for ${r}`}
1667
+ aria-label=${`${this.period} horoscope for ${t}`}
1130
1668
  >
1131
1669
  <header class="head">
1132
- <span class="glyph" aria-hidden="true">${a}</span>
1670
+ <span class="glyph" aria-hidden="true">${s}</span>
1133
1671
  <div>
1134
- <h2 class="title">${r} ${this.period}</h2>
1135
- ${n?s`<div class="date">${n}</div>`:l}
1672
+ <h2 class="title">${t} ${this.period}</h2>
1673
+ ${l?a`<div class="date">${l}</div>`:n}
1136
1674
  </div>
1137
- ${i!==null?s`<span class="energy" aria-label=${`Energy ${i} of 10`}>
1138
- Energy ${i}/10
1675
+ ${o!==null?a`<span class="energy" aria-label=${`Energy ${o} of 10`}>
1676
+ Energy ${o}/10
1139
1677
  <span class="energy-bar"
1140
- ><span style="width: ${i/10*100}%"></span
1678
+ ><span style="width: ${o/10*100}%"></span
1141
1679
  ></span>
1142
- </span>`:l}
1680
+ </span>`:n}
1143
1681
  </header>
1144
1682
 
1145
- ${e.overview?s`<p class="overview">${e.overview}</p>`:l}
1683
+ ${e.overview?a`<p class="overview">${e.overview}</p>`:n}
1146
1684
 
1147
1685
  <div class="sections">
1148
- ${e.love?s`<div class="section">
1686
+ ${e.love?a`<div class="section">
1149
1687
  <h3>Love</h3>
1150
1688
  <p>${e.love}</p>
1151
- </div>`:l}
1152
- ${e.career?s`<div class="section">
1689
+ </div>`:n}
1690
+ ${e.career?a`<div class="section">
1153
1691
  <h3>Career</h3>
1154
1692
  <p>${e.career}</p>
1155
- </div>`:l}
1156
- ${e.health?s`<div class="section">
1693
+ </div>`:n}
1694
+ ${e.health?a`<div class="section">
1157
1695
  <h3>Health</h3>
1158
1696
  <p>${e.health}</p>
1159
- </div>`:l}
1160
- ${e.finance?s`<div class="section">
1697
+ </div>`:n}
1698
+ ${e.finance?a`<div class="section">
1161
1699
  <h3>Finance</h3>
1162
1700
  <p>${e.finance}</p>
1163
- </div>`:l}
1164
- ${e.advice?s`<div class="section">
1701
+ </div>`:n}
1702
+ ${"advice"in e&&e.advice?a`<div class="section">
1165
1703
  <h3>Advice</h3>
1166
1704
  <p>${e.advice}</p>
1167
- </div>`:l}
1705
+ </div>`:n}
1168
1706
  </div>
1169
1707
 
1170
- ${e.luckyNumber||e.luckyColor||(e.compatibleSigns?.length??0)>0?s`<div class="lucky">
1171
- ${e.luckyNumber!==void 0?s`<span>Lucky number <strong>${e.luckyNumber}</strong></span>`:l}
1172
- ${e.luckyColor?s`<span>Lucky color <strong>${e.luckyColor}</strong></span>`:l}
1173
- ${e.luckyNumbers?.length?s`<span
1708
+ ${(()=>{let d="luckyNumber"in e&&e.luckyNumber!==void 0?e.luckyNumber:void 0,p="luckyColor"in e&&e.luckyColor?e.luckyColor:"",m="luckyNumbers"in e&&e.luckyNumbers?e.luckyNumbers:[],h="luckyDays"in e&&e.luckyDays?e.luckyDays:[],g=e.compatibleSigns??[];return d===void 0&&!p&&m.length===0&&h.length===0&&g.length===0?n:a`<div class="lucky">
1709
+ ${d!==void 0?a`<span>Lucky number <strong>${d}</strong></span>`:n}
1710
+ ${p?a`<span>Lucky color <strong>${p}</strong></span>`:n}
1711
+ ${m.length?a`<span
1174
1712
  >Lucky numbers
1175
- <strong>${e.luckyNumbers.join(", ")}</strong></span
1176
- >`:l}
1177
- ${e.luckyDays?.length?s`<span
1178
- >Lucky days <strong>${e.luckyDays.join(", ")}</strong></span
1179
- >`:l}
1180
- ${e.compatibleSigns?.length?s`<span class="compat-wrap">
1713
+ <strong>${m.join(", ")}</strong></span
1714
+ >`:n}
1715
+ ${h.length?a`<span
1716
+ >Lucky days <strong>${h.join(", ")}</strong></span
1717
+ >`:n}
1718
+ ${g.length?a`<span class="compat-wrap">
1181
1719
  Best with
1182
1720
  <span class="compat"
1183
- >${e.compatibleSigns.map(c=>s`<span>${c}</span>`)}</span
1721
+ >${g.map(f=>a`<span>${f}</span>`)}</span
1184
1722
  >
1185
- </span>`:l}
1186
- </div>`:l}
1187
- </article>`}};D.styles=[f,y`
1723
+ </span>`:n}
1724
+ </div>`})()}
1725
+ </article>`}};U.styles=[b,x`
1188
1726
  .card {
1189
1727
  background: var(--roxy-bg, #fff);
1190
1728
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -1286,6 +1824,13 @@
1286
1824
  font-weight: var(--roxy-weight-bold, 600);
1287
1825
  }
1288
1826
 
1827
+ .compat-wrap {
1828
+ width: 100%;
1829
+ display: flex;
1830
+ align-items: center;
1831
+ flex-wrap: wrap;
1832
+ gap: var(--roxy-space-xs, 0.25rem);
1833
+ }
1289
1834
  .compat {
1290
1835
  display: flex;
1291
1836
  flex-wrap: wrap;
@@ -1299,14 +1844,14 @@
1299
1844
  font-size: var(--roxy-text-xs, 0.75rem);
1300
1845
  text-transform: capitalize;
1301
1846
  }
1302
- `],d([p({attribute:!1})],D.prototype,"data",2),d([p({type:String,reflect:!0})],D.prototype,"period",2),D=d([x("roxy-horoscope-card")],D);function jr(o){return o.charAt(0).toUpperCase()+o.slice(1).toLowerCase()}var Y=class extends g{constructor(){super(...arguments);this.data=null}render(){if(!this.data)return s`<div class="roxy-empty" role="status">No KP data</div>`;let e=this.data.planets??[];return s`<div
1847
+ `],c([y({attribute:!1})],U.prototype,"data",2),c([y({type:String,reflect:!0})],U.prototype,"period",2),U=c([v("roxy-horoscope-card")],U);var ae=class extends u{constructor(){super(...arguments);this.data=null}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No KP data</div>`;let e=this.data.planets??[];return a`<div
1303
1848
  class="wrap"
1304
1849
  aria-label="KP planets table"
1305
1850
  tabindex="0"
1306
1851
  >
1307
1852
  <header class="head">
1308
1853
  <h2 class="title">KP planets</h2>
1309
- ${this.data.ayanamsa?s`<span class="ayanamsa">Ayanamsa: ${this.data.ayanamsa}</span>`:l}
1854
+ ${typeof this.data.ayanamsa=="number"?a`<span class="ayanamsa">Ayanamsa: ${w(this.data.ayanamsa,2)}°</span>`:n}
1310
1855
  </header>
1311
1856
  <table role="table">
1312
1857
  <thead>
@@ -1322,22 +1867,22 @@
1322
1867
  </tr>
1323
1868
  </thead>
1324
1869
  <tbody>
1325
- ${e.map(r=>s`<tr>
1870
+ ${e.map(t=>a`<tr>
1326
1871
  <td class="planet">
1327
- ${r.planet??r.name??""}
1328
- ${r.retrograde?s`<span class="retro">R</span>`:l}
1872
+ ${t.planet}
1873
+ ${t.retrograde?a`<span class="retro">R</span>`:n}
1329
1874
  </td>
1330
- <td>${r.sign??""}</td>
1331
- <td>${r.signLord??""}</td>
1332
- <td>${r.nakshatra??""}</td>
1333
- <td>${r.starLord??r.nakshatraLord??""}</td>
1334
- <td>${r.subLord??""}</td>
1335
- <td>${r.subSubLord??""}</td>
1336
- <td>${r.kpNumber??""}</td>
1875
+ <td>${t.sign??""}</td>
1876
+ <td>${t.signLord??""}</td>
1877
+ <td>${t.nakshatra??""}</td>
1878
+ <td>${t.nakshatraLord??""}</td>
1879
+ <td>${t.subLord??""}</td>
1880
+ <td>${t.subSubLord??""}</td>
1881
+ <td>${t.kpNumber??""}</td>
1337
1882
  </tr>`)}
1338
1883
  </tbody>
1339
1884
  </table>
1340
- </div>`}};Y.styles=[f,y`
1885
+ </div>`}};ae.styles=[b,x`
1341
1886
  .wrap {
1342
1887
  border: 1px solid var(--roxy-border, #e4e4e7);
1343
1888
  border-radius: var(--roxy-radius-md, 8px);
@@ -1392,11 +1937,11 @@
1392
1937
  color: var(--roxy-fg, #0a0a0a);
1393
1938
  }
1394
1939
  .retro {
1395
- color: var(--roxy-warning, #ea580c);
1940
+ color: var(--roxy-warning-fg, #9a3412);
1396
1941
  font-size: var(--roxy-text-xs, 0.75rem);
1397
1942
  margin-left: 4px;
1398
1943
  }
1399
- `],d([p({attribute:!1})],Y.prototype,"data",2),Y=d([x("roxy-kp-planets-table")],Y);function or(o,t){let e;return((...r)=>{e&&clearTimeout(e),e=setTimeout(()=>o(...r),t)})}var k=class extends g{constructor(){super(...arguments);this.endpoint="https://roxyapi.com/api/v2/location/search";this.placeholder="Search city";this.defaultValue="";this.query="";this.results=[];this.isOpen=!1;this.isLoading=!1;this.highlight=-1;this.debouncedFetch=or(e=>{this.fetchResults(e)},300);this.onInput=e=>{let r=e.target.value;if(this.query=r,r.length<2){this.results=[],this.isOpen=!1,this.highlight=-1;return}this.debouncedFetch(r)};this.onKeyDown=e=>{if(!this.isOpen||this.results.length===0){e.key==="ArrowDown"&&this.query.length>=2&&(this.fetchResults(this.query),e.preventDefault());return}if(e.key==="ArrowDown")e.preventDefault(),this.highlight=(this.highlight+1)%this.results.length;else if(e.key==="ArrowUp")e.preventDefault(),this.highlight=(this.highlight-1+this.results.length)%this.results.length;else if(e.key==="Enter"){e.preventDefault();let r=this.results[this.highlight]??this.results[0];r&&this.select(r)}else e.key==="Escape"&&(this.isOpen=!1)}}connectedCallback(){super.connectedCallback(),this.query=this.defaultValue,this.clickOutsideHandler=e=>{e.composedPath().includes(this)||(this.isOpen=!1)},document.addEventListener("mousedown",this.clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this.clickOutsideHandler&&document.removeEventListener("mousedown",this.clickOutsideHandler)}async fetchResults(e){this.isLoading=!0;try{let r=new URL(this.endpoint);r.searchParams.set("q",e),r.searchParams.set("limit","8");let a={Accept:"application/json"};this.apiKey&&(a["X-API-Key"]=this.apiKey),this.publishableKey&&(a["X-API-Key"]=this.publishableKey);let i=await fetch(r,{headers:a});if(!i.ok)throw new Error(`HTTP ${i.status}`);let n=await i.json();this.results=n.cities??[],this.isOpen=this.results.length>0,this.highlight=this.results.length>0?0:-1}catch{this.results=[],this.isOpen=!1}finally{this.isLoading=!1}}select(e){this.query=`${e.city}${e.province?`, ${e.province}`:""}, ${e.country}`,this.isOpen=!1,this.results=[],this.dispatchEvent(new CustomEvent("roxy-location-select",{detail:e,bubbles:!0,composed:!0}))}render(){return s`<div class="field">
1944
+ `],c([y({attribute:!1})],ae.prototype,"data",2),ae=c([v("roxy-kp-planets-table")],ae);function je(i,r){let e,t=((...s)=>{e&&clearTimeout(e),e=setTimeout(()=>{e=void 0,i(...s)},r)});return t.cancel=()=>{e&&(clearTimeout(e),e=void 0)},t}var T=class extends u{constructor(){super(...arguments);this.endpoint="https://roxyapi.com/api/v2/location/search";this.placeholder="Search city";this.defaultValue="";this.query="";this.results=[];this.isOpen=!1;this.isLoading=!1;this.highlight=-1;this.secretKeyWarned=!1;this.debouncedFetch=je(e=>{this.fetchResults(e)},300);this.onInput=e=>{let t=e.target.value;if(this.query=t,t.length<2){this.results=[],this.isOpen=!1,this.highlight=-1;return}this.debouncedFetch(t)};this.onKeyDown=e=>{if(!this.isOpen||this.results.length===0){e.key==="ArrowDown"&&this.query.length>=2&&(this.fetchResults(this.query),e.preventDefault());return}if(e.key==="ArrowDown")e.preventDefault(),this.highlight=(this.highlight+1)%this.results.length;else if(e.key==="ArrowUp")e.preventDefault(),this.highlight=(this.highlight-1+this.results.length)%this.results.length;else if(e.key==="Enter"){e.preventDefault();let t=this.results[this.highlight]??this.results[0];t&&this.select(t)}else e.key==="Escape"&&(this.isOpen=!1)}}connectedCallback(){super.connectedCallback(),this.query=this.defaultValue,this.clickOutsideHandler=e=>{e.composedPath().includes(this)||(this.isOpen=!1)},document.addEventListener("mousedown",this.clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this.clickOutsideHandler&&document.removeEventListener("mousedown",this.clickOutsideHandler),this.debouncedFetch.cancel(),this.abortController&&(this.abortController.abort(),this.abortController=void 0)}warnIfSecretKey(){if(this.secretKeyWarned||!this.apiKey||this.apiKey.startsWith("pk_"))return;this.secretKeyWarned=!0;let e="Possible secret key in client-side <roxy-location-search>; use a `pk_` publishable key with origin allowlist instead.";console.warn(e),this.dispatchEvent(new CustomEvent("roxy-validation-error",{detail:{reason:"possible-secret-key",message:e},bubbles:!0,composed:!0}))}async fetchResults(e){this.warnIfSecretKey(),this.abortController&&this.abortController.abort();let t=new AbortController;this.abortController=t,this.isLoading=!0;try{let s=new URL(this.endpoint);s.searchParams.set("q",e),s.searchParams.set("limit","8");let o={Accept:"application/json"};this.apiKey&&(o["X-API-Key"]=this.apiKey),this.publishableKey&&(o["X-API-Key"]=this.publishableKey);let l=await fetch(s,{headers:o,signal:t.signal});if(!l.ok)throw new Error(`HTTP ${l.status}`);let d=await l.json();if(t.signal.aborted)return;this.results=d.cities??[],this.isOpen=this.results.length>0,this.highlight=this.results.length>0?0:-1}catch(s){if(s?.name==="AbortError")return;this.results=[],this.isOpen=!1}finally{this.abortController===t&&(this.abortController=void 0),t.signal.aborted||(this.isLoading=!1)}}select(e){this.query=`${e.city}${e.province?`, ${e.province}`:""}, ${e.country}`,this.isOpen=!1,this.results=[],this.dispatchEvent(new CustomEvent("roxy-location-select",{detail:e,bubbles:!0,composed:!0}))}render(){return a`<div class="field">
1400
1945
  <input
1401
1946
  type="text"
1402
1947
  role="combobox"
@@ -1410,32 +1955,32 @@
1410
1955
  @keydown=${this.onKeyDown}
1411
1956
  @focus=${()=>{this.results.length>0&&(this.isOpen=!0)}}
1412
1957
  />
1413
- ${this.isLoading?s`<span class="spinner" role="status" aria-label="Loading"></span>`:l}
1414
- ${this.isOpen?s`<ul
1958
+ ${this.isLoading?a`<span class="spinner" role="status" aria-label="Loading"></span>`:n}
1959
+ ${this.isOpen?a`<ul
1415
1960
  id="roxy-location-listbox"
1416
1961
  class="results"
1417
1962
  role="listbox"
1418
1963
  >
1419
- ${this.results.length===0?s`<li class="empty" role="status">No cities found</li>`:this.results.map((e,r)=>s`<li role="presentation">
1964
+ ${this.results.length===0?a`<li class="empty" role="status">No cities found</li>`:this.results.map((e,t)=>a`<li role="presentation">
1420
1965
  <button
1421
1966
  type="button"
1422
1967
  class="option"
1423
1968
  role="option"
1424
- aria-selected=${this.highlight===r?"true":"false"}
1969
+ aria-selected=${this.highlight===t?"true":"false"}
1425
1970
  @click=${()=>this.select(e)}
1426
- @mouseenter=${()=>{this.highlight=r}}
1971
+ @mouseenter=${()=>{this.highlight=t}}
1427
1972
  >
1428
1973
  <span class="city">${e.city}</span>
1429
1974
  <span class="where"
1430
- >${e.province?s`${e.province}, `:""}${e.country}</span
1975
+ >${e.province?a`${e.province}, `:""}${e.country}</span
1431
1976
  >
1432
1977
  <span class="tz"
1433
1978
  >UTC${e.utcOffset>=0?"+":""}${e.utcOffset}</span
1434
1979
  >
1435
1980
  </button>
1436
1981
  </li>`)}
1437
- </ul>`:l}
1438
- </div>`}};k.styles=[f,y`
1982
+ </ul>`:n}
1983
+ </div>`}};T.styles=[b,x`
1439
1984
  :host {
1440
1985
  display: block;
1441
1986
  position: relative;
@@ -1536,49 +2081,49 @@
1536
2081
  color: var(--roxy-muted, #71717a);
1537
2082
  font-size: var(--roxy-text-sm, 0.875rem);
1538
2083
  }
1539
- `],d([p({type:String,attribute:"api-key"})],k.prototype,"apiKey",2),d([p({type:String,attribute:"publishable-key"})],k.prototype,"publishableKey",2),d([p({type:String})],k.prototype,"endpoint",2),d([p({type:String})],k.prototype,"placeholder",2),d([p({type:String,attribute:"default-value"})],k.prototype,"defaultValue",2),d([_()],k.prototype,"query",2),d([_()],k.prototype,"results",2),d([_()],k.prototype,"isOpen",2),d([_()],k.prototype,"isLoading",2),d([_()],k.prototype,"highlight",2),k=d([x("roxy-location-search")],k);var O=class extends g{constructor(){super(...arguments);this.data=null;this.mode="current"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No moon phase data</div>`;let r=e.phases??e.upcoming??[];return this.mode!=="current"&&r.length>0?s`<article
2084
+ `],c([y({type:String,attribute:"api-key"})],T.prototype,"apiKey",2),c([y({type:String,attribute:"publishable-key"})],T.prototype,"publishableKey",2),c([y({type:String})],T.prototype,"endpoint",2),c([y({type:String})],T.prototype,"placeholder",2),c([y({type:String,attribute:"default-value"})],T.prototype,"defaultValue",2),c([E()],T.prototype,"query",2),c([E()],T.prototype,"results",2),c([E()],T.prototype,"isOpen",2),c([E()],T.prototype,"isLoading",2),c([E()],T.prototype,"highlight",2),T=c([v("roxy-location-search")],T);var Y=class extends u{constructor(){super(...arguments);this.data=null;this.mode="current"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No moon phase data</div>`;let t="phases"in e?e.phases:"calendar"in e?e.calendar:[];if(this.mode!=="current"&&t.length>0){let s="month"in e?e.month:void 0,o="year"in e?e.year:void 0;return a`<article
1540
2085
  class="card"
1541
2086
  aria-label="Moon phase calendar"
1542
2087
  >
1543
- <h2 class="label">${e.month??"Moon phases"} ${e.year??""}</h2>
2088
+ <h2 class="label">${s??"Moon phases"} ${o??""}</h2>
1544
2089
  <div class="list" role="list">
1545
- ${r.map(a=>this.renderListItem(a))}
2090
+ ${t.map(l=>this.renderListItem(l))}
1546
2091
  </div>
1547
- </article>`:this.renderSingle(e)}renderSingle(e){let r=lr(e.phase);return s`<article class="card" aria-label="Current moon phase">
2092
+ </article>`}return"phase"in e?this.renderSingle(e):n}renderSingle(e){let t=Mt(e.phase);return a`<article class="card" aria-label="Current moon phase">
1548
2093
  <div class="hero">
1549
- <span class="emoji" aria-hidden="true">${r}</span>
2094
+ <span class="emoji" aria-hidden="true">${t}</span>
1550
2095
  <div>
1551
2096
  <h2 class="label">${e.phase??"Moon"}</h2>
1552
- ${e.date?s`<div class="date">${e.date}</div>`:l}
2097
+ ${e.date?a`<div class="date">${e.date}</div>`:n}
1553
2098
  </div>
1554
2099
  </div>
1555
2100
  <div class="stats">
1556
- ${typeof e.illumination=="number"?s`<div>
2101
+ ${typeof e.illumination=="number"?a`<div>
1557
2102
  <span>Illumination</span>
1558
- <strong>${(e.illumination*100).toFixed(0)}%</strong>
1559
- </div>`:l}
1560
- ${typeof e.age=="number"?s`<div>
2103
+ <strong>${xr(e.illumination)}</strong>
2104
+ </div>`:n}
2105
+ ${typeof e.age=="number"?a`<div>
1561
2106
  <span>Age</span>
1562
- <strong>${e.age.toFixed(1)} days</strong>
1563
- </div>`:l}
1564
- ${e.sign?s`<div>
2107
+ <strong>${w(e.age,1)} days</strong>
2108
+ </div>`:n}
2109
+ ${e.sign?a`<div>
1565
2110
  <span>Sign</span>
1566
2111
  <strong>${e.sign}</strong>
1567
- </div>`:l}
1568
- ${typeof e.distance=="number"?s`<div>
2112
+ </div>`:n}
2113
+ ${typeof e.distance=="number"?a`<div>
1569
2114
  <span>Distance</span>
1570
2115
  <strong>${(e.distance/1e3).toFixed(0)}k km</strong>
1571
- </div>`:l}
2116
+ </div>`:n}
1572
2117
  </div>
1573
- ${e.meaning?.description?s`<p class="meaning">${e.meaning.description}</p>`:l}
1574
- ${e.meaning?.keywords?.length?s`<div class="keywords">
1575
- ${e.meaning.keywords.map(a=>s`<span>${a}</span>`)}
1576
- </div>`:l}
1577
- </article>`}renderListItem(e){let r=lr(e.phase);return s`<div class="list-item" role="listitem">
1578
- <span aria-hidden="true">${r}</span>
2118
+ ${e.meaning?.description?a`<p class="meaning">${e.meaning.description}</p>`:n}
2119
+ ${e.meaning?.keywords?.length?a`<div class="keywords">
2120
+ ${e.meaning.keywords.map(s=>a`<span>${s}</span>`)}
2121
+ </div>`:n}
2122
+ </article>`}renderListItem(e){let t=Mt(e.phase);return a`<div class="list-item" role="listitem">
2123
+ <span aria-hidden="true">${t}</span>
1579
2124
  <span>${e.phase}</span>
1580
2125
  <span>${e.date??""}</span>
1581
- </div>`}};O.styles=[f,y`
2126
+ </div>`}};Y.styles=[b,x`
1582
2127
  .card {
1583
2128
  background: var(--roxy-bg, #fff);
1584
2129
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -1660,15 +2205,15 @@
1660
2205
  .list-item:last-child {
1661
2206
  border-bottom: none;
1662
2207
  }
1663
- `],d([p({attribute:!1})],O.prototype,"data",2),d([p({type:String,reflect:!0})],O.prototype,"mode",2),O=d([x("roxy-moon-phase")],O);function lr(o){return o?nr[o.toLowerCase()]??"\u{1F319}":"\u{1F319}"}function P(o,t,e,r){let a=r*Math.PI/180;return{x:o+e*Math.cos(a),y:t+e*Math.sin(a)}}var De=320,b=De/2,cr=150,Ur=134,Ce=110,fe=88,H=class extends g{constructor(){super(...arguments);this.data=null;this.houseSystem="placidus"}getPlanets(){let e=this.data?.planets;return e?Array.isArray(e)?e:Object.entries(e).map(([r,a])=>({...a,name:r})):[]}render(){if(!this.data)return s`<div class="roxy-empty" role="status">No chart data</div>`;let e=this.getPlanets(),r=this.data.aspects??[];return s`<div class="wrap">
2208
+ `],c([y({attribute:!1})],Y.prototype,"data",2),c([y({type:String,reflect:!0})],Y.prototype,"mode",2),Y=c([v("roxy-moon-phase")],Y);function Mt(i){return i?Tt[i.toLowerCase()]??"\u{1F319}":"\u{1F319}"}function xr(i){let r=i<=1?i*100:i;return`${Math.round(r)}%`}function R(i,r,e,t){let s=t*Math.PI/180;return{x:i+e*Math.cos(s),y:r+e*Math.sin(s)}}var lt=420,A=lt/2,it=164,fr=146,nt=120,Ie=96,vr=178,br=196,K=class extends u{constructor(){super(...arguments);this.data=null;this.houseSystem="placidus"}getPlanets(){return this.data?.planets??[]}getAscendant(){return this.data?.ascendant?.longitude??0}getMidheaven(){let e=this.data?.midheaven?.longitude;return typeof e=="number"?e:null}toAngle(e){return 180+this.getAscendant()-e}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No chart data</div>`;let e=this.getPlanets(),t=this.data.aspects??[];return a`<div class="wrap">
1664
2209
  <header>
1665
2210
  <h2 class="title">Natal chart</h2>
1666
- ${this.data.birthDetails?s`<div class="meta">
1667
- ${[this.data.birthDetails.date,this.data.birthDetails.time,this.data.birthDetails.location].filter(Boolean).join(" \xB7 ")}
1668
- </div>`:l}
2211
+ ${this.data.birthDetails?a`<div class="meta">
2212
+ ${[this.data.birthDetails.date,this.data.birthDetails.time].filter(Boolean).join(" \xB7 ")}
2213
+ </div>`:n}
1669
2214
  </header>
1670
2215
  <svg
1671
- viewBox="0 0 ${De} ${De}"
2216
+ viewBox="0 0 ${lt} ${lt}"
1672
2217
  role="img"
1673
2218
  aria-label="Natal chart wheel with twelve houses, planets, and aspects"
1674
2219
  >
@@ -1679,34 +2224,85 @@
1679
2224
  </desc>
1680
2225
  <circle
1681
2226
  class="wheel-line"
1682
- cx=${b}
1683
- cy=${b}
1684
- r=${cr}
2227
+ cx=${A}
2228
+ cy=${A}
2229
+ r=${it}
1685
2230
  stroke-width="1.5"
1686
2231
  />
1687
2232
  <circle
1688
2233
  class="wheel-line"
1689
- cx=${b}
1690
- cy=${b}
1691
- r=${Ce}
2234
+ cx=${A}
2235
+ cy=${A}
2236
+ r=${nt}
1692
2237
  stroke-width="1"
1693
2238
  />
1694
2239
  <circle
1695
2240
  class="wheel-line"
1696
- cx=${b}
1697
- cy=${b}
1698
- r=${fe-16}
2241
+ cx=${A}
2242
+ cy=${A}
2243
+ r=${Ie-16}
1699
2244
  stroke-width="0.5"
1700
2245
  />
1701
2246
  ${this.renderSpokes()} ${this.renderSigns()} ${this.renderHouseNumbers()}
1702
- ${this.renderAspects(e,r)} ${this.renderPlanets(e)}
2247
+ ${this.renderAspects(e,t)} ${this.renderPlanets(e)}
2248
+ ${this.renderAngles()}
1703
2249
  </svg>
1704
2250
  <div class="legend">
1705
2251
  <span>${e.length} planets</span>
1706
- <span>${r.length} aspects</span>
1707
- <span>House system: ${this.houseSystem}</span>
2252
+ <span>${t.length} aspects</span>
2253
+ <span><span class="legend-swatch" style="background: var(--roxy-success)"></span>harmonious</span>
2254
+ <span><span class="legend-swatch" style="background: var(--roxy-danger)"></span>challenging</span>
1708
2255
  </div>
1709
- </div>`}renderSpokes(){return Array.from({length:12},(e,r)=>{let a=r*30-90,i=P(b,b,Ce,a),n=P(b,b,cr,a);return $`<line class="wheel-line" x1=${i.x} y1=${i.y} x2=${n.x} y2=${n.y} stroke-width="0.8" />`})}renderSigns(){return["Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius","Pisces"].map((r,a)=>{let i=a*30+15-90,n=P(b,b,Ur,i);return $`<text class="sign-glyph" x=${n.x} y=${n.y} text-anchor="middle" dominant-baseline="central">${re[r]}</text>`})}renderHouseNumbers(){return Array.from({length:12},(e,r)=>{let a=r*30+15-90,i=P(b,b,Ce-12,a);return $`<text class="house-num" x=${i.x} y=${i.y} text-anchor="middle" dominant-baseline="central">${r+1}</text>`})}renderPlanets(e){return e.map(r=>{let a=typeof r.longitude=="number"?r.longitude:typeof r.degree=="number"?r.degree:NaN;if(!Number.isFinite(a))return l;let i=a-90,n=P(b,b,fe,i),c=r.name??r.planet??"",m=xe[ve(c)]??c.slice(0,2),u=r.retrograde||r.isRetrograde?" R":"";return $`<text class="planet-glyph" x=${n.x} y=${n.y} text-anchor="middle" dominant-baseline="central"><title>${c}${u}</title>${m}</text>`})}renderAspects(e,r){let a=new Map;for(let i of e){let n=typeof i.longitude=="number"?i.longitude:typeof i.degree=="number"?i.degree:null;if(n===null)continue;let c=ve(i.name??i.planet??"");c&&a.set(c,n)}return r.map(i=>{let n=a.get(ve(i.planet1??"")),c=a.get(ve(i.planet2??""));if(n===void 0||c===void 0)return l;let m=P(b,b,fe-18,n-90),u=P(b,b,fe-18,c-90);return $`<line class="aspect" x1=${m.x} y1=${m.y} x2=${u.x} y2=${u.y} />`})}};H.styles=[f,y`
2256
+ ${this.renderDetails()}
2257
+ ${this.renderInterpretations()}
2258
+ </div>`}renderAngles(){let e=this.getAscendant(),t=this.getMidheaven(),s=[this.renderAngleMark(e,"ASC")];return t!==null&&s.push(this.renderAngleMark(t,"MC")),s}renderAngleMark(e,t){let s=this.toAngle(e),o=R(A,A,it,s),l=R(A,A,vr,s),d=R(A,A,br,s);return S`
2259
+ <g>
2260
+ <line class="angle-tick" x1=${o.x} y1=${o.y} x2=${l.x} y2=${l.y} />
2261
+ <text class="angle-marker" x=${d.x} y=${d.y} text-anchor="middle" dominant-baseline="central">${t}</text>
2262
+ </g>
2263
+ `}renderSpokes(){return Array.from({length:12},(e,t)=>{let s=this.toAngle(t*30),o=R(A,A,nt,s),l=R(A,A,it,s);return S`<line class="wheel-line" x1=${o.x} y1=${o.y} x2=${l.x} y2=${l.y} stroke-width="0.8" />`})}renderSigns(){return pe.map((e,t)=>{let s=this.toAngle(t*30+15),o=R(A,A,fr,s);return S`<text class="sign-glyph" x=${o.x} y=${o.y} text-anchor="middle" dominant-baseline="central">${N[e]}</text>`})}renderHouseNumbers(){let e=Math.floor(this.getAscendant()/30);return Array.from({length:12},(t,s)=>{let o=this.toAngle(s*30+15),l=R(A,A,nt-12,o),d=(s-e+12)%12+1;return S`<text class="house-num" x=${l.x} y=${l.y} text-anchor="middle" dominant-baseline="central">${d}</text>`})}renderPlanets(e){return e.map(t=>{if(!Number.isFinite(t.longitude))return n;let s=this.toAngle(t.longitude),o=R(A,A,Ie,s),l=L[C(t.name)]??t.name.slice(0,2),d=t.isRetrograde?" R":"",p=d?`${l}\u1D3F`:l;return S`<text class="planet-glyph" x=${o.x} y=${o.y} text-anchor="middle" dominant-baseline="central"><title>${t.name}${d}</title>${p}</text>`})}renderDetails(){let e=this.data?.summary,t=this.data?.aspectsInterpretation;if(!e&&!t)return n;let s=e?.retrogradePlanets??[],o=e?.elementDistribution??{},l=e?.modalityDistribution??{},d=Math.max(1,...Object.values(o)),p=Math.max(1,...Object.values(l));return a`<div class="details">
2264
+ ${e?.dominantElement||e?.dominantModality?a`<div class="pill-row">
2265
+ ${e.dominantElement?a`<span class="pill">Dominant element: ${e.dominantElement}</span>`:n}
2266
+ ${e.dominantModality?a`<span class="pill">Dominant modality: ${e.dominantModality}</span>`:n}
2267
+ </div>`:n}
2268
+ ${t?a`<div class="pill-row">
2269
+ <span class="pill pill--success">Harmonious ${t.harmonious}</span>
2270
+ <span class="pill pill--danger">Challenging ${t.challenging}</span>
2271
+ <span class="pill pill--muted">Neutral ${t.neutral}</span>
2272
+ </div>`:n}
2273
+ ${s.length>0?a`<div class="pill-row">
2274
+ ${s.map(m=>{let h=L[m]??m.slice(0,2);return a`<span class="pill pill--muted">${h} ${m} R</span>`})}
2275
+ </div>`:n}
2276
+ ${t?.summary?a`<p class="summary">${t.summary}</p>`:n}
2277
+ ${Object.keys(o).length>0||Object.keys(l).length>0?a`<div class="dist-grid">
2278
+ ${Object.keys(o).length>0?a`<div class="dist-section">
2279
+ <h3>Elements</h3>
2280
+ ${Object.entries(o).map(([m,h])=>a`<div class="dist-row">
2281
+ <span>${m}</span>
2282
+ <div class="dist-bar"><span style="width: ${Math.round(h/d*100)}%"></span></div>
2283
+ <span>${h}</span>
2284
+ </div>`)}
2285
+ </div>`:n}
2286
+ ${Object.keys(l).length>0?a`<div class="dist-section">
2287
+ <h3>Modalities</h3>
2288
+ ${Object.entries(l).map(([m,h])=>a`<div class="dist-row">
2289
+ <span>${m}</span>
2290
+ <div class="dist-bar"><span style="width: ${Math.round(h/p*100)}%"></span></div>
2291
+ <span>${h}</span>
2292
+ </div>`)}
2293
+ </div>`:n}
2294
+ </div>`:n}
2295
+ </div>`}renderInterpretations(){let e=this.getPlanets().filter(t=>t.interpretation);return e.length===0?n:a`<section class="interpretations">
2296
+ <h3>Planet readings</h3>
2297
+ ${e.map(t=>{let s=t.interpretation,o=L[C(t.name)]??"",l=w(t.degree??0,1);return a`<details class="interp-card">
2298
+ <summary>${o} ${t.name} <small>${t.sign??""} ${l}</small></summary>
2299
+ <div class="interp-body">
2300
+ ${s.summary?a`<p class="interp-summary">${s.summary}</p>`:n}
2301
+ ${s.detailed?a`<p class="interp-detail">${s.detailed}</p>`:n}
2302
+ ${s.keywords?.length?a`<div class="interp-keywords">${s.keywords.map(d=>a`<span class="kw">${d}</span>`)}</div>`:n}
2303
+ </div>
2304
+ </details>`})}
2305
+ </section>`}renderAspects(e,t){let s=new Map;for(let o of e){if(typeof o.longitude!="number")continue;let l=C(o.name);l&&s.set(l,o.longitude)}return t.map(o=>{let l=s.get(C(o.planet1)),d=s.get(C(o.planet2));if(l===void 0||d===void 0)return n;let p=R(A,A,Ie-18,this.toAngle(l)),m=R(A,A,Ie-18,this.toAngle(d)),h=ke(o),g=ze[h]??"aspect-other",f=w(o.orb,1);return S`<line class=${`aspect ${g}`} x1=${p.x} y1=${p.y} x2=${m.x} y2=${m.y}><title>${o.planet1} ${h||""} ${o.planet2}${f?` (orb ${f}\xB0)`:""}</title></line>`})}};K.styles=[b,x`
1710
2306
  .wrap {
1711
2307
  width: 100%;
1712
2308
  display: grid;
@@ -1758,9 +2354,36 @@
1758
2354
  }
1759
2355
 
1760
2356
  .aspect {
1761
- stroke: color-mix(in srgb, var(--roxy-accent, #f59e0b) 32%, transparent);
1762
- stroke-width: 0.6;
2357
+ stroke-width: 0.8;
1763
2358
  fill: none;
2359
+ opacity: 0.55;
2360
+ }
2361
+ .aspect-trine,
2362
+ .aspect-sextile {
2363
+ stroke: var(--roxy-success, #16a34a);
2364
+ }
2365
+ .aspect-square,
2366
+ .aspect-opposition {
2367
+ stroke: var(--roxy-danger, #dc2626);
2368
+ }
2369
+ .aspect-conjunction {
2370
+ stroke: var(--roxy-accent-fg, #b45309);
2371
+ }
2372
+ .aspect-other {
2373
+ stroke: var(--roxy-muted, #71717a);
2374
+ opacity: 0.4;
2375
+ }
2376
+
2377
+ .angle-marker {
2378
+ fill: var(--roxy-accent-fg, #b45309);
2379
+ font-size: 10px;
2380
+ font-weight: 700;
2381
+ font-family: var(--roxy-font-sans);
2382
+ letter-spacing: 0.04em;
2383
+ }
2384
+ .angle-tick {
2385
+ stroke: var(--roxy-accent-fg, #b45309);
2386
+ stroke-width: 1.5;
1764
2387
  }
1765
2388
 
1766
2389
  .legend {
@@ -1770,37 +2393,183 @@
1770
2393
  flex-wrap: wrap;
1771
2394
  gap: var(--roxy-space-md, 1rem);
1772
2395
  }
1773
- `],d([p({attribute:!1})],H.prototype,"data",2),d([p({type:String,attribute:"house-system",reflect:!0})],H.prototype,"houseSystem",2),H=d([x("roxy-natal-chart")],H);function ve(o){return o?o.charAt(0).toUpperCase()+o.slice(1).toLowerCase():""}var j=class extends g{constructor(){super(...arguments);this.data=null;this.type="life-path"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No numerology data</div>`;let r=Rr[this.type]??this.type,a=e.personalYear??e.number,i=e.coreNumbers?Object.entries(e.coreNumbers).filter(([,n])=>n!=null):[];return s`<article
1774
- class="card"
1775
- aria-label=${r}
1776
- >
2396
+ .legend-swatch {
2397
+ display: inline-block;
2398
+ width: 8px;
2399
+ height: 8px;
2400
+ border-radius: 50%;
2401
+ margin-right: 4px;
2402
+ vertical-align: middle;
2403
+ }
2404
+
2405
+ .details {
2406
+ margin-top: var(--roxy-space-md, 1rem);
2407
+ }
2408
+
2409
+ .pill-row {
2410
+ display: flex;
2411
+ flex-wrap: wrap;
2412
+ gap: var(--roxy-space-xs, 0.25rem);
2413
+ margin-bottom: var(--roxy-space-xs, 0.25rem);
2414
+ }
2415
+
2416
+ .pill {
2417
+ padding: 2px 8px;
2418
+ border-radius: var(--roxy-radius-sm, 4px);
2419
+ font-size: var(--roxy-text-xs, 0.75rem);
2420
+ background: color-mix(in srgb, var(--roxy-fg, #0f172a) 8%, transparent);
2421
+ color: var(--roxy-fg, #0f172a);
2422
+ }
2423
+
2424
+ .pill--success {
2425
+ background: color-mix(in srgb, var(--roxy-success, #16a34a) 15%, transparent);
2426
+ color: var(--roxy-success, #16a34a);
2427
+ }
2428
+
2429
+ .pill--danger {
2430
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 15%, transparent);
2431
+ color: var(--roxy-danger, #dc2626);
2432
+ }
2433
+
2434
+ .pill--muted {
2435
+ background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent);
2436
+ color: var(--roxy-fg, #0a0a0a);
2437
+ }
2438
+
2439
+ .summary {
2440
+ color: var(--roxy-fg, #0f172a);
2441
+ font-size: var(--roxy-text-sm, 0.875rem);
2442
+ margin: var(--roxy-space-md, 1rem) 0;
2443
+ }
2444
+
2445
+ .dist-grid {
2446
+ display: grid;
2447
+ grid-template-columns: 1fr 1fr;
2448
+ gap: var(--roxy-space-md, 1rem);
2449
+ }
2450
+
2451
+ @container (max-width: 639px) {
2452
+ .dist-grid {
2453
+ grid-template-columns: 1fr;
2454
+ }
2455
+ }
2456
+
2457
+ .dist-section h3 {
2458
+ font-size: var(--roxy-text-xs, 0.75rem);
2459
+ font-weight: var(--roxy-weight-bold, 600);
2460
+ color: var(--roxy-muted, #71717a);
2461
+ margin: 0 0 var(--roxy-space-xs, 0.25rem);
2462
+ text-transform: uppercase;
2463
+ letter-spacing: 0.05em;
2464
+ }
2465
+
2466
+ .dist-row {
2467
+ display: grid;
2468
+ grid-template-columns: 4rem 1fr 1.5rem;
2469
+ align-items: center;
2470
+ gap: var(--roxy-space-xs, 0.25rem);
2471
+ font-size: var(--roxy-text-xs, 0.75rem);
2472
+ color: var(--roxy-fg, #0f172a);
2473
+ margin-bottom: 4px;
2474
+ }
2475
+
2476
+ .dist-bar {
2477
+ background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 20%, transparent);
2478
+ height: 6px;
2479
+ border-radius: 3px;
2480
+ }
2481
+
2482
+ .dist-bar > span {
2483
+ display: block;
2484
+ height: 100%;
2485
+ background: var(--roxy-accent, #f59e0b);
2486
+ border-radius: 3px;
2487
+ }
2488
+
2489
+ .interpretations {
2490
+ margin-top: var(--roxy-space-md, 1rem);
2491
+ }
2492
+ .interpretations h3 {
2493
+ font-size: var(--roxy-text-sm, 0.875rem);
2494
+ font-weight: 600;
2495
+ color: var(--roxy-muted, #71717a);
2496
+ text-transform: uppercase;
2497
+ letter-spacing: 0.06em;
2498
+ margin: 0 0 var(--roxy-space-sm, 0.5rem);
2499
+ }
2500
+ .interp-card {
2501
+ border: 1px solid var(--roxy-border, #e4e4e7);
2502
+ border-radius: var(--roxy-radius-md, 8px);
2503
+ padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
2504
+ margin-bottom: var(--roxy-space-xs, 0.25rem);
2505
+ }
2506
+ .interp-card summary {
2507
+ cursor: pointer;
2508
+ font-weight: 500;
2509
+ color: var(--roxy-fg, #0f172a);
2510
+ }
2511
+ .interp-card summary small {
2512
+ color: var(--roxy-muted, #71717a);
2513
+ margin-left: 0.5em;
2514
+ font-weight: 400;
2515
+ }
2516
+ .interp-body {
2517
+ margin-top: var(--roxy-space-xs, 0.25rem);
2518
+ color: var(--roxy-fg, #0f172a);
2519
+ font-size: var(--roxy-text-sm, 0.875rem);
2520
+ }
2521
+ .interp-keywords {
2522
+ display: flex;
2523
+ flex-wrap: wrap;
2524
+ gap: 0.25rem;
2525
+ margin-top: 0.5rem;
2526
+ }
2527
+ .interp-keywords .kw {
2528
+ padding: 1px 8px;
2529
+ border-radius: 9999px;
2530
+ background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 14%, transparent);
2531
+ color: var(--roxy-accent-fg, #b45309);
2532
+ font-size: var(--roxy-text-xs, 0.75rem);
2533
+ }
2534
+ `],c([y({attribute:!1})],K.prototype,"data",2),c([y({type:String,attribute:"house-system",reflect:!0})],K.prototype,"houseSystem",2),K=c([v("roxy-natal-chart")],K);var V=class extends u{constructor(){super(...arguments);this.data=null;this.type="life-path"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No numerology data</div>`;let t=$r[this.type]??this.type;return"coreNumbers"in e?this.renderChart(e,t):"personalYear"in e?this.renderPersonalYear(e,t):this.renderNumberCard(e,t)}renderNumberCard(e,t){let s=e.meaning?.keywords??[];return a`<article class="card" aria-label=${t}>
1777
2535
  <div class="hero">
1778
- ${typeof a=="number"?s`<div class="numeral">${a}</div>`:l}
2536
+ ${typeof e.number=="number"?a`<div class="numeral">${e.number}</div>`:n}
1779
2537
  <div>
1780
- <p class="label">${r}</p>
1781
- ${e.title?s`<h2 class="title">${e.title}</h2>`:e.type?s`<h2 class="title">
1782
- ${e.type==="master"?"Master number":"Single digit"}
1783
- </h2>`:l}
2538
+ <p class="label">${t}</p>
2539
+ ${e.meaning?.title?a`<h2 class="title">${e.meaning.title}</h2>`:n}
1784
2540
  </div>
1785
2541
  </div>
1786
- ${e.theme?s`<p><strong>Theme:</strong> ${e.theme}</p>`:l}
1787
- ${e.meaning?s`<p class="meaning">${e.meaning}</p>`:l}
1788
- ${e.advice?s`<p>${e.advice}</p>`:l}
1789
- ${e.calculation?s`<pre class="calc">${e.calculation}</pre>`:l}
1790
- ${e.keywords?.length?s`<div class="chips">
1791
- ${e.keywords.map(n=>s`<span>${n}</span>`)}
1792
- </div>`:l}
1793
- ${i.length>0?s`<div class="cores">
1794
- ${i.map(([n,c])=>{let m=typeof c=="number"?c:c.number;return s`<div class="item">
1795
- <span>${Ir(n)}</span>
1796
- <strong>${m??""}</strong>
1797
- </div>`})}
1798
- </div>`:l}
1799
- ${e.hasKarmicDebt&&e.karmicDebtNumber?s`<div class="karmic">
2542
+ ${e.meaning?.description?a`<p class="meaning">${e.meaning.description}</p>`:n}
2543
+ ${e.calculation?a`<pre class="calc">${e.calculation}</pre>`:n}
2544
+ ${s.length>0?a`<div class="chips">
2545
+ ${s.map(o=>a`<span>${o}</span>`)}
2546
+ </div>`:n}
2547
+ ${e.hasKarmicDebt&&e.karmicDebtNumber?a`<div class="karmic">
1800
2548
  Karmic debt ${e.karmicDebtNumber}.
1801
- ${e.karmicDebtMeaning?e.karmicDebtMeaning:""}
1802
- </div>`:l}
1803
- </article>`}};j.styles=[f,y`
2549
+ ${wr(e.karmicDebtMeaning)}
2550
+ </div>`:n}
2551
+ </article>`}renderPersonalYear(e,t){return a`<article class="card" aria-label=${t}>
2552
+ <div class="hero">
2553
+ ${typeof e.personalYear=="number"?a`<div class="numeral">${e.personalYear}</div>`:n}
2554
+ <div>
2555
+ <p class="label">${t}</p>
2556
+ ${e.theme?a`<h2 class="title">${e.theme}</h2>`:n}
2557
+ </div>
2558
+ </div>
2559
+ ${e.forecast?a`<p class="meaning">${e.forecast}</p>`:n}
2560
+ ${e.advice?a`<p>${e.advice}</p>`:n}
2561
+ </article>`}renderChart(e,t){let s=Object.entries(e.coreNumbers).filter(([,o])=>o!=null);return a`<article class="card" aria-label=${t}>
2562
+ <div>
2563
+ <p class="label">${t}</p>
2564
+ ${e.profile?.name?a`<h2 class="title">${e.profile.name}</h2>`:n}
2565
+ </div>
2566
+ ${s.length>0?a`<div class="cores">
2567
+ ${s.map(([o,l])=>a`<div class="item">
2568
+ <span>${ee(o)}</span>
2569
+ <strong>${l.number??""}</strong>
2570
+ </div>`)}
2571
+ </div>`:n}
2572
+ </article>`}};V.styles=[b,x`
1804
2573
  .card {
1805
2574
  background: var(--roxy-bg, #fff);
1806
2575
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -1848,7 +2617,8 @@
1848
2617
  background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 30%, transparent);
1849
2618
  padding: var(--roxy-space-sm, 0.5rem);
1850
2619
  border-radius: var(--roxy-radius-sm, 4px);
1851
- word-break: break-all;
2620
+ white-space: pre-wrap;
2621
+ overflow-wrap: anywhere;
1852
2622
  }
1853
2623
 
1854
2624
  .chips {
@@ -1895,56 +2665,56 @@
1895
2665
  font-size: var(--roxy-text-sm, 0.875rem);
1896
2666
  color: var(--roxy-fg, #0a0a0a);
1897
2667
  }
1898
- `],d([p({attribute:!1})],j.prototype,"data",2),d([p({type:String,reflect:!0})],j.prototype,"type",2),j=d([x("roxy-numerology-card")],j);var Rr={"life-path":"Life Path",expression:"Expression","personal-year":"Personal Year",chart:"Numerology chart"};function Ir(o){return o.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/^\w/,t=>t.toUpperCase())}var U=class extends g{constructor(){super(...arguments);this.data=null;this.detail="detailed"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No panchang data</div>`;let r=[["Tithi",this.formatPart(e.tithi)],["Nakshatra",this.formatPart(e.nakshatra)],["Yoga",this.formatPart(e.yoga)],["Karana",this.formatPart(e.karana)],["Vara",e.vara??""]],a=[["Brahma Muhurta",e.brahmaMuhurta],["Abhijit Muhurta",e.abhijitMuhurta],["Vijaya Muhurta",e.vijayaMuhurta],["Godhuli Muhurta",e.godhuliMuhurta],["Nishita Muhurta",e.nishitaMuhurta],["Pratah Sandhya",e.pratahSandhya],["Sayahna Sandhya",e.sayahnaSandhya]],i=[["Rahu Kaal",e.rahuKaal],["Yamaganda",e.yamaganda],["Gulika",e.gulika]];return s`<div class="wrap" aria-label="Panchang">
2668
+ `],c([y({attribute:!1})],V.prototype,"data",2),c([y({type:String,reflect:!0})],V.prototype,"type",2),V=c([v("roxy-numerology-card")],V);var $r={"life-path":"Life Path",expression:"Expression","personal-year":"Personal Year",chart:"Numerology chart"};function wr(i){return i?[i.description,i.challenge,i.resolution].filter(Boolean).join(" "):""}var F=class extends u{constructor(){super(...arguments);this.data=null;this.detail="detailed"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No panchang data</div>`;let t="sunrise"in e?e:null,s=[["Tithi",this.formatPart(e.tithi)],["Nakshatra",this.formatPart(e.nakshatra)],["Yoga",this.formatPart(e.yoga)],["Karana",this.formatPart(e.karana)]];t&&s.push(["Vara",this.formatPart(t.vara)]);let o=t?[["Brahma Muhurta",t.brahmaMuhurta],["Abhijit Muhurta",t.abhijitMuhurta],["Vijaya Muhurta",t.vijayaMuhurta],["Godhuli Muhurta",t.godhuliMuhurta],["Nishita Muhurta",t.nishitaMuhurta],["Pratah Sandhya",t.pratahSandhya],["Sayahna Sandhya",t.sayahnaSandhya]]:[],l=t?[["Rahu Kaal",t.rahuKaal],["Yamaganda",t.yamaganda],["Gulika",t.gulika]]:[];return a`<div class="wrap" aria-label="Panchang">
1899
2669
  <header class="head">
1900
2670
  <h2 class="title">Panchang</h2>
1901
- <span class="date">${e.date??""}</span>
2671
+ <span class="date">${t?Ne(t.date):""}</span>
1902
2672
  </header>
1903
2673
  <table>
1904
2674
  <tbody>
1905
- ${r.map(([n,c])=>s`<tr>
1906
- <th>${n}</th>
1907
- <td>${c}</td>
2675
+ ${s.map(([d,p])=>a`<tr>
2676
+ <th>${d}</th>
2677
+ <td>${p}</td>
1908
2678
  </tr>`)}
1909
- ${e.sunrise?s`<tr>
2679
+ ${t?.sunrise?a`<tr>
1910
2680
  <th>Sunrise</th>
1911
- <td>${e.sunrise}</td>
1912
- </tr>`:l}
1913
- ${e.sunset?s`<tr>
2681
+ <td>${O(t.sunrise)}</td>
2682
+ </tr>`:n}
2683
+ ${t?.sunset?a`<tr>
1914
2684
  <th>Sunset</th>
1915
- <td>${e.sunset}</td>
1916
- </tr>`:l}
1917
- ${e.moonrise?s`<tr>
2685
+ <td>${O(t.sunset)}</td>
2686
+ </tr>`:n}
2687
+ ${t?.moonrise?a`<tr>
1918
2688
  <th>Moonrise</th>
1919
- <td>${e.moonrise}</td>
1920
- </tr>`:l}
1921
- ${e.moonset?s`<tr>
2689
+ <td>${O(t.moonrise)}</td>
2690
+ </tr>`:n}
2691
+ ${t?.moonset?a`<tr>
1922
2692
  <th>Moonset</th>
1923
- <td>${e.moonset}</td>
1924
- </tr>`:l}
2693
+ <td>${O(t.moonset)}</td>
2694
+ </tr>`:n}
1925
2695
  </tbody>
1926
2696
  </table>
1927
- ${this.detail==="detailed"&&(a.some(n=>!!n[1])||i.some(n=>!!n[1]))?s`
2697
+ ${this.detail==="detailed"&&(o.some(d=>!!d[1])||l.some(d=>!!d[1]))?a`
1928
2698
  <div class="section">Auspicious muhurtas</div>
1929
2699
  <table>
1930
2700
  <tbody>
1931
- ${a.filter(([,n])=>!!n).map(([n,c])=>s`<tr>
1932
- <th>${n}</th>
1933
- <td>${dr(c)}</td>
2701
+ ${o.filter(([,d])=>!!d).map(([d,p])=>a`<tr>
2702
+ <th>${d}</th>
2703
+ <td>${st(p)}</td>
1934
2704
  </tr>`)}
1935
2705
  </tbody>
1936
2706
  </table>
1937
2707
  <div class="section">Inauspicious periods</div>
1938
2708
  <table>
1939
2709
  <tbody>
1940
- ${i.filter(([,n])=>!!n).map(([n,c])=>s`<tr>
1941
- <th>${n}</th>
1942
- <td>${dr(c)}</td>
2710
+ ${l.filter(([,d])=>!!d).map(([d,p])=>a`<tr>
2711
+ <th>${d}</th>
2712
+ <td>${st(p)}</td>
1943
2713
  </tr>`)}
1944
2714
  </tbody>
1945
2715
  </table>
1946
- `:l}
1947
- </div>`}formatPart(e){if(!e)return"";if(typeof e=="string")return e;if(typeof e=="object"){let r=e;return[r.name,r.lord?`(${r.lord})`:"",r.phase].filter(Boolean).join(" ")}return String(e)}};U.styles=[f,y`
2716
+ `:n}
2717
+ </div>`}formatPart(e){if(!e)return"";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;return[t.name,t.lord?`(${t.lord})`:"",t.phase].filter(Boolean).join(" ")}return String(e)}};F.styles=[b,x`
1948
2718
  .wrap {
1949
2719
  border: 1px solid var(--roxy-border, #e4e4e7);
1950
2720
  border-radius: var(--roxy-radius-md, 8px);
@@ -2002,63 +2772,287 @@
2002
2772
  text-transform: uppercase;
2003
2773
  letter-spacing: 0.06em;
2004
2774
  }
2005
- `],d([p({attribute:!1})],U.prototype,"data",2),d([p({type:String,reflect:!0})],U.prototype,"detail",2),U=d([x("roxy-panchang-table")],U);function dr(o){return o?o.start&&o.end?`${o.start} - ${o.end}`:o.start??o.end??"":""}var Oe=360,E=Oe/2,mr=170,qr=154,Br=124,be=96,F=class extends g{constructor(){super(...arguments);this.data=null}render(){if(!this.data)return s`<div class="roxy-empty" role="status">No synastry data</div>`;let{person1:e,person2:r,compatibilityScore:a,summary:i,interAspects:n=[]}=this.data,c=this.normalizePlanets(e?.planets),m=this.normalizePlanets(r?.planets);return s`<div
2006
- class="wrap"
2007
- aria-label="Synastry compatibility chart"
2008
- >
2775
+ `],c([y({attribute:!1})],F.prototype,"data",2),c([y({type:String,reflect:!0})],F.prototype,"detail",2),F=c([v("roxy-panchang-table")],F);var dt=[{key:"sthanaBala",label:"Sthana",color:"var(--roxy-info, #0284c7)"},{key:"digBala",label:"Dig",color:"var(--roxy-success, #16a34a)"},{key:"kalaBala",label:"Kala",color:"var(--roxy-warning, #ea580c)"},{key:"chestaBala",label:"Chesta",color:"var(--roxy-accent, #f59e0b)"},{key:"naisargikaBala",label:"Naisargika",color:"var(--roxy-secondary, #475569)"},{key:"drikBala",label:"Drik",color:"var(--roxy-danger, #dc2626)"}],se=class extends u{constructor(){super(...arguments);this.data=null}render(){if(!this.data?.planets?.length)return a`<div class="roxy-empty" role="status">No shadbala data</div>`;let e=[...this.data.planets].sort((t,s)=>t.relativeRank-s.relativeRank);return a`<div class="wrap" aria-label="Shadbala planetary strength">
2009
2776
  <div class="head">
2010
- <h2 class="title">Synastry</h2>
2011
- ${typeof a=="number"?s`<span class="score" aria-label=${`Score ${a} of 100`}
2012
- >${a} / 100</span
2013
- >`:l}
2777
+ <h2 class="title">Shadbala</h2>
2778
+ <p class="subtitle">${e.length} planets ranked by strength</p>
2014
2779
  </div>
2015
- <svg
2016
- viewBox="0 0 ${Oe} ${Oe}"
2017
- role="img"
2780
+
2781
+ <div role="list" aria-label="Planet strength bars">
2782
+ ${e.map(t=>this.renderPlanetRow(t))}
2783
+ </div>
2784
+
2785
+ <div class="legend" aria-label="Strength component legend">
2786
+ ${dt.map(t=>a`<div class="legend-row">
2787
+ <span
2788
+ class="legend-swatch"
2789
+ style="background: ${t.color}"
2790
+ aria-hidden="true"
2791
+ ></span>
2792
+ ${t.label}
2793
+ </div>`)}
2794
+ </div>
2795
+ </div>`}renderPlanetRow(e){let t=L[C(e.planet)]??"",s=dt.map(h=>Math.max(0,e[h.key])),o=s.reduce((h,g)=>h+g,0),l=typeof e.strengthRatio=="number"&&e.strengthRatio>=1,d=l?"adequacy-badge--adequate":"adequacy-badge--weak",p=l?"adequate":"weak",m=w(e.totalRupas,2)&&w(e.minRequired,2)?`${w(e.totalRupas,2)} / ${w(e.minRequired,2)} R`:"";return a`<div class="planet-row" role="listitem" aria-label="${e.planet} shadbala">
2796
+ <div class="planet-label">
2797
+ <span class="glyph" aria-hidden="true">${t}</span>
2798
+ ${e.planet}
2799
+ <span class="rank-badge" aria-label="rank ${e.relativeRank}">#${e.relativeRank}</span>
2800
+ </div>
2801
+ <div class="bar-wrap">
2802
+ <div class="bar" role="img" aria-label="Strength components for ${e.planet}">
2803
+ ${o>0?dt.map((h,g)=>{let f=s[g];if(f<=0)return n;let k=f/o*100;return a`<div
2804
+ class="bar-segment"
2805
+ style="flex-grow: ${k}; background: ${h.color};"
2806
+ title="${h.label}: ${w(f,1)}"
2807
+ ></div>`}):n}
2808
+ </div>
2809
+ </div>
2810
+ <div class="pills">
2811
+ ${m?a`<span class="rupas-label">${m}</span>`:n}
2812
+ <span class="${`adequacy-badge ${d}`}">${p}</span>
2813
+ </div>
2814
+ </div>`}};se.styles=[b,x`
2815
+ .wrap {
2816
+ display: grid;
2817
+ gap: var(--roxy-space-md, 1rem);
2818
+ }
2819
+
2820
+ .head {
2821
+ display: flex;
2822
+ justify-content: space-between;
2823
+ align-items: baseline;
2824
+ gap: var(--roxy-space-md, 1rem);
2825
+ flex-wrap: wrap;
2826
+ }
2827
+
2828
+ .title {
2829
+ font-size: var(--roxy-text-lg, 1.125rem);
2830
+ font-weight: var(--roxy-weight-bold, 600);
2831
+ margin: 0;
2832
+ }
2833
+
2834
+ .subtitle {
2835
+ color: var(--roxy-muted, #71717a);
2836
+ font-size: var(--roxy-text-sm, 0.875rem);
2837
+ margin: 0;
2838
+ }
2839
+
2840
+ .planet-row {
2841
+ display: grid;
2842
+ grid-template-columns: 8rem 1fr auto;
2843
+ align-items: center;
2844
+ gap: var(--roxy-space-sm, 0.5rem);
2845
+ padding: var(--roxy-space-sm, 0.5rem) 0;
2846
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
2847
+ }
2848
+
2849
+ .planet-row:last-of-type {
2850
+ border-bottom: none;
2851
+ }
2852
+
2853
+ .planet-label {
2854
+ display: flex;
2855
+ align-items: center;
2856
+ gap: 6px;
2857
+ font-size: var(--roxy-text-sm, 0.875rem);
2858
+ font-weight: var(--roxy-weight-bold, 600);
2859
+ }
2860
+
2861
+ .glyph {
2862
+ font-size: 1.2em;
2863
+ line-height: 1;
2864
+ }
2865
+
2866
+ .bar-wrap {
2867
+ display: flex;
2868
+ flex-direction: column;
2869
+ gap: 4px;
2870
+ }
2871
+
2872
+ .bar {
2873
+ display: flex;
2874
+ height: 12px;
2875
+ border-radius: var(--roxy-radius-sm, 4px);
2876
+ overflow: hidden;
2877
+ background: var(--roxy-border, #e4e4e7);
2878
+ }
2879
+
2880
+ .bar-segment {
2881
+ height: 100%;
2882
+ transition: flex-grow var(--roxy-motion-duration, 200ms)
2883
+ var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1));
2884
+ }
2885
+
2886
+ .pills {
2887
+ display: flex;
2888
+ flex-direction: column;
2889
+ align-items: flex-end;
2890
+ gap: 4px;
2891
+ }
2892
+
2893
+ .rupas-label {
2894
+ font-variant-numeric: tabular-nums;
2895
+ font-size: var(--roxy-text-xs, 0.75rem);
2896
+ color: var(--roxy-muted, #71717a);
2897
+ white-space: nowrap;
2898
+ }
2899
+
2900
+ .adequacy-badge {
2901
+ display: inline-block;
2902
+ padding: 1px 6px;
2903
+ border-radius: var(--roxy-radius-full, 9999px);
2904
+ font-size: var(--roxy-text-xs, 0.75rem);
2905
+ font-weight: var(--roxy-weight-bold, 600);
2906
+ }
2907
+
2908
+ .adequacy-badge--adequate {
2909
+ background: color-mix(in srgb, var(--roxy-success, #16a34a) 12%, transparent);
2910
+ color: var(--roxy-success-fg, #166534);
2911
+ }
2912
+
2913
+ .adequacy-badge--weak {
2914
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 12%, transparent);
2915
+ color: var(--roxy-danger-fg, #991b1b);
2916
+ }
2917
+
2918
+ .rank-badge {
2919
+ font-size: var(--roxy-text-xs, 0.75rem);
2920
+ color: var(--roxy-accent-fg, #b45309);
2921
+ font-weight: var(--roxy-weight-bold, 600);
2922
+ }
2923
+
2924
+ .legend {
2925
+ display: flex;
2926
+ flex-wrap: wrap;
2927
+ gap: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
2928
+ border-top: 1px solid var(--roxy-border, #e4e4e7);
2929
+ padding-top: var(--roxy-space-sm, 0.5rem);
2930
+ }
2931
+
2932
+ .legend-row {
2933
+ display: flex;
2934
+ align-items: center;
2935
+ gap: 6px;
2936
+ font-size: var(--roxy-text-xs, 0.75rem);
2937
+ color: var(--roxy-muted, #71717a);
2938
+ }
2939
+
2940
+ .legend-swatch {
2941
+ display: inline-block;
2942
+ width: 10px;
2943
+ height: 10px;
2944
+ border-radius: var(--roxy-radius-sm, 4px);
2945
+ flex-shrink: 0;
2946
+ }
2947
+
2948
+ @container (max-width: 480px) {
2949
+ .planet-row {
2950
+ grid-template-columns: 6rem 1fr;
2951
+ grid-template-rows: auto auto;
2952
+ }
2953
+ .pills {
2954
+ grid-column: 1 / -1;
2955
+ flex-direction: row;
2956
+ align-items: center;
2957
+ justify-content: flex-start;
2958
+ }
2959
+ }
2960
+ `],c([y({attribute:!1})],se.prototype,"data",2),se=c([v("roxy-shadbala-table")],se);var ct=360,P=ct/2,Dt=170,kr=154,Ot=124,Se=96,oe=class extends u{constructor(){super(...arguments);this.data=null}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No synastry data</div>`;let{person1:e,person2:t,compatibilityScore:s,analysis:o}=this.data,l=this.data.interAspects??[],d=e?.planets??[],p=t?.planets??[],m=typeof s=="number"?Math.round(s):void 0,h=o?.overall,g=o?.strengths??[],f=o?.challenges??[];return d.length>0&&p.length>0?a`<div
2961
+ class="wrap"
2962
+ aria-label="Synastry compatibility chart"
2963
+ >
2964
+ <div class="head">
2965
+ <h2 class="title">Synastry</h2>
2966
+ ${typeof m=="number"?a`<span class="score" aria-label=${`Score ${m} of 100`}
2967
+ >${m} / 100</span
2968
+ >`:n}
2969
+ </div>
2970
+ <svg
2971
+ viewBox="0 0 ${ct} ${ct}"
2972
+ role="img"
2018
2973
  aria-label="Dual chart wheel comparing two natal charts"
2019
2974
  >
2020
2975
  <title>Synastry dual wheel</title>
2021
2976
  <circle
2022
2977
  class="wheel-line"
2023
- cx=${E}
2024
- cy=${E}
2025
- r=${mr}
2978
+ cx=${P}
2979
+ cy=${P}
2980
+ r=${Dt}
2026
2981
  stroke-width="1.5"
2027
2982
  />
2028
2983
  <circle
2029
2984
  class="wheel-line"
2030
- cx=${E}
2031
- cy=${E}
2032
- r=${be+14}
2985
+ cx=${P}
2986
+ cy=${P}
2987
+ r=${Se+14}
2033
2988
  stroke-width="0.8"
2034
2989
  />
2035
2990
  <circle
2036
2991
  class="wheel-line"
2037
- cx=${E}
2038
- cy=${E}
2039
- r=${be-14}
2992
+ cx=${P}
2993
+ cy=${P}
2994
+ r=${Se-14}
2040
2995
  stroke-width="0.6"
2041
2996
  />
2042
2997
  ${this.renderSpokes()} ${this.renderSigns()}
2043
- ${this.renderRing(c,Br,"p1")} ${this.renderRing(m,be,"p2")}
2998
+ ${this.renderInterAspectLines(d,p,l)}
2999
+ ${this.renderRing(d,Ot,"p1")} ${this.renderRing(p,Se,"p2")}
2044
3000
  </svg>
2045
- ${i?s`<p class="summary">${i}</p>`:l}
2046
- ${n.length>0?this.renderAspects(n):l}
2047
- ${(this.data.strengths?.length??0)>0||(this.data.challenges?.length??0)>0?s`<div class="lists">
2048
- ${this.data.strengths?.length?s`<div>
3001
+ <div class="legend-row">
3002
+ <span><span class="swatch" style="background: var(--roxy-accent)"></span>Person 1</span>
3003
+ <span><span class="swatch" style="background: var(--roxy-info)"></span>Person 2</span>
3004
+ <span><span class="swatch" style="background: var(--roxy-success)"></span>harmonious</span>
3005
+ <span><span class="swatch" style="background: var(--roxy-danger)"></span>challenging</span>
3006
+ </div>
3007
+ ${h?a`<p class="summary">${h}</p>`:n}
3008
+ ${l.length>0?this.renderAspects(l):n}
3009
+ ${g.length>0||f.length>0?a`<div class="lists">
3010
+ ${g.length?a`<div>
2049
3011
  <h3>Strengths</h3>
2050
3012
  <ul>
2051
- ${this.data.strengths.map(u=>s`<li>${u}</li>`)}
3013
+ ${g.map($=>a`<li>${$}</li>`)}
2052
3014
  </ul>
2053
- </div>`:l}
2054
- ${this.data.challenges?.length?s`<div>
3015
+ </div>`:n}
3016
+ ${f.length?a`<div>
2055
3017
  <h3>Challenges</h3>
2056
3018
  <ul>
2057
- ${this.data.challenges.map(u=>s`<li>${u}</li>`)}
3019
+ ${f.map($=>a`<li>${$}</li>`)}
2058
3020
  </ul>
2059
- </div>`:l}
2060
- </div>`:l}
2061
- </div>`}normalizePlanets(e){return e?Array.isArray(e)?e:Object.entries(e).map(([r,a])=>({...a,name:r})):[]}renderSpokes(){return Array.from({length:12},(e,r)=>{let a=r*30-90,i=P(E,E,be-14,a),n=P(E,E,mr,a);return $`<line class="wheel-line" x1=${i.x} y1=${i.y} x2=${n.x} y2=${n.y} stroke-width="0.6" />`})}renderSigns(){return["Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius","Pisces"].map((r,a)=>{let i=a*30+15-90,n=P(E,E,qr,i);return $`<text class="sign" x=${n.x} y=${n.y} text-anchor="middle" dominant-baseline="central">${re[r]}</text>`})}renderRing(e,r,a){return e.map(i=>{let n=typeof i.longitude=="number"?i.longitude:typeof i.degree=="number"?i.degree:NaN;if(!Number.isFinite(n))return l;let c=P(E,E,r,n-90),m=i.name??i.planet??"",u=xe[Kr(m)]??m.slice(0,2);return $`<text class=${a} x=${c.x} y=${c.y} text-anchor="middle" dominant-baseline="central"><title>${m}</title>${u}</text>`})}renderAspects(e){return s`<table>
3021
+ </div>`:n}
3022
+ </div>`:n}
3023
+ </div>`:a`<div
3024
+ class="wrap"
3025
+ aria-label="Synastry compatibility chart"
3026
+ >
3027
+ <div class="head">
3028
+ <h2 class="title">Synastry</h2>
3029
+ ${typeof m=="number"?a`<span class="score" aria-label=${`Score ${m} of 100`}
3030
+ >${m} / 100</span
3031
+ >`:n}
3032
+ </div>
3033
+ <div class="missing-planets" role="status">
3034
+ Synastry response missing planet positions. Pass
3035
+ <code>data</code> with <code>person1.planets</code> and
3036
+ <code>person2.planets</code> arrays from the natal-chart endpoint, or
3037
+ use the <code>&lt;roxy-data&gt;</code> fallback.
3038
+ </div>
3039
+ ${h?a`<p class="summary">${h}</p>`:n}
3040
+ ${l.length>0?this.renderAspects(l):n}
3041
+ ${g.length>0||f.length>0?a`<div class="lists">
3042
+ ${g.length?a`<div>
3043
+ <h3>Strengths</h3>
3044
+ <ul>
3045
+ ${g.map($=>a`<li>${$}</li>`)}
3046
+ </ul>
3047
+ </div>`:n}
3048
+ ${f.length?a`<div>
3049
+ <h3>Challenges</h3>
3050
+ <ul>
3051
+ ${f.map($=>a`<li>${$}</li>`)}
3052
+ </ul>
3053
+ </div>`:n}
3054
+ </div>`:n}
3055
+ </div>`}toAngle(e){return 180-e}renderSpokes(){return Array.from({length:12},(e,t)=>{let s=this.toAngle(t*30),o=R(P,P,Se-14,s),l=R(P,P,Dt,s);return S`<line class="wheel-line" x1=${o.x} y1=${o.y} x2=${l.x} y2=${l.y} stroke-width="0.6" />`})}renderSigns(){return pe.map((e,t)=>{let s=this.toAngle(t*30+15),o=R(P,P,kr,s);return S`<text class="sign" x=${o.x} y=${o.y} text-anchor="middle" dominant-baseline="central">${N[e]}</text>`})}renderRing(e,t,s){return e.map(o=>{if(!Number.isFinite(o.longitude))return n;let l=R(P,P,t,this.toAngle(o.longitude)),d=L[C(o.name)]??o.name.slice(0,2);return S`<text class=${s} x=${l.x} y=${l.y} text-anchor="middle" dominant-baseline="central"><title>${o.name}</title>${d}</text>`})}renderInterAspectLines(e,t,s){let o=(l,d)=>{let p=C(d);for(let m of l)if(C(m.name)===p&&typeof m.longitude=="number")return m.longitude};return s.map(l=>{let d=o(e,l.planet1),p=o(t,l.planet2);if(d===void 0||p===void 0)return n;let m=R(P,P,Ot-12,this.toAngle(d)),h=R(P,P,Se+8,this.toAngle(p)),g=ke(l),f=ze[g]??"aspect-other",k=w(l.orb,1);return S`<line class=${`aspect ${f}`} x1=${m.x} y1=${m.y} x2=${h.x} y2=${h.y}><title>${l.planet1} ${g} ${l.planet2}${k?` (orb ${k}\xB0)`:""}</title></line>`})}renderAspects(e){return a`<table>
2062
3056
  <thead>
2063
3057
  <tr>
2064
3058
  <th>Planet 1</th>
@@ -2069,17 +3063,15 @@
2069
3063
  </tr>
2070
3064
  </thead>
2071
3065
  <tbody>
2072
- ${e.slice(0,16).map(r=>s`<tr>
2073
- <td>${r.planet1??""}</td>
2074
- <td>${r.planet2??""}</td>
2075
- <td>${r.aspect??""}</td>
2076
- <td class="orb">
2077
- ${typeof r.orb=="number"?r.orb.toFixed(1):""}
2078
- </td>
2079
- <td>${r.strength??""}</td>
3066
+ ${e.slice(0,12).map(t=>a`<tr>
3067
+ <td>${t.planet1}</td>
3068
+ <td>${t.planet2}</td>
3069
+ <td>${ke(t)||""}</td>
3070
+ <td class="orb">${w(t.orb,1)}</td>
3071
+ <td>${Sr(t.strength)}</td>
2080
3072
  </tr>`)}
2081
3073
  </tbody>
2082
- </table>`}};F.styles=[f,y`
3074
+ </table>`}};oe.styles=[b,x`
2083
3075
  .wrap {
2084
3076
  display: grid;
2085
3077
  gap: var(--roxy-space-md, 1rem);
@@ -2131,6 +3123,42 @@
2131
3123
  font-weight: 600;
2132
3124
  font-size: 13px;
2133
3125
  }
3126
+ .aspect {
3127
+ stroke-width: 0.8;
3128
+ fill: none;
3129
+ opacity: 0.5;
3130
+ }
3131
+ .aspect-trine,
3132
+ .aspect-sextile {
3133
+ stroke: var(--roxy-success, #16a34a);
3134
+ }
3135
+ .aspect-square,
3136
+ .aspect-opposition {
3137
+ stroke: var(--roxy-danger, #dc2626);
3138
+ }
3139
+ .aspect-conjunction {
3140
+ stroke: var(--roxy-accent-fg, #b45309);
3141
+ }
3142
+ .aspect-other {
3143
+ stroke: var(--roxy-muted, #71717a);
3144
+ opacity: 0.35;
3145
+ }
3146
+ .legend-row {
3147
+ display: flex;
3148
+ flex-wrap: wrap;
3149
+ gap: var(--roxy-space-md, 1rem);
3150
+ font-size: var(--roxy-text-xs, 0.75rem);
3151
+ color: var(--roxy-muted, #71717a);
3152
+ margin-top: calc(var(--roxy-space-xs, 0.25rem) * -1);
3153
+ }
3154
+ .legend-row .swatch {
3155
+ display: inline-block;
3156
+ width: 8px;
3157
+ height: 8px;
3158
+ border-radius: 50%;
3159
+ margin-right: 4px;
3160
+ vertical-align: middle;
3161
+ }
2134
3162
 
2135
3163
  .summary {
2136
3164
  margin: 0;
@@ -2178,17 +3206,70 @@
2178
3206
  padding-left: var(--roxy-space-md, 1rem);
2179
3207
  font-size: var(--roxy-text-sm, 0.875rem);
2180
3208
  }
2181
- `],d([p({attribute:!1})],F.prototype,"data",2),F=d([x("roxy-synastry-chart")],F);function Kr(o){return o?o.charAt(0).toUpperCase()+o.slice(1).toLowerCase():""}var R=class extends g{constructor(){super(...arguments);this.data=null;this.flipped=!1;this.toggleFlip=()=>{this.flipped=!this.flipped}}getCard(){return this.data?"card"in this.data&&this.data.card?this.data.card:this.data:null}render(){let e=this.getCard();if(!e)return s`<div class="roxy-empty" role="status">No tarot data</div>`;let r=this.flipped!==!!e.reversed,a=typeof e.meaning=="string"?e.meaning:(r?e.meaning?.reversed:e.meaning?.upright)??e.meaning?.spiritual??e.upright?.meaning,i=this.data&&"dailyMessage"in this.data?this.data.dailyMessage:void 0;return s`<article class="card" aria-label=${e.name??"Tarot card"}>
3209
+
3210
+ .missing-planets {
3211
+ background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 8%, transparent);
3212
+ border: 1px solid var(--roxy-border, #e4e4e7);
3213
+ border-radius: var(--roxy-radius-md, 8px);
3214
+ padding: var(--roxy-space-md, 1rem);
3215
+ color: var(--roxy-fg, #0a0a0a);
3216
+ font-size: var(--roxy-text-sm, 0.875rem);
3217
+ line-height: 1.5;
3218
+ }
3219
+ .missing-planets code {
3220
+ font-family: var(--roxy-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
3221
+ font-size: 0.95em;
3222
+ background: color-mix(in srgb, var(--roxy-fg, #0a0a0a) 6%, transparent);
3223
+ padding: 0 4px;
3224
+ border-radius: 4px;
3225
+ }
3226
+ `],c([y({attribute:!1})],oe.prototype,"data",2),oe=c([v("roxy-synastry-chart")],oe);function Sr(i){return typeof i=="number"?Math.round(i).toString():""}var W=class extends u{constructor(){super(...arguments);this.data=null;this.flipped=!1;this.toggleFlip=()=>{this.flipped=!this.flipped}}render(){let e=this.data;return e?"card"in e?this.renderDailyCard(e):this.renderFullCard(e):a`<div class="roxy-empty" role="status">No tarot data</div>`}renderDailyCard(e){let t=e.card,s=this.flipped!==!!t.reversed,o=t.keywords??[];return a`<article class="card" aria-label=${t.name??"Tarot card"}>
3227
+ <div class="image-wrap">
3228
+ ${t.imageUrl?a`<img
3229
+ class=${`image ${s?"reversed":""}`}
3230
+ src=${t.imageUrl}
3231
+ alt=${t.name??"Tarot card"}
3232
+ tabindex="0"
3233
+ @click=${this.toggleFlip}
3234
+ @keydown=${l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),this.toggleFlip())}}
3235
+ />`:a`<div
3236
+ class=${`image ${s?"reversed":""}`}
3237
+ style="aspect-ratio: 0.6; display: flex; align-items: center; justify-content: center; color: var(--roxy-muted)"
3238
+ >
3239
+ ${t.name??"?"}
3240
+ </div>`}
3241
+ </div>
3242
+ <div>
3243
+ <div class="meta">
3244
+ ${t.arcana?a`${t.arcana} arcana`:n}
3245
+ ${s?a` · reversed`:n}
3246
+ </div>
3247
+ <h2 class="title">${t.name??"Tarot card"}</h2>
3248
+ ${e.dailyMessage?a`<p class="message">${e.dailyMessage}</p>`:n}
3249
+ ${t.meaning?a`<p>${t.meaning}</p>`:n}
3250
+ ${o.length>0?a`<div class="chips">
3251
+ ${o.map(l=>a`<span>${l}</span>`)}
3252
+ </div>`:n}
3253
+ <button
3254
+ class="flip"
3255
+ type="button"
3256
+ @click=${this.toggleFlip}
3257
+ aria-pressed=${this.flipped?"true":"false"}
3258
+ >
3259
+ Flip card
3260
+ </button>
3261
+ </div>
3262
+ </article>`}renderFullCard(e){let t=this.flipped,s=t?e.reversed:e.upright,o=t?e.keywords?.reversed??[]:e.keywords?.upright??[];return a`<article class="card" aria-label=${e.name??"Tarot card"}>
2182
3263
  <div class="image-wrap">
2183
- ${e.imageUrl?s`<img
2184
- class=${`image ${r?"reversed":""}`}
3264
+ ${e.imageUrl?a`<img
3265
+ class=${`image ${t?"reversed":""}`}
2185
3266
  src=${e.imageUrl}
2186
3267
  alt=${e.name??"Tarot card"}
2187
3268
  tabindex="0"
2188
3269
  @click=${this.toggleFlip}
2189
- @keydown=${n=>{(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),this.toggleFlip())}}
2190
- />`:s`<div
2191
- class=${`image ${r?"reversed":""}`}
3270
+ @keydown=${l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),this.toggleFlip())}}
3271
+ />`:a`<div
3272
+ class=${`image ${t?"reversed":""}`}
2192
3273
  style="aspect-ratio: 0.6; display: flex; align-items: center; justify-content: center; color: var(--roxy-muted)"
2193
3274
  >
2194
3275
  ${e.name??"?"}
@@ -2196,17 +3277,15 @@
2196
3277
  </div>
2197
3278
  <div>
2198
3279
  <div class="meta">
2199
- ${e.arcana?s`${e.arcana} arcana`:l}
2200
- ${e.number!==void 0&&e.number!==null?s` · ${e.number}`:l}
2201
- ${r?s` · reversed`:l}
2202
- ${e.position?s`<span class="position">${e.position}</span>`:l}
3280
+ ${e.arcana?a`${e.arcana} arcana`:n}
3281
+ ${e.number!==void 0&&e.number!==null?a` · ${e.number}`:n}
3282
+ ${t?a` · reversed`:n}
2203
3283
  </div>
2204
3284
  <h2 class="title">${e.name??"Tarot card"}</h2>
2205
- ${i?s`<p class="message">${i}</p>`:l}
2206
- ${a?s`<p>${a}</p>`:l}
2207
- ${e.keywords?.length?s`<div class="chips">
2208
- ${e.keywords.map(n=>s`<span>${n}</span>`)}
2209
- </div>`:l}
3285
+ ${s?.description?a`<p>${s.description}</p>`:n}
3286
+ ${o.length>0?a`<div class="chips">
3287
+ ${o.map(l=>a`<span>${l}</span>`)}
3288
+ </div>`:n}
2210
3289
  <button
2211
3290
  class="flip"
2212
3291
  type="button"
@@ -2216,7 +3295,7 @@
2216
3295
  Flip card
2217
3296
  </button>
2218
3297
  </div>
2219
- </article>`}};R.styles=[f,y`
3298
+ </article>`}};W.styles=[b,x`
2220
3299
  .card {
2221
3300
  background: var(--roxy-bg, #fff);
2222
3301
  border: 1px solid var(--roxy-border, #e4e4e7);
@@ -2270,11 +3349,6 @@
2270
3349
  letter-spacing: 0.06em;
2271
3350
  margin-bottom: var(--roxy-space-sm, 0.5rem);
2272
3351
  }
2273
- .position {
2274
- color: var(--roxy-info, #0284c7);
2275
- margin-left: var(--roxy-space-xs, 0.25rem);
2276
- text-transform: capitalize;
2277
- }
2278
3352
 
2279
3353
  .message {
2280
3354
  color: var(--roxy-fg, #0a0a0a);
@@ -2311,35 +3385,51 @@
2311
3385
  .flip:hover {
2312
3386
  transform: scale(1.02);
2313
3387
  }
2314
- `],d([p({attribute:!1})],R.prototype,"data",2),d([_()],R.prototype,"flipped",2),R=d([x("roxy-tarot-card")],R);var I=class extends g{constructor(){super(...arguments);this.data=null;this.spread="three-card"}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No tarot spread</div>`;let r=e.positions??e.cards??[],a=!!e.answer,i=a?(e.answer??"").toLowerCase().replace(/[^a-z]/g,""):"";return s`<article class="wrap" aria-label="Tarot spread">
3388
+ `],c([y({attribute:!1})],W.prototype,"data",2),c([E()],W.prototype,"flipped",2),W=c([v("roxy-tarot-card")],W);var J=class extends u{constructor(){super(...arguments);this.data=null;this.spread="three-card"}render(){let e=this.data;if(!e)return a`<div class="roxy-empty" role="status">No tarot spread</div>`;let t="answer"in e,s="cards"in e&&!("spread"in e),o=s?[]:"positions"in e?e.positions??[]:[],l=s&&"cards"in e?e.cards:[],d=t?e.answer:void 0,p=t?e.strength:void 0,m="spread"in e?e.spread:this.spread.replace(/-/g," "),h="question"in e?e.question:void 0,g="summary"in e?e.summary:void 0,f=t?e.interpretation:void 0,k=d?d.toLowerCase().replace(/[^a-z]/g,""):"";return a`<article class="wrap" aria-label="Tarot spread">
2315
3389
  <header class="head">
2316
- <h2 class="title">${e.spread??this.spread.replace(/-/g," ")}</h2>
2317
- ${e.question?s`<span class="question">"${e.question}"</span>`:l}
3390
+ <h2 class="title">${m}</h2>
3391
+ ${h?a`<span class="question">"${h}"</span>`:n}
2318
3392
  </header>
2319
- ${a?s`<div>
2320
- <span class=${`answer ${i}`}>${e.answer}</span>
2321
- ${e.strength?s`<small> · ${e.strength}</small>`:l}
2322
- </div>`:l}
2323
- ${r.length>0?s`<div class="grid">
2324
- ${r.map(n=>s`<div class="card">
2325
- <p class="label">${n.label??n.name??n.position??""}</p>
3393
+ ${t?a`<div>
3394
+ <span class=${`answer ${k}`}>${d}</span>
3395
+ ${p?a`<small> · ${p}</small>`:n}
3396
+ </div>`:n}
3397
+ ${o.length>0?a`<div class="grid">
3398
+ ${o.map($=>a`<div class="card">
3399
+ <p class="label">${$.name??""}</p>
2326
3400
  <div class="image">
2327
- ${n.card?.imageUrl?s`<img
2328
- src=${n.card.imageUrl}
2329
- alt=${n.card.name??"tarot card"}
2330
- class=${n.card.reversed?"reversed":""}
2331
- />`:s`${n.card?.name??"?"}`}
3401
+ ${$.card?.imageUrl?a`<img
3402
+ src=${$.card.imageUrl}
3403
+ alt=${$.card.name??"tarot card"}
3404
+ class=${$.card.reversed?"reversed":""}
3405
+ />`:a`${$.card?.name??"?"}`}
2332
3406
  </div>
2333
3407
  <p class="name">
2334
- ${n.card?.name??""}
2335
- ${n.card?.reversed?s`<small>(reversed)</small>`:l}
3408
+ ${$.card?.name??""}
3409
+ ${$.card?.reversed?a`<small>(reversed)</small>`:n}
2336
3410
  </p>
2337
- ${n.interpretation?s`<p class="interp">${n.interpretation}</p>`:l}
3411
+ ${$.interpretation?a`<p class="interp">${$.interpretation}</p>`:n}
2338
3412
  </div>`)}
2339
- </div>`:l}
2340
- ${e.reading?s`<p class="reading">${e.reading}</p>`:l}
2341
- ${e.interpretation&&!e.reading?s`<p class="reading">${e.interpretation}</p>`:l}
2342
- </article>`}};I.styles=[f,y`
3413
+ </div>`:n}
3414
+ ${l.length>0?a`<div class="grid">
3415
+ ${l.map($=>a`<div class="card">
3416
+ <div class="image">
3417
+ ${$.imageUrl?a`<img
3418
+ src=${$.imageUrl}
3419
+ alt=${$.name??"tarot card"}
3420
+ class=${$.reversed?"reversed":""}
3421
+ />`:a`${$.name??"?"}`}
3422
+ </div>
3423
+ <p class="name">
3424
+ ${$.name??""}
3425
+ ${$.reversed?a`<small>(reversed)</small>`:n}
3426
+ </p>
3427
+ ${$.meaning?a`<p class="interp">${$.meaning}</p>`:n}
3428
+ </div>`)}
3429
+ </div>`:n}
3430
+ ${g?a`<p class="reading">${g}</p>`:n}
3431
+ ${f?a`<p class="reading">${f}</p>`:n}
3432
+ </article>`}};J.styles=[b,x`
2343
3433
  .wrap {
2344
3434
  display: grid;
2345
3435
  gap: var(--roxy-space-md, 1rem);
@@ -2375,15 +3465,15 @@
2375
3465
  }
2376
3466
  .answer.yes {
2377
3467
  background: color-mix(in srgb, var(--roxy-success, #16a34a) 16%, transparent);
2378
- color: var(--roxy-success, #16a34a);
3468
+ color: var(--roxy-success-fg, #166534);
2379
3469
  }
2380
3470
  .answer.no {
2381
3471
  background: color-mix(in srgb, var(--roxy-danger, #dc2626) 16%, transparent);
2382
- color: var(--roxy-danger, #dc2626);
3472
+ color: var(--roxy-danger-fg, #991b1b);
2383
3473
  }
2384
3474
  .answer.maybe {
2385
3475
  background: color-mix(in srgb, var(--roxy-warning, #ea580c) 16%, transparent);
2386
- color: var(--roxy-warning, #ea580c);
3476
+ color: var(--roxy-warning-fg, #9a3412);
2387
3477
  }
2388
3478
 
2389
3479
  .grid {
@@ -2445,7 +3535,271 @@
2445
3535
  margin: 0;
2446
3536
  color: var(--roxy-fg, #0a0a0a);
2447
3537
  }
2448
- `],d([p({attribute:!1})],I.prototype,"data",2),d([p({type:String,reflect:!0})],I.prototype,"spread",2),I=d([x("roxy-tarot-spread")],I);var Gr={1:{x:150,y:58},2:{x:205,y:52},3:{x:253,y:112},4:{x:243,y:150},5:{x:253,y:188},6:{x:205,y:248},7:{x:150,y:242},8:{x:95,y:248},9:{x:47,y:188},10:{x:57,y:150},11:{x:47,y:112},12:{x:95,y:52}},Yr={1:{x:150,y:35},2:{x:222,y:40},3:{x:265,y:100},4:{x:265,y:150},5:{x:265,y:200},6:{x:222,y:260},7:{x:150,y:265},8:{x:78,y:260},9:{x:35,y:200},10:{x:35,y:150},11:{x:35,y:100},12:{x:78,y:40}},Fr=["aries","taurus","gemini","cancer","leo","virgo","libra","scorpio","sagittarius","capricorn","aquarius","pisces"],Vr={aries:"Aries",taurus:"Taurus",gemini:"Gemini",cancer:"Cancer",leo:"Leo",virgo:"Virgo",libra:"Libra",scorpio:"Scorpio",sagittarius:"Sagittarius",capricorn:"Capricorn",aquarius:"Aquarius",pisces:"Pisces"},q=class extends g{constructor(){super(...arguments);this.data=null;this.chartStyle="south"}buildHouses(){if(!this.data)return[];let e=[];if(Array.isArray(this.data.houses)){for(let r of this.data.houses)e.push({house:r.house??r.number??e.length+1,sign:r.sign??"",planets:r.planets??[]});if(e.length>0)return e}for(let r=0;r<12;r++){let a=Fr[r],n=(this.data[a]?.signs??[]).map(c=>c.planet??"").filter(Boolean);e.push({house:r+1,sign:Vr[a]??"",planets:n})}return e}render(){if(!this.data)return s`<div class="roxy-empty" role="status">No kundli data</div>`;let e=this.buildHouses();return s`<div class="wrap">
3538
+ `],c([y({attribute:!1})],J.prototype,"data",2),c([y({type:String,reflect:!0})],J.prototype,"spread",2),J=c([v("roxy-tarot-spread")],J);var ie=class extends u{constructor(){super(...arguments);this.data=null}render(){if(!this.data?.transitPlanets?.length)return a`<div class="roxy-empty" role="status">No transits data</div>`;let{transitDate:e,transitTime:t,transitPlanets:s,transitAspects:o,summary:l}=this.data,d=[Ne(e),O(t)].filter(Boolean).join(" ");return a`<div class="wrap" aria-label="Transit positions table">
3539
+ <div class="head">
3540
+ <h2 class="title">Transits</h2>
3541
+ ${d?a`<p class="subtitle">${d}</p>`:n}
3542
+ </div>
3543
+
3544
+ ${l?this.renderSummaryPills(l):n}
3545
+
3546
+ <div>
3547
+ <p class="section-label">Planet positions</p>
3548
+ <div class="overflow-scroll">
3549
+ ${this.renderPlanetsTable(s)}
3550
+ </div>
3551
+ </div>
3552
+
3553
+ ${o?.length?a`<div>
3554
+ <p class="section-label">Transit aspects</p>
3555
+ <div class="overflow-scroll">
3556
+ ${this.renderAspectsTable(o)}
3557
+ </div>
3558
+ </div>`:n}
3559
+ </div>`}renderSummaryPills(e){return a`<div class="summary-pills" role="region" aria-label="Aspect summary">
3560
+ <span class="pill pill--muted">
3561
+ Total: ${e.totalAspects}
3562
+ </span>
3563
+ <span class="pill pill--success">
3564
+ Harmonious: ${e.harmonious}
3565
+ </span>
3566
+ <span class="pill pill--danger">
3567
+ Challenging: ${e.challenging}
3568
+ </span>
3569
+ <span class="pill pill--muted">
3570
+ Neutral: ${e.neutral}
3571
+ </span>
3572
+ </div>`}renderPlanetsTable(e){return a`<table class="planets-table">
3573
+ <thead>
3574
+ <tr>
3575
+ <th scope="col">Planet</th>
3576
+ <th scope="col">Sign</th>
3577
+ <th scope="col">Degree</th>
3578
+ <th scope="col">Speed</th>
3579
+ </tr>
3580
+ </thead>
3581
+ <tbody>
3582
+ ${e.map(t=>{let s=L[C(t.name)]??"",o=N[C(t.sign)]??"",l=t.speed>=0?"\u2191":"\u2193";return a`<tr>
3583
+ <td>
3584
+ <div class="planet-cell">
3585
+ <span class="glyph" aria-hidden="true">${s}</span>
3586
+ ${t.name}
3587
+ ${t.isRetrograde?a`<span class="retro-badge" aria-label="retrograde">R</span>`:n}
3588
+ </div>
3589
+ </td>
3590
+ <td>
3591
+ <div class="planet-cell">
3592
+ <span class="glyph" aria-hidden="true">${o}</span>
3593
+ ${t.sign}
3594
+ </div>
3595
+ </td>
3596
+ <td class="num">${w(t.degree,2)}</td>
3597
+ <td class="speed">
3598
+ <span class="speed-arrow" aria-hidden="true">${l}</span>
3599
+ ${w(Math.abs(t.speed),4)}
3600
+ </td>
3601
+ </tr>`})}
3602
+ </tbody>
3603
+ </table>`}renderAspectsTable(e){return a`<table class="aspects-table">
3604
+ <thead>
3605
+ <tr>
3606
+ <th scope="col">Transit Planet</th>
3607
+ <th scope="col">Natal Planet</th>
3608
+ <th scope="col">Type</th>
3609
+ <th scope="col">Orb</th>
3610
+ <th scope="col">Status</th>
3611
+ <th scope="col">Strength</th>
3612
+ <th scope="col" class="interp">Interpretation</th>
3613
+ </tr>
3614
+ </thead>
3615
+ <tbody>
3616
+ ${e.map(t=>{let s=L[C(t.transitPlanet)]??"",o=L[C(t.natalPlanet)]??"",l=`nature-${(t.nature??"").toLowerCase()}`,d=t.interpretation?.summary??"",p=d.length>120?`${d.slice(0,120)}...`:d;return a`<tr>
3617
+ <td>
3618
+ <div class="arrow-cell">
3619
+ <span class="glyph" aria-hidden="true">${s}</span>
3620
+ ${t.transitPlanet}
3621
+ </div>
3622
+ </td>
3623
+ <td>
3624
+ <div class="arrow-cell">
3625
+ <span class="glyph" aria-hidden="true">${o}</span>
3626
+ ${t.natalPlanet}
3627
+ </div>
3628
+ </td>
3629
+ <td class=${l}>${(t.type??"").toLowerCase()}</td>
3630
+ <td class="num">${w(t.orb,2)}</td>
3631
+ <td>${t.isApplying?"Applying":"Separating"}</td>
3632
+ <td class="num">${w(t.strength,1)}</td>
3633
+ <td class="interp" title=${d}>${p}</td>
3634
+ </tr>`})}
3635
+ </tbody>
3636
+ </table>`}};ie.styles=[b,x`
3637
+ .wrap {
3638
+ display: grid;
3639
+ gap: var(--roxy-space-md, 1rem);
3640
+ }
3641
+
3642
+ .head {
3643
+ display: flex;
3644
+ justify-content: space-between;
3645
+ align-items: baseline;
3646
+ gap: var(--roxy-space-md, 1rem);
3647
+ flex-wrap: wrap;
3648
+ }
3649
+
3650
+ .title {
3651
+ font-size: var(--roxy-text-lg, 1.125rem);
3652
+ font-weight: var(--roxy-weight-bold, 600);
3653
+ margin: 0;
3654
+ }
3655
+
3656
+ .subtitle {
3657
+ color: var(--roxy-muted, #71717a);
3658
+ font-size: var(--roxy-text-sm, 0.875rem);
3659
+ margin: 0;
3660
+ }
3661
+
3662
+ .summary-pills {
3663
+ display: flex;
3664
+ flex-wrap: wrap;
3665
+ gap: var(--roxy-space-sm, 0.5rem);
3666
+ }
3667
+
3668
+ .pill {
3669
+ display: inline-flex;
3670
+ align-items: center;
3671
+ gap: 4px;
3672
+ padding: 2px var(--roxy-space-sm, 0.5rem);
3673
+ border-radius: var(--roxy-radius-full, 9999px);
3674
+ font-size: var(--roxy-text-xs, 0.75rem);
3675
+ font-weight: var(--roxy-weight-bold, 600);
3676
+ border: 1px solid currentColor;
3677
+ }
3678
+
3679
+ .pill--muted {
3680
+ color: var(--roxy-fg, #0a0a0a);
3681
+ background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent);
3682
+ }
3683
+
3684
+ .pill--success {
3685
+ color: var(--roxy-success-fg, #166534);
3686
+ background: color-mix(in srgb, var(--roxy-success, #16a34a) 10%, transparent);
3687
+ }
3688
+
3689
+ .pill--danger {
3690
+ color: var(--roxy-danger-fg, #991b1b);
3691
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 10%, transparent);
3692
+ }
3693
+
3694
+ table {
3695
+ width: 100%;
3696
+ border-collapse: collapse;
3697
+ font-size: var(--roxy-text-sm, 0.875rem);
3698
+ }
3699
+
3700
+ th,
3701
+ td {
3702
+ padding: var(--roxy-space-sm, 0.5rem);
3703
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
3704
+ text-align: left;
3705
+ }
3706
+
3707
+ th {
3708
+ color: var(--roxy-muted, #71717a);
3709
+ font-weight: var(--roxy-weight-bold, 600);
3710
+ text-transform: uppercase;
3711
+ font-size: var(--roxy-text-xs, 0.75rem);
3712
+ letter-spacing: 0.06em;
3713
+ }
3714
+
3715
+ .section-label {
3716
+ font-size: var(--roxy-text-xs, 0.75rem);
3717
+ color: var(--roxy-muted, #71717a);
3718
+ text-transform: uppercase;
3719
+ letter-spacing: 0.06em;
3720
+ font-weight: var(--roxy-weight-bold, 600);
3721
+ margin: 0 0 var(--roxy-space-xs, 0.25rem) 0;
3722
+ }
3723
+
3724
+ .glyph {
3725
+ font-size: 1.1em;
3726
+ margin-right: 2px;
3727
+ line-height: 1;
3728
+ }
3729
+
3730
+ .planet-cell {
3731
+ display: flex;
3732
+ align-items: center;
3733
+ gap: 4px;
3734
+ white-space: nowrap;
3735
+ }
3736
+
3737
+ .retro-badge {
3738
+ display: inline-block;
3739
+ font-size: 0.7em;
3740
+ padding: 1px 4px;
3741
+ border-radius: var(--roxy-radius-sm, 4px);
3742
+ background: color-mix(in srgb, var(--roxy-warning, #ea580c) 12%, transparent);
3743
+ color: var(--roxy-warning-fg, #9a3412);
3744
+ font-weight: var(--roxy-weight-bold, 600);
3745
+ margin-left: 2px;
3746
+ vertical-align: middle;
3747
+ }
3748
+
3749
+ .speed {
3750
+ font-variant-numeric: tabular-nums;
3751
+ color: var(--roxy-muted, #71717a);
3752
+ white-space: nowrap;
3753
+ }
3754
+
3755
+ .speed-arrow {
3756
+ font-size: 0.85em;
3757
+ }
3758
+
3759
+ td.num {
3760
+ font-variant-numeric: tabular-nums;
3761
+ color: var(--roxy-muted, #71717a);
3762
+ }
3763
+
3764
+ .nature-harmonious {
3765
+ color: var(--roxy-success-fg, #166534);
3766
+ }
3767
+
3768
+ .nature-challenging {
3769
+ color: var(--roxy-danger-fg, #991b1b);
3770
+ }
3771
+
3772
+ .nature-neutral {
3773
+ color: var(--roxy-muted, #71717a);
3774
+ }
3775
+
3776
+ .arrow-cell {
3777
+ display: inline-flex;
3778
+ align-items: center;
3779
+ gap: 4px;
3780
+ white-space: nowrap;
3781
+ }
3782
+
3783
+ .interp {
3784
+ color: var(--roxy-secondary, #475569);
3785
+ font-size: var(--roxy-text-xs, 0.75rem);
3786
+ max-width: 22rem;
3787
+ white-space: nowrap;
3788
+ overflow: hidden;
3789
+ text-overflow: ellipsis;
3790
+ }
3791
+
3792
+ @container (max-width: 600px) {
3793
+ .interp {
3794
+ display: none;
3795
+ }
3796
+ }
3797
+
3798
+ .overflow-scroll {
3799
+ overflow-x: auto;
3800
+ -webkit-overflow-scrolling: touch;
3801
+ }
3802
+ `],c([y({attribute:!1})],ie.prototype,"data",2),ie=c([v("roxy-transits-table")],ie);var X=class extends u{constructor(){super(...arguments);this.data=null;this.chartStyle="south"}buildHouses(){if(!this.data)return[];let e=this.data,t=this.data?.meta?.Lagna?.rashi??"",s=[];for(let o=0;o<12;o++){let l=_e[o],p=(e[l]?.signs??[]).map(h=>h.graha).filter(Boolean),m=Me[l]??"";s.push({number:o+1,sign:m,planets:p,isLagna:t?t.toLowerCase()===m.toLowerCase():!1})}return s}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No kundli data</div>`;let e=this.buildHouses(),t=this.chartStyle==="north";return a`<div class="wrap">
2449
3803
  <h2 class="title">Vedic kundli</h2>
2450
3804
  <svg
2451
3805
  viewBox="0 0 300 300"
@@ -2453,29 +3807,10 @@
2453
3807
  aria-label="Vedic birth chart with twelve sign houses"
2454
3808
  >
2455
3809
  <title>Vedic kundli</title>
2456
- <polygon class="line" points="150,10 290,150 150,290 10,150" stroke-width="1.5" />
2457
- <polygon
2458
- class="line"
2459
- points="220,80 220,220 80,220 80,80"
2460
- stroke-width="1"
2461
- fill="none"
2462
- />
2463
- <line class="line" x1="150" y1="10" x2="80" y2="80" stroke-width="1" />
2464
- <line class="line" x1="150" y1="10" x2="220" y2="80" stroke-width="1" />
2465
- <line class="line" x1="290" y1="150" x2="220" y2="80" stroke-width="1" />
2466
- <line class="line" x1="290" y1="150" x2="220" y2="220" stroke-width="1" />
2467
- <line class="line" x1="150" y1="290" x2="220" y2="220" stroke-width="1" />
2468
- <line class="line" x1="150" y1="290" x2="80" y2="220" stroke-width="1" />
2469
- <line class="line" x1="10" y1="150" x2="80" y2="220" stroke-width="1" />
2470
- <line class="line" x1="10" y1="150" x2="80" y2="80" stroke-width="1" />
2471
- ${e.map(r=>this.renderHouseGroup(r))}
3810
+ ${t?Oe():Ge()}
3811
+ ${t?e.map(s=>He(s)):e.map(s=>De(s))}
2472
3812
  </svg>
2473
- </div>`}renderHouseGroup(e){let r=Gr[e.house],a=Yr[e.house];if(!r||!a)return l;let i=ir[e.sign]??"",n=e.planets??[];return $`
2474
- <g>
2475
- ${i?$`<text class="sign-text" x=${a.x} y=${a.y} text-anchor="middle" dominant-baseline="central">${i}</text>`:l}
2476
- ${n.map((c,m)=>{let u=sr[Jr(c)]??c.slice(0,2),h=13,S=r.y-(n.length-1)*h/2+m*h;return $`<text class="planet-text" x=${r.x} y=${S} text-anchor="middle" dominant-baseline="central">${u}</text>`})}
2477
- </g>
2478
- `}};q.styles=[f,y`
3813
+ </div>`}};X.styles=[b,x`
2479
3814
  .wrap {
2480
3815
  display: grid;
2481
3816
  gap: var(--roxy-space-md, 1rem);
@@ -2507,7 +3842,232 @@
2507
3842
  font-weight: 600;
2508
3843
  font-family: var(--roxy-font-sans);
2509
3844
  }
2510
- `],d([p({attribute:!1})],q.prototype,"data",2),d([p({type:String,reflect:!0,attribute:"chart-style"})],q.prototype,"chartStyle",2),q=d([x("roxy-vedic-kundli")],q);function Jr(o){return o?o.charAt(0).toUpperCase()+o.slice(1).toLowerCase():""}var Wr="0.1.0",Zr=["natal-chart","horoscope-card","synastry-chart","compatibility-card","moon-phase","vedic-kundli","panchang-table","dasha-timeline","dosha-card","guna-milan","kp-planets-table","numerology-card","tarot-card","tarot-spread","biorhythm-chart","hexagram","endpoint-form","location-search","data"];return xr(Xr);})();
3845
+ .house-num {
3846
+ fill: var(--roxy-muted, #71717a);
3847
+ font-size: 9px;
3848
+ font-weight: 400;
3849
+ font-family: var(--roxy-font-sans);
3850
+ }
3851
+ .lagna-marker {
3852
+ fill: var(--roxy-accent-fg, #b45309);
3853
+ font-size: 8px;
3854
+ font-weight: 700;
3855
+ font-family: var(--roxy-font-sans);
3856
+ letter-spacing: 0.05em;
3857
+ }
3858
+ .lagna-bg {
3859
+ fill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 12%, transparent);
3860
+ stroke: color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);
3861
+ stroke-width: 0.8;
3862
+ }
3863
+ `],c([y({attribute:!1})],X.prototype,"data",2),c([y({type:String,reflect:!0,attribute:"chart-style"})],X.prototype,"chartStyle",2),X=c([v("roxy-vedic-kundli")],X);var Z=class extends u{constructor(){super(...arguments);this.data=null;this.filter="";this.handleInput=je(e=>{this.filter=e.target.value},200)}renderQualityChip(e){let t=`quality-chip quality-${e}`;return a`<span class=${t}>${e}</span>`}renderDetailCard(e){return a`<div class="detail-card">
3864
+ <p class="detail-name">
3865
+ ${e.name}
3866
+ ${e.quality?this.renderQualityChip(e.quality):n}
3867
+ </p>
3868
+ ${e.description?a`<p class="description">${e.description}</p>`:n}
3869
+ ${e.result?a`<details>
3870
+ <summary>Effects</summary>
3871
+ <div class="result-body">${e.result}</div>
3872
+ </details>`:n}
3873
+ </div>`}render(){if(!this.data)return a`<div class="roxy-empty" role="status">No yoga data</div>`;let e=this.data,t=this.filter.toLowerCase();if("description"in e&&typeof e.description=="string"){let s=e;return a`<div class="wrap">${this.renderDetailCard(s)}</div>`}if("yogas"in e&&Array.isArray(e.yogas)){let s=e.yogas;if(s.length>0&&"description"in s[0]){let m=s,h=t?m.filter(f=>f.name.toLowerCase().includes(t)):m,g=e.total;return a`<div class="wrap">
3874
+ <div class="head">
3875
+ <h2 class="title">Yoga catalog</h2>
3876
+ ${g!==void 0?a`<span class="count">${g} total</span>`:n}
3877
+ </div>
3878
+ <div class="search-wrap">
3879
+ <input
3880
+ class="search"
3881
+ type="search"
3882
+ placeholder="Filter yogas..."
3883
+ aria-label="Filter yoga list by name"
3884
+ .value=${this.filter}
3885
+ @input=${this.handleInput}
3886
+ />
3887
+ </div>
3888
+ <div
3889
+ class="detail-grid"
3890
+ role="region"
3891
+ aria-live="polite"
3892
+ aria-label="Yoga results"
3893
+ >
3894
+ ${h.length>0?h.map(f=>this.renderDetailCard(f)):a`<p class="no-results">No yogas match your search.</p>`}
3895
+ </div>
3896
+ </div>`}let l=s,d=t?l.filter(m=>m.name.toLowerCase().includes(t)):l,p=e.total;return a`<div class="wrap">
3897
+ <div class="head">
3898
+ <h2 class="title">Yoga catalog</h2>
3899
+ ${p!==void 0?a`<span class="count">${p} total</span>`:n}
3900
+ </div>
3901
+ <div class="search-wrap">
3902
+ <input
3903
+ class="search"
3904
+ type="search"
3905
+ placeholder="Filter yogas..."
3906
+ aria-label="Filter yoga list by name"
3907
+ .value=${this.filter}
3908
+ @input=${this.handleInput}
3909
+ />
3910
+ </div>
3911
+ <div
3912
+ class="grid"
3913
+ role="region"
3914
+ aria-live="polite"
3915
+ aria-label="Yoga results"
3916
+ >
3917
+ ${d.length>0?d.map(m=>a`<div class="yoga-chip">
3918
+ ${m.name}
3919
+ <span class="yoga-id">${m.id}</span>
3920
+ </div>`):a`<p class="no-results">No yogas match your search.</p>`}
3921
+ </div>
3922
+ </div>`}return a`<div class="roxy-empty" role="status">No yoga data</div>`}};Z.styles=[b,x`
3923
+ .wrap {
3924
+ display: grid;
3925
+ gap: var(--roxy-space-md, 1rem);
3926
+ }
3927
+ .head {
3928
+ display: flex;
3929
+ justify-content: space-between;
3930
+ align-items: baseline;
3931
+ flex-wrap: wrap;
3932
+ gap: var(--roxy-space-sm, 0.5rem);
3933
+ }
3934
+ .title {
3935
+ font-size: var(--roxy-text-lg, 1.125rem);
3936
+ font-weight: var(--roxy-weight-bold, 600);
3937
+ margin: 0;
3938
+ }
3939
+ .count {
3940
+ font-size: var(--roxy-text-sm, 0.875rem);
3941
+ color: var(--roxy-muted, #71717a);
3942
+ }
3943
+ .search-wrap {
3944
+ display: flex;
3945
+ align-items: center;
3946
+ gap: var(--roxy-space-sm, 0.5rem);
3947
+ }
3948
+ .search {
3949
+ width: 100%;
3950
+ max-width: 280px;
3951
+ padding: 0.35em 0.75em;
3952
+ font-size: var(--roxy-text-sm, 0.875rem);
3953
+ font-family: var(--roxy-font-sans);
3954
+ border: 1px solid var(--roxy-border, #e4e4e7);
3955
+ border-radius: var(--roxy-radius-md, 8px);
3956
+ background: var(--roxy-bg, #fff);
3957
+ color: var(--roxy-fg, #0a0a0a);
3958
+ outline: none;
3959
+ }
3960
+ .search::placeholder {
3961
+ color: var(--roxy-fg, #0a0a0a);
3962
+ opacity: 0.65;
3963
+ }
3964
+ .search:focus {
3965
+ border-color: var(--roxy-accent, #f59e0b);
3966
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--roxy-accent, #f59e0b) 30%, transparent);
3967
+ }
3968
+ .grid {
3969
+ display: grid;
3970
+ gap: var(--roxy-space-sm, 0.5rem);
3971
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
3972
+ }
3973
+ .yoga-chip {
3974
+ padding: 0.4em 0.8em;
3975
+ border: 1px solid var(--roxy-border, #e4e4e7);
3976
+ border-radius: var(--roxy-radius-md, 8px);
3977
+ font-size: var(--roxy-text-sm, 0.875rem);
3978
+ background: var(--roxy-bg, #fff);
3979
+ color: var(--roxy-fg, #0a0a0a);
3980
+ word-break: break-word;
3981
+ }
3982
+ .yoga-chip .yoga-id {
3983
+ display: block;
3984
+ font-size: 0.7em;
3985
+ color: var(--roxy-fg, #0a0a0a);
3986
+ opacity: 0.75;
3987
+ margin-top: 0.15em;
3988
+ }
3989
+ .detail-card {
3990
+ border: 1px solid var(--roxy-border, #e4e4e7);
3991
+ border-radius: var(--roxy-radius-md, 8px);
3992
+ padding: var(--roxy-space-md, 1rem);
3993
+ background: var(--roxy-bg, #fff);
3994
+ display: grid;
3995
+ gap: var(--roxy-space-sm, 0.5rem);
3996
+ }
3997
+ .detail-name {
3998
+ font-size: var(--roxy-text-lg, 1.125rem);
3999
+ font-weight: var(--roxy-weight-bold, 600);
4000
+ margin: 0;
4001
+ display: flex;
4002
+ align-items: center;
4003
+ gap: var(--roxy-space-sm, 0.5rem);
4004
+ flex-wrap: wrap;
4005
+ }
4006
+ .quality-chip {
4007
+ display: inline-block;
4008
+ font-size: var(--roxy-text-xs, 0.75rem);
4009
+ font-weight: 600;
4010
+ padding: 0.15em 0.6em;
4011
+ border-radius: 999px;
4012
+ }
4013
+ .quality-Positive {
4014
+ background: color-mix(in srgb, var(--roxy-success, #22c55e) 18%, transparent);
4015
+ color: var(--roxy-success-fg, #15803d);
4016
+ border: 1px solid color-mix(in srgb, var(--roxy-success, #22c55e) 40%, transparent);
4017
+ }
4018
+ .quality-Negative {
4019
+ background: color-mix(in srgb, var(--roxy-danger, #ef4444) 18%, transparent);
4020
+ color: var(--roxy-danger-fg, #b91c1c);
4021
+ border: 1px solid color-mix(in srgb, var(--roxy-danger, #ef4444) 40%, transparent);
4022
+ }
4023
+ .quality-Both {
4024
+ background: color-mix(in srgb, var(--roxy-warning, #f59e0b) 18%, transparent);
4025
+ color: var(--roxy-warning-fg, #b45309);
4026
+ border: 1px solid color-mix(in srgb, var(--roxy-warning, #f59e0b) 40%, transparent);
4027
+ }
4028
+ .description {
4029
+ font-size: var(--roxy-text-sm, 0.875rem);
4030
+ color: var(--roxy-muted, #71717a);
4031
+ margin: 0;
4032
+ line-height: var(--roxy-leading-normal, 1.5);
4033
+ }
4034
+ details {
4035
+ font-size: var(--roxy-text-sm, 0.875rem);
4036
+ }
4037
+ details summary {
4038
+ cursor: pointer;
4039
+ color: var(--roxy-accent-fg, #b45309);
4040
+ font-weight: 500;
4041
+ padding: 0.25em 0;
4042
+ list-style: none;
4043
+ display: flex;
4044
+ align-items: center;
4045
+ gap: 0.4em;
4046
+ }
4047
+ details summary::before {
4048
+ content: '+';
4049
+ font-size: 1.1em;
4050
+ line-height: 1;
4051
+ }
4052
+ details[open] summary::before {
4053
+ content: '-';
4054
+ }
4055
+ details .result-body {
4056
+ padding-top: var(--roxy-space-xs, 0.25rem);
4057
+ color: var(--roxy-fg, #0a0a0a);
4058
+ line-height: var(--roxy-leading-normal, 1.5);
4059
+ }
4060
+ .no-results {
4061
+ color: var(--roxy-muted, #71717a);
4062
+ font-size: var(--roxy-text-sm, 0.875rem);
4063
+ padding: var(--roxy-space-md, 1rem) 0;
4064
+ text-align: center;
4065
+ }
4066
+ .detail-grid {
4067
+ display: grid;
4068
+ gap: var(--roxy-space-sm, 0.5rem);
4069
+ }
4070
+ `],c([y({attribute:!1})],Z.prototype,"data",2),c([E()],Z.prototype,"filter",2),Z=c([v("roxy-yoga-list")],Z);var Be=[{pascal:"RoxyNatalChart",tag:"roxy-natal-chart",slug:"natal-chart",heading:"Natal chart",description:"Western natal chart wheel for /astrology/natal-chart responses",docsLabel:"Western",endpointLabel:"POST /astrology/natal-chart",docsSummary:"Natal chart wheel with planet glyphs and aspect lines",topic:"Astrology"},{pascal:"RoxyHoroscopeCard",tag:"roxy-horoscope-card",slug:"horoscope-card",heading:"Daily horoscope",description:"Daily, weekly, or monthly horoscope card for /astrology/horoscope/...",docsLabel:"Western",endpointLabel:"GET /astrology/horoscope/{sign}/{daily,weekly,monthly}",docsSummary:"Daily, weekly, or monthly horoscope card",topic:"Astrology"},{pascal:"RoxySynastryChart",tag:"roxy-synastry-chart",slug:"synastry-chart",heading:"Synastry",description:"Dual-wheel synastry chart with inter-aspects table",docsLabel:"Western",endpointLabel:"POST /astrology/synastry",docsSummary:"Dual-wheel synastry with inter-aspects table",topic:"Astrology"},{pascal:"RoxyCompatibilityCard",tag:"roxy-compatibility-card",slug:"compatibility-card",heading:"Compatibility score",description:"Cross-domain compatibility score card",docsLabel:"Cross",endpointLabel:"POST /astrology/compatibility-score, /numerology/compatibility, /biorhythm/compatibility",docsSummary:"Score card with category breakdown",topic:"Astrology"},{pascal:"RoxyMoonPhase",tag:"roxy-moon-phase",slug:"moon-phase",heading:"Moon phase",description:"Moon phase card and calendar",docsLabel:"Western",endpointLabel:"GET /astrology/moon-phase/{current,upcoming,calendar/...}",docsSummary:"Moon phase card and calendar",topic:"Astrology"},{pascal:"RoxyVedicKundli",tag:"roxy-vedic-kundli",slug:"vedic-kundli",heading:"Vedic kundli",description:"South or North Indian Vedic kundli for /vedic-astrology/birth-chart",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/birth-chart",docsSummary:"South or North Indian kundli",topic:"Vedic"},{pascal:"RoxyPanchangTable",tag:"roxy-panchang-table",slug:"panchang-table",heading:"Panchang",description:"Panchang muhurta table with auspicious and inauspicious periods",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/panchang/{basic,detailed}",docsSummary:"15+ muhurtas in detailed mode",topic:"Vedic"},{pascal:"RoxyDashaTimeline",tag:"roxy-dasha-timeline",slug:"dasha-timeline",heading:"Vimshottari dasha",description:"Vimshottari dasha timeline with active mahadasha highlighted",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/dasha/{current,major,sub/...}",docsSummary:"Vimshottari mahadasha + antardasha + pratyantardasha",topic:"Vedic"},{pascal:"RoxyDoshaCard",tag:"roxy-dosha-card",slug:"dosha-card",heading:"Manglik dosha",description:"Manglik, Kaal Sarp, or Sade Sati presence card",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/dosha/{manglik,kalsarpa,sadhesati}",docsSummary:"Presence, severity, remedies, scoped effects",topic:"Vedic"},{pascal:"RoxyGunaMilan",tag:"roxy-guna-milan",slug:"guna-milan",heading:"Guna milan",description:"36-point Ashtakoota matrimonial compatibility breakdown",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/compatibility",docsSummary:"36-point Ashtakoota with eight sub-scores",topic:"Vedic"},{pascal:"RoxyKpPlanetsTable",tag:"roxy-kp-planets-table",slug:"kp-planets-table",heading:"KP planets",description:"KP planets table with sub-lord and sub-sub-lord columns",docsLabel:"Vedic (KP)",endpointLabel:"POST /vedic-astrology/kp/planets",docsSummary:"Sub-lord and sub-sub-lord columns",topic:"Vedic"},{pascal:"RoxyTransitsTable",tag:"roxy-transits-table",slug:"transits-table",heading:"Transits",description:"Live planet positions plus aspects to a natal chart",docsLabel:"Western",endpointLabel:"POST /astrology/transits",docsSummary:"Transit planet positions plus optional aspects to a natal chart",topic:"Astrology"},{pascal:"RoxyDivisionalChart",tag:"roxy-divisional-chart",slug:"divisional-chart",heading:"Divisional chart",description:"D2 to D60 varga chart wheel with Vargottama markers",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/divisional-chart",docsSummary:"Generic divisional varga wheel from D2 Hora to D60 Shashtiamsa",topic:"Vedic"},{pascal:"RoxyAshtakavargaGrid",tag:"roxy-ashtakavarga-grid",slug:"ashtakavarga-grid",heading:"Ashtakavarga",description:"Sarva and Bhinna ashtakavarga heatmap with bindu scores",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/ashtakavarga",docsSummary:"Sarva, Bhinna, and Shodhya Pinda views in a tabbed heatmap",topic:"Vedic"},{pascal:"RoxyShadbalaTable",tag:"roxy-shadbala-table",slug:"shadbala-table",heading:"Shadbala",description:"Six-fold planetary strength with adequacy badge per planet",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/shadbala",docsSummary:"Six-fold planetary strength bar plus rupas and adequacy badge",topic:"Vedic"},{pascal:"RoxyYogaList",tag:"roxy-yoga-list",slug:"yoga-list",heading:"Yoga catalog",description:"Yoga reference cards from the catalog with optional detail mode",docsLabel:"Vedic",endpointLabel:"GET /vedic-astrology/yoga, /yoga/{id}",docsSummary:"Filterable yoga cards from the 300 plus yoga catalog",topic:"Vedic"},{pascal:"RoxyChoghadiyaGrid",tag:"roxy-choghadiya-grid",slug:"choghadiya-grid",heading:"Choghadiya",description:"Day and night Choghadiya muhurta tiles for activity timing",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/panchang/choghadiya",docsSummary:"Day and night Choghadiya muhurta tiles colored by effect",topic:"Vedic"},{pascal:"RoxyNumerologyCard",tag:"roxy-numerology-card",slug:"numerology-card",heading:"Life path number",description:"Numerology card for life path, expression, personal year, or full chart",docsLabel:"Numerology",endpointLabel:"POST /numerology/{life-path,expression,personal-year,chart}",docsSummary:"Life path, expression, personal year, full chart",topic:"Numerology"},{pascal:"RoxyTarotCard",tag:"roxy-tarot-card",slug:"tarot-card",heading:"Daily tarot card",description:"Single tarot card with upright/reversed flip animation",docsLabel:"Tarot",endpointLabel:"GET /tarot/cards/{id}, POST /tarot/daily",docsSummary:"Single card with upright and reversed flip",topic:"Tarot"},{pascal:"RoxyTarotSpread",tag:"roxy-tarot-spread",slug:"tarot-spread",heading:"Three-card spread",description:"Tarot spread renderer for three-card, Celtic Cross, love, or yes/no",docsLabel:"Tarot",endpointLabel:"POST /tarot/spreads/{three-card,celtic-cross,love}, /tarot/yes-no, /tarot/draw",docsSummary:"Spreads with positions and reading",topic:"Tarot"},{pascal:"RoxyBiorhythmChart",tag:"roxy-biorhythm-chart",slug:"biorhythm-chart",heading:"Daily biorhythm",description:"Daily biorhythm bars or multi-day forecast cycle lines",docsLabel:"Biorhythm",endpointLabel:"POST /biorhythm/{daily,forecast,critical-days}",docsSummary:"Daily bars, forecast cycle lines, critical days",topic:"Biorhythm"},{pascal:"RoxyHexagram",tag:"roxy-hexagram",slug:"hexagram",heading:"I Ching hexagram",description:"I Ching hexagram with trigram glyphs, judgment, image, and changing lines",docsLabel:"I Ching",endpointLabel:"GET /iching/hexagrams/{number}, /iching/cast, POST /iching/daily, /iching/daily/cast",docsSummary:"Hexagram with trigrams, judgment, image, changing lines",topic:"I Ching"},{pascal:"RoxyEndpointForm",tag:"roxy-endpoint-form",slug:"endpoint-form",heading:"Schema-driven form",description:"Schema-driven form that emits roxy-submit with a validated payload",docsLabel:"Helper",endpointLabel:"Any endpoint via x-roxy-ui hints",docsSummary:"Schema-driven form, emits roxy-submit",topic:"Helpers",selfFetching:!0},{pascal:"RoxyLocationSearch",tag:"roxy-location-search",slug:"location-search",heading:"City search",description:"City search input with debounced /location/search calls",docsLabel:"Helper",endpointLabel:"GET /location/search",docsSummary:"Debounced city search input, emits roxy-location-select",topic:"Helpers",selfFetching:!0},{pascal:"RoxyData",tag:"roxy-data",slug:"data",heading:"Generic renderer",description:"Generic fallback renderer for any OpenAPI response shape",docsLabel:"Helper",endpointLabel:"Any response shape",docsSummary:"Generic fallback renderer for unknown shapes",topic:"Helpers",selfFetching:!0}];var Ht="0.2.0";var Ar=Be.map(i=>i.slug);return qt(Cr);})();
2511
4071
  /*! Bundled license information:
2512
4072
 
2513
4073
  @lit/reactive-element/css-tag.js: