@roxyapi/ui 0.8.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/AGENTS.md +54 -13
  2. package/README.md +33 -22
  3. package/THEMING.md +7 -5
  4. package/dist/cdn/components/angel-number-card.js +45 -0
  5. package/dist/cdn/components/angel-number-card.js.map +7 -0
  6. package/dist/cdn/components/angel-number-lookup.js +45 -0
  7. package/dist/cdn/components/angel-number-lookup.js.map +7 -0
  8. package/dist/cdn/components/ashtakavarga-grid.js +3 -3
  9. package/dist/cdn/components/ashtakavarga-grid.js.map +3 -3
  10. package/dist/cdn/components/biorhythm-chart.js +3 -3
  11. package/dist/cdn/components/biorhythm-chart.js.map +3 -3
  12. package/dist/cdn/components/bodygraph.js +8 -8
  13. package/dist/cdn/components/bodygraph.js.map +3 -3
  14. package/dist/cdn/components/choghadiya-grid.js +3 -3
  15. package/dist/cdn/components/choghadiya-grid.js.map +3 -3
  16. package/dist/cdn/components/compatibility-card.js +2 -2
  17. package/dist/cdn/components/compatibility-card.js.map +3 -3
  18. package/dist/cdn/components/crystal-grid.js +45 -0
  19. package/dist/cdn/components/crystal-grid.js.map +7 -0
  20. package/dist/cdn/components/dasha-timeline.js +2 -2
  21. package/dist/cdn/components/dasha-timeline.js.map +3 -3
  22. package/dist/cdn/components/data.js +2 -2
  23. package/dist/cdn/components/data.js.map +3 -3
  24. package/dist/cdn/components/divisional-chart.js +7 -7
  25. package/dist/cdn/components/divisional-chart.js.map +3 -3
  26. package/dist/cdn/components/dosha-card.js +3 -3
  27. package/dist/cdn/components/dosha-card.js.map +3 -3
  28. package/dist/cdn/components/dream-card.js +45 -0
  29. package/dist/cdn/components/dream-card.js.map +7 -0
  30. package/dist/cdn/components/forecast-timeline.js +3 -3
  31. package/dist/cdn/components/forecast-timeline.js.map +3 -3
  32. package/dist/cdn/components/guna-milan.js +3 -3
  33. package/dist/cdn/components/guna-milan.js.map +3 -3
  34. package/dist/cdn/components/hexagram.js +2 -2
  35. package/dist/cdn/components/hexagram.js.map +3 -3
  36. package/dist/cdn/components/horoscope-card.js +3 -3
  37. package/dist/cdn/components/horoscope-card.js.map +3 -3
  38. package/dist/cdn/components/kp-chart.js +2 -2
  39. package/dist/cdn/components/kp-chart.js.map +3 -3
  40. package/dist/cdn/components/kp-planets-table.js +3 -3
  41. package/dist/cdn/components/kp-planets-table.js.map +3 -3
  42. package/dist/cdn/components/kp-ruling-planets.js +3 -3
  43. package/dist/cdn/components/kp-ruling-planets.js.map +3 -3
  44. package/dist/cdn/components/moon-phase.js +3 -3
  45. package/dist/cdn/components/moon-phase.js.map +3 -3
  46. package/dist/cdn/components/nakshatra-card.js +3 -3
  47. package/dist/cdn/components/nakshatra-card.js.map +3 -3
  48. package/dist/cdn/components/natal-chart.js +2 -2
  49. package/dist/cdn/components/natal-chart.js.map +3 -3
  50. package/dist/cdn/components/numerology-card.js +3 -3
  51. package/dist/cdn/components/numerology-card.js.map +3 -3
  52. package/dist/cdn/components/panchang-table.js +2 -2
  53. package/dist/cdn/components/panchang-table.js.map +3 -3
  54. package/dist/cdn/components/shadbala-table.js +3 -3
  55. package/dist/cdn/components/shadbala-table.js.map +3 -3
  56. package/dist/cdn/components/synastry-chart.js +5 -5
  57. package/dist/cdn/components/synastry-chart.js.map +3 -3
  58. package/dist/cdn/components/tarot-card.js.map +3 -3
  59. package/dist/cdn/components/tarot-spread.js +3 -3
  60. package/dist/cdn/components/tarot-spread.js.map +3 -3
  61. package/dist/cdn/components/transits-table.js +3 -3
  62. package/dist/cdn/components/transits-table.js.map +3 -3
  63. package/dist/cdn/components/vedic-kundli.js +16 -16
  64. package/dist/cdn/components/vedic-kundli.js.map +3 -3
  65. package/dist/cdn/components/vedic-planets-table.js +3 -3
  66. package/dist/cdn/components/vedic-planets-table.js.map +3 -3
  67. package/dist/cdn/components/western-planets-table.js +2 -2
  68. package/dist/cdn/components/western-planets-table.js.map +3 -3
  69. package/dist/cdn/components/yoga-list.js +2 -2
  70. package/dist/cdn/components/yoga-list.js.map +3 -3
  71. package/dist/cdn/roxy-ui.js +289 -66
  72. package/dist/cdn/roxy-ui.js.map +4 -4
  73. package/dist/cdn.d.ts +8 -0
  74. package/dist/cdn.d.ts.map +1 -0
  75. package/dist/components/angel-number-card.d.ts +18 -0
  76. package/dist/components/angel-number-card.d.ts.map +1 -0
  77. package/dist/components/angel-number-card.js +2 -0
  78. package/dist/components/angel-number-card.js.map +7 -0
  79. package/dist/components/angel-number-lookup.d.ts +18 -0
  80. package/dist/components/angel-number-lookup.d.ts.map +1 -0
  81. package/dist/components/angel-number-lookup.js +2 -0
  82. package/dist/components/angel-number-lookup.js.map +7 -0
  83. package/dist/components/ashtakavarga-grid.js +1 -1
  84. package/dist/components/ashtakavarga-grid.js.map +3 -3
  85. package/dist/components/biorhythm-chart.js +1 -1
  86. package/dist/components/biorhythm-chart.js.map +3 -3
  87. package/dist/components/bodygraph.js +4 -4
  88. package/dist/components/bodygraph.js.map +3 -3
  89. package/dist/components/choghadiya-grid.js +1 -1
  90. package/dist/components/choghadiya-grid.js.map +3 -3
  91. package/dist/components/compatibility-card.js +1 -1
  92. package/dist/components/compatibility-card.js.map +3 -3
  93. package/dist/components/crystal-grid.d.ts +27 -0
  94. package/dist/components/crystal-grid.d.ts.map +1 -0
  95. package/dist/components/crystal-grid.js +2 -0
  96. package/dist/components/crystal-grid.js.map +7 -0
  97. package/dist/components/dasha-timeline.js +1 -1
  98. package/dist/components/dasha-timeline.js.map +3 -3
  99. package/dist/components/data.js +1 -1
  100. package/dist/components/data.js.map +3 -3
  101. package/dist/components/divisional-chart.js +34 -34
  102. package/dist/components/divisional-chart.js.map +3 -3
  103. package/dist/components/dosha-card.js +1 -1
  104. package/dist/components/dosha-card.js.map +3 -3
  105. package/dist/components/dream-card.d.ts +17 -0
  106. package/dist/components/dream-card.d.ts.map +1 -0
  107. package/dist/components/dream-card.js +2 -0
  108. package/dist/components/dream-card.js.map +7 -0
  109. package/dist/components/forecast-timeline.js.map +3 -3
  110. package/dist/components/guna-milan.js +1 -1
  111. package/dist/components/guna-milan.js.map +3 -3
  112. package/dist/components/hexagram.js +1 -1
  113. package/dist/components/hexagram.js.map +3 -3
  114. package/dist/components/horoscope-card.js +1 -1
  115. package/dist/components/horoscope-card.js.map +3 -3
  116. package/dist/components/kp-chart.js +1 -1
  117. package/dist/components/kp-chart.js.map +3 -3
  118. package/dist/components/kp-planets-table.js +1 -1
  119. package/dist/components/kp-planets-table.js.map +3 -3
  120. package/dist/components/kp-ruling-planets.js +1 -1
  121. package/dist/components/kp-ruling-planets.js.map +3 -3
  122. package/dist/components/moon-phase.js +1 -1
  123. package/dist/components/moon-phase.js.map +3 -3
  124. package/dist/components/nakshatra-card.js +1 -1
  125. package/dist/components/nakshatra-card.js.map +3 -3
  126. package/dist/components/natal-chart.js +5 -5
  127. package/dist/components/natal-chart.js.map +3 -3
  128. package/dist/components/numerology-card.d.ts +7 -3
  129. package/dist/components/numerology-card.d.ts.map +1 -1
  130. package/dist/components/numerology-card.js +1 -1
  131. package/dist/components/numerology-card.js.map +3 -3
  132. package/dist/components/panchang-table.js +1 -1
  133. package/dist/components/panchang-table.js.map +3 -3
  134. package/dist/components/shadbala-table.js +1 -1
  135. package/dist/components/shadbala-table.js.map +3 -3
  136. package/dist/components/synastry-chart.js +4 -4
  137. package/dist/components/synastry-chart.js.map +3 -3
  138. package/dist/components/tarot-card.js +1 -1
  139. package/dist/components/tarot-card.js.map +3 -3
  140. package/dist/components/tarot-spread.js +1 -1
  141. package/dist/components/tarot-spread.js.map +3 -3
  142. package/dist/components/transits-table.js +1 -1
  143. package/dist/components/transits-table.js.map +3 -3
  144. package/dist/components/vedic-kundli.d.ts +18 -0
  145. package/dist/components/vedic-kundli.d.ts.map +1 -1
  146. package/dist/components/vedic-kundli.js +62 -62
  147. package/dist/components/vedic-kundli.js.map +3 -3
  148. package/dist/components/vedic-planets-table.js +1 -1
  149. package/dist/components/vedic-planets-table.js.map +3 -3
  150. package/dist/components/western-planets-table.js +1 -1
  151. package/dist/components/western-planets-table.js.map +3 -3
  152. package/dist/components/yoga-list.js +1 -1
  153. package/dist/components/yoga-list.js.map +3 -3
  154. package/dist/index.cjs +74 -74
  155. package/dist/index.cjs.map +4 -4
  156. package/dist/index.d.ts +5 -0
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +74 -74
  159. package/dist/index.js.map +4 -4
  160. package/dist/manifest.d.ts.map +1 -1
  161. package/dist/manifest.json +28 -24
  162. package/dist/styles/tokens-css.d.ts +2 -0
  163. package/dist/styles/tokens-css.d.ts.map +1 -0
  164. package/dist/styles/tokens.css +26 -11
  165. package/dist/types/index.d.ts +1 -1
  166. package/dist/types/index.d.ts.map +1 -1
  167. package/dist/types/types.gen.d.ts +43 -26
  168. package/dist/types/types.gen.d.ts.map +1 -1
  169. package/dist/utils/inject-tokens.d.ts +16 -0
  170. package/dist/utils/inject-tokens.d.ts.map +1 -0
  171. package/dist/utils/kundli-render.d.ts +2 -1
  172. package/dist/utils/kundli-render.d.ts.map +1 -1
  173. package/dist/utils/markup-data.d.ts +34 -0
  174. package/dist/utils/markup-data.d.ts.map +1 -1
  175. package/dist/version.d.ts +1 -1
  176. package/dist/version.d.ts.map +1 -1
  177. package/package.json +1 -1
  178. package/src/cdn.ts +15 -0
  179. package/src/components/angel-number-card.ts +234 -0
  180. package/src/components/angel-number-lookup.ts +208 -0
  181. package/src/components/crystal-grid.ts +191 -0
  182. package/src/components/dream-card.ts +98 -0
  183. package/src/components/numerology-card.ts +22 -10
  184. package/src/components/vedic-kundli.ts +37 -2
  185. package/src/index.ts +14 -0
  186. package/src/manifest.ts +57 -5
  187. package/src/styles/tokens-css.ts +225 -0
  188. package/src/styles/tokens.css +26 -11
  189. package/src/types/index.ts +1 -1
  190. package/src/types/types.gen.ts +43 -26
  191. package/src/utils/inject-tokens.ts +27 -0
  192. package/src/utils/kundli-render.ts +9 -2
  193. package/src/utils/markup-data.ts +45 -0
  194. package/src/version.ts +1 -1
