@roxyapi/ui 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +30 -51
- package/README.md +69 -40
- package/dist/cdn/roxy-ui.js +1 -1
- package/dist/cdn/roxy-ui.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/version.ts +1 -1
package/AGENTS.md
CHANGED
|
@@ -120,16 +120,13 @@ const { data: chart } = await roxy.astrology.generateNatalChart({
|
|
|
120
120
|
|
|
121
121
|
Every chart endpoint accepts `timezone` as either a decimal-hour offset (`5.5` for IST, `-5` for EST) or an IANA name (`'Asia/Kolkata'`, `'America/New_York'`). The decimal form is what `/location/search` returns; the IANA form is correct over DST boundaries. Pick one and stay consistent in a single integration. Mixing them does not break the API but makes the bug surface area larger.
|
|
122
122
|
|
|
123
|
-
### 4.
|
|
123
|
+
### 4. API key in the browser
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
Keys are server side only. Call `createRoxy(process.env.ROXY_API_KEY!)` on your server (Node, Bun, Hono, Next.js route handlers, Workers, Edge functions), then send the response, not the key, to the component. Never ship the key in a client bundle. Browser-safe keys for direct client-side embedding are on the roadmap, not yet available.
|
|
126
126
|
|
|
127
127
|
```ts
|
|
128
|
-
// Server
|
|
128
|
+
// Server side only
|
|
129
129
|
const roxy = createRoxy(process.env.ROXY_API_KEY!);
|
|
130
|
-
|
|
131
|
-
// Browser (widgets auto-mount): publishable key
|
|
132
|
-
<div data-roxy-widget="natal-chart" data-publishable-key="pk_live_xxx" ...></div>
|
|
133
130
|
```
|
|
134
131
|
|
|
135
132
|
### 5. Missing `'use client'` in Next.js App Router
|
|
@@ -194,30 +191,30 @@ import type { NatalChartResponse } from '@roxyapi/sdk';
|
|
|
194
191
|
|
|
195
192
|
### Pattern 1: vanilla HTML, no build step
|
|
196
193
|
|
|
194
|
+
Fetch on your server with the secret key, then inline the response into the component as a child `<script type="application/json" class="roxy-data">`. The component reads it on load. No key in the browser.
|
|
195
|
+
|
|
197
196
|
```html
|
|
198
197
|
<script
|
|
199
198
|
src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js"
|
|
200
199
|
crossorigin="anonymous"
|
|
201
200
|
></script>
|
|
202
201
|
|
|
203
|
-
<roxy-natal-chart
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const { data } = await roxy.astrology.generateNatalChart({
|
|
209
|
-
body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
|
|
210
|
-
});
|
|
211
|
-
document.getElementById('chart').data = data;
|
|
212
|
-
</script>
|
|
202
|
+
<roxy-natal-chart>
|
|
203
|
+
<script type="application/json" class="roxy-data">
|
|
204
|
+
{ "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
|
|
205
|
+
</script>
|
|
206
|
+
</roxy-natal-chart>
|
|
213
207
|
```
|
|
214
208
|
|
|
215
|
-
|
|
209
|
+
Setting the JavaScript `data` property always wins over the inlined JSON, so the same element also drives dynamic pages.
|
|
210
|
+
|
|
211
|
+
### Pattern 2: React, interactive
|
|
212
|
+
|
|
213
|
+
`<RoxyLocationSearch>` runs in the browser. On select, call your own route, which holds the secret key, and set the returned data on the chart. The key never reaches the client.
|
|
216
214
|
|
|
217
215
|
```tsx
|
|
218
216
|
'use client';
|
|
219
217
|
|
|
220
|
-
import { createRoxy } from '@roxyapi/sdk';
|
|
221
218
|
import {
|
|
222
219
|
RoxyNatalChart,
|
|
223
220
|
RoxyLocationSearch,
|
|
@@ -225,18 +222,18 @@ import {
|
|
|
225
222
|
} from '@roxyapi/ui-react';
|
|
226
223
|
import { useState } from 'react';
|
|
227
224
|
|
|
228
|
-
const roxy = createRoxy(process.env.NEXT_PUBLIC_ROXY_API_KEY!);
|
|
229
|
-
|
|
230
225
|
export function BirthChartView() {
|
|
231
226
|
const [chart, setChart] = useState<RoxyNatalChartProps['data']>(undefined);
|
|
232
227
|
|
|
233
228
|
const onLocationSelect = async (e: CustomEvent<{ latitude?: number; longitude?: number; timezone?: number | string }>) => {
|
|
234
229
|
const { latitude, longitude, timezone } = e.detail;
|
|
235
230
|
if (latitude == null || longitude == null) return;
|
|
236
|
-
|
|
237
|
-
|
|
231
|
+
// Your route calls roxy.astrology.generateNatalChart with the secret key.
|
|
232
|
+
const res = await fetch('/api/natal-chart', {
|
|
233
|
+
method: 'POST',
|
|
234
|
+
body: JSON.stringify({ date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone }),
|
|
238
235
|
});
|
|
239
|
-
setChart(
|
|
236
|
+
setChart(await res.json());
|
|
240
237
|
};
|
|
241
238
|
|
|
242
239
|
return (
|
|
@@ -248,9 +245,11 @@ export function BirthChartView() {
|
|
|
248
245
|
}
|
|
249
246
|
```
|
|
250
247
|
|
|
248
|
+
For a static chart with no picker, fetch in a Server Component and pass `data` to a client component (Pattern 6).
|
|
249
|
+
|
|
251
250
|
### Pattern 3: schema-driven form
|
|
252
251
|
|
|
253
|
-
`<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint.
|
|
252
|
+
`<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint. On `roxy-submit`, POST the validated values to your own route, which calls the SDK with the secret key, then set the returned data on the target component.
|
|
254
253
|
|
|
255
254
|
```html
|
|
256
255
|
<roxy-endpoint-form
|
|
@@ -258,41 +257,21 @@ export function BirthChartView() {
|
|
|
258
257
|
method="POST"
|
|
259
258
|
submit-label="Generate kundli"
|
|
260
259
|
></roxy-endpoint-form>
|
|
260
|
+
<roxy-vedic-kundli chart-style="south"></roxy-vedic-kundli>
|
|
261
261
|
|
|
262
262
|
<script type="module">
|
|
263
|
-
import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
|
|
264
|
-
const roxy = createRoxy('pk_live_xxx');
|
|
265
263
|
const form = document.querySelector('roxy-endpoint-form');
|
|
266
264
|
form.addEventListener('roxy-submit', async (e) => {
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
document.querySelector('roxy-vedic-kundli').data =
|
|
265
|
+
// Your route calls roxy.vedicAstrology.generateBirthChart with the secret key.
|
|
266
|
+
const res = await fetch('/api/kundli', { method: 'POST', body: JSON.stringify(e.detail.values) });
|
|
267
|
+
document.querySelector('roxy-vedic-kundli').data = await res.json();
|
|
270
268
|
});
|
|
271
269
|
</script>
|
|
272
270
|
```
|
|
273
271
|
|
|
274
|
-
### Pattern 4: widgets auto-mount (
|
|
275
|
-
|
|
276
|
-
Use a publishable key (`pk_live_*` or `pk_test_*`) for client-side embeds. Get one at <https://roxyapi.com/account>. Publishable keys are origin-restricted at the API gateway. Register the customer domain (e.g. `https://customer.com`) when creating the key, and the gateway will reject requests from any other origin. Never use a secret key in client-side code (secret keys are unprefixed and live server-side only).
|
|
277
|
-
|
|
278
|
-
```html
|
|
279
|
-
<script
|
|
280
|
-
src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js"
|
|
281
|
-
defer
|
|
282
|
-
></script>
|
|
283
|
-
|
|
284
|
-
<div
|
|
285
|
-
data-roxy-widget="natal-chart"
|
|
286
|
-
data-publishable-key="pk_live_xxx"
|
|
287
|
-
data-date="1990-01-15"
|
|
288
|
-
data-time="14:30:00"
|
|
289
|
-
data-latitude="19.07"
|
|
290
|
-
data-longitude="72.88"
|
|
291
|
-
data-timezone="5.5"
|
|
292
|
-
></div>
|
|
293
|
-
```
|
|
272
|
+
### Pattern 4: widgets auto-mount (coming soon)
|
|
294
273
|
|
|
295
|
-
|
|
274
|
+
A zero-wiring embed that reads `data-*` attributes and renders the matching component is on the roadmap. It needs browser-safe keys, which are not yet available. Until then, use Pattern 1 (inline JSON) for no-build pages.
|
|
296
275
|
|
|
297
276
|
### Pattern 5: MCP tool-call response
|
|
298
277
|
|
|
@@ -396,7 +375,7 @@ Every visible aspect of the chart is driven by `--roxy-*` CSS custom properties
|
|
|
396
375
|
|
|
397
376
|
## Domain ordering
|
|
398
377
|
|
|
399
|
-
When listing domains in user-visible copy, use the canonical order: Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, crystals, dreams, angel numbers. Location is utility, not a selling domain.
|
|
378
|
+
When listing domains in user-visible copy, use the canonical order: Western astrology, Vedic astrology, numerology, tarot, human design, forecast, biorhythm, I Ching, crystals, dreams, angel numbers. Location is utility, not a selling domain.
|
|
400
379
|
|
|
401
380
|
## What not to ship
|
|
402
381
|
|
package/README.md
CHANGED
|
@@ -221,42 +221,24 @@ Tables, cards, forms, and helper components in the [live demo](https://roxyapi.g
|
|
|
221
221
|
|
|
222
222
|
## Start with one component
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
Fetch with the typed SDK, pass `data` to the component. No glue code.
|
|
225
225
|
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
crossorigin="anonymous"
|
|
230
|
-
defer
|
|
231
|
-
></script>
|
|
232
|
-
<roxy-natal-chart id="chart"></roxy-natal-chart>
|
|
233
|
-
<script type="module">
|
|
234
|
-
import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
|
|
235
|
-
const roxy = createRoxy('YOUR_API_KEY');
|
|
236
|
-
const { data } = await roxy.astrology.generateNatalChart({
|
|
237
|
-
body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
|
|
238
|
-
});
|
|
239
|
-
document.getElementById('chart').data = data;
|
|
240
|
-
</script>
|
|
241
|
-
```
|
|
226
|
+
```tsx
|
|
227
|
+
import { createRoxy } from '@roxyapi/sdk';
|
|
228
|
+
import { RoxyHoroscopeCard } from '@roxyapi/ui-react';
|
|
242
229
|
|
|
243
|
-
|
|
230
|
+
const roxy = createRoxy(process.env.ROXY_API_KEY!);
|
|
244
231
|
|
|
245
|
-
|
|
232
|
+
const { data } = await roxy.astrology.getDailyHoroscope({ path: { sign: 'aries' } });
|
|
246
233
|
|
|
247
|
-
|
|
248
|
-
<roxy-vedic-kundli id="kundli" chart-style="south"></roxy-vedic-kundli>
|
|
249
|
-
<script type="module">
|
|
250
|
-
import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
|
|
251
|
-
const roxy = createRoxy('YOUR_API_KEY');
|
|
252
|
-
const { data } = await roxy.vedicAstrology.generateBirthChart({
|
|
253
|
-
body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
|
|
254
|
-
});
|
|
255
|
-
document.getElementById('kundli').data = data;
|
|
256
|
-
</script>
|
|
234
|
+
return <RoxyHoroscopeCard data={data} />;
|
|
257
235
|
```
|
|
258
236
|
|
|
259
|
-
|
|
237
|
+
Then expand into natal charts, kundli, dasha, tarot, and every other domain. The SDK returns `data`, the component renders it; the same pairing holds for all 32 components.
|
|
238
|
+
|
|
239
|
+
> **Pass `data`, not the envelope.** The SDK returns `{ data, error, request, response }`. Pass `data`, or the component renders `[object Object]`. This is the most common integration bug.
|
|
240
|
+
|
|
241
|
+
The key stays on your server. Vanilla HTML or a server-rendered page fetches the same way, then [inlines the JSON into the component](#server-rendered-no-javascript-wiring): no build step, no key in the browser. Try every component in the [live demo](https://roxyapi.github.io/ui/), each with Preview, Code, and shadcn tabs and a live color customizer.
|
|
260
242
|
|
|
261
243
|
## Install
|
|
262
244
|
|
|
@@ -312,7 +294,12 @@ Always call `/location/search` first. Every chart endpoint expects latitude, lon
|
|
|
312
294
|
|
|
313
295
|
Server-rendered and cached pages (WordPress, JSX SSR, static HTML) cannot always run JavaScript to set the `data` property per element. Render the response into a child `<script type="application/json" class="roxy-data">` on the server instead. The component reads it on load. No per-element script, no API key in the browser.
|
|
314
296
|
|
|
297
|
+
Load the bundle once anywhere on the page. It registers every `roxy-*` element, so every component on the page renders from that single tag.
|
|
298
|
+
|
|
315
299
|
```html
|
|
300
|
+
<!-- Once per page: defines every roxy-* element -->
|
|
301
|
+
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js" crossorigin="anonymous" defer></script>
|
|
302
|
+
|
|
316
303
|
<roxy-natal-chart>
|
|
317
304
|
<script type="application/json" class="roxy-data">
|
|
318
305
|
{ "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
|
|
@@ -464,7 +451,48 @@ const { data: cc } = await roxy.tarot.castCelticCross({
|
|
|
464
451
|
<RoxyTarotSpread data={cc} />
|
|
465
452
|
```
|
|
466
453
|
|
|
467
|
-
### 5.
|
|
454
|
+
### 5. Human Design (bodygraph)
|
|
455
|
+
|
|
456
|
+
The breakout 2026 self-knowledge category, computed from the same ephemeris as Western astrology plus the I Ching gate wheel and chakra-style centers. Self-discovery apps, dating and compatibility products, and AI coaching bots ship the full bodygraph first. No coordinates needed; Human Design uses the birth instant, not the observer location.
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
import { RoxyBodygraph } from '@roxyapi/ui-react';
|
|
460
|
+
|
|
461
|
+
// Full bodygraph. The head term every Human Design app leads with ("human design chart").
|
|
462
|
+
// Type, strategy, authority, profile, the nine centers, channels, and every gate
|
|
463
|
+
// activation in one call. Pass the birth instant only, no latitude or longitude.
|
|
464
|
+
const { data: bodygraph } = await roxy.humanDesign.generateBodygraph({
|
|
465
|
+
body: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 },
|
|
466
|
+
});
|
|
467
|
+
<RoxyBodygraph data={bodygraph} />
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### 6. Forecast (transits, cross-domain timeline)
|
|
471
|
+
|
|
472
|
+
The first cross-domain, stateless forecast in the catalog: one call merges Western transits, Vedic Vimshottari dasha boundaries, and biorhythm critical days into a single significance-scored, time-ordered timeline. Forecast feeds, transit alerts, and timing tools are the buyers. Acquire on the high-volume `astrology transits` search, convert on the cross-domain timeline no competitor ships. No coordinates needed.
|
|
473
|
+
|
|
474
|
+
```tsx
|
|
475
|
+
import { RoxyForecastTimeline } from '@roxyapi/ui-react';
|
|
476
|
+
|
|
477
|
+
// Transit forecast. The demand leader. Western transit-to-natal aspects, sign
|
|
478
|
+
// ingresses, and retrograde stations over the window.
|
|
479
|
+
const { data: transits } = await roxy.forecast.forecastTransits({
|
|
480
|
+
body: { birthData: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 } },
|
|
481
|
+
});
|
|
482
|
+
<RoxyForecastTimeline data={transits} />
|
|
483
|
+
|
|
484
|
+
// Cross-domain timeline. The same window merged with Vedic dasha boundaries and
|
|
485
|
+
// biorhythm critical days into one significance-scored timeline.
|
|
486
|
+
const { data: timeline } = await roxy.forecast.generateTimeline({
|
|
487
|
+
body: {
|
|
488
|
+
birthData: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 },
|
|
489
|
+
domains: ['western', 'vedic', 'biorhythm'],
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
<RoxyForecastTimeline data={timeline} />
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 7. Biorhythm (daily, forecast)
|
|
468
496
|
|
|
469
497
|
Zero competition domain. Steady search volume with the top Google result being a static calculator page. Pure land-grab for wellness, productivity, sports, and couples apps.
|
|
470
498
|
|
|
@@ -485,7 +513,7 @@ const { data: forecast } = await roxy.biorhythm.getForecast({
|
|
|
485
513
|
<RoxyBiorhythmChart data={forecast} mode="forecast" />
|
|
486
514
|
```
|
|
487
515
|
|
|
488
|
-
###
|
|
516
|
+
### 8. I Ching (cast a reading, hexagram lookup)
|
|
489
517
|
|
|
490
518
|
Meditation apps, decision-making tools, and wisdom chatbots. `i ching API` and `hexagram API` are the keywords.
|
|
491
519
|
|
|
@@ -505,12 +533,13 @@ const { data: random } = await roxy.iching.getRandomHexagram();
|
|
|
505
533
|
|
|
506
534
|
## API keys
|
|
507
535
|
|
|
508
|
-
Get
|
|
536
|
+
Get a key at <https://roxyapi.com/account>.
|
|
537
|
+
|
|
538
|
+
Today every key is a **secret key**: use it server side only (Node, Bun, Hono, Next.js route handlers, Workers). Never commit it, never ship it in a client bundle. Fetch on your server and send the rendered response, not the key, to the browser. The [Start with one component](#start-with-one-component) section and the [framework recipes](#most-used-components-per-domain) show the pattern.
|
|
509
539
|
|
|
510
|
-
|
|
511
|
-
- **Publishable key** (`pk_live_*` / `pk_test_*`). Safe in browsers, locked to the origins you register on the key. Use with the widgets auto-mount script for WordPress, Shopify, static HTML, embed scenarios. The API gateway rejects requests from any origin not on the allowlist.
|
|
540
|
+
Set `ROXY_API_KEY` to your secret key in your server env for every SDK example on this page.
|
|
512
541
|
|
|
513
|
-
|
|
542
|
+
Browser-safe keys for direct client-side embedding are on the roadmap, not yet available. Until they ship, keep the fetch on your server.
|
|
514
543
|
|
|
515
544
|
## Distribution
|
|
516
545
|
|
|
@@ -520,7 +549,7 @@ For the SDK examples on this page, set `ROXY_API_KEY` to a secret key in your se
|
|
|
520
549
|
| npm `@roxyapi/ui-react` | `npmjs.com/package/@roxyapi/ui-react` |
|
|
521
550
|
| jsDelivr CDN (full bundle) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js` |
|
|
522
551
|
| jsDelivr CDN (per component) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/components/{name}.js` |
|
|
523
|
-
| Widgets auto-mount | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js` |
|
|
552
|
+
| Widgets auto-mount (with browser keys, coming soon) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js` |
|
|
524
553
|
| shadcn registry | `npx shadcn@latest add https://cdn.jsdelivr.net/gh/RoxyAPI/ui@latest/registry/{name}.json` |
|
|
525
554
|
|
|
526
555
|
## Components
|
|
@@ -770,7 +799,7 @@ Components ship in Shadow DOM for style isolation; Tailwind utilities are scoped
|
|
|
770
799
|
<details>
|
|
771
800
|
<summary><strong>What is the security model for API keys?</strong></summary>
|
|
772
801
|
|
|
773
|
-
|
|
802
|
+
Today keys are secret keys: they live server side only and grant full access, so never ship one in a client bundle. Fetch on your server and pass the rendered response, not the key, to the browser. Browser-safe keys with an origin allowlist for direct client-side embedding are on the roadmap and not yet available.
|
|
774
803
|
|
|
775
804
|
For CSP, allow `script-src https://cdn.jsdelivr.net` if loading the bundle from the CDN. Subresource Integrity hashes are available via the jsDelivr SRI API for any pinned version.
|
|
776
805
|
</details>
|
|
@@ -781,11 +810,11 @@ For CSP, allow `script-src https://cdn.jsdelivr.net` if loading the bundle from
|
|
|
781
810
|
Semver. Pre-1.0, minor bumps may include breaking changes (we will note them in the changelog). Patch bumps are always backwards-compatible. Pin a concrete version in production code:
|
|
782
811
|
|
|
783
812
|
```bash
|
|
784
|
-
npm install @roxyapi/ui@0.
|
|
813
|
+
npm install @roxyapi/ui@0.8.x
|
|
785
814
|
```
|
|
786
815
|
|
|
787
816
|
```html
|
|
788
|
-
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@0.
|
|
817
|
+
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@0.8.0/dist/cdn/roxy-ui.js"></script>
|
|
789
818
|
```
|
|
790
819
|
|
|
791
820
|
The `@latest` URL on this page is for paste-friendly marketing; production code should pin.
|
package/dist/cdn/roxy-ui.js
CHANGED
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
</g>`})}renderAscendants(e){let t=[],r=(o,i)=>{if(!o)return;let d=_.findIndex(S=>S.toLowerCase()===o.sign.toLowerCase());if(d===-1)return;let c=d*30+o.degree,m=this.toAngle(c),g=i===1?Jt+14:qe+14,h=T(M,M,g,m),y=T(M,M,Wt+14,m);t.push(w`<g>
|
|
91
91
|
<line class="asc-tick" x1=${h.x} y1=${h.y} x2=${y.x} y2=${y.y} />
|
|
92
92
|
<text class="asc-label" x=${y.x} y=${y.y} text-anchor="middle" dominant-baseline="central">Asc${i}</text>
|
|
93
|
-
</g>`)};return r(e.person1?.ascendant,1),r(e.person2?.ascendant,2),t}renderInterAspectLines(e,t,r){let o=(i,d)=>{let c=A(d);for(let m of i)if(A(m.name)===c&&typeof m.longitude=="number")return m.longitude};return r.map(i=>{let d=o(e,i.planet1),c=o(t,i.planet2);if(d===void 0||c===void 0)return l;let m=T(M,M,Jt-12,this.toAngle(d)),g=T(M,M,qe+8,this.toAngle(c)),h=Ge(i),y=_e[h]??"aspect-other",S=C(i.orb,1);return w`<line class=${`aspect ${y}`} x1=${m.x} y1=${m.y} x2=${g.x} y2=${g.y}><title>${i.planet1} ${h} ${i.planet2}${S?` (orb ${S}\xB0)`:""}</title></line>`})}renderAspects(e){return s`<table><thead><tr><th>Planet 1</th><th>Planet 2</th><th>Aspect</th><th>Orb</th><th>Strength</th></tr></thead><tbody>${e.slice(0,12).map(t=>s`<tr><td>${t.planet1}</td><td>${t.planet2}</td><td>${Ge(t)||""}</td><td class="orb">${C(t.orb,1)}</td><td>${Qa(t.strength)}</td></tr>`)}</tbody></table>`}};Ae.styles=[v,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:center;gap:var(--roxy-space-md,1rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.score{font-variant-numeric:tabular-nums;font-weight:var(--roxy-weight-bold,600);color:var(--roxy-accent-ink,#b45309);font-size:var(--roxy-text-xl,1.5rem)}svg{aspect-ratio:1;width:100%;max-width:560px;height:auto;margin:0 auto;display:block}.wheel-line{fill:none;stroke:var(--roxy-border,#e4e4e7)}.sign{fill:var(--roxy-secondary,#475569);font-size:14px}.p1{fill:var(--roxy-accent,#f59e0b);font-size:13px;font-weight:600}.p2{fill:var(--roxy-info,#0284c7);font-size:13px;font-weight:600}.person-tag{opacity:.85;font-size:7px;font-weight:700}.planet-deg{fill:var(--roxy-muted,#71717a);font-size:7px;font-family:var(--roxy-font-sans)}.planet-deg .retro{fill:var(--roxy-danger,#dc2626)}.asc-tick{stroke:var(--roxy-accent-ink,#b45309);stroke-width:1px;opacity:.75}.asc-label{fill:var(--roxy-accent-ink,#b45309);font-size:9px;font-weight:700;font-family:var(--roxy-font-sans);letter-spacing:.04em}.aspect{stroke-width:.8px;fill:none;opacity:.5}.aspect-trine,.aspect-sextile{stroke:var(--roxy-success,#16a34a)}.aspect-square,.aspect-opposition{stroke:var(--roxy-danger,#dc2626)}.aspect-conjunction{stroke:var(--roxy-accent-ink,#b45309)}.aspect-other{stroke:var(--roxy-muted,#71717a);opacity:.35}.legend-row{gap:var(--roxy-space-md,1rem);font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);margin-top:calc(var(--roxy-space-xs,.25rem) * -1);flex-wrap:wrap;display:flex}.legend-row .swatch{vertical-align:middle;border-radius:50%;width:8px;height:8px;margin-right:4px;display:inline-block}.summary{color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-base,1rem);margin:0}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem)}th,td{padding:var(--roxy-space-sm,.5rem);border-bottom:1px solid var(--roxy-border,#e4e4e7);text-align:left}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.06em}td.orb{font-variant-numeric:tabular-nums;color:var(--roxy-muted,#71717a)}.lists{gap:var(--roxy-space-md,1rem);grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));display:grid}.lists h3{margin:0 0 var(--roxy-space-xs,.25rem) 0;font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em}.lists ul{padding-left:var(--roxy-space-md,1rem);font-size:var(--roxy-text-sm,.875rem);margin:0}.missing-planets{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 8%, transparent);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-md,1rem);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-sm,.875rem);line-height:1.5}.missing-planets code{font-family:var(--roxy-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);background:color-mix(in srgb, var(--roxy-fg,#0a0a0a) 6%, transparent);border-radius:4px;padding:0 4px;font-size:.95em}`],p([u({attribute:!1})],Ae.prototype,"data",2),Ae=p([b("roxy-synastry-chart")],Ae);function Qa(n){return typeof n=="number"?Math.round(n).toString():""}var de=class extends f{constructor(){super();this.data=null;this.flipped=!1;this.toggleFlip=()=>{this.flipped=!this.flipped};new $(this)}render(){let e=this.data;return e?"card"in e?this.renderDailyCard(e):this.renderFullCard(e):s`<div class="roxy-empty" role="status">No tarot data</div>`}renderDailyCard(e){let t=e.card,r=this.flipped!==!!t.reversed,o=t.keywords??[];return s`<article class="card" aria-label="${t.name??"Tarot card"}"><div class="image-wrap">${t.imageUrl?s`<img class="${`image ${r?"reversed":""}`}" src="${t.imageUrl}" alt="${t.name??"Tarot card"}" tabindex="0" @click="${this.toggleFlip}" @keydown="${i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),this.toggleFlip())}}">`:s`<div class="${`image ${r?"reversed":""}`}" style="aspect-ratio:0.6;display:flex;align-items:center;justify-content:center;color:var(--roxy-muted)">${t.name??"?"}</div>`}</div><div><div class="meta">${t.arcana?s`${t.arcana} arcana`:l} ${r?s`· reversed`:l}</div><h2 class="title">${t.name??"Tarot card"}</h2>${e.dailyMessage?s`<p class="message">${e.dailyMessage}</p>`:l} ${t.meaning?s`<p>${t.meaning}</p>`:l} ${o.length>0?s`<div class="chips">${o.map(i=>s`<span>${i}</span>`)}</div>`:l} <button class="flip" type="button" @click="${this.toggleFlip}" aria-pressed="${this.flipped?"true":"false"}">Flip card</button></div></article>`}renderFullCard(e){let t=this.flipped,r=t?e.reversed:e.upright,o=t?e.keywords?.reversed??[]:e.keywords?.upright??[];return s`<article class="card" aria-label="${e.name??"Tarot card"}"><div class="image-wrap">${e.imageUrl?s`<img class="${`image ${t?"reversed":""}`}" src="${e.imageUrl}" alt="${e.name??"Tarot card"}" tabindex="0" @click="${this.toggleFlip}" @keydown="${i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),this.toggleFlip())}}">`:s`<div class="${`image ${t?"reversed":""}`}" style="aspect-ratio:0.6;display:flex;align-items:center;justify-content:center;color:var(--roxy-muted)">${e.name??"?"}</div>`}</div><div><div class="meta">${e.arcana?s`${e.arcana} arcana`:l} ${e.number!==void 0&&e.number!==null?s`· ${e.number}`:l} ${t?s`· reversed`:l}</div><h2 class="title">${e.name??"Tarot card"}</h2>${r?.description?s`<p>${r.description}</p>`:l} ${o.length>0?s`<div class="chips">${o.map(i=>s`<span>${i}</span>`)}</div>`:l} <button class="flip" type="button" @click="${this.toggleFlip}" aria-pressed="${this.flipped?"true":"false"}">Flip card</button></div></article>`}};de.styles=[v,x`.card{background:var(--roxy-bg,#fff);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-lg,1.5rem);box-shadow:var(--roxy-shadow-sm);gap:var(--roxy-space-lg,1.5rem);grid-template-columns:minmax(0,9rem) 1fr;align-items:start;display:grid}@container (width<=480px){.card{grid-template-columns:1fr}}.image-wrap{perspective:800px}.image{border-radius:var(--roxy-radius-md,8px);background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent);width:100%;height:auto;transition:transform var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1));cursor:pointer;display:block}.image.reversed{transform:rotate(180deg)}.image:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}.title{font-size:var(--roxy-text-xl,1.5rem);font-weight:var(--roxy-weight-bold,600);letter-spacing:var(--roxy-tracking-tight);margin:0}.meta{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--roxy-space-sm,.5rem)}.message{color:var(--roxy-fg,#0a0a0a);margin:var(--roxy-space-sm,.5rem) 0 var(--roxy-space-md,1rem)}.chips{gap:var(--roxy-space-xs,.25rem);margin-top:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.chips span{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 14%, transparent);border-radius:var(--roxy-radius-full,9999px);font-size:var(--roxy-text-xs,.75rem);padding:2px 8px}.flip{margin-top:var(--roxy-space-sm,.5rem);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);font-family:inherit;font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-secondary,#475569);cursor:pointer;transition:transform var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1));background:0 0;padding:4px 12px}.flip:hover{transform:scale(1.02)}`],p([u({attribute:!1})],de.prototype,"data",2),p([N()],de.prototype,"flipped",2),de=p([b("roxy-tarot-card")],de);var ce=class extends f{constructor(){super();this.data=null;this.spread="three-card";new $(this)}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No tarot spread</div>`;let t="answer"in e,r="cards"in e&&!("spread"in e),o=r?[]:"positions"in e?e.positions??[]:[],i=r&&"cards"in e?e.cards:[],d=t?e.answer:void 0,c=t?e.strength:void 0,m="spread"in e?e.spread:this.spread.replace(/-/g," "),g="question"in e?e.question:void 0,h="summary"in e?e.summary:void 0,y=t?e.interpretation:void 0,S=d?d.toLowerCase().replace(/[^a-z]/g,""):"";return s`<article class="wrap" aria-label="Tarot spread"><header class="head"><h2 class="title">${m}</h2>${g?s`<span class="question">"${g}"</span>`:l}</header>${t?s`<div><span class="${`answer ${S}`}">${d}</span> ${c?s`<small>· ${c}</small>`:l}</div>`:l} ${o.length>0?s`<div class="grid">${o.map(k=>s`<div class="card"><p class="label">${k.name??""}</p><div class="image">${k.card?.imageUrl?s`<img src="${k.card.imageUrl}" alt="${k.card.name??"tarot card"}" class="${k.card.reversed?"reversed":""}">`:s`${k.card?.name??"?"}`}</div><p class="name">${k.card?.name??""} ${k.card?.reversed?s`<small>(reversed)</small>`:l}</p>${k.interpretation?s`<p class="interp">${k.interpretation}</p>`:l}</div>`)}</div>`:l} ${i.length>0?s`<div class="grid">${i.map(k=>s`<div class="card"><div class="image">${k.imageUrl?s`<img src="${k.imageUrl}" alt="${k.name??"tarot card"}" class="${k.reversed?"reversed":""}">`:s`${k.name??"?"}`}</div><p class="name">${k.name??""} ${k.reversed?s`<small>(reversed)</small>`:l}</p>${k.meaning?s`<p class="interp">${k.meaning}</p>`:l}</div>`)}</div>`:l} ${h?s`<p class="reading">${h}</p>`:l} ${y?s`<p class="reading">${y}</p>`:l}</article>`}};ce.styles=[v,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;gap:var(--roxy-space-md,1rem);flex-wrap:wrap;align-items:baseline;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);text-transform:capitalize;margin:0}.question{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);font-style:italic}.answer{border-radius:var(--roxy-radius-full,9999px);font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-base,1rem);text-transform:uppercase;letter-spacing:.06em;padding:4px 14px;display:inline-block}.answer.yes{background:color-mix(in srgb, var(--roxy-success,#16a34a) 16%, transparent);color:var(--roxy-success-fg,#166534)}.answer.no{background:color-mix(in srgb, var(--roxy-danger,#dc2626) 16%, transparent);color:var(--roxy-danger-fg,#991b1b)}.answer.maybe{background:color-mix(in srgb, var(--roxy-warning,#ea580c) 16%, transparent);color:var(--roxy-warning-fg,#9a3412)}.grid{gap:var(--roxy-space-md,1rem);grid-template-columns:repeat(auto-fit,minmax(8rem,1fr));display:grid}.card{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-sm,.5rem);background:var(--roxy-bg,#fff);gap:var(--roxy-space-xs,.25rem);display:grid}.label{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em;margin:0}.image{aspect-ratio:.6;background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent);border-radius:var(--roxy-radius-sm,4px);width:100%;font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);justify-content:center;align-items:center;display:flex;overflow:hidden}.image img{object-fit:cover;width:100%;height:100%;transition:transform var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1))}.image img.reversed{transform:rotate(180deg)}.name{font-size:var(--roxy-text-sm,.875rem);font-weight:var(--roxy-weight-bold,600);margin:0}.interp{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-secondary,#475569);margin:0}.reading{color:var(--roxy-fg,#0a0a0a);margin:0}`],p([u({attribute:!1})],ce.prototype,"data",2),p([u({type:String,reflect:!0})],ce.prototype,"spread",2),ce=p([b("roxy-tarot-spread")],ce);var pe=class extends f{constructor(){super();this.data=null;this.tab="positions";new $(this)}render(){if(!this.data?.transitPlanets?.length)return s`<div class="roxy-empty" role="status">No transits data</div>`;let{transitDate:e,transitTime:t,transitPlanets:r,transitAspects:o,summary:i}=this.data,d=[xe(e),K(t)].filter(Boolean).join(" "),c=o?.length??0,m=this.tab;return s`<div class="wrap" aria-label="Transits"><div class="head"><h2 class="title">Transits</h2>${d?s`<p class="subtitle">${d}</p>`:l}</div>${c>0?s`${Ie({items:[{id:"positions",label:"Positions"},{id:"aspects",label:`Aspects (${c})`}],active:m,onSelect:g=>{this.tab=g},label:"Transit views",idPrefix:"transits",controls:!0})}<div id="transits-panel-${m}" role="tabpanel" aria-labelledby="transits-tab-${m}">${m==="positions"?s`<div class="overflow-scroll">${this.renderPlanetsTable(r)}</div>`:s`${i?this.renderSummaryPills(i):l}<div class="overflow-scroll">${this.renderAspectsList(o??[])}</div>`}</div>`:s`<div class="overflow-scroll">${this.renderPlanetsTable(r)}</div>`}</div>`}renderSummaryPills(e){return s`<div class="summary-pills" role="region" aria-label="Aspect summary"><span class="pill pill--muted">Total: ${e.totalAspects} </span><span class="pill pill--success">Harmonious: ${e.harmonious} </span><span class="pill pill--danger">Challenging: ${e.challenging} </span><span class="pill pill--muted">Neutral: ${e.neutral}</span></div>`}renderPlanetsTable(e){return s`<table class="planets-table"><thead><tr><th scope="col">Planet</th><th scope="col">Sign</th><th scope="col">Degree</th><th scope="col">Speed</th></tr></thead><tbody>${e.map(t=>{let r=L[A(t.name)]??"",o=G[A(t.sign)]??"",i=t.speed>=0?"\u2191":"\u2193";return s`<tr><td><div class="planet-cell"><span class="glyph" aria-hidden="true">${r}</span> ${t.name} ${t.isRetrograde?s`<span class="retro-badge" aria-label="retrograde">R</span>`:l}</div></td><td><div class="planet-cell"><span class="glyph" aria-hidden="true">${o}</span> ${t.sign}</div></td><td class="num">${C(t.degree,2)}</td><td class="speed"><span class="speed-arrow" aria-hidden="true">${i}</span> ${C(Math.abs(t.speed),4)}</td></tr>`})}</tbody></table>`}renderAspectsList(e){return s`<div role="list" aria-label="Transit aspects">${e.map((t,r)=>{let o=L[A(t.transitPlanet)]??"",i=L[A(t.natalPlanet)]??"",d=(t.nature??"neutral").toLowerCase(),c=t.interpretation,m=(t.type??"").toLowerCase(),g=t.isApplying?"Applying":"Separating";return s`<details class="aspect-card" role="listitem" name="transit-aspects" ?open="${r===0}"><summary><span aria-hidden="true">${o}</span> ${t.transitPlanet} <span class="nature-badge ${d}">${m}</span> <span aria-hidden="true">${i}</span> ${t.natalPlanet} <span class="meta">${g} · orb ${C(t.orb,2)}° · strength ${C(t.strength,1)} </span>${Y()}</summary><div class="interp-body">${c?.summary?s`<p>${c.summary}</p>`:l} ${c?.impact?s`<p><strong>Impact:</strong> ${c.impact}</p>`:l} ${c?.timing?s`<p><strong>Timing:</strong> ${c.timing}</p>`:l} ${c?.guidance?s`<p><strong>Guidance:</strong> ${c.guidance}</p>`:l} ${c?.keywords?.length?s`<div class="interp-keywords">${c.keywords.map(h=>s`<span class="kw">${h}</span>`)}</div>`:l}</div></details>`})}</div>`}};pe.styles=[v,fe,je,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:baseline;gap:var(--roxy-space-md,1rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.subtitle{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);margin:0}.summary-pills{gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.pill{padding:2px var(--roxy-space-sm,.5rem);border-radius:var(--roxy-radius-full,9999px);font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600);border:1px solid;align-items:center;gap:4px;display:inline-flex}.pill--muted{color:var(--roxy-fg,#0a0a0a);background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent)}.pill--success{color:var(--roxy-success-fg,#166534);background:color-mix(in srgb, var(--roxy-success,#16a34a) 10%, transparent)}.pill--danger{color:var(--roxy-danger-fg,#991b1b);background:color-mix(in srgb, var(--roxy-danger,#dc2626) 10%, transparent)}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem)}th,td{padding:var(--roxy-space-sm,.5rem);border-bottom:1px solid var(--roxy-border,#e4e4e7);text-align:left}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.06em}.section-label{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em;font-weight:var(--roxy-weight-bold,600);margin:0 0 var(--roxy-space-xs,.25rem) 0}.glyph{margin-right:2px;font-size:1.1em;line-height:1}.planet-cell{white-space:nowrap;align-items:center;gap:4px;display:flex}.retro-badge{border-radius:var(--roxy-radius-sm,4px);background:color-mix(in srgb, var(--roxy-warning,#ea580c) 12%, transparent);color:var(--roxy-warning-fg,#9a3412);font-size:.7em;font-weight:var(--roxy-weight-bold,600);vertical-align:middle;margin-left:2px;padding:1px 4px;display:inline-block}.speed{font-variant-numeric:tabular-nums;color:var(--roxy-muted,#71717a);white-space:nowrap}.speed-arrow{font-size:.85em}td.num{font-variant-numeric:tabular-nums;color:var(--roxy-muted,#71717a)}.overflow-scroll{-webkit-overflow-scrolling:touch;overflow-x:auto}.aspect-card{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);margin-bottom:var(--roxy-space-xs,.25rem)}.aspect-card summary{cursor:pointer;color:var(--roxy-fg,#0a0a0a);flex-wrap:wrap;align-items:center;gap:.5em;font-weight:500;display:flex}.aspect-card summary .meta{color:var(--roxy-muted,#71717a);font-weight:400;font-size:var(--roxy-text-xs,.75rem);font-variant-numeric:tabular-nums;margin-left:auto}.aspect-card .interp-body{margin-top:var(--roxy-space-xs,.25rem);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-sm,.875rem);line-height:1.45}.aspect-card .interp-body p{margin:0 0 var(--roxy-space-xs,.25rem)}.interp-keywords{flex-wrap:wrap;gap:.25rem;margin-top:.5rem;display:flex}.interp-keywords .kw{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 14%, transparent);color:var(--roxy-accent-ink,#b45309);font-size:var(--roxy-text-xs,.75rem);border-radius:9999px;padding:1px 8px}.nature-badge{font-size:var(--roxy-text-xs,.75rem);border-radius:9999px;padding:1px 8px;font-weight:600;display:inline-block}.nature-badge.harmonious{background:color-mix(in srgb, var(--roxy-success,#16a34a) 12%, transparent);color:var(--roxy-success-fg,#166534)}.nature-badge.challenging{background:color-mix(in srgb, var(--roxy-danger,#dc2626) 12%, transparent);color:var(--roxy-danger-fg,#991b1b)}.nature-badge.neutral{background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent);color:var(--roxy-fg,#0a0a0a)}`],p([u({attribute:!1})],pe.prototype,"data",2),p([N()],pe.prototype,"tab",2),pe=p([b("roxy-transits-table")],pe);var me=class extends f{constructor(){super();this.data=null;this.chartStyle="north";this.setStyle=e=>{this.chartStyle=e};new $(this)}viewModel(){return this.data?.meta?vt(this.data.meta,"D1 Rashi"):null}render(){let e=this.viewModel();return e?s`<div class="wrap"><div class="header"><h2 class="title">Vedic kundli</h2>${wt(this.chartStyle,this.setStyle)}</div><svg viewBox="0 0 400 400" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Vedic birth chart with twelve sign houses"><title>Vedic kundli</title>${$t(e,this.chartStyle)}</svg></div>`:s`<div class="roxy-empty" role="status">No kundli data</div>`}};me.styles=[v,kt,fe],p([u({attribute:!1})],me.prototype,"data",2),p([u({type:String,reflect:!0,attribute:"chart-style"})],me.prototype,"chartStyle",2),me=p([b("roxy-vedic-kundli")],me);var es=["Lagna","Sun","Moon","Mars","Mercury","Jupiter","Venus","Saturn","Rahu","Ketu"],Ce=class extends f{constructor(){super();this.data=null;new $(this)}orderedRows(){let e=this.data?.meta??{},t=new Set,r=[];for(let o of es){let i=e[o];i&&(r.push([o,i]),t.add(o))}for(let[o,i]of Object.entries(e))t.has(o)||r.push([o,i]);return r}render(){if(!this.data?.meta)return s`<div class="roxy-empty" role="status">No chart data</div>`;let e=this.orderedRows();return s`<div class="wrap" aria-label="Vedic planetary positions"><header class="head"><h2 class="title">Planetary positions</h2></header><div class="scroll" tabindex="0"><table role="table"><thead><tr><th scope="col">Graha</th><th scope="col">Rashi</th><th scope="col">Degree</th><th scope="col">Nakshatra</th><th scope="col">Pada</th><th scope="col">Nak. lord</th><th scope="col">House</th><th scope="col">Avastha</th><th scope="col">Retro</th></tr></thead><tbody>${e.map(([t,r])=>{let o=(r.graha??t)==="Lagna",i=L[A(r.graha??t)]??"",d=G[A(r.rashi??"")]??"";return s`<tr class="${o?"lagna":""}"><td class="graha">${i?s`<span class="glyph">${i}</span>`:l}${r.graha??t}</td><td>${d?s`<span class="glyph">${d}</span>`:l}${r.rashi??""}</td><td class="num">${typeof r.longitude=="number"?ft(r.longitude):""}</td><td>${r.nakshatra?.name??""}</td><td class="num">${r.nakshatra?.pada??""}</td><td>${r.nakshatra?.lord??""}</td><td class="num">${typeof r.house=="number"?r.house:""}</td><td>${r.awastha??""}</td><td>${r.isRetrograde?s`<span class="retro">R</span>`:l}</td></tr>`})}</tbody></table></div>${this.renderCombustion()} ${this.renderPlanetaryWar()} ${this.renderInterpretations()} ${this.renderYogas()} ${this.renderHouses()}</div>`}renderCombustion(){let e=this.data?.combustion??[];return e.length===0?l:s`<details class="panel"><summary>Combust grahas<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>{let r=L[A(t.planet)]??"",o=C(t.distanceFromSun,2),i=C(t.orb,1);return s`<div class="condition"><span class="planet">${r?`${r} `:""}${t.planet}</span> <span class="detail">${o} deg from Sun, within ${i} deg orb</span></div>`})}</div></details>`}renderPlanetaryWar(){let e=this.data?.planetaryWar??[];return e.length===0?l:s`<details class="panel"><summary>Planetary wars<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>{let r=C(t.distance,2);return s`<div class="condition"><span class="planet">${t.planet1} vs ${t.planet2}</span> <span class="detail">${r} deg apart</span> <span class="winner">${t.winner} wins</span></div>`})}</div></details>`}renderInterpretations(){let e=this.data?.interpretations??{},t=this.orderedRows().map(([r,o])=>[o.graha??r,e[o.graha??r]]).filter(([,r])=>r!=null);return t.length===0?l:s`<details class="panel"><summary>Interpretations<span class="summary-count">${t.length}</span>${Y()}</summary><div class="panel-body">${t.map(([r,o])=>{let i=L[A(r)]??"";return s`<div class="interp"><span class="planet">${i?`${i} `:""}${r}</span> ${o.rashi?s`<p><span class="label">Rashi.</span> ${o.rashi}</p>`:l} ${o.nakshatra?s`<p><span class="label">Nakshatra.</span> ${o.nakshatra}</p>`:l}</div>`})}</div></details>`}renderHouses(){let e=(this.data?.houses??[]).filter(t=>t.name||t.description);return e.length===0?l:s`<details class="panel"><summary>Bhava significations<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>s`<div class="bhava"><span class="name">${t.number}. ${t.name??""}</span> ${t.description?s`<p class="desc">${t.description}</p>`:l}</div>`)}</div></details>`}renderYogas(){let e=(this.data?.yogas??[]).filter(t=>t.present);return e.length===0?l:s`<details class="panel"><summary>Yogas<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>s`<div class="bhava"><span class="name">${t.name} ${t.quality?s`<span class="quality ${t.quality.toLowerCase()}">${t.quality}</span>`:l}</span> ${t.result?s`<p class="desc">${t.result}</p>`:l}</div>`)}</div></details>`}};Ce.styles=[v,je,x`.wrap{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);background:var(--roxy-bg,#fff);box-shadow:var(--roxy-shadow-sm);overflow:hidden}.head{padding:var(--roxy-space-md,1rem);border-bottom:1px solid var(--roxy-border,#e4e4e7)}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.scroll{overflow-x:auto}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem);min-width:620px}thead{background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 20%, transparent)}th,td{padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);text-align:left;white-space:nowrap}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.04em}tbody tr{border-top:1px solid var(--roxy-border,#e4e4e7)}tbody tr.lagna{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 10%, transparent)}td.graha{font-weight:var(--roxy-weight-bold,600);color:var(--roxy-fg,#0a0a0a)}.glyph{color:var(--roxy-muted,#71717a);margin-right:.4em}tbody tr.lagna .glyph{color:var(--roxy-accent-ink,#b45309)}.retro{color:var(--roxy-warning-fg,#9a3412);font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600)}.num{font-variant-numeric:tabular-nums}details.panel{border-top:1px solid var(--roxy-border,#e4e4e7)}details.panel>summary{justify-content:space-between;align-items:center;gap:var(--roxy-space-sm,.5rem);padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);cursor:pointer;font-size:var(--roxy-text-sm,.875rem);font-weight:var(--roxy-weight-bold,600);color:var(--roxy-fg,#0a0a0a);display:flex}details.panel>summary:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:-2px}.summary-count{margin-left:auto;margin-right:var(--roxy-space-xs,.25rem);font-weight:var(--roxy-weight-normal,400);color:var(--roxy-muted,#71717a);font-variant-numeric:tabular-nums}.panel-body{padding:0 var(--roxy-space-md,1rem) var(--roxy-space-md,1rem);gap:var(--roxy-space-sm,.5rem);display:grid}.condition{font-size:var(--roxy-text-sm,.875rem);flex-wrap:wrap;align-items:baseline;gap:.4em;display:flex}.condition .planet{font-weight:var(--roxy-weight-bold,600)}.condition .detail{color:var(--roxy-muted,#71717a);font-variant-numeric:tabular-nums}.condition .winner{color:var(--roxy-success-fg,#166534);font-weight:var(--roxy-weight-bold,600)}.interp{gap:.15em;display:grid}.interp .planet{font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-sm,.875rem)}.interp p{font-size:var(--roxy-text-sm,.875rem);line-height:var(--roxy-leading-normal,1.5);margin:0}.interp .label{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600)}.bhava{gap:.15em;display:grid}.bhava .name{font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-sm,.875rem)}.bhava .desc{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);line-height:var(--roxy-leading-normal,1.5);margin:0}.quality{font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;letter-spacing:.04em}.quality.positive{color:var(--roxy-success-fg,#166534)}.quality.negative{color:var(--roxy-danger-fg,#991b1b)}.quality.both{color:var(--roxy-muted,#71717a)}`],p([u({attribute:!1})],Ce.prototype,"data",2),Ce=p([b("roxy-vedic-planets-table")],Ce);var Pe=class extends f{constructor(){super();this.data=null;new $(this)}rows(){let e=this.data;if(!e)return[];let t=(e.planets??[]).map(r=>({name:r.name,sign:r.sign,longitude:r.longitude,house:r.house,speed:r.speed,isRetrograde:r.isRetrograde}));for(let[r,o]of[["Ascendant",e.ascendant],["Midheaven",e.midheaven],["Part of Fortune",e.partOfFortune],["Vertex",e.vertex]])o&&t.push({name:r,sign:o.sign,longitude:o.longitude,isPoint:!0});return t}render(){if(!this.data?.planets)return s`<div class="roxy-empty" role="status">No chart data</div>`;let e=this.rows();return s`<div class="wrap" aria-label="Western planetary positions" tabindex="0"><header class="head"><h2 class="title">Planetary positions</h2></header><table role="table"><thead><tr><th scope="col">Body</th><th scope="col">Sign</th><th scope="col">Degree</th><th scope="col">House</th><th scope="col">Motion</th></tr></thead><tbody>${e.map(t=>{let r=L[A(t.name)]??"",o=G[A(t.sign??"")]??"",i=typeof t.speed=="number"?C(t.speed,3):"";return s`<tr class="${t.isPoint?"point":""}"><td class="body">${r?s`<span class="glyph">${r}</span>`:l}${t.name}</td><td>${o?s`<span class="glyph">${o}</span>`:l}${t.sign??""}</td><td class="num">${typeof t.longitude=="number"?ft(t.longitude):""}</td><td class="num">${typeof t.house=="number"?t.house:""}</td><td class="num">${i?s`${i}°/day`:l} ${t.isRetrograde?s`<span class="retro">℞</span>`:l}</td></tr>`})}</tbody></table></div>`}};Pe.styles=[v,x`.wrap{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);background:var(--roxy-bg,#fff);box-shadow:var(--roxy-shadow-sm);overflow:auto}.head{padding:var(--roxy-space-md,1rem);border-bottom:1px solid var(--roxy-border,#e4e4e7)}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem);min-width:460px}thead{background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 20%, transparent)}th,td{padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);text-align:left;white-space:nowrap}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.04em}tbody tr{border-top:1px solid var(--roxy-border,#e4e4e7)}tbody tr.point{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 8%, transparent)}td.body{font-weight:var(--roxy-weight-bold,600);color:var(--roxy-fg,#0a0a0a)}.glyph{color:var(--roxy-muted,#71717a);margin-right:.4em}.retro{color:var(--roxy-danger,#dc2626);font-weight:var(--roxy-weight-bold,600)}.num{font-variant-numeric:tabular-nums}`],p([u({attribute:!1})],Pe.prototype,"data",2),Pe=p([b("roxy-western-planets-table")],Pe);var he=class extends f{constructor(){super();this.data=null;this.filter="";this.handleInput=e=>{this.filter=e.target.value};new $(this)}renderQualityChip(e){let t=`quality-chip quality-${e}`;return s`<span class="${t}">${e}</span>`}renderDetailCard(e){return s`<div class="detail-card"><p class="detail-name">${e.name} ${e.quality?this.renderQualityChip(e.quality):l}</p>${e.description?s`<p class="description">${e.description}</p>`:l} ${e.result?s`<details><summary>Effects</summary><div class="result-body">${e.result}</div></details>`:l}</div>`}render(){if(!this.data)return s`<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 r=e;return s`<div class="wrap">${this.renderDetailCard(r)}</div>`}if("yogas"in e&&Array.isArray(e.yogas)){let r=e.yogas;if(r.length>0&&"description"in r[0]){let m=r,g=t?m.filter(y=>y.name.toLowerCase().includes(t)):m,h=e.total;return s`<div class="wrap"><div class="head"><h2 class="title">Yoga catalog</h2>${h!==void 0?s`<span class="count">${h} total</span>`:l}</div><div class="search-wrap"><input class="search" type="search" placeholder="Filter yogas..." aria-label="Filter yoga list by name" .value="${this.filter}" @input="${this.handleInput}"></div><div class="detail-grid" role="region" aria-live="polite" aria-label="Yoga results">${g.length>0?g.map(y=>this.renderDetailCard(y)):s`<p class="no-results">No yogas match your search.</p>`}</div></div>`}let i=r,d=t?i.filter(m=>m.name.toLowerCase().includes(t)):i,c=e.total;return s`<div class="wrap"><div class="head"><h2 class="title">Yoga catalog</h2>${c!==void 0?s`<span class="count">${c} total</span>`:l}</div><div class="search-wrap"><input class="search" type="search" placeholder="Filter yogas..." aria-label="Filter yoga list by name" .value="${this.filter}" @input="${this.handleInput}"></div><div class="grid" role="region" aria-live="polite" aria-label="Yoga results">${d.length>0?d.map(m=>s`<div class="yoga-chip">${m.name} <span class="yoga-id">${m.id}</span></div>`):s`<p class="no-results">No yogas match your search.</p>`}</div></div>`}return s`<div class="roxy-empty" role="status">No yoga data</div>`}};he.styles=[v,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:baseline;gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.count{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a)}.search-wrap{align-items:center;gap:var(--roxy-space-sm,.5rem);display:flex}.search{width:100%;max-width:280px;font-size:var(--roxy-text-sm,.875rem);font-family:var(--roxy-font-sans);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);background:var(--roxy-bg,#fff);color:var(--roxy-fg,#0a0a0a);outline:none;padding:.35em .75em}.search::placeholder{color:var(--roxy-fg,#0a0a0a);opacity:.65}.search:focus{border-color:var(--roxy-accent,#f59e0b);box-shadow:0 0 0 2px color-mix(in srgb, var(--roxy-accent,#f59e0b) 30%, transparent)}.grid{gap:var(--roxy-space-sm,.5rem);grid-template-columns:repeat(auto-fill,minmax(180px,1fr));display:grid}.yoga-chip{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);font-size:var(--roxy-text-sm,.875rem);background:var(--roxy-bg,#fff);color:var(--roxy-fg,#0a0a0a);word-break:break-word;padding:.4em .8em}.yoga-chip .yoga-id{color:var(--roxy-fg,#0a0a0a);opacity:.75;margin-top:.15em;font-size:.7em;display:block}.detail-card{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-md,1rem);background:var(--roxy-bg,#fff);gap:var(--roxy-space-sm,.5rem);display:grid}.detail-name{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);align-items:center;gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;margin:0;display:flex}.quality-chip{font-size:var(--roxy-text-xs,.75rem);border-radius:999px;padding:.15em .6em;font-weight:600;display:inline-block}.quality-Positive{background:color-mix(in srgb, var(--roxy-success,#22c55e) 18%, transparent);color:var(--roxy-success-fg,#15803d);border:1px solid color-mix(in srgb, var(--roxy-success,#22c55e) 40%, transparent)}.quality-Negative{background:color-mix(in srgb, var(--roxy-danger,#ef4444) 18%, transparent);color:var(--roxy-danger-fg,#b91c1c);border:1px solid color-mix(in srgb, var(--roxy-danger,#ef4444) 40%, transparent)}.quality-Both{background:color-mix(in srgb, var(--roxy-warning,#f59e0b) 18%, transparent);color:var(--roxy-warning-fg,#b45309);border:1px solid color-mix(in srgb, var(--roxy-warning,#f59e0b) 40%, transparent)}.description{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);line-height:var(--roxy-leading-normal,1.5);margin:0}details{font-size:var(--roxy-text-sm,.875rem)}details summary{cursor:pointer;color:var(--roxy-accent-ink,#b45309);align-items:center;gap:.4em;padding:.25em 0;font-weight:500;list-style:none;display:flex}details summary:before{content:"+";font-size:1.1em;line-height:1}details[open] summary:before{content:"-"}details .result-body{padding-top:var(--roxy-space-xs,.25rem);color:var(--roxy-fg,#0a0a0a);line-height:var(--roxy-leading-normal,1.5)}.no-results{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);padding:var(--roxy-space-md,1rem) 0;text-align:center}.detail-grid{gap:var(--roxy-space-sm,.5rem);display:grid}`],p([u({attribute:!1})],he.prototype,"data",2),p([N()],he.prototype,"filter",2),he=p([b("roxy-yoga-list")],he);var St=[{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:"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:"RoxyWesternPlanetsTable",tag:"roxy-western-planets-table",slug:"western-planets-table",heading:"Western planets",description:"Western planetary positions table with sign, degree, house, and motion plus the chart angles",docsLabel:"Western",endpointLabel:"POST /astrology/natal-chart",docsSummary:"Sign, degree, house, motion columns plus ASC, MC, PoF, Vertex",topic:"Astrology"},{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:"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:"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:"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:"RoxyVedicKundli",tag:"roxy-vedic-kundli",slug:"vedic-kundli",heading:"Vedic kundli",description:"South, North, or East Indian Vedic kundli for /vedic-astrology/birth-chart with per-planet degree and nakshatra detail",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/birth-chart",docsSummary:"South, North, or East Indian kundli with degree detail",topic:"Vedic"},{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:"RoxyKpChart",tag:"roxy-kp-chart",slug:"kp-chart",heading:"KP chart",description:"Full KP chart with Ascendant, Placidus cusps, and planets in tabbed stellar-hierarchy tables",docsLabel:"Vedic (KP)",endpointLabel:"POST /vedic-astrology/kp/chart",docsSummary:"Ascendant, cusps, and planets with KP stellar hierarchy",topic:"Vedic"},{pascal:"RoxyVedicPlanetsTable",tag:"roxy-vedic-planets-table",slug:"vedic-planets-table",heading:"Vedic planets",description:"Vedic planetary positions table with degree, nakshatra, pada, nakshatra lord, bhava, and avastha",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/birth-chart",docsSummary:"Degree, nakshatra, pada, lord, bhava, avastha columns",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:"RoxyKpRulingPlanets",tag:"roxy-kp-ruling-planets",slug:"kp-ruling-planets",heading:"KP ruling planets",description:"KP ruling planets with day lord, Moon and Lagna stellar hierarchies, and house significators",docsLabel:"Vedic (KP)",endpointLabel:"POST /vedic-astrology/kp/ruling-planets",docsSummary:"Day lord, Moon/Lagna hierarchies, ruling planets, significators",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:"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:"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:"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:"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:"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:"RoxyNakshatraCard",tag:"roxy-nakshatra-card",slug:"nakshatra-card",heading:"Nakshatra",description:"Nakshatra reference card with lord, deity, symbol, characteristics, and remedies",docsLabel:"Vedic",endpointLabel:"GET /vedic-astrology/nakshatras/{id}",docsSummary:"Lord, deity, symbol, characteristics, remedies",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:"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:"RoxyBodygraph",tag:"roxy-bodygraph",slug:"bodygraph",heading:"Bodygraph",description:"Human Design bodygraph with nine centers, channels, and activated gates plus a type, authority, and profile summary",docsLabel:"Human Design",endpointLabel:"POST /human-design/bodygraph",docsSummary:"Nine-center chart with defined and open centers, active channels, gates, and a type and authority summary",topic:"Human Design"},{pascal:"RoxyForecastTimeline",tag:"roxy-forecast-timeline",slug:"forecast-timeline",heading:"Forecast timeline",description:"Cross-domain forecast event strip colored by domain and weighted by significance",docsLabel:"Forecast",endpointLabel:"POST /forecast/timeline",docsSummary:"Date-grouped events across Western, Vedic, and biorhythm domains, weighted by significance",topic:"Forecast"},{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 Mr="0.8.0";var ts=St.map(n=>n.slug);return Hr(rs);})();
|
|
93
|
+
</g>`)};return r(e.person1?.ascendant,1),r(e.person2?.ascendant,2),t}renderInterAspectLines(e,t,r){let o=(i,d)=>{let c=A(d);for(let m of i)if(A(m.name)===c&&typeof m.longitude=="number")return m.longitude};return r.map(i=>{let d=o(e,i.planet1),c=o(t,i.planet2);if(d===void 0||c===void 0)return l;let m=T(M,M,Jt-12,this.toAngle(d)),g=T(M,M,qe+8,this.toAngle(c)),h=Ge(i),y=_e[h]??"aspect-other",S=C(i.orb,1);return w`<line class=${`aspect ${y}`} x1=${m.x} y1=${m.y} x2=${g.x} y2=${g.y}><title>${i.planet1} ${h} ${i.planet2}${S?` (orb ${S}\xB0)`:""}</title></line>`})}renderAspects(e){return s`<table><thead><tr><th>Planet 1</th><th>Planet 2</th><th>Aspect</th><th>Orb</th><th>Strength</th></tr></thead><tbody>${e.slice(0,12).map(t=>s`<tr><td>${t.planet1}</td><td>${t.planet2}</td><td>${Ge(t)||""}</td><td class="orb">${C(t.orb,1)}</td><td>${Qa(t.strength)}</td></tr>`)}</tbody></table>`}};Ae.styles=[v,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:center;gap:var(--roxy-space-md,1rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.score{font-variant-numeric:tabular-nums;font-weight:var(--roxy-weight-bold,600);color:var(--roxy-accent-ink,#b45309);font-size:var(--roxy-text-xl,1.5rem)}svg{aspect-ratio:1;width:100%;max-width:560px;height:auto;margin:0 auto;display:block}.wheel-line{fill:none;stroke:var(--roxy-border,#e4e4e7)}.sign{fill:var(--roxy-secondary,#475569);font-size:14px}.p1{fill:var(--roxy-accent,#f59e0b);font-size:13px;font-weight:600}.p2{fill:var(--roxy-info,#0284c7);font-size:13px;font-weight:600}.person-tag{opacity:.85;font-size:7px;font-weight:700}.planet-deg{fill:var(--roxy-muted,#71717a);font-size:7px;font-family:var(--roxy-font-sans)}.planet-deg .retro{fill:var(--roxy-danger,#dc2626)}.asc-tick{stroke:var(--roxy-accent-ink,#b45309);stroke-width:1px;opacity:.75}.asc-label{fill:var(--roxy-accent-ink,#b45309);font-size:9px;font-weight:700;font-family:var(--roxy-font-sans);letter-spacing:.04em}.aspect{stroke-width:.8px;fill:none;opacity:.5}.aspect-trine,.aspect-sextile{stroke:var(--roxy-success,#16a34a)}.aspect-square,.aspect-opposition{stroke:var(--roxy-danger,#dc2626)}.aspect-conjunction{stroke:var(--roxy-accent-ink,#b45309)}.aspect-other{stroke:var(--roxy-muted,#71717a);opacity:.35}.legend-row{gap:var(--roxy-space-md,1rem);font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);margin-top:calc(var(--roxy-space-xs,.25rem) * -1);flex-wrap:wrap;display:flex}.legend-row .swatch{vertical-align:middle;border-radius:50%;width:8px;height:8px;margin-right:4px;display:inline-block}.summary{color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-base,1rem);margin:0}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem)}th,td{padding:var(--roxy-space-sm,.5rem);border-bottom:1px solid var(--roxy-border,#e4e4e7);text-align:left}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.06em}td.orb{font-variant-numeric:tabular-nums;color:var(--roxy-muted,#71717a)}.lists{gap:var(--roxy-space-md,1rem);grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));display:grid}.lists h3{margin:0 0 var(--roxy-space-xs,.25rem) 0;font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em}.lists ul{padding-left:var(--roxy-space-md,1rem);font-size:var(--roxy-text-sm,.875rem);margin:0}.missing-planets{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 8%, transparent);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-md,1rem);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-sm,.875rem);line-height:1.5}.missing-planets code{font-family:var(--roxy-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);background:color-mix(in srgb, var(--roxy-fg,#0a0a0a) 6%, transparent);border-radius:4px;padding:0 4px;font-size:.95em}`],p([u({attribute:!1})],Ae.prototype,"data",2),Ae=p([b("roxy-synastry-chart")],Ae);function Qa(n){return typeof n=="number"?Math.round(n).toString():""}var de=class extends f{constructor(){super();this.data=null;this.flipped=!1;this.toggleFlip=()=>{this.flipped=!this.flipped};new $(this)}render(){let e=this.data;return e?"card"in e?this.renderDailyCard(e):this.renderFullCard(e):s`<div class="roxy-empty" role="status">No tarot data</div>`}renderDailyCard(e){let t=e.card,r=this.flipped!==!!t.reversed,o=t.keywords??[];return s`<article class="card" aria-label="${t.name??"Tarot card"}"><div class="image-wrap">${t.imageUrl?s`<img class="${`image ${r?"reversed":""}`}" src="${t.imageUrl}" alt="${t.name??"Tarot card"}" tabindex="0" @click="${this.toggleFlip}" @keydown="${i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),this.toggleFlip())}}">`:s`<div class="${`image ${r?"reversed":""}`}" style="aspect-ratio:0.6;display:flex;align-items:center;justify-content:center;color:var(--roxy-muted)">${t.name??"?"}</div>`}</div><div><div class="meta">${t.arcana?s`${t.arcana} arcana`:l} ${r?s`· reversed`:l}</div><h2 class="title">${t.name??"Tarot card"}</h2>${e.dailyMessage?s`<p class="message">${e.dailyMessage}</p>`:l} ${t.meaning?s`<p>${t.meaning}</p>`:l} ${o.length>0?s`<div class="chips">${o.map(i=>s`<span>${i}</span>`)}</div>`:l} <button class="flip" type="button" @click="${this.toggleFlip}" aria-pressed="${this.flipped?"true":"false"}">Flip card</button></div></article>`}renderFullCard(e){let t=this.flipped,r=t?e.reversed:e.upright,o=t?e.keywords?.reversed??[]:e.keywords?.upright??[];return s`<article class="card" aria-label="${e.name??"Tarot card"}"><div class="image-wrap">${e.imageUrl?s`<img class="${`image ${t?"reversed":""}`}" src="${e.imageUrl}" alt="${e.name??"Tarot card"}" tabindex="0" @click="${this.toggleFlip}" @keydown="${i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),this.toggleFlip())}}">`:s`<div class="${`image ${t?"reversed":""}`}" style="aspect-ratio:0.6;display:flex;align-items:center;justify-content:center;color:var(--roxy-muted)">${e.name??"?"}</div>`}</div><div><div class="meta">${e.arcana?s`${e.arcana} arcana`:l} ${e.number!==void 0&&e.number!==null?s`· ${e.number}`:l} ${t?s`· reversed`:l}</div><h2 class="title">${e.name??"Tarot card"}</h2>${r?.description?s`<p>${r.description}</p>`:l} ${o.length>0?s`<div class="chips">${o.map(i=>s`<span>${i}</span>`)}</div>`:l} <button class="flip" type="button" @click="${this.toggleFlip}" aria-pressed="${this.flipped?"true":"false"}">Flip card</button></div></article>`}};de.styles=[v,x`.card{background:var(--roxy-bg,#fff);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-lg,1.5rem);box-shadow:var(--roxy-shadow-sm);gap:var(--roxy-space-lg,1.5rem);grid-template-columns:minmax(0,9rem) 1fr;align-items:start;display:grid}@container (width<=480px){.card{grid-template-columns:1fr}}.image-wrap{perspective:800px}.image{border-radius:var(--roxy-radius-md,8px);background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent);width:100%;height:auto;transition:transform var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1));cursor:pointer;display:block}.image.reversed{transform:rotate(180deg)}.image:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}.title{font-size:var(--roxy-text-xl,1.5rem);font-weight:var(--roxy-weight-bold,600);letter-spacing:var(--roxy-tracking-tight);margin:0}.meta{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--roxy-space-sm,.5rem)}.message{color:var(--roxy-fg,#0a0a0a);margin:var(--roxy-space-sm,.5rem) 0 var(--roxy-space-md,1rem)}.chips{gap:var(--roxy-space-xs,.25rem);margin-top:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.chips span{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 14%, transparent);border-radius:var(--roxy-radius-full,9999px);font-size:var(--roxy-text-xs,.75rem);padding:2px 8px}.flip{margin-top:var(--roxy-space-sm,.5rem);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);font-family:inherit;font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-secondary,#475569);cursor:pointer;transition:transform var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1));background:0 0;padding:4px 12px}.flip:hover{transform:scale(1.02)}`],p([u({attribute:!1})],de.prototype,"data",2),p([N()],de.prototype,"flipped",2),de=p([b("roxy-tarot-card")],de);var ce=class extends f{constructor(){super();this.data=null;this.spread="three-card";new $(this)}render(){let e=this.data;if(!e)return s`<div class="roxy-empty" role="status">No tarot spread</div>`;let t="answer"in e,r="cards"in e&&!("spread"in e),o=r?[]:"positions"in e?e.positions??[]:[],i=r&&"cards"in e?e.cards:[],d=t?e.answer:void 0,c=t?e.strength:void 0,m="spread"in e?e.spread:this.spread.replace(/-/g," "),g="question"in e?e.question:void 0,h="summary"in e?e.summary:void 0,y=t?e.interpretation:void 0,S=d?d.toLowerCase().replace(/[^a-z]/g,""):"";return s`<article class="wrap" aria-label="Tarot spread"><header class="head"><h2 class="title">${m}</h2>${g?s`<span class="question">"${g}"</span>`:l}</header>${t?s`<div><span class="${`answer ${S}`}">${d}</span> ${c?s`<small>· ${c}</small>`:l}</div>`:l} ${o.length>0?s`<div class="grid">${o.map(k=>s`<div class="card"><p class="label">${k.name??""}</p><div class="image">${k.card?.imageUrl?s`<img src="${k.card.imageUrl}" alt="${k.card.name??"tarot card"}" class="${k.card.reversed?"reversed":""}">`:s`${k.card?.name??"?"}`}</div><p class="name">${k.card?.name??""} ${k.card?.reversed?s`<small>(reversed)</small>`:l}</p>${k.interpretation?s`<p class="interp">${k.interpretation}</p>`:l}</div>`)}</div>`:l} ${i.length>0?s`<div class="grid">${i.map(k=>s`<div class="card"><div class="image">${k.imageUrl?s`<img src="${k.imageUrl}" alt="${k.name??"tarot card"}" class="${k.reversed?"reversed":""}">`:s`${k.name??"?"}`}</div><p class="name">${k.name??""} ${k.reversed?s`<small>(reversed)</small>`:l}</p>${k.meaning?s`<p class="interp">${k.meaning}</p>`:l}</div>`)}</div>`:l} ${h?s`<p class="reading">${h}</p>`:l} ${y?s`<p class="reading">${y}</p>`:l}</article>`}};ce.styles=[v,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;gap:var(--roxy-space-md,1rem);flex-wrap:wrap;align-items:baseline;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);text-transform:capitalize;margin:0}.question{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);font-style:italic}.answer{border-radius:var(--roxy-radius-full,9999px);font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-base,1rem);text-transform:uppercase;letter-spacing:.06em;padding:4px 14px;display:inline-block}.answer.yes{background:color-mix(in srgb, var(--roxy-success,#16a34a) 16%, transparent);color:var(--roxy-success-fg,#166534)}.answer.no{background:color-mix(in srgb, var(--roxy-danger,#dc2626) 16%, transparent);color:var(--roxy-danger-fg,#991b1b)}.answer.maybe{background:color-mix(in srgb, var(--roxy-warning,#ea580c) 16%, transparent);color:var(--roxy-warning-fg,#9a3412)}.grid{gap:var(--roxy-space-md,1rem);grid-template-columns:repeat(auto-fit,minmax(8rem,1fr));display:grid}.card{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-sm,.5rem);background:var(--roxy-bg,#fff);gap:var(--roxy-space-xs,.25rem);display:grid}.label{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em;margin:0}.image{aspect-ratio:.6;background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent);border-radius:var(--roxy-radius-sm,4px);width:100%;font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);justify-content:center;align-items:center;display:flex;overflow:hidden}.image img{object-fit:cover;width:100%;height:100%;transition:transform var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1))}.image img.reversed{transform:rotate(180deg)}.name{font-size:var(--roxy-text-sm,.875rem);font-weight:var(--roxy-weight-bold,600);margin:0}.interp{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-secondary,#475569);margin:0}.reading{color:var(--roxy-fg,#0a0a0a);margin:0}`],p([u({attribute:!1})],ce.prototype,"data",2),p([u({type:String,reflect:!0})],ce.prototype,"spread",2),ce=p([b("roxy-tarot-spread")],ce);var pe=class extends f{constructor(){super();this.data=null;this.tab="positions";new $(this)}render(){if(!this.data?.transitPlanets?.length)return s`<div class="roxy-empty" role="status">No transits data</div>`;let{transitDate:e,transitTime:t,transitPlanets:r,transitAspects:o,summary:i}=this.data,d=[xe(e),K(t)].filter(Boolean).join(" "),c=o?.length??0,m=this.tab;return s`<div class="wrap" aria-label="Transits"><div class="head"><h2 class="title">Transits</h2>${d?s`<p class="subtitle">${d}</p>`:l}</div>${c>0?s`${Ie({items:[{id:"positions",label:"Positions"},{id:"aspects",label:`Aspects (${c})`}],active:m,onSelect:g=>{this.tab=g},label:"Transit views",idPrefix:"transits",controls:!0})}<div id="transits-panel-${m}" role="tabpanel" aria-labelledby="transits-tab-${m}">${m==="positions"?s`<div class="overflow-scroll">${this.renderPlanetsTable(r)}</div>`:s`${i?this.renderSummaryPills(i):l}<div class="overflow-scroll">${this.renderAspectsList(o??[])}</div>`}</div>`:s`<div class="overflow-scroll">${this.renderPlanetsTable(r)}</div>`}</div>`}renderSummaryPills(e){return s`<div class="summary-pills" role="region" aria-label="Aspect summary"><span class="pill pill--muted">Total: ${e.totalAspects} </span><span class="pill pill--success">Harmonious: ${e.harmonious} </span><span class="pill pill--danger">Challenging: ${e.challenging} </span><span class="pill pill--muted">Neutral: ${e.neutral}</span></div>`}renderPlanetsTable(e){return s`<table class="planets-table"><thead><tr><th scope="col">Planet</th><th scope="col">Sign</th><th scope="col">Degree</th><th scope="col">Speed</th></tr></thead><tbody>${e.map(t=>{let r=L[A(t.name)]??"",o=G[A(t.sign)]??"",i=t.speed>=0?"\u2191":"\u2193";return s`<tr><td><div class="planet-cell"><span class="glyph" aria-hidden="true">${r}</span> ${t.name} ${t.isRetrograde?s`<span class="retro-badge" aria-label="retrograde">R</span>`:l}</div></td><td><div class="planet-cell"><span class="glyph" aria-hidden="true">${o}</span> ${t.sign}</div></td><td class="num">${C(t.degree,2)}</td><td class="speed"><span class="speed-arrow" aria-hidden="true">${i}</span> ${C(Math.abs(t.speed),4)}</td></tr>`})}</tbody></table>`}renderAspectsList(e){return s`<div role="list" aria-label="Transit aspects">${e.map((t,r)=>{let o=L[A(t.transitPlanet)]??"",i=L[A(t.natalPlanet)]??"",d=(t.nature??"neutral").toLowerCase(),c=t.interpretation,m=(t.type??"").toLowerCase(),g=t.isApplying?"Applying":"Separating";return s`<details class="aspect-card" role="listitem" name="transit-aspects" ?open="${r===0}"><summary><span aria-hidden="true">${o}</span> ${t.transitPlanet} <span class="nature-badge ${d}">${m}</span> <span aria-hidden="true">${i}</span> ${t.natalPlanet} <span class="meta">${g} · orb ${C(t.orb,2)}° · strength ${C(t.strength,1)} </span>${Y()}</summary><div class="interp-body">${c?.summary?s`<p>${c.summary}</p>`:l} ${c?.impact?s`<p><strong>Impact:</strong> ${c.impact}</p>`:l} ${c?.timing?s`<p><strong>Timing:</strong> ${c.timing}</p>`:l} ${c?.guidance?s`<p><strong>Guidance:</strong> ${c.guidance}</p>`:l} ${c?.keywords?.length?s`<div class="interp-keywords">${c.keywords.map(h=>s`<span class="kw">${h}</span>`)}</div>`:l}</div></details>`})}</div>`}};pe.styles=[v,fe,je,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:baseline;gap:var(--roxy-space-md,1rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.subtitle{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);margin:0}.summary-pills{gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.pill{padding:2px var(--roxy-space-sm,.5rem);border-radius:var(--roxy-radius-full,9999px);font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600);border:1px solid;align-items:center;gap:4px;display:inline-flex}.pill--muted{color:var(--roxy-fg,#0a0a0a);background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent)}.pill--success{color:var(--roxy-success-fg,#166534);background:color-mix(in srgb, var(--roxy-success,#16a34a) 10%, transparent)}.pill--danger{color:var(--roxy-danger-fg,#991b1b);background:color-mix(in srgb, var(--roxy-danger,#dc2626) 10%, transparent)}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem)}th,td{padding:var(--roxy-space-sm,.5rem);border-bottom:1px solid var(--roxy-border,#e4e4e7);text-align:left}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.06em}.section-label{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em;font-weight:var(--roxy-weight-bold,600);margin:0 0 var(--roxy-space-xs,.25rem) 0}.glyph{margin-right:2px;font-size:1.1em;line-height:1}.planet-cell{white-space:nowrap;align-items:center;gap:4px;display:flex}.retro-badge{border-radius:var(--roxy-radius-sm,4px);background:color-mix(in srgb, var(--roxy-warning,#ea580c) 12%, transparent);color:var(--roxy-warning-fg,#9a3412);font-size:.7em;font-weight:var(--roxy-weight-bold,600);vertical-align:middle;margin-left:2px;padding:1px 4px;display:inline-block}.speed{font-variant-numeric:tabular-nums;color:var(--roxy-muted,#71717a);white-space:nowrap}.speed-arrow{font-size:.85em}td.num{font-variant-numeric:tabular-nums;color:var(--roxy-muted,#71717a)}.overflow-scroll{-webkit-overflow-scrolling:touch;overflow-x:auto}.aspect-card{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);margin-bottom:var(--roxy-space-xs,.25rem)}.aspect-card summary{cursor:pointer;color:var(--roxy-fg,#0a0a0a);flex-wrap:wrap;align-items:center;gap:.5em;font-weight:500;display:flex}.aspect-card summary .meta{color:var(--roxy-muted,#71717a);font-weight:400;font-size:var(--roxy-text-xs,.75rem);font-variant-numeric:tabular-nums;margin-left:auto}.aspect-card .interp-body{margin-top:var(--roxy-space-xs,.25rem);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-sm,.875rem);line-height:1.45}.aspect-card .interp-body p{margin:0 0 var(--roxy-space-xs,.25rem)}.interp-keywords{flex-wrap:wrap;gap:.25rem;margin-top:.5rem;display:flex}.interp-keywords .kw{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 14%, transparent);color:var(--roxy-accent-ink,#b45309);font-size:var(--roxy-text-xs,.75rem);border-radius:9999px;padding:1px 8px}.nature-badge{font-size:var(--roxy-text-xs,.75rem);border-radius:9999px;padding:1px 8px;font-weight:600;display:inline-block}.nature-badge.harmonious{background:color-mix(in srgb, var(--roxy-success,#16a34a) 12%, transparent);color:var(--roxy-success-fg,#166534)}.nature-badge.challenging{background:color-mix(in srgb, var(--roxy-danger,#dc2626) 12%, transparent);color:var(--roxy-danger-fg,#991b1b)}.nature-badge.neutral{background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent);color:var(--roxy-fg,#0a0a0a)}`],p([u({attribute:!1})],pe.prototype,"data",2),p([N()],pe.prototype,"tab",2),pe=p([b("roxy-transits-table")],pe);var me=class extends f{constructor(){super();this.data=null;this.chartStyle="north";this.setStyle=e=>{this.chartStyle=e};new $(this)}viewModel(){return this.data?.meta?vt(this.data.meta,"D1 Rashi"):null}render(){let e=this.viewModel();return e?s`<div class="wrap"><div class="header"><h2 class="title">Vedic kundli</h2>${wt(this.chartStyle,this.setStyle)}</div><svg viewBox="0 0 400 400" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Vedic birth chart with twelve sign houses"><title>Vedic kundli</title>${$t(e,this.chartStyle)}</svg></div>`:s`<div class="roxy-empty" role="status">No kundli data</div>`}};me.styles=[v,kt,fe],p([u({attribute:!1})],me.prototype,"data",2),p([u({type:String,reflect:!0,attribute:"chart-style"})],me.prototype,"chartStyle",2),me=p([b("roxy-vedic-kundli")],me);var es=["Lagna","Sun","Moon","Mars","Mercury","Jupiter","Venus","Saturn","Rahu","Ketu"],Ce=class extends f{constructor(){super();this.data=null;new $(this)}orderedRows(){let e=this.data?.meta??{},t=new Set,r=[];for(let o of es){let i=e[o];i&&(r.push([o,i]),t.add(o))}for(let[o,i]of Object.entries(e))t.has(o)||r.push([o,i]);return r}render(){if(!this.data?.meta)return s`<div class="roxy-empty" role="status">No chart data</div>`;let e=this.orderedRows();return s`<div class="wrap" aria-label="Vedic planetary positions"><header class="head"><h2 class="title">Planetary positions</h2></header><div class="scroll" tabindex="0"><table role="table"><thead><tr><th scope="col">Graha</th><th scope="col">Rashi</th><th scope="col">Degree</th><th scope="col">Nakshatra</th><th scope="col">Pada</th><th scope="col">Nak. lord</th><th scope="col">House</th><th scope="col">Avastha</th><th scope="col">Retro</th></tr></thead><tbody>${e.map(([t,r])=>{let o=(r.graha??t)==="Lagna",i=L[A(r.graha??t)]??"",d=G[A(r.rashi??"")]??"";return s`<tr class="${o?"lagna":""}"><td class="graha">${i?s`<span class="glyph">${i}</span>`:l}${r.graha??t}</td><td>${d?s`<span class="glyph">${d}</span>`:l}${r.rashi??""}</td><td class="num">${typeof r.longitude=="number"?ft(r.longitude):""}</td><td>${r.nakshatra?.name??""}</td><td class="num">${r.nakshatra?.pada??""}</td><td>${r.nakshatra?.lord??""}</td><td class="num">${typeof r.house=="number"?r.house:""}</td><td>${r.awastha??""}</td><td>${r.isRetrograde?s`<span class="retro">R</span>`:l}</td></tr>`})}</tbody></table></div>${this.renderCombustion()} ${this.renderPlanetaryWar()} ${this.renderInterpretations()} ${this.renderYogas()} ${this.renderHouses()}</div>`}renderCombustion(){let e=this.data?.combustion??[];return e.length===0?l:s`<details class="panel"><summary>Combust grahas<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>{let r=L[A(t.planet)]??"",o=C(t.distanceFromSun,2),i=C(t.orb,1);return s`<div class="condition"><span class="planet">${r?`${r} `:""}${t.planet}</span> <span class="detail">${o} deg from Sun, within ${i} deg orb</span></div>`})}</div></details>`}renderPlanetaryWar(){let e=this.data?.planetaryWar??[];return e.length===0?l:s`<details class="panel"><summary>Planetary wars<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>{let r=C(t.distance,2);return s`<div class="condition"><span class="planet">${t.planet1} vs ${t.planet2}</span> <span class="detail">${r} deg apart</span> <span class="winner">${t.winner} wins</span></div>`})}</div></details>`}renderInterpretations(){let e=this.data?.interpretations??{},t=this.orderedRows().map(([r,o])=>[o.graha??r,e[o.graha??r]]).filter(([,r])=>r!=null);return t.length===0?l:s`<details class="panel"><summary>Interpretations<span class="summary-count">${t.length}</span>${Y()}</summary><div class="panel-body">${t.map(([r,o])=>{let i=L[A(r)]??"";return s`<div class="interp"><span class="planet">${i?`${i} `:""}${r}</span> ${o.rashi?s`<p><span class="label">Rashi.</span> ${o.rashi}</p>`:l} ${o.nakshatra?s`<p><span class="label">Nakshatra.</span> ${o.nakshatra}</p>`:l}</div>`})}</div></details>`}renderHouses(){let e=(this.data?.houses??[]).filter(t=>t.name||t.description);return e.length===0?l:s`<details class="panel"><summary>Bhava significations<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>s`<div class="bhava"><span class="name">${t.number}. ${t.name??""}</span> ${t.description?s`<p class="desc">${t.description}</p>`:l}</div>`)}</div></details>`}renderYogas(){let e=(this.data?.yogas??[]).filter(t=>t.present);return e.length===0?l:s`<details class="panel"><summary>Yogas<span class="summary-count">${e.length}</span>${Y()}</summary><div class="panel-body">${e.map(t=>s`<div class="bhava"><span class="name">${t.name} ${t.quality?s`<span class="quality ${t.quality.toLowerCase()}">${t.quality}</span>`:l}</span> ${t.result?s`<p class="desc">${t.result}</p>`:l}</div>`)}</div></details>`}};Ce.styles=[v,je,x`.wrap{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);background:var(--roxy-bg,#fff);box-shadow:var(--roxy-shadow-sm);overflow:hidden}.head{padding:var(--roxy-space-md,1rem);border-bottom:1px solid var(--roxy-border,#e4e4e7)}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.scroll{overflow-x:auto}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem);min-width:620px}thead{background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 20%, transparent)}th,td{padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);text-align:left;white-space:nowrap}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.04em}tbody tr{border-top:1px solid var(--roxy-border,#e4e4e7)}tbody tr.lagna{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 10%, transparent)}td.graha{font-weight:var(--roxy-weight-bold,600);color:var(--roxy-fg,#0a0a0a)}.glyph{color:var(--roxy-muted,#71717a);margin-right:.4em}tbody tr.lagna .glyph{color:var(--roxy-accent-ink,#b45309)}.retro{color:var(--roxy-warning-fg,#9a3412);font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600)}.num{font-variant-numeric:tabular-nums}details.panel{border-top:1px solid var(--roxy-border,#e4e4e7)}details.panel>summary{justify-content:space-between;align-items:center;gap:var(--roxy-space-sm,.5rem);padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);cursor:pointer;font-size:var(--roxy-text-sm,.875rem);font-weight:var(--roxy-weight-bold,600);color:var(--roxy-fg,#0a0a0a);display:flex}details.panel>summary:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:-2px}.summary-count{margin-left:auto;margin-right:var(--roxy-space-xs,.25rem);font-weight:var(--roxy-weight-normal,400);color:var(--roxy-muted,#71717a);font-variant-numeric:tabular-nums}.panel-body{padding:0 var(--roxy-space-md,1rem) var(--roxy-space-md,1rem);gap:var(--roxy-space-sm,.5rem);display:grid}.condition{font-size:var(--roxy-text-sm,.875rem);flex-wrap:wrap;align-items:baseline;gap:.4em;display:flex}.condition .planet{font-weight:var(--roxy-weight-bold,600)}.condition .detail{color:var(--roxy-muted,#71717a);font-variant-numeric:tabular-nums}.condition .winner{color:var(--roxy-success-fg,#166534);font-weight:var(--roxy-weight-bold,600)}.interp{gap:.15em;display:grid}.interp .planet{font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-sm,.875rem)}.interp p{font-size:var(--roxy-text-sm,.875rem);line-height:var(--roxy-leading-normal,1.5);margin:0}.interp .label{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600)}.bhava{gap:.15em;display:grid}.bhava .name{font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-sm,.875rem)}.bhava .desc{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);line-height:var(--roxy-leading-normal,1.5);margin:0}.quality{font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;letter-spacing:.04em}.quality.positive{color:var(--roxy-success-fg,#166534)}.quality.negative{color:var(--roxy-danger-fg,#991b1b)}.quality.both{color:var(--roxy-muted,#71717a)}`],p([u({attribute:!1})],Ce.prototype,"data",2),Ce=p([b("roxy-vedic-planets-table")],Ce);var Pe=class extends f{constructor(){super();this.data=null;new $(this)}rows(){let e=this.data;if(!e)return[];let t=(e.planets??[]).map(r=>({name:r.name,sign:r.sign,longitude:r.longitude,house:r.house,speed:r.speed,isRetrograde:r.isRetrograde}));for(let[r,o]of[["Ascendant",e.ascendant],["Midheaven",e.midheaven],["Part of Fortune",e.partOfFortune],["Vertex",e.vertex]])o&&t.push({name:r,sign:o.sign,longitude:o.longitude,isPoint:!0});return t}render(){if(!this.data?.planets)return s`<div class="roxy-empty" role="status">No chart data</div>`;let e=this.rows();return s`<div class="wrap" aria-label="Western planetary positions" tabindex="0"><header class="head"><h2 class="title">Planetary positions</h2></header><table role="table"><thead><tr><th scope="col">Body</th><th scope="col">Sign</th><th scope="col">Degree</th><th scope="col">House</th><th scope="col">Motion</th></tr></thead><tbody>${e.map(t=>{let r=L[A(t.name)]??"",o=G[A(t.sign??"")]??"",i=typeof t.speed=="number"?C(t.speed,3):"";return s`<tr class="${t.isPoint?"point":""}"><td class="body">${r?s`<span class="glyph">${r}</span>`:l}${t.name}</td><td>${o?s`<span class="glyph">${o}</span>`:l}${t.sign??""}</td><td class="num">${typeof t.longitude=="number"?ft(t.longitude):""}</td><td class="num">${typeof t.house=="number"?t.house:""}</td><td class="num">${i?s`${i}°/day`:l} ${t.isRetrograde?s`<span class="retro">℞</span>`:l}</td></tr>`})}</tbody></table></div>`}};Pe.styles=[v,x`.wrap{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);background:var(--roxy-bg,#fff);box-shadow:var(--roxy-shadow-sm);overflow:auto}.head{padding:var(--roxy-space-md,1rem);border-bottom:1px solid var(--roxy-border,#e4e4e7)}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}table{border-collapse:collapse;width:100%;font-size:var(--roxy-text-sm,.875rem);min-width:460px}thead{background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 20%, transparent)}th,td{padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);text-align:left;white-space:nowrap}th{color:var(--roxy-muted,#71717a);font-weight:var(--roxy-weight-bold,600);text-transform:uppercase;font-size:var(--roxy-text-xs,.75rem);letter-spacing:.04em}tbody tr{border-top:1px solid var(--roxy-border,#e4e4e7)}tbody tr.point{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 8%, transparent)}td.body{font-weight:var(--roxy-weight-bold,600);color:var(--roxy-fg,#0a0a0a)}.glyph{color:var(--roxy-muted,#71717a);margin-right:.4em}.retro{color:var(--roxy-danger,#dc2626);font-weight:var(--roxy-weight-bold,600)}.num{font-variant-numeric:tabular-nums}`],p([u({attribute:!1})],Pe.prototype,"data",2),Pe=p([b("roxy-western-planets-table")],Pe);var he=class extends f{constructor(){super();this.data=null;this.filter="";this.handleInput=e=>{this.filter=e.target.value};new $(this)}renderQualityChip(e){let t=`quality-chip quality-${e}`;return s`<span class="${t}">${e}</span>`}renderDetailCard(e){return s`<div class="detail-card"><p class="detail-name">${e.name} ${e.quality?this.renderQualityChip(e.quality):l}</p>${e.description?s`<p class="description">${e.description}</p>`:l} ${e.result?s`<details><summary>Effects</summary><div class="result-body">${e.result}</div></details>`:l}</div>`}render(){if(!this.data)return s`<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 r=e;return s`<div class="wrap">${this.renderDetailCard(r)}</div>`}if("yogas"in e&&Array.isArray(e.yogas)){let r=e.yogas;if(r.length>0&&"description"in r[0]){let m=r,g=t?m.filter(y=>y.name.toLowerCase().includes(t)):m,h=e.total;return s`<div class="wrap"><div class="head"><h2 class="title">Yoga catalog</h2>${h!==void 0?s`<span class="count">${h} total</span>`:l}</div><div class="search-wrap"><input class="search" type="search" placeholder="Filter yogas..." aria-label="Filter yoga list by name" .value="${this.filter}" @input="${this.handleInput}"></div><div class="detail-grid" role="region" aria-live="polite" aria-label="Yoga results">${g.length>0?g.map(y=>this.renderDetailCard(y)):s`<p class="no-results">No yogas match your search.</p>`}</div></div>`}let i=r,d=t?i.filter(m=>m.name.toLowerCase().includes(t)):i,c=e.total;return s`<div class="wrap"><div class="head"><h2 class="title">Yoga catalog</h2>${c!==void 0?s`<span class="count">${c} total</span>`:l}</div><div class="search-wrap"><input class="search" type="search" placeholder="Filter yogas..." aria-label="Filter yoga list by name" .value="${this.filter}" @input="${this.handleInput}"></div><div class="grid" role="region" aria-live="polite" aria-label="Yoga results">${d.length>0?d.map(m=>s`<div class="yoga-chip">${m.name} <span class="yoga-id">${m.id}</span></div>`):s`<p class="no-results">No yogas match your search.</p>`}</div></div>`}return s`<div class="roxy-empty" role="status">No yoga data</div>`}};he.styles=[v,x`.wrap{gap:var(--roxy-space-md,1rem);display:grid}.head{justify-content:space-between;align-items:baseline;gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;display:flex}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.count{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a)}.search-wrap{align-items:center;gap:var(--roxy-space-sm,.5rem);display:flex}.search{width:100%;max-width:280px;font-size:var(--roxy-text-sm,.875rem);font-family:var(--roxy-font-sans);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);background:var(--roxy-bg,#fff);color:var(--roxy-fg,#0a0a0a);outline:none;padding:.35em .75em}.search::placeholder{color:var(--roxy-fg,#0a0a0a);opacity:.65}.search:focus{border-color:var(--roxy-accent,#f59e0b);box-shadow:0 0 0 2px color-mix(in srgb, var(--roxy-accent,#f59e0b) 30%, transparent)}.grid{gap:var(--roxy-space-sm,.5rem);grid-template-columns:repeat(auto-fill,minmax(180px,1fr));display:grid}.yoga-chip{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);font-size:var(--roxy-text-sm,.875rem);background:var(--roxy-bg,#fff);color:var(--roxy-fg,#0a0a0a);word-break:break-word;padding:.4em .8em}.yoga-chip .yoga-id{color:var(--roxy-fg,#0a0a0a);opacity:.75;margin-top:.15em;font-size:.7em;display:block}.detail-card{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);padding:var(--roxy-space-md,1rem);background:var(--roxy-bg,#fff);gap:var(--roxy-space-sm,.5rem);display:grid}.detail-name{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);align-items:center;gap:var(--roxy-space-sm,.5rem);flex-wrap:wrap;margin:0;display:flex}.quality-chip{font-size:var(--roxy-text-xs,.75rem);border-radius:999px;padding:.15em .6em;font-weight:600;display:inline-block}.quality-Positive{background:color-mix(in srgb, var(--roxy-success,#22c55e) 18%, transparent);color:var(--roxy-success-fg,#15803d);border:1px solid color-mix(in srgb, var(--roxy-success,#22c55e) 40%, transparent)}.quality-Negative{background:color-mix(in srgb, var(--roxy-danger,#ef4444) 18%, transparent);color:var(--roxy-danger-fg,#b91c1c);border:1px solid color-mix(in srgb, var(--roxy-danger,#ef4444) 40%, transparent)}.quality-Both{background:color-mix(in srgb, var(--roxy-warning,#f59e0b) 18%, transparent);color:var(--roxy-warning-fg,#b45309);border:1px solid color-mix(in srgb, var(--roxy-warning,#f59e0b) 40%, transparent)}.description{font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-muted,#71717a);line-height:var(--roxy-leading-normal,1.5);margin:0}details{font-size:var(--roxy-text-sm,.875rem)}details summary{cursor:pointer;color:var(--roxy-accent-ink,#b45309);align-items:center;gap:.4em;padding:.25em 0;font-weight:500;list-style:none;display:flex}details summary:before{content:"+";font-size:1.1em;line-height:1}details[open] summary:before{content:"-"}details .result-body{padding-top:var(--roxy-space-xs,.25rem);color:var(--roxy-fg,#0a0a0a);line-height:var(--roxy-leading-normal,1.5)}.no-results{color:var(--roxy-muted,#71717a);font-size:var(--roxy-text-sm,.875rem);padding:var(--roxy-space-md,1rem) 0;text-align:center}.detail-grid{gap:var(--roxy-space-sm,.5rem);display:grid}`],p([u({attribute:!1})],he.prototype,"data",2),p([N()],he.prototype,"filter",2),he=p([b("roxy-yoga-list")],he);var St=[{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:"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:"RoxyWesternPlanetsTable",tag:"roxy-western-planets-table",slug:"western-planets-table",heading:"Western planets",description:"Western planetary positions table with sign, degree, house, and motion plus the chart angles",docsLabel:"Western",endpointLabel:"POST /astrology/natal-chart",docsSummary:"Sign, degree, house, motion columns plus ASC, MC, PoF, Vertex",topic:"Astrology"},{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:"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:"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:"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:"RoxyVedicKundli",tag:"roxy-vedic-kundli",slug:"vedic-kundli",heading:"Vedic kundli",description:"South, North, or East Indian Vedic kundli for /vedic-astrology/birth-chart with per-planet degree and nakshatra detail",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/birth-chart",docsSummary:"South, North, or East Indian kundli with degree detail",topic:"Vedic"},{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:"RoxyKpChart",tag:"roxy-kp-chart",slug:"kp-chart",heading:"KP chart",description:"Full KP chart with Ascendant, Placidus cusps, and planets in tabbed stellar-hierarchy tables",docsLabel:"Vedic (KP)",endpointLabel:"POST /vedic-astrology/kp/chart",docsSummary:"Ascendant, cusps, and planets with KP stellar hierarchy",topic:"Vedic"},{pascal:"RoxyVedicPlanetsTable",tag:"roxy-vedic-planets-table",slug:"vedic-planets-table",heading:"Vedic planets",description:"Vedic planetary positions table with degree, nakshatra, pada, nakshatra lord, bhava, and avastha",docsLabel:"Vedic",endpointLabel:"POST /vedic-astrology/birth-chart",docsSummary:"Degree, nakshatra, pada, lord, bhava, avastha columns",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:"RoxyKpRulingPlanets",tag:"roxy-kp-ruling-planets",slug:"kp-ruling-planets",heading:"KP ruling planets",description:"KP ruling planets with day lord, Moon and Lagna stellar hierarchies, and house significators",docsLabel:"Vedic (KP)",endpointLabel:"POST /vedic-astrology/kp/ruling-planets",docsSummary:"Day lord, Moon/Lagna hierarchies, ruling planets, significators",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:"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:"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:"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:"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:"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:"RoxyNakshatraCard",tag:"roxy-nakshatra-card",slug:"nakshatra-card",heading:"Nakshatra",description:"Nakshatra reference card with lord, deity, symbol, characteristics, and remedies",docsLabel:"Vedic",endpointLabel:"GET /vedic-astrology/nakshatras/{id}",docsSummary:"Lord, deity, symbol, characteristics, remedies",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:"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:"RoxyBodygraph",tag:"roxy-bodygraph",slug:"bodygraph",heading:"Bodygraph",description:"Human Design bodygraph with nine centers, channels, and activated gates plus a type, authority, and profile summary",docsLabel:"Human Design",endpointLabel:"POST /human-design/bodygraph",docsSummary:"Nine-center chart with defined and open centers, active channels, gates, and a type and authority summary",topic:"Human Design"},{pascal:"RoxyForecastTimeline",tag:"roxy-forecast-timeline",slug:"forecast-timeline",heading:"Forecast timeline",description:"Cross-domain forecast event strip colored by domain and weighted by significance",docsLabel:"Forecast",endpointLabel:"POST /forecast/timeline",docsSummary:"Date-grouped events across Western, Vedic, and biorhythm domains, weighted by significance",topic:"Forecast"},{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 Mr="0.8.1";var ts=St.map(n=>n.slug);return Hr(rs);})();
|
|
94
94
|
/*! Bundled license information:
|
|
95
95
|
|
|
96
96
|
@lit/reactive-element/css-tag.js:
|