package/AGENTS.md CHANGED
@@ -37,6 +37,10 @@ Map the natural-language request to a component first; fall back to the table be
37
37
  | "biorhythm", "physical/emotional/intellectual cycle", "critical days" | `<roxy-biorhythm-chart>` |
38
38
  | "I Ching", "hexagram", "cast the coins", "Book of Changes" | `<roxy-hexagram>` |
39
39
  | "moon phase", "moon calendar", "next full moon", "current moon" | `<roxy-moon-phase>` |
40
+ | "what does my dream mean", "dream symbol", "dream dictionary", "I dreamt of {symbol}" | `<roxy-dream-card>` |
41
+ | "angel number {n}", "meaning of 111 / 222 / 1111", "I keep seeing this number" | `<roxy-angel-number-card>` |
42
+ | "what does {any number} mean", "analyze this number", "is 1234 an angel number" | `<roxy-angel-number-lookup>` |
43
+ | "crystals for {chakra}", "healing stones", "birthstone for {month}", "crystals for {sign}" | `<roxy-crystal-grid>` |
40
44
  | "search a city", "geocode", "lat/long for a place" | `<roxy-location-search>` |
41
45
  | "build a form for endpoint X" | `<roxy-endpoint-form>` |
42
46
 
@@ -56,7 +60,7 @@ Use the table below for the formal endpoint to component mapping.
56
60
  | `<roxy-moon-phase>` | Western | GET /astrology/moon-phase/{current,upcoming,calendar/...} | Moon phase card and calendar |
57
61
  | `<roxy-horoscope-card>` | Western | GET /astrology/horoscope/{sign}/{daily,weekly,monthly} | Daily, weekly, or monthly horoscope card |
58
62
  | `<roxy-compatibility-card>` | Cross | POST /astrology/compatibility-score, /numerology/compatibility, /biorhythm/compatibility | Score card with category breakdown |
59
- | `<roxy-vedic-kundli>` | Vedic | POST /vedic-astrology/birth-chart | South, North, or East Indian kundli with degree detail |
63
+ | `<roxy-vedic-kundli>` | Vedic | POST /vedic-astrology/birth-chart | South, North, or East Indian kundli with degree detail and optional Chandra Lagna view |
60
64
  | `<roxy-divisional-chart>` | Vedic | POST /vedic-astrology/divisional-chart | Generic divisional varga wheel from D2 Hora to D60 Shashtiamsa |
61
65
  | `<roxy-kp-chart>` | Vedic (KP) | POST /vedic-astrology/kp/chart | Ascendant, cusps, and planets with KP stellar hierarchy |
62
66
  | `<roxy-vedic-planets-table>` | Vedic | POST /vedic-astrology/birth-chart | Degree, nakshatra, pada, lord, bhava, avastha columns |
@@ -71,13 +75,17 @@ Use the table below for the formal endpoint to component mapping.
71
75
  | `<roxy-yoga-list>` | Vedic | GET /vedic-astrology/yoga, /yoga/{id} | Filterable yoga cards from the 300 plus yoga catalog |
72
76
  | `<roxy-nakshatra-card>` | Vedic | GET /vedic-astrology/nakshatras/{id} | Lord, deity, symbol, characteristics, remedies |
73
77
  | `<roxy-dosha-card>` | Vedic | POST /vedic-astrology/dosha/{manglik,kalsarpa,sadhesati} | Presence, severity, remedies, scoped effects |
74
- | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,personal-year,chart} | Life path, expression, personal year, full chart |
78
+ | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,soul-urge,personality,personal-year,chart} | Life path, expression, soul urge, personality, personal year, full chart |
75
79
  | `<roxy-tarot-card>` | Tarot | GET /tarot/cards/{id}, POST /tarot/daily | Single card with upright and reversed flip |
76
80
  | `<roxy-tarot-spread>` | Tarot | POST /tarot/spreads/{three-card,celtic-cross,love}, /tarot/yes-no, /tarot/draw | Spreads with positions and reading |
77
81
  | `<roxy-bodygraph>` | Human Design | POST /human-design/bodygraph | Nine-center chart with defined and open centers, active channels, gates, and a type and authority summary |
78
82
  | `<roxy-forecast-timeline>` | Forecast | POST /forecast/timeline | Date-grouped events across Western, Vedic, and biorhythm domains, weighted by significance |
79
83
  | `<roxy-biorhythm-chart>` | Biorhythm | POST /biorhythm/{daily,forecast,critical-days} | Daily bars, forecast cycle lines, critical days |
80
84
  | `<roxy-hexagram>` | I Ching | GET /iching/hexagrams/{number}, /iching/cast, POST /iching/daily, /iching/daily/cast | Hexagram with trigrams, judgment, image, changing lines |
85
+ | `<roxy-crystal-grid>` | Crystals | GET /crystals, /crystals/chakra/{chakra}, /crystals/element/{element}, /crystals/zodiac/{sign}, /crystals/birthstone/{month}, /crystals/search | Crystal gallery tiles with photo, name, and colour swatches |
86
+ | `<roxy-dream-card>` | Dreams | GET /dreams/symbols/{id} | Symbol name, interpretation body, and letter chip |
87
+ | `<roxy-angel-number-card>` | Angel Numbers | GET /angel-numbers/numbers/{number} | Number meaning with spiritual, love, career, and twin flame sections |
88
+ | `<roxy-angel-number-lookup>` | Angel Numbers | GET /angel-numbers/lookup | Pattern analysis plus known meaning and digit-root fallback |
81
89
  | `<roxy-endpoint-form>` | Helper | Any endpoint via x-roxy-ui hints | Schema-driven form, emits roxy-submit |
82
90
  | `<roxy-location-search>` | Helper | GET /location/search | Debounced city search input, emits roxy-location-select |
83
91
  | `<roxy-data>` | Helper | Any response shape | Generic fallback renderer for unknown shapes |
@@ -120,15 +128,17 @@ const { data: chart } = await roxy.astrology.generateNatalChart({
120
128
 
121
129
  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
130
 
123
- ### 4. API key in the browser
131
+ ### 4. Secret key in the browser
124
132
 
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.
133
+ Secret keys (`sk_*`) grant full account access and 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 a secret key in a client bundle.
126
134
 
127
135
  ```ts
128
- // Server side only
136
+ // Secret key: server side only
129
137
  const roxy = createRoxy(process.env.ROXY_API_KEY!);
130
138
  ```
131
139
 
140
+ For direct client-side calls, use a **publishable key** (`pk_live_*` / `pk_test_*`) instead. Publishable keys are browser-safe: mint one at `roxyapi.com/account`, register the origins you embed on, and the API gateway returns 403 for any other origin. See the client-side pattern below.
141
+
132
142
  ### 5. Missing `'use client'` in Next.js App Router
133
143
 
134
144
  The React components in `@roxyapi/ui-react` mount Custom Elements, which need the DOM. In the App Router, files that import them must declare `'use client'` at the top. Server Components can fetch with the SDK; the client component renders.
@@ -269,9 +279,30 @@ For a static chart with no picker, fetch in a Server Component and pass `data` t
269
279
  </script>
270
280
  ```
271
281
 
272
- ### Pattern 4: widgets auto-mount (coming soon)
282
+ ### Pattern 4: fully client-side with a publishable key (no server)
283
+
284
+ When you do not want a backend at all, mint a **publishable key** (`pk_live_*`) at `roxyapi.com/account`, register the origins you embed on, and call RoxyAPI directly from the browser. The publishable key is safe to ship in client code: it is origin-restricted (any other origin gets 403) and cannot read your account. `<roxy-location-search>` accepts the key via its `publishable-key` attribute and fetches geocoding itself; for the data endpoints you make a normal browser `fetch` with the key in the `X-API-Key` header, then assign the response to the rendering component.
273
285
 
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.
286
+ ```html
287
+ <roxy-location-search publishable-key="pk_live_..."></roxy-location-search>
288
+ <roxy-natal-chart></roxy-natal-chart>
289
+
290
+ <script type="module">
291
+ const chart = document.querySelector('roxy-natal-chart');
292
+ document.querySelector('roxy-location-search').addEventListener('roxy-location-select', async (e) => {
293
+ const { latitude, longitude, timezone } = e.detail;
294
+ if (latitude == null || longitude == null) return;
295
+ const res = await fetch('https://roxyapi.com/api/v2/astrology/natal-chart', {
296
+ method: 'POST',
297
+ headers: { 'X-API-Key': 'pk_live_...', 'Content-Type': 'application/json' },
298
+ body: JSON.stringify({ date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone }),
299
+ });
300
+ chart.data = await res.json(); // pass the unwrapped response, not an envelope
301
+ });
302
+ </script>
303
+ ```
304
+
305
+ Rendering components do not fetch on their own; you set `data`. Only `<roxy-location-search>` (and `<roxy-endpoint-form>` for the spec) fetch internally. A zero-wiring `data-*` auto-mount that fetches and renders with no script is still on the roadmap.
275
306
 
276
307
  ### Pattern 5: MCP tool-call response
277
308
 
@@ -320,32 +351,42 @@ export default function BirthChartView({ data }: { data: unknown }) {
320
351
 
321
352
  When the page is rendered on the server or served from cache, there may be no JavaScript to set the `data` property per element. Render the response into a child `<script type="application/json" class="roxy-data">` instead. The component reads the embedded JSON on load. No per-element script, no API key in the browser.
322
353
 
354
+ **Always serialize with the shipped helper. Never hand-roll the escape and never use a bare `JSON.stringify`.** `@roxyapi/ui` exports `roxyDataScript(data)` (returns the full `<script class="roxy-data">…</script>` element) and `serializeRoxyData(data)` (returns just the escaped JSON string). They escape `<`, `>`, and `&` so a string field containing `</script>` cannot break out of the block. A raw `JSON.stringify` of a response with interpretation prose can contain `</script>` and corrupt the page or open an injection hole.
355
+
356
+ ```ts
357
+ import { roxyDataScript } from '@roxyapi/ui';
358
+
359
+ const { data } = await roxy.astrology.generateNatalChart({ body });
360
+ const html = `<roxy-natal-chart>${roxyDataScript(data)}</roxy-natal-chart>`;
361
+ ```
362
+
363
+ The emitted markup:
364
+
323
365
  ```html
324
366
  <roxy-natal-chart>
325
- <script type="application/json" class="roxy-data">
326
- { "planets": [ ], "houses": [ ], "aspects": [ ] }
327
- </script>
367
+ <script type="application/json" class="roxy-data">{ "planets": [ ], "houses": [ ], "aspects": [ ] }</script>
328
368
  </roxy-natal-chart>
329
369
  ```
330
370
 
331
371
  Rules for this pattern:
332
372
 
333
373
  - The JSON must be the unwrapped RoxyAPI response, the same shape you would assign to `element.data`. Do not embed the SDK envelope (`{ data, error, request, response }`); embed `data`.
334
- - The script must be a direct child of the component and carry both `type="application/json"` and `class="roxy-data"`.
374
+ - The script must be a direct child of the component and carry both `type="application/json"` and `class="roxy-data"`. `roxyDataScript` emits both.
335
375
  - The JavaScript property always wins. If you assign `element.data` in script, the markup is ignored. One component covers both server-rendered and dynamic pages with no branching.
336
376
  - You can nest a server-rendered HTML fallback inside the same element for no-JavaScript and crawler views. The component reads only the marked script and leaves the fallback in place.
377
+ - In a language that cannot call the TS helper (PHP, Python, Go), mirror its rule exactly: escape `<`, `>`, and `&` to their `\u003c`, `\u003e`, `\u0026` JSON escapes. The WordPress example does this in PHP.
337
378
 
338
379
  This is how the WordPress plugin renders: PHP fetches the response server-side, caches it, and writes the script into the page. The same shape works in any framework that emits HTML.
339
380
 
340
381
  ## Theming and dark mode
341
382
 
342
- Components react to three signals in priority order. No events to dispatch. No JS bridge to write.
383
+ Components react to three signals in priority order. No events to dispatch. No JS bridge to write. The CDN bundle (`dist/cdn/roxy-ui.js`) auto-loads the design tokens, so a single script tag yields full theming and dark mode with nothing else to add. The npm and React paths inherit the same tokens through the components; only set up `tokens.css` yourself if you import per component without the full bundle.
343
384
 
344
385
  | Signal | Where | Effect |
345
386
  |---|---|---|
346
387
  | `prefers-color-scheme: dark` | OS | Default. Follows user system setting. |
347
388
  | `data-theme="light"` or `data-theme="dark"` | `<html>` / `<body>` / any ancestor / the component itself | Wins over OS. Per-element override scope works. |
348
- | `.dark` class | Any ancestor | Equivalent to `data-theme="dark"`. Use when the host stack already ships a `.dark` toggle (Tailwind, shadcn). |
389
+ | `.dark` class | The component itself or any ancestor (typically `<html>`) | Same effect as `data-theme="dark"`. Use when the host stack already ships a `.dark` toggle (Tailwind, shadcn). |
349
390
 
350
391
  To toggle at runtime:
351
392
 
package/README.md CHANGED
@@ -55,7 +55,7 @@ Light, dark, your brand. Override one CSS variable and every component updates.
55
55
  ```css
56
56
  :root {
57
57
  /* Surface */
58
- --roxy-bg: #fafafa;
58
+ --roxy-bg: #ffffff;
59
59
  --roxy-fg: #0a0a0a;
60
60
  --roxy-muted: #71717a;
61
61
  --roxy-border: #e4e4e7;
@@ -66,13 +66,13 @@ Light, dark, your brand. Override one CSS variable and every component updates.
66
66
 
67
67
  /* Status (each has a -fg variant for WCAG-AA text contrast) */
68
68
  --roxy-success: #16a34a;
69
- --roxy-warning: #f59e0b;
69
+ --roxy-warning: #ea580c;
70
70
  --roxy-danger: #dc2626;
71
- --roxy-info: #2563eb;
71
+ --roxy-info: #0284c7;
72
72
 
73
73
  /* Shape + motion */
74
- --roxy-radius-md: 12px;
75
- --roxy-shadow-md: 0 4px 12px rgba(0,0,0,0.08);
74
+ --roxy-radius-md: 8px;
75
+ --roxy-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.08), 0 2px 4px -2px rgba(0,0,0,0.06);
76
76
  --roxy-motion-duration: 200ms; /* 0ms when prefers-reduced-motion */
77
77
  }
78
78
 
@@ -234,7 +234,7 @@ const { data } = await roxy.astrology.getDailyHoroscope({ path: { sign: 'aries'
234
234
  return <RoxyHoroscopeCard data={data} />;
235
235
  ```
236
236
 
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.
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 36 components.
238
238
 
239
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
240
 
@@ -294,16 +294,25 @@ Always call `/location/search` first. Every chart endpoint expects latitude, lon
294
294
 
295
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.
296
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.
297
+ Serialize with the shipped helper, never a bare `JSON.stringify`. `@roxyapi/ui` exports `roxyDataScript(data)` (the full `<script class="roxy-data">…</script>` element) and `serializeRoxyData(data)` (just the escaped JSON). They escape `<`, `>`, and `&` so a string field containing `</script>` cannot break out of the block and corrupt the page.
298
298
 
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>
299
+ Load the bundle once anywhere on the page. It registers every `roxy-*` element and loads the design tokens, so every component on the page renders themed, in light or dark, from that single tag. Nothing else to add.
300
+
301
+ ```ts
302
+ import { roxyDataScript } from '@roxyapi/ui';
303
+
304
+ const { data } = await roxy.astrology.generateNatalChart({ body });
305
+ const html = `
306
+ <script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js" crossorigin="anonymous" defer></script>
307
+ <roxy-natal-chart>${roxyDataScript(data)}</roxy-natal-chart>
308
+ `;
309
+ ```
310
+
311
+ The emitted markup:
302
312
 
313
+ ```html
303
314
  <roxy-natal-chart>
304
- <script type="application/json" class="roxy-data">
305
- { "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
306
- </script>
315
+ <script type="application/json" class="roxy-data">{ "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }</script>
307
316
  </roxy-natal-chart>
308
317
  ```
309
318
 
@@ -535,11 +544,9 @@ const { data: random } = await roxy.iching.getRandomHexagram();
535
544
 
536
545
  Get a key at <https://roxyapi.com/account>.
537
546
 
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.
539
-
540
- Set `ROXY_API_KEY` to your secret key in your server env for every SDK example on this page.
547
+ Two key types. **Secret keys** (`sk_*`) grant full account access: use them server side only (Node, Bun, Hono, Next.js route handlers, Workers). Never commit one, never ship one in a client bundle. **Publishable keys** (`pk_live_*` / `pk_test_*`) are browser-safe: mint one, register the origins you embed on, and any other origin gets a 403 at the gateway. Use a publishable key when you call RoxyAPI directly from the browser with no backend.
541
548
 
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.
549
+ Set `ROXY_API_KEY` to your secret key in your server env for the server-side SDK examples on this page. For direct client-side embedding with no backend, use a publishable key (see the fully client-side pattern in [`AGENTS.md`](AGENTS.md)).
543
550
 
544
551
  ## Distribution
545
552
 
@@ -564,7 +571,7 @@ Browser-safe keys for direct client-side embedding are on the roadmap, not yet a
564
571
  | `<roxy-moon-phase>` | Western | GET /astrology/moon-phase/{current,upcoming,calendar/...} | Moon phase card and calendar |
565
572
  | `<roxy-horoscope-card>` | Western | GET /astrology/horoscope/{sign}/{daily,weekly,monthly} | Daily, weekly, or monthly horoscope card |
566
573
  | `<roxy-compatibility-card>` | Cross | POST /astrology/compatibility-score, /numerology/compatibility, /biorhythm/compatibility | Score card with category breakdown |
567
- | `<roxy-vedic-kundli>` | Vedic | POST /vedic-astrology/birth-chart | South, North, or East Indian kundli with degree detail |
574
+ | `<roxy-vedic-kundli>` | Vedic | POST /vedic-astrology/birth-chart | South, North, or East Indian kundli with degree detail and optional Chandra Lagna view |
568
575
  | `<roxy-divisional-chart>` | Vedic | POST /vedic-astrology/divisional-chart | Generic divisional varga wheel from D2 Hora to D60 Shashtiamsa |
569
576
  | `<roxy-kp-chart>` | Vedic (KP) | POST /vedic-astrology/kp/chart | Ascendant, cusps, and planets with KP stellar hierarchy |
570
577
  | `<roxy-vedic-planets-table>` | Vedic | POST /vedic-astrology/birth-chart | Degree, nakshatra, pada, lord, bhava, avastha columns |
@@ -579,13 +586,17 @@ Browser-safe keys for direct client-side embedding are on the roadmap, not yet a
579
586
  | `<roxy-yoga-list>` | Vedic | GET /vedic-astrology/yoga, /yoga/{id} | Filterable yoga cards from the 300 plus yoga catalog |
580
587
  | `<roxy-nakshatra-card>` | Vedic | GET /vedic-astrology/nakshatras/{id} | Lord, deity, symbol, characteristics, remedies |
581
588
  | `<roxy-dosha-card>` | Vedic | POST /vedic-astrology/dosha/{manglik,kalsarpa,sadhesati} | Presence, severity, remedies, scoped effects |
582
- | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,personal-year,chart} | Life path, expression, personal year, full chart |
589
+ | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,soul-urge,personality,personal-year,chart} | Life path, expression, soul urge, personality, personal year, full chart |
583
590
  | `<roxy-tarot-card>` | Tarot | GET /tarot/cards/{id}, POST /tarot/daily | Single card with upright and reversed flip |
584
591
  | `<roxy-tarot-spread>` | Tarot | POST /tarot/spreads/{three-card,celtic-cross,love}, /tarot/yes-no, /tarot/draw | Spreads with positions and reading |
585
592
  | `<roxy-bodygraph>` | Human Design | POST /human-design/bodygraph | Nine-center chart with defined and open centers, active channels, gates, and a type and authority summary |
586
593
  | `<roxy-forecast-timeline>` | Forecast | POST /forecast/timeline | Date-grouped events across Western, Vedic, and biorhythm domains, weighted by significance |
587
594
  | `<roxy-biorhythm-chart>` | Biorhythm | POST /biorhythm/{daily,forecast,critical-days} | Daily bars, forecast cycle lines, critical days |
588
595
  | `<roxy-hexagram>` | I Ching | GET /iching/hexagrams/{number}, /iching/cast, POST /iching/daily, /iching/daily/cast | Hexagram with trigrams, judgment, image, changing lines |
596
+ | `<roxy-crystal-grid>` | Crystals | GET /crystals, /crystals/chakra/{chakra}, /crystals/element/{element}, /crystals/zodiac/{sign}, /crystals/birthstone/{month}, /crystals/search | Crystal gallery tiles with photo, name, and colour swatches |
597
+ | `<roxy-dream-card>` | Dreams | GET /dreams/symbols/{id} | Symbol name, interpretation body, and letter chip |
598
+ | `<roxy-angel-number-card>` | Angel Numbers | GET /angel-numbers/numbers/{number} | Number meaning with spiritual, love, career, and twin flame sections |
599
+ | `<roxy-angel-number-lookup>` | Angel Numbers | GET /angel-numbers/lookup | Pattern analysis plus known meaning and digit-root fallback |
589
600
  | `<roxy-endpoint-form>` | Helper | Any endpoint via x-roxy-ui hints | Schema-driven form, emits roxy-submit |
590
601
  | `<roxy-location-search>` | Helper | GET /location/search | Debounced city search input, emits roxy-location-select |
591
602
  | `<roxy-data>` | Helper | Any response shape | Generic fallback renderer for unknown shapes |
@@ -603,7 +614,7 @@ Browser-safe keys for direct client-side embedding are on the roadmap, not yet a
603
614
 
604
615
  ## Theming
605
616
 
606
- Every component reads from `--roxy-*` CSS custom properties. Override globally on `:root` or per element. Light + dark defaults, container queries for responsive layouts at 320px and up. See [THEMING.md](https://github.com/RoxyAPI/ui/blob/main/packages/ui/THEMING.md) for the full token reference.
617
+ Every component reads from `--roxy-*` CSS custom properties. Override globally on `:root` or per element. Light + dark defaults, container queries for responsive layouts at 320px and up. The CDN bundle auto-loads these tokens; your `:root { --roxy-* }` overrides always win over the defaults. See [THEMING.md](https://github.com/RoxyAPI/ui/blob/main/packages/ui/THEMING.md) for the full token reference.
607
618
 
608
619
  ```css
609
620
  :root {
@@ -686,7 +697,7 @@ Persist the choice in `localStorage` from your own code; the components do not o
686
697
  <details>
687
698
  <summary><strong>How big is each component? What is the bundle cost?</strong></summary>
688
699
 
689
- Per-component bundles run 6-10 KB gzipped, capped at 30 KB by CI. The full bundle (every component, helpers, base styles) stays well under the 150 KB CI cap, around 45 KB gzipped today. The React package loads the runtime on mount, so a route that renders one chart pays for one component, not the whole catalog. Pin a concrete version in production for byte-stable cache hits.
700
+ Per-component bundles run 6-10 KB gzipped, capped at 30 KB by CI. The full bundle (every component, helpers, base styles, and the inlined design tokens) stays well under the 150 KB CI cap, around 54 KB gzipped today. The React package loads the runtime on mount, so a route that renders one chart pays for one component, not the whole catalog. Pin a concrete version in production for byte-stable cache hits.
690
701
  </details>
691
702
 
692
703
  <details>
@@ -799,7 +810,7 @@ Components ship in Shadow DOM for style isolation; Tailwind utilities are scoped
799
810
  <details>
800
811
  <summary><strong>What is the security model for API keys?</strong></summary>
801
812
 
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.
813
+ Two key types. Secret keys (`sk_*`) 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. Publishable keys (`pk_live_*` / `pk_test_*`) are browser-safe for direct client-side embedding: they carry an origin allowlist, so a key leaked to any other origin returns 403 instead of working. Mint either at `roxyapi.com/account`.
803
814
 
804
815
  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.
805
816
  </details>
package/THEMING.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Theming Roxy UI
2
2
 
3
- Every Roxy UI component reads its colors, fonts, spacing, and motion from a single set of CSS custom properties on `:host`. Override them at `:root` to brand the whole library, or scope to one element to skin a single component.
3
+ Every Roxy UI component reads its colors, fonts, spacing, and motion from a single set of `--roxy-*` CSS custom properties. Override them at `:root` to brand the whole library, or scope to one element to skin a single component. Custom properties inherit through the Shadow DOM boundary, so a value set on `:root` or any light-DOM ancestor reaches every component. The CDN bundle auto-loads the token defaults; your `:root` overrides always win over them.
4
4
 
5
5
  ## Token reference
6
6
 
@@ -99,18 +99,20 @@ roxy-natal-chart {
99
99
 
100
100
  ### Dark mode
101
101
 
102
- Three opt-in mechanisms work out of the box.
102
+ Three opt-in mechanisms work out of the box. The CDN bundle auto-loads the tokens, so all three work from one script tag; on the npm path the full `@roxyapi/ui` import pulls the same tokens in.
103
103
 
104
104
  ```css
105
105
  /* System preference: nothing to do */
106
106
 
107
- /* data-theme on the document */
107
+ /* data-theme on the document, an ancestor, or the element itself */
108
108
  :root[data-theme='dark'] { /* automatic */ }
109
109
 
110
- /* Tailwind dark class on an ancestor */
111
- .dark roxy-natal-chart { /* automatic */ }
110
+ /* Tailwind dark class on the document, an ancestor, or the element itself */
111
+ .dark { /* automatic */ }
112
112
  ```
113
113
 
114
+ Tokens set on the `:root` / `.dark` / `[data-theme]` light-DOM element inherit through the shadow boundary into every component, so a `.dark` class anywhere above a component themes it. Per-element scope works too: `<roxy-natal-chart data-theme="dark">` runs one chart in dark on an otherwise light page.
115
+
114
116
  ### Map Tailwind tokens
115
117
 
116
118
  Tailwind users can map our tokens to theirs in five lines of `globals.css`. Pick the syntax that matches your Tailwind version.
@@ -0,0 +1,45 @@
1
+ "use strict";var RoxyUI_angel_number_card=(()=>{var H=Object.defineProperty;var oe=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var we=(o,e)=>{for(var t in e)H(o,t,{get:e[t],enumerable:!0})},Ce=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Se(e))!Ee.call(o,s)&&s!==t&&H(o,s,{get:()=>e[s],enumerable:!(r=oe(e,s))||r.enumerable});return o};var Pe=o=>Ce(H({},"__esModule",{value:!0}),o),V=(o,e,t,r)=>{for(var s=r>1?void 0:r?oe(e,t):e,i=o.length-1,n;i>=0;i--)(n=o[i])&&(s=(r?n(e,t,s):n(s))||s);return r&&s&&H(e,t,s),s};var Je={};we(Je,{RoxyAngelNumberCard:()=>A});var z=globalThis,D=z.ShadowRoot&&(z.ShadyCSS===void 0||z.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,W=Symbol(),ie=new WeakMap,w=class{constructor(e,t,r){if(this._$cssResult$=!0,r!==W)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,t=this.t;if(D&&e===void 0){let r=t!==void 0&&t.length===1;r&&(e=ie.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),r&&ie.set(t,e))}return e}toString(){return this.cssText}},ne=o=>new w(typeof o=="string"?o:o+"",void 0,W),C=(o,...e)=>{let t=o.length===1?o[0]:e.reduce((r,s,i)=>r+(n=>{if(n._$cssResult$===!0)return n.cssText;if(typeof n=="number")return n;throw Error("Value passed to 'css' function must be a 'css' function result: "+n+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+o[i+1],o[0]);return new w(t,o,W)},ae=(o,e)=>{if(D)o.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let r=document.createElement("style"),s=z.litNonce;s!==void 0&&r.setAttribute("nonce",s),r.textContent=t.cssText,o.appendChild(r)}},F=D?o=>o:o=>o instanceof CSSStyleSheet?(e=>{let t="";for(let r of e.cssRules)t+=r.cssText;return ne(t)})(o):o;var{is:ke,defineProperty:Re,getOwnPropertyDescriptor:Ue,getOwnPropertyNames:Oe,getOwnPropertySymbols:Te,getPrototypeOf:Me}=Object,L=globalThis,le=L.trustedTypes,Ne=le?le.emptyScript:"",He=L.reactiveElementPolyfillSupport,P=(o,e)=>o,k={toAttribute(o,e){switch(e){case Boolean:o=o?Ne:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o)}return o},fromAttribute(o,e){let t=o;switch(e){case Boolean:t=o!==null;break;case Number:t=o===null?null:Number(o);break;case Object:case Array:try{t=JSON.parse(o)}catch{t=null}}return t}},j=(o,e)=>!ke(o,e),ce={attribute:!0,type:String,converter:k,reflect:!1,useDefault:!1,hasChanged:j};Symbol.metadata??=Symbol("metadata"),L.litPropertyMetadata??=new WeakMap;var f=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=ce){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){let r=Symbol(),s=this.getPropertyDescriptor(e,r,t);s!==void 0&&Re(this.prototype,e,s)}}static getPropertyDescriptor(e,t,r){let{get:s,set:i}=Ue(this.prototype,e)??{get(){return this[t]},set(n){this[t]=n}};return{get:s,set(n){let l=s?.call(this);i?.call(this,n),this.requestUpdate(e,l,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??ce}static _$Ei(){if(this.hasOwnProperty(P("elementProperties")))return;let e=Me(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(P("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(P("properties"))){let t=this.properties,r=[...Oe(t),...Te(t)];for(let s of r)this.createProperty(s,t[s])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[r,s]of t)this.elementProperties.set(r,s)}this._$Eh=new Map;for(let[t,r]of this.elementProperties){let s=this._$Eu(t,r);s!==void 0&&this._$Eh.set(s,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let r=new Set(e.flat(1/0).reverse());for(let s of r)t.unshift(F(s))}else e!==void 0&&t.push(F(e));return t}static _$Eu(e,t){let r=t.attribute;return r===!1?void 0:typeof r=="string"?r:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let r of t.keys())this.hasOwnProperty(r)&&(e.set(r,this[r]),delete this[r]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return ae(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,r){this._$AK(e,r)}_$ET(e,t){let r=this.constructor.elementProperties.get(e),s=this.constructor._$Eu(e,r);if(s!==void 0&&r.reflect===!0){let i=(r.converter?.toAttribute!==void 0?r.converter:k).toAttribute(t,r.type);this._$Em=e,i==null?this.removeAttribute(s):this.setAttribute(s,i),this._$Em=null}}_$AK(e,t){let r=this.constructor,s=r._$Eh.get(e);if(s!==void 0&&this._$Em!==s){let i=r.getPropertyOptions(s),n=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:k;this._$Em=s;let l=n.fromAttribute(t,i.type);this[s]=l??this._$Ej?.get(s)??l,this._$Em=null}}requestUpdate(e,t,r,s=!1,i){if(e!==void 0){let n=this.constructor;if(s===!1&&(i=this[e]),r??=n.getPropertyOptions(e),!((r.hasChanged??j)(i,t)||r.useDefault&&r.reflect&&i===this._$Ej?.get(e)&&!this.hasAttribute(n._$Eu(e,r))))return;this.C(e,t,r)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(e,t,{useDefault:r,reflect:s,wrapped:i},n){r&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,n??t??this[e]),i!==!0||n!==void 0)||(this._$AL.has(e)||(this.hasUpdated||r||(t=void 0),this._$AL.set(e,t)),s===!0&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}let e=this.scheduleUpdate();return e!=null&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[s,i]of this._$Ep)this[s]=i;this._$Ep=void 0}let r=this.constructor.elementProperties;if(r.size>0)for(let[s,i]of r){let{wrapped:n}=i,l=this[s];n!==!0||this._$AL.has(s)||l===void 0||this.C(s,void 0,i,l)}}let e=!1,t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(r=>r.hostUpdate?.()),this.update(t)):this._$EM()}catch(r){throw e=!1,this._$EM(),r}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(e){}firstUpdated(e){}};f.elementStyles=[],f.shadowRootOptions={mode:"open"},f[P("elementProperties")]=new Map,f[P("finalized")]=new Map,He?.({ReactiveElement:f}),(L.reactiveElementVersions??=[]).push("2.1.2");var Q=globalThis,he=o=>o,q=Q.trustedTypes,pe=q?q.createPolicy("lit-html",{createHTML:o=>o}):void 0,ge="$lit$",g=`lit$${Math.random().toFixed(9).slice(2)}$`,$e="?"+g,ze=`<${$e}>`,_=document,U=()=>_.createComment(""),O=o=>o===null||typeof o!="object"&&typeof o!="function",ee=Array.isArray,De=o=>ee(o)||typeof o?.[Symbol.iterator]=="function",J=`[
2
+ \f\r]`,R=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,de=/-->/g,ue=/>/g,x=RegExp(`>|${J}(?:([^\\s"'>=/]+)(${J}*=${J}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),me=/'/g,fe=/"/g,xe=/^(?:script|style|textarea|title)$/i,te=o=>(e,...t)=>({_$litType$:o,strings:e,values:t}),u=te(1),Qe=te(2),et=te(3),b=Symbol.for("lit-noChange"),c=Symbol.for("lit-nothing"),ye=new WeakMap,v=_.createTreeWalker(_,129);function ve(o,e){if(!ee(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return pe!==void 0?pe.createHTML(e):e}var Le=(o,e)=>{let t=o.length-1,r=[],s,i=e===2?"<svg>":e===3?"<math>":"",n=R;for(let l=0;l<t;l++){let a=o[l],p,d,h=-1,m=0;for(;m<a.length&&(n.lastIndex=m,d=n.exec(a),d!==null);)m=n.lastIndex,n===R?d[1]==="!--"?n=de:d[1]!==void 0?n=ue:d[2]!==void 0?(xe.test(d[2])&&(s=RegExp("</"+d[2],"g")),n=x):d[3]!==void 0&&(n=x):n===x?d[0]===">"?(n=s??R,h=-1):d[1]===void 0?h=-2:(h=n.lastIndex-d[2].length,p=d[1],n=d[3]===void 0?x:d[3]==='"'?fe:me):n===fe||n===me?n=x:n===de||n===ue?n=R:(n=x,s=void 0);let y=n===x&&o[l+1].startsWith("/>")?" ":"";i+=n===R?a+ze:h>=0?(r.push(p),a.slice(0,h)+ge+a.slice(h)+g+y):a+g+(h===-2?l:y)}return[ve(o,i+(o[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),r]},T=class o{constructor({strings:e,_$litType$:t},r){let s;this.parts=[];let i=0,n=0,l=e.length-1,a=this.parts,[p,d]=Le(e,t);if(this.el=o.createElement(p,r),v.currentNode=this.el.content,t===2||t===3){let h=this.el.content.firstChild;h.replaceWith(...h.childNodes)}for(;(s=v.nextNode())!==null&&a.length<l;){if(s.nodeType===1){if(s.hasAttributes())for(let h of s.getAttributeNames())if(h.endsWith(ge)){let m=d[n++],y=s.getAttribute(h).split(g),N=/([.?@])?(.*)/.exec(m);a.push({type:1,index:i,name:N[2],strings:y,ctor:N[1]==="."?K:N[1]==="?"?Y:N[1]==="@"?X:E}),s.removeAttribute(h)}else h.startsWith(g)&&(a.push({type:6,index:i}),s.removeAttribute(h));if(xe.test(s.tagName)){let h=s.textContent.split(g),m=h.length-1;if(m>0){s.textContent=q?q.emptyScript:"";for(let y=0;y<m;y++)s.append(h[y],U()),v.nextNode(),a.push({type:2,index:++i});s.append(h[m],U())}}}else if(s.nodeType===8)if(s.data===$e)a.push({type:2,index:i});else{let h=-1;for(;(h=s.data.indexOf(g,h+1))!==-1;)a.push({type:7,index:i}),h+=g.length-1}i++}}static createElement(e,t){let r=_.createElement("template");return r.innerHTML=e,r}};function S(o,e,t=o,r){if(e===b)return e;let s=r!==void 0?t._$Co?.[r]:t._$Cl,i=O(e)?void 0:e._$litDirective$;return s?.constructor!==i&&(s?._$AO?.(!1),i===void 0?s=void 0:(s=new i(o),s._$AT(o,t,r)),r!==void 0?(t._$Co??=[])[r]=s:t._$Cl=s),s!==void 0&&(e=S(o,s._$AS(o,e.values),s,r)),e}var G=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:r}=this._$AD,s=(e?.creationScope??_).importNode(t,!0);v.currentNode=s;let i=v.nextNode(),n=0,l=0,a=r[0];for(;a!==void 0;){if(n===a.index){let p;a.type===2?p=new M(i,i.nextSibling,this,e):a.type===1?p=new a.ctor(i,a.name,a.strings,this,e):a.type===6&&(p=new Z(i,this,e)),this._$AV.push(p),a=r[++l]}n!==a?.index&&(i=v.nextNode(),n++)}return v.currentNode=_,s}p(e){let t=0;for(let r of this._$AV)r!==void 0&&(r.strings!==void 0?(r._$AI(e,r,t),t+=r.strings.length-2):r._$AI(e[t])),t++}},M=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,r,s){this.type=2,this._$AH=c,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=r,this.options=s,this._$Cv=s?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=S(this,e,t),O(e)?e===c||e==null||e===""?(this._$AH!==c&&this._$AR(),this._$AH=c):e!==this._$AH&&e!==b&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):De(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==c&&O(this._$AH)?this._$AA.nextSibling.data=e:this.T(_.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:r}=e,s=typeof r=="number"?this._$AC(e):(r.el===void 0&&(r.el=T.createElement(ve(r.h,r.h[0]),this.options)),r);if(this._$AH?._$AD===s)this._$AH.p(t);else{let i=new G(s,this),n=i.u(this.options);i.p(t),this.T(n),this._$AH=i}}_$AC(e){let t=ye.get(e.strings);return t===void 0&&ye.set(e.strings,t=new T(e)),t}k(e){ee(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,r,s=0;for(let i of e)s===t.length?t.push(r=new o(this.O(U()),this.O(U()),this,this.options)):r=t[s],r._$AI(i),s++;s<t.length&&(this._$AR(r&&r._$AB.nextSibling,s),t.length=s)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let r=he(e).nextSibling;he(e).remove(),e=r}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},E=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,r,s,i){this.type=1,this._$AH=c,this._$AN=void 0,this.element=e,this.name=t,this._$AM=s,this.options=i,r.length>2||r[0]!==""||r[1]!==""?(this._$AH=Array(r.length-1).fill(new String),this.strings=r):this._$AH=c}_$AI(e,t=this,r,s){let i=this.strings,n=!1;if(i===void 0)e=S(this,e,t,0),n=!O(e)||e!==this._$AH&&e!==b,n&&(this._$AH=e);else{let l=e,a,p;for(e=i[0],a=0;a<i.length-1;a++)p=S(this,l[r+a],t,a),p===b&&(p=this._$AH[a]),n||=!O(p)||p!==this._$AH[a],p===c?e=c:e!==c&&(e+=(p??"")+i[a+1]),this._$AH[a]=p}n&&!s&&this.j(e)}j(e){e===c?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??"")}},K=class extends E{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===c?void 0:e}},Y=class extends E{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==c)}},X=class extends E{constructor(e,t,r,s,i){super(e,t,r,s,i),this.type=5}_$AI(e,t=this){if((e=S(this,e,t,0)??c)===b)return;let r=this._$AH,s=e===c&&r!==c||e.capture!==r.capture||e.once!==r.once||e.passive!==r.passive,i=e!==c&&(r===c||s);s&&this.element.removeEventListener(this.name,this,r),i&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}},Z=class{constructor(e,t,r){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=r}get _$AU(){return this._$AM._$AU}_$AI(e){S(this,e)}};var je=Q.litHtmlPolyfillSupport;je?.(T,M),(Q.litHtmlVersions??=[]).push("3.3.2");var _e=(o,e,t)=>{let r=t?.renderBefore??e,s=r._$litPart$;if(s===void 0){let i=t?.renderBefore??null;r._$litPart$=s=new M(e.insertBefore(U(),i),i,void 0,t??{})}return s._$AI(o),s};var re=globalThis,$=class extends f{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=_e(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return b}};$._$litElement$=!0,$.finalized=!0,re.litElementHydrateSupport?.({LitElement:$});var qe=re.litElementPolyfillSupport;qe?.({LitElement:$});(re.litElementVersions??=[]).push("4.2.2");var be=o=>(e,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(o,e)}):customElements.define(o,e)};var Ie={attribute:!0,type:String,converter:k,reflect:!1,hasChanged:j},Be=(o=Ie,e,t)=>{let{kind:r,metadata:s}=t,i=globalThis.litPropertyMetadata.get(s);if(i===void 0&&globalThis.litPropertyMetadata.set(s,i=new Map),r==="setter"&&((o=Object.create(o)).wrapped=!0),i.set(t.name,o),r==="accessor"){let{name:n}=t;return{set(l){let a=e.get.call(this);e.set.call(this,l),this.requestUpdate(n,a,o,!0,l)},init(l){return l!==void 0&&this.C(n,void 0,o,l),l}}}if(r==="setter"){let{name:n}=t;return function(l){let a=this[n];e.call(this,l),this.requestUpdate(n,a,o,!0,l)}}throw Error("Unsupported decorator location: "+r)};function se(o){return(e,t)=>typeof t=="object"?Be(o,e,t):((r,s,i)=>{let n=s.hasOwnProperty(i);return s.constructor.createProperty(i,r),n?Object.getOwnPropertyDescriptor(s,i):void 0})(o,e,t)}var Ae=C`:host{font-family:var(--roxy-font-sans,system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-base,1rem);line-height:var(--roxy-leading-normal,1.5);animation:roxy-fade-in var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1)) both;background:0 0;display:block;container-type:inline-size}*,:before,:after{box-sizing:border-box}@keyframes roxy-fade-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){:host{animation:none}}.roxy-skeleton{background:linear-gradient(90deg, var(--roxy-border,#e4e4e7) 0%, color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent) 50%, var(--roxy-border,#e4e4e7) 100%);border-radius:var(--roxy-radius-md,8px);background-size:200% 100%;animation:1.4s ease-in-out infinite roxy-shimmer}@keyframes roxy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.roxy-skeleton{animation:none}}.roxy-empty{padding:var(--roxy-space-lg,1.5rem);color:var(--roxy-muted,#71717a);text-align:center;font-size:var(--roxy-text-sm,.875rem)}:host(:focus-within) .roxy-card{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}:host{font-variant-emoji:text}`;var Ve="roxy-data";function We(o){return o.nodeName==="SCRIPT"&&o.getAttribute("type")==="application/json"}var B=class{constructor(e){this.host=e,e.addController(this)}hostConnected(){if(this.host.data!=null)return;let e=this.read();e!==void 0&&(this.host.data=e,this.host.requestUpdate())}read(){let e=this.findInlineScript();return e?this.parse(e.textContent):void 0}findInlineScript(){for(let e of Array.from(this.host.children))if(We(e)&&e.classList.contains(Ve))return e;return null}parse(e){if(e?.trim())try{return JSON.parse(e)}catch{return}}};var Fe=[{key:"spiritual",label:"Spiritual"},{key:"love",label:"Love"},{key:"career",label:"Career"},{key:"twinFlame",label:"Twin flame"}],A=class extends ${constructor(){super();this.data=null;new B(this)}render(){let t=this.data;if(!t)return u`<div class="roxy-empty" role="status">No angel number</div>`;let r=(t.energy??"").toLowerCase(),s=r==="positive"||r==="cautionary"||r==="neutral"?r:"",i=t.keywords??[],n=t.actionSteps??[];return u`<article class="card" aria-label="${`Angel number ${t.number??""}`}"><div class="hero">${t.number?u`<div class="numeral">${t.number}</div>`:c}<div><p class="label">Angel number</p>${t.title?u`<h2 class="title">${t.title}</h2>`:c}</div></div>${t.coreMessage?u`<p class="core">${t.coreMessage}</p>`:c}<div class="badges">${t.type?u`<span class="badge">${t.type}</span>`:c} ${typeof t.digitRoot=="number"?u`<span class="badge">Digit root ${t.digitRoot}</span>`:c} ${t.energy?u`<span class="${`badge ${s}`}">${t.energy}</span>`:c}</div>${i.length>0?u`<div class="chips">${i.map(l=>u`<span>${l}</span>`)}</div>`:c} ${this.renderSections(t)} ${t.affirmation?u`<p class="affirmation">${t.affirmation}</p>`:c} ${n.length>0?u`<div class="steps"><h3>Action steps</h3><ul>${n.map(l=>u`<li>${l}</li>`)}</ul></div>`:c}</article>`}renderSections(t){let r=t.meaning;if(!r)return c;let s=Fe.filter(i=>r[i.key]);return s.length===0?c:u`<div class="sections">${s.map((i,n)=>u`<details name="angel-meaning" ?open="${n===0}"><summary>${i.label}</summary><p>${r[i.key]}</p></details>`)}</div>`}};A.styles=[Ae,C`.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-md,1rem);display:grid}.hero{align-items:center;gap:var(--roxy-space-md,1rem);display:flex}.numeral{font-size:3rem;line-height:1;font-weight:var(--roxy-weight-bold,600);color:var(--roxy-accent-ink,#b45309);font-variant-numeric:tabular-nums}.label{font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em;margin:0}.title{font-size:var(--roxy-text-lg,1.125rem);font-weight:var(--roxy-weight-bold,600);margin:0}.core{color:var(--roxy-fg,#0a0a0a);margin:0;line-height:1.6}.badges{gap:var(--roxy-space-xs,.25rem);flex-wrap:wrap;display:flex}.badge{align-items:center;gap:var(--roxy-space-xs,.25rem);border-radius:var(--roxy-radius-full,9999px);font-size:var(--roxy-text-xs,.75rem);font-weight:var(--roxy-weight-bold,600);background:color-mix(in srgb, var(--roxy-border,#e4e4e7) 35%, transparent);color:var(--roxy-fg,#0a0a0a);text-transform:capitalize;padding:3px 10px;display:inline-flex}.badge.positive{background:color-mix(in srgb, var(--roxy-success,#16a34a) 16%, transparent);color:var(--roxy-success-fg,#166534)}.badge.cautionary{background:color-mix(in srgb, var(--roxy-danger,#dc2626) 16%, transparent);color:var(--roxy-danger-fg,#991b1b)}.badge.neutral{background:color-mix(in srgb, var(--roxy-info,#0284c7) 16%, transparent);color:var(--roxy-info-fg,#075985)}.chips{gap:var(--roxy-space-xs,.25rem);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}.sections{gap:var(--roxy-space-xs,.25rem);border-top:1px solid var(--roxy-border,#e4e4e7);padding-top:var(--roxy-space-md,1rem);display:grid}details{border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-sm,4px);overflow:hidden}summary{cursor:pointer;padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);font-weight:var(--roxy-weight-bold,600);font-size:var(--roxy-text-sm,.875rem);list-style-position:inside}details p{padding:0 var(--roxy-space-md,1rem) var(--roxy-space-md,1rem);font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-fg,#0a0a0a);margin:0;line-height:1.6}.affirmation{background:color-mix(in srgb, var(--roxy-accent,#f59e0b) 12%, transparent);border-left:3px solid var(--roxy-accent,#f59e0b);padding:var(--roxy-space-sm,.5rem) var(--roxy-space-md,1rem);border-radius:var(--roxy-radius-sm,4px);color:var(--roxy-fg,#0a0a0a);margin:0;font-style:italic}.steps h3{margin:0 0 var(--roxy-space-xs,.25rem);font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-transform:uppercase;letter-spacing:.06em}.steps ul{padding-left:var(--roxy-space-md,1rem);font-size:var(--roxy-text-sm,.875rem);color:var(--roxy-fg,#0a0a0a);gap:2px;margin:0;display:grid}`],V([se({attribute:!1})],A.prototype,"data",2),A=V([be("roxy-angel-number-card")],A);return Pe(Je);})();
4
+ /*! Bundled license information:
5
+
6
+ @lit/reactive-element/css-tag.js:
7
+ (**
8
+ * @license
9
+ * Copyright 2019 Google LLC
10
+ * SPDX-License-Identifier: BSD-3-Clause
11
+ *)
12
+
13
+ @lit/reactive-element/reactive-element.js:
14
+ lit-html/lit-html.js:
15
+ lit-element/lit-element.js:
16
+ @lit/reactive-element/decorators/custom-element.js:
17
+ @lit/reactive-element/decorators/property.js:
18
+ @lit/reactive-element/decorators/state.js:
19
+ @lit/reactive-element/decorators/event-options.js:
20
+ @lit/reactive-element/decorators/base.js:
21
+ @lit/reactive-element/decorators/query.js:
22
+ @lit/reactive-element/decorators/query-all.js:
23
+ @lit/reactive-element/decorators/query-async.js:
24
+ @lit/reactive-element/decorators/query-assigned-nodes.js:
25
+ (**
26
+ * @license
27
+ * Copyright 2017 Google LLC
28
+ * SPDX-License-Identifier: BSD-3-Clause
29
+ *)
30
+
31
+ lit-html/is-server.js:
32
+ (**
33
+ * @license
34
+ * Copyright 2022 Google LLC
35
+ * SPDX-License-Identifier: BSD-3-Clause
36
+ *)
37
+
38
+ @lit/reactive-element/decorators/query-assigned-elements.js:
39
+ (**
40
+ * @license
41
+ * Copyright 2021 Google LLC
42
+ * SPDX-License-Identifier: BSD-3-Clause
43
+ *)
44
+ */
45
+ //# sourceMappingURL=angel-number-card.js.map