@roxyapi/ui 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/AGENTS.md +169 -0
  2. package/THEMING.md +129 -0
  3. package/dist/cdn/components/biorhythm-chart.js +261 -0
  4. package/dist/cdn/components/biorhythm-chart.js.map +7 -0
  5. package/dist/cdn/components/compatibility-card.js +257 -0
  6. package/dist/cdn/components/compatibility-card.js.map +7 -0
  7. package/dist/cdn/components/dasha-timeline.js +244 -0
  8. package/dist/cdn/components/dasha-timeline.js.map +7 -0
  9. package/dist/cdn/components/data.js +258 -0
  10. package/dist/cdn/components/data.js.map +7 -0
  11. package/dist/cdn/components/dosha-card.js +254 -0
  12. package/dist/cdn/components/dosha-card.js.map +7 -0
  13. package/dist/cdn/components/endpoint-form.js +253 -0
  14. package/dist/cdn/components/endpoint-form.js.map +7 -0
  15. package/dist/cdn/components/guna-milan.js +256 -0
  16. package/dist/cdn/components/guna-milan.js.map +7 -0
  17. package/dist/cdn/components/hexagram.js +275 -0
  18. package/dist/cdn/components/hexagram.js.map +7 -0
  19. package/dist/cdn/components/horoscope-card.js +302 -0
  20. package/dist/cdn/components/horoscope-card.js.map +7 -0
  21. package/dist/cdn/components/kp-planets-table.js +224 -0
  22. package/dist/cdn/components/kp-planets-table.js.map +7 -0
  23. package/dist/cdn/components/location-search.js +267 -0
  24. package/dist/cdn/components/location-search.js.map +7 -0
  25. package/dist/cdn/components/moon-phase.js +251 -0
  26. package/dist/cdn/components/moon-phase.js.map +7 -0
  27. package/dist/cdn/components/natal-chart.js +237 -0
  28. package/dist/cdn/components/natal-chart.js.map +7 -0
  29. package/dist/cdn/components/numerology-card.js +252 -0
  30. package/dist/cdn/components/numerology-card.js.map +7 -0
  31. package/dist/cdn/components/panchang-table.js +234 -0
  32. package/dist/cdn/components/panchang-table.js.map +7 -0
  33. package/dist/cdn/components/synastry-chart.js +303 -0
  34. package/dist/cdn/components/synastry-chart.js.map +7 -0
  35. package/dist/cdn/components/tarot-card.js +260 -0
  36. package/dist/cdn/components/tarot-card.js.map +7 -0
  37. package/dist/cdn/components/tarot-spread.js +261 -0
  38. package/dist/cdn/components/tarot-spread.js.map +7 -0
  39. package/dist/cdn/components/vedic-kundli.js +189 -0
  40. package/dist/cdn/components/vedic-kundli.js.map +7 -0
  41. package/dist/cdn/roxy-ui.js +2552 -0
  42. package/dist/cdn/roxy-ui.js.map +7 -0
  43. package/dist/cdn/widgets.js +114 -0
  44. package/dist/components/biorhythm-chart.d.ts +66 -0
  45. package/dist/components/biorhythm-chart.d.ts.map +1 -0
  46. package/dist/components/biorhythm-chart.js +318 -0
  47. package/dist/components/biorhythm-chart.js.map +7 -0
  48. package/dist/components/compatibility-card.d.ts +46 -0
  49. package/dist/components/compatibility-card.d.ts.map +1 -0
  50. package/dist/components/compatibility-card.js +279 -0
  51. package/dist/components/compatibility-card.js.map +7 -0
  52. package/dist/components/dasha-timeline.d.ts +53 -0
  53. package/dist/components/dasha-timeline.d.ts.map +1 -0
  54. package/dist/components/dasha-timeline.js +269 -0
  55. package/dist/components/dasha-timeline.js.map +7 -0
  56. package/dist/components/data.d.ts +40 -0
  57. package/dist/components/data.d.ts.map +1 -0
  58. package/dist/components/data.js +339 -0
  59. package/dist/components/data.js.map +7 -0
  60. package/dist/components/dosha-card.d.ts +35 -0
  61. package/dist/components/dosha-card.d.ts.map +1 -0
  62. package/dist/components/dosha-card.js +278 -0
  63. package/dist/components/dosha-card.js.map +7 -0
  64. package/dist/components/endpoint-form.d.ts +39 -0
  65. package/dist/components/endpoint-form.d.ts.map +1 -0
  66. package/dist/components/endpoint-form.js +432 -0
  67. package/dist/components/endpoint-form.js.map +7 -0
  68. package/dist/components/guna-milan.d.ts +35 -0
  69. package/dist/components/guna-milan.d.ts.map +1 -0
  70. package/dist/components/guna-milan.js +302 -0
  71. package/dist/components/guna-milan.js.map +7 -0
  72. package/dist/components/hexagram.d.ts +47 -0
  73. package/dist/components/hexagram.d.ts.map +1 -0
  74. package/dist/components/hexagram.js +334 -0
  75. package/dist/components/hexagram.js.map +7 -0
  76. package/dist/components/horoscope-card.d.ts +38 -0
  77. package/dist/components/horoscope-card.d.ts.map +1 -0
  78. package/dist/components/horoscope-card.js +332 -0
  79. package/dist/components/horoscope-card.js.map +7 -0
  80. package/dist/components/kp-planets-table.d.ts +36 -0
  81. package/dist/components/kp-planets-table.d.ts.map +1 -0
  82. package/dist/components/kp-planets-table.js +227 -0
  83. package/dist/components/kp-planets-table.js.map +7 -0
  84. package/dist/components/location-search.d.ts +56 -0
  85. package/dist/components/location-search.d.ts.map +1 -0
  86. package/dist/components/location-search.js +401 -0
  87. package/dist/components/location-search.js.map +7 -0
  88. package/dist/components/moon-phase.d.ts +38 -0
  89. package/dist/components/moon-phase.d.ts.map +1 -0
  90. package/dist/components/moon-phase.js +284 -0
  91. package/dist/components/moon-phase.js.map +7 -0
  92. package/dist/components/natal-chart.d.ts +65 -0
  93. package/dist/components/natal-chart.d.ts.map +1 -0
  94. package/dist/components/natal-chart.js +407 -0
  95. package/dist/components/natal-chart.js.map +7 -0
  96. package/dist/components/numerology-card.d.ts +55 -0
  97. package/dist/components/numerology-card.d.ts.map +1 -0
  98. package/dist/components/numerology-card.js +274 -0
  99. package/dist/components/numerology-card.js.map +7 -0
  100. package/dist/components/panchang-table.d.ts +77 -0
  101. package/dist/components/panchang-table.d.ts.map +1 -0
  102. package/dist/components/panchang-table.js +285 -0
  103. package/dist/components/panchang-table.js.map +7 -0
  104. package/dist/components/synastry-chart.d.ts +52 -0
  105. package/dist/components/synastry-chart.d.ts.map +1 -0
  106. package/dist/components/synastry-chart.js +415 -0
  107. package/dist/components/synastry-chart.js.map +7 -0
  108. package/dist/components/tarot-card.d.ts +47 -0
  109. package/dist/components/tarot-card.d.ts.map +1 -0
  110. package/dist/components/tarot-card.js +281 -0
  111. package/dist/components/tarot-card.js.map +7 -0
  112. package/dist/components/tarot-spread.d.ts +42 -0
  113. package/dist/components/tarot-spread.d.ts.map +1 -0
  114. package/dist/components/tarot-spread.js +271 -0
  115. package/dist/components/tarot-spread.js.map +7 -0
  116. package/dist/components/vedic-kundli.d.ts +45 -0
  117. package/dist/components/vedic-kundli.d.ts.map +1 -0
  118. package/dist/components/vedic-kundli.js +325 -0
  119. package/dist/components/vedic-kundli.js.map +7 -0
  120. package/dist/index.cjs +4174 -0
  121. package/dist/index.cjs.map +7 -0
  122. package/dist/index.d.ts +30 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +4154 -0
  125. package/dist/index.js.map +7 -0
  126. package/dist/manifest.json +24 -0
  127. package/dist/styles/tokens.css +147 -0
  128. package/dist/tokens/index.d.ts +17 -0
  129. package/dist/tokens/index.d.ts.map +1 -0
  130. package/dist/utils/base-styles.d.ts +6 -0
  131. package/dist/utils/base-styles.d.ts.map +1 -0
  132. package/dist/utils/debounce.d.ts +5 -0
  133. package/dist/utils/debounce.d.ts.map +1 -0
  134. package/dist/utils/degree.d.ts +29 -0
  135. package/dist/utils/degree.d.ts.map +1 -0
  136. package/dist/utils/motion.d.ts +13 -0
  137. package/dist/utils/motion.d.ts.map +1 -0
  138. package/package.json +69 -3
  139. package/src/components/biorhythm-chart.ts +290 -0
  140. package/src/components/compatibility-card.ts +231 -0
  141. package/src/components/dasha-timeline.ts +251 -0
  142. package/src/components/data.ts +287 -0
  143. package/src/components/dosha-card.ts +215 -0
  144. package/src/components/endpoint-form.ts +433 -0
  145. package/src/components/guna-milan.ts +245 -0
  146. package/src/components/hexagram.ts +279 -0
  147. package/src/components/horoscope-card.ts +291 -0
  148. package/src/components/kp-planets-table.ts +156 -0
  149. package/src/components/location-search.ts +335 -0
  150. package/src/components/moon-phase.ts +221 -0
  151. package/src/components/natal-chart.ts +298 -0
  152. package/src/components/numerology-card.ts +243 -0
  153. package/src/components/panchang-table.ts +265 -0
  154. package/src/components/synastry-chart.ts +341 -0
  155. package/src/components/tarot-card.ts +235 -0
  156. package/src/components/tarot-spread.ts +224 -0
  157. package/src/components/vedic-kundli.ts +257 -0
  158. package/src/index.ts +61 -0
  159. package/src/styles/tokens.css +147 -0
  160. package/src/tokens/index.ts +130 -0
  161. package/src/types/index.ts +3 -0
  162. package/src/types/types.gen.ts +28526 -0
  163. package/src/utils/base-styles.ts +89 -0
  164. package/src/utils/debounce.ts +13 -0
  165. package/src/utils/degree.ts +64 -0
  166. package/src/utils/motion.ts +18 -0
package/AGENTS.md ADDED
@@ -0,0 +1,169 @@
1
+ # AGENTS.md
2
+
3
+ This file teaches AI coding agents (Claude Code, Cursor, Copilot, Codex, Gemini CLI) how to use Roxy UI when integrating RoxyAPI into a project.
4
+
5
+ ## Identity
6
+
7
+ Roxy UI is the official web component library for the RoxyAPI catalog. Components and helpers cover Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, crystals, dreams, angel numbers, with the location helper for geocoding. New endpoints regenerate component types automatically.
8
+
9
+ ## Decision tree for picking a component
10
+
11
+ Use the table below. Match the user request against the endpoint, render the matching component.
12
+
13
+ <!-- BEGIN:COMPONENTS -->
14
+ | Element | Domain | Endpoint(s) | What it renders |
15
+ |---|---|---|---|
16
+ | `<roxy-natal-chart>` | Western | POST /astrology/natal-chart | Natal chart wheel with planet glyphs and aspect lines |
17
+ | `<roxy-horoscope-card>` | Western | GET /astrology/horoscope/{sign}/{daily,weekly,monthly} | Daily, weekly, or monthly horoscope card |
18
+ | `<roxy-synastry-chart>` | Western | POST /astrology/synastry | Dual-wheel synastry with inter-aspects table |
19
+ | `<roxy-compatibility-card>` | Cross | POST /astrology/compatibility-score, /numerology/compatibility, /biorhythm/compatibility | Score card with category breakdown |
20
+ | `<roxy-moon-phase>` | Western | GET /astrology/moon-phase/{current,upcoming,calendar/...} | Moon phase card and calendar |
21
+ | `<roxy-vedic-kundli>` | Vedic | POST /vedic-astrology/birth-chart | South or North Indian kundli |
22
+ | `<roxy-panchang-table>` | Vedic | POST /vedic-astrology/panchang/{basic,detailed} | 15+ muhurtas in detailed mode |
23
+ | `<roxy-dasha-timeline>` | Vedic | POST /vedic-astrology/dasha/{current,major,sub/...} | Vimshottari mahadasha + antardasha + pratyantardasha |
24
+ | `<roxy-dosha-card>` | Vedic | POST /vedic-astrology/dosha/{manglik,kalsarpa,sadhesati} | Presence, severity, remedies, scoped effects |
25
+ | `<roxy-guna-milan>` | Vedic | POST /vedic-astrology/compatibility | 36-point Ashtakoota with eight sub-scores |
26
+ | `<roxy-kp-planets-table>` | Vedic (KP) | POST /vedic-astrology/kp/planets | Sub-lord and sub-sub-lord columns |
27
+ | `<roxy-numerology-card>` | Numerology | POST /numerology/{life-path,expression,personal-year,chart} | Life path, expression, personal year, full chart |
28
+ | `<roxy-tarot-card>` | Tarot | GET /tarot/cards/{id}, POST /tarot/daily | Single card with upright and reversed flip |
29
+ | `<roxy-tarot-spread>` | Tarot | POST /tarot/spreads/{three-card,celtic-cross,love}, /tarot/yes-no, /tarot/draw | Spreads with positions and reading |
30
+ | `<roxy-biorhythm-chart>` | Biorhythm | POST /biorhythm/{daily,forecast,critical-days} | Daily bars, forecast cycle lines, critical days |
31
+ | `<roxy-hexagram>` | I Ching | GET /iching/hexagrams/{number}, /iching/cast, POST /iching/daily, /iching/daily/cast | Hexagram with trigrams, judgment, image, changing lines |
32
+ | `<roxy-endpoint-form>` | Helper | Any endpoint via x-roxy-ui hints | Schema-driven form, emits roxy-submit |
33
+ | `<roxy-location-search>` | Helper | GET /location/search | Debounced city search input, emits roxy-location-select |
34
+ | `<roxy-data>` | Helper | Any response shape | Generic fallback renderer for unknown shapes |
35
+ <!-- END:COMPONENTS -->
36
+
37
+ ## Integration patterns
38
+
39
+ ### Pattern 1: vanilla HTML, no build step
40
+
41
+ ```html
42
+ <script
43
+ src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@1/dist/cdn/roxy-ui.js"
44
+ crossorigin="anonymous"
45
+ ></script>
46
+
47
+ <roxy-natal-chart id="chart"></roxy-natal-chart>
48
+
49
+ <script type="module">
50
+ const res = await fetch('https://roxyapi.com/api/v2/astrology/natal-chart', {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json', 'X-API-Key': 'roxy_xxx' },
53
+ body: JSON.stringify({
54
+ date: '1990-01-15',
55
+ time: '14:30:00',
56
+ latitude: 28.6139,
57
+ longitude: 77.209,
58
+ timezone: 5.5,
59
+ }),
60
+ });
61
+ const data = await res.json();
62
+ document.getElementById('chart').data = data;
63
+ </script>
64
+ ```
65
+
66
+ ### Pattern 2: React, with the typed SDK
67
+
68
+ ```tsx
69
+ import { createRoxy } from '@roxyapi/sdk';
70
+ import { RoxyNatalChart, RoxyLocationSearch } from '@roxyapi/ui-react';
71
+ import { useState } from 'react';
72
+
73
+ const roxy = createRoxy(process.env.NEXT_PUBLIC_ROXY_API_KEY!);
74
+
75
+ export function BirthChartView() {
76
+ const [chart, setChart] = useState(null);
77
+
78
+ const onLocationSelect = async (e: CustomEvent<{ latitude: number; longitude: number; timezone: string }>) => {
79
+ const { data } = await roxy.astrology.generateNatalChart({
80
+ body: { date: '1990-01-15', time: '14:30:00', ...e.detail },
81
+ });
82
+ setChart(data);
83
+ };
84
+
85
+ return (
86
+ <div>
87
+ <RoxyLocationSearch onroxy-location-select={onLocationSelect} />
88
+ {chart && <RoxyNatalChart data={chart} />}
89
+ </div>
90
+ );
91
+ }
92
+ ```
93
+
94
+ ### Pattern 3: schema-driven form
95
+
96
+ `<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint. Listen for the `roxy-submit` event with the validated payload.
97
+
98
+ ```html
99
+ <roxy-endpoint-form
100
+ data-endpoint="vedic-astrology/birth-chart"
101
+ method="POST"
102
+ submit-label="Generate kundli"
103
+ ></roxy-endpoint-form>
104
+
105
+ <script type="module">
106
+ const form = document.querySelector('roxy-endpoint-form');
107
+ form.addEventListener('roxy-submit', async (e) => {
108
+ const { endpoint, values } = e.detail;
109
+ const res = await fetch(`https://roxyapi.com/api/v2/${endpoint}`, {
110
+ method: 'POST',
111
+ headers: { 'Content-Type': 'application/json', 'X-API-Key': 'roxy_xxx' },
112
+ body: JSON.stringify(values),
113
+ });
114
+ const kundli = await res.json();
115
+ document.querySelector('roxy-vedic-kundli').data = kundli;
116
+ });
117
+ </script>
118
+ ```
119
+
120
+ ### Pattern 4: widgets auto-mount (no JavaScript wiring)
121
+
122
+ Use the publishable key flow for vibecoder embeds.
123
+
124
+ ```html
125
+ <script
126
+ src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@1/dist/cdn/widgets.js"
127
+ defer
128
+ ></script>
129
+
130
+ <div
131
+ data-roxy-widget="natal-chart"
132
+ data-publishable-key="pk_live_xxx"
133
+ data-date="1990-01-15"
134
+ data-time="14:30:00"
135
+ data-latitude="28.6139"
136
+ data-longitude="77.209"
137
+ data-timezone="5.5"
138
+ ></div>
139
+ ```
140
+
141
+ The auto-mount script reads `data-*` attributes, calls the matching endpoint, and renders the matching component.
142
+
143
+ ## Rules every agent must follow
144
+
145
+ - Always call `/location/search` first before any chart endpoint that takes latitude, longitude, or timezone. Use `<roxy-location-search>` for the input UI.
146
+ - Pass the response object directly. Components are stateless; they do not fetch internally except for `<roxy-location-search>`, `<roxy-endpoint-form>`, and the widgets auto-mount script.
147
+ - Use the typed SDK from `@roxyapi/sdk` so prop shapes match the spec automatically.
148
+ - Theming is CSS custom properties on `:root` or per element. Do not write Tailwind classes inside the components; the shadow DOM ignores them.
149
+ - Honor reduced motion. The library already respects `prefers-reduced-motion: reduce` and the `--roxy-motion-duration` variable.
150
+ - A11y violations are CI failures. Do not paste over `role` or `aria-*` attributes; the components emit them correctly already.
151
+
152
+ ## Domain ordering
153
+
154
+ 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.
155
+
156
+ ## What not to ship
157
+
158
+ - Do not bundle `@roxyapi/ui` and `@roxyapi/ui-react` together; they are decoupled by design.
159
+ - Use `@roxyapi/ui-react` for React projects. Use `@roxyapi/ui` directly elsewhere.
160
+ - Do not write your own kundli component. The lifted layout in `<roxy-vedic-kundli>` is the canonical RoxyAPI render path.
161
+ - Do not call astrology endpoints with hardcoded coordinates. Always geocode first via `<roxy-location-search>` or `roxy.location.searchCities()`.
162
+
163
+ ## Where to look next
164
+
165
+ - Component source: `packages/ui/src/components/`
166
+ - Sample data for every component: `apps/docs/sample-data.js`
167
+ - Token reference: `packages/ui/THEMING.md`
168
+ - Live preview: `bun run preview` then open `http://localhost:3001`
169
+ - Money endpoints reference: see the RoxyAPI methodology page at `roxyapi.com/methodology`
package/THEMING.md ADDED
@@ -0,0 +1,129 @@
1
+ # Theming Roxy UI
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.
4
+
5
+ ## Token reference
6
+
7
+ ### Color
8
+
9
+ | Variable | Light default | Dark default | Used by |
10
+ |---|---|---|---|
11
+ | `--roxy-primary` | `#0f172a` | `#f8fafc` | Headings, primary text |
12
+ | `--roxy-secondary` | `#475569` | `#94a3b8` | Subheadings, muted accents |
13
+ | `--roxy-accent` | `#f59e0b` | `#fbbf24` | Planet glyphs, hexagram lines, focused state |
14
+ | `--roxy-success` | `#16a34a` | `#22c55e` | Positive doshas, biorhythm peaks |
15
+ | `--roxy-warning` | `#ea580c` | `#fb923c` | Caution states, mid severity |
16
+ | `--roxy-danger` | `#dc2626` | `#ef4444` | Manglik present, critical days |
17
+ | `--roxy-info` | `#0284c7` | `#38bdf8` | Informational badges |
18
+ | `--roxy-bg` | `#ffffff` | `#0a0a0a` | Card and chart backgrounds |
19
+ | `--roxy-fg` | `#0a0a0a` | `#fafafa` | Body text |
20
+ | `--roxy-muted` | `#71717a` | `#a1a1aa` | Secondary text |
21
+ | `--roxy-border` | `#e4e4e7` | `#27272a` | Wheel lines, table borders |
22
+ | `--roxy-ring` | `rgba(245, 158, 11, 0.4)` | `rgba(251, 191, 36, 0.45)` | Focus outlines |
23
+
24
+ ### Typography
25
+
26
+ | Variable | Default | Notes |
27
+ |---|---|---|
28
+ | `--roxy-font-sans` | `Geist, system-ui, ...` | Body and headings |
29
+ | `--roxy-font-mono` | `Geist Mono, ui-monospace, ...` | Numeric tables, code |
30
+ | `--roxy-text-xs` | `0.75rem` | Captions |
31
+ | `--roxy-text-sm` | `0.875rem` | Body small |
32
+ | `--roxy-text-base` | `1rem` | Body |
33
+ | `--roxy-text-lg` | `1.125rem` | Subheading |
34
+ | `--roxy-text-xl` | `1.5rem` | Heading |
35
+ | `--roxy-weight-normal` | `400` | Body |
36
+ | `--roxy-weight-bold` | `600` | Heading |
37
+ | `--roxy-leading-tight` | `1.2` | Heading |
38
+ | `--roxy-leading-normal` | `1.5` | Body |
39
+ | `--roxy-tracking-tight` | `-0.02em` | Heading |
40
+ | `--roxy-tracking-normal` | `0em` | Body |
41
+
42
+ ### Spacing
43
+
44
+ | Variable | Default |
45
+ |---|---|
46
+ | `--roxy-space-xs` | `0.25rem` |
47
+ | `--roxy-space-sm` | `0.5rem` |
48
+ | `--roxy-space-md` | `1rem` |
49
+ | `--roxy-space-lg` | `1.5rem` |
50
+ | `--roxy-space-xl` | `2.5rem` |
51
+
52
+ ### Radius
53
+
54
+ | Variable | Default |
55
+ |---|---|
56
+ | `--roxy-radius-sm` | `4px` |
57
+ | `--roxy-radius-md` | `8px` |
58
+ | `--roxy-radius-lg` | `12px` |
59
+ | `--roxy-radius-full` | `9999px` |
60
+
61
+ ### Shadow
62
+
63
+ | Variable | Default |
64
+ |---|---|
65
+ | `--roxy-shadow-sm` | `0 1px 2px rgba(0, 0, 0, 0.06)` |
66
+ | `--roxy-shadow-md` | `0 4px 6px -1px rgba(0, 0, 0, 0.08), ...` |
67
+ | `--roxy-shadow-lg` | `0 12px 24px -8px rgba(0, 0, 0, 0.14)` |
68
+
69
+ ### Motion
70
+
71
+ | Variable | Default | Notes |
72
+ |---|---|---|
73
+ | `--roxy-motion-duration` | `200ms` | Set to `0ms` to disable transitions and entry animations |
74
+ | `--roxy-motion-easing` | `cubic-bezier(0.4, 0, 0.2, 1)` | Standard ease |
75
+
76
+ `prefers-reduced-motion: reduce` always pins duration to `0ms`. Honor this by default.
77
+
78
+ ## Patterns
79
+
80
+ ### Brand the whole library
81
+
82
+ ```css
83
+ :root {
84
+ --roxy-accent: #6d28d9;
85
+ --roxy-radius-md: 12px;
86
+ --roxy-font-sans: 'Inter', system-ui;
87
+ }
88
+ ```
89
+
90
+ ### Brand one component
91
+
92
+ ```css
93
+ roxy-natal-chart {
94
+ --roxy-accent: #d946ef;
95
+ --roxy-border: #f0abfc;
96
+ }
97
+ ```
98
+
99
+ ### Dark mode
100
+
101
+ Three opt-in mechanisms work out of the box.
102
+
103
+ ```css
104
+ /* System preference: nothing to do */
105
+
106
+ /* data-theme on the document */
107
+ :root[data-theme='dark'] { /* automatic */ }
108
+
109
+ /* Tailwind dark class on an ancestor */
110
+ .dark roxy-natal-chart { /* automatic */ }
111
+ ```
112
+
113
+ ### Map Tailwind tokens
114
+
115
+ Tailwind users can map our tokens to theirs in five lines of `globals.css`:
116
+
117
+ ```css
118
+ :root {
119
+ --roxy-bg: theme(colors.background);
120
+ --roxy-fg: theme(colors.foreground);
121
+ --roxy-accent: theme(colors.primary.DEFAULT);
122
+ --roxy-border: theme(colors.border);
123
+ --roxy-radius-md: theme(borderRadius.md);
124
+ }
125
+ ```
126
+
127
+ ## A11y
128
+
129
+ Color contrast must stay at 4.5:1 minimum against `--roxy-bg` for body text and 3:1 for large text. The defaults pass WCAG AA. Verify any custom palette with the axe Chrome extension or any contrast checker before shipping.
@@ -0,0 +1,261 @@
1
+ "use strict";var RoxyUI_biorhythm_chart=(()=>{var T=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var wt=Object.getOwnPropertyNames;var Ct=Object.prototype.hasOwnProperty;var Pt=(i,t)=>{for(var e in t)T(i,e,{get:t[e],enumerable:!0})},Dt=(i,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of wt(t))!Ct.call(i,r)&&r!==e&&T(i,r,{get:()=>t[r],enumerable:!(s=rt(t,r))||s.enumerable});return i};var Ot=i=>Dt(T({},"__esModule",{value:!0}),i),H=(i,t,e,s)=>{for(var r=s>1?void 0:s?rt(t,e):t,o=i.length-1,n;o>=0;o--)(n=i[o])&&(r=(s?n(t,e,r):n(r))||r);return s&&r&&T(t,e,r),r};var Wt={};Pt(Wt,{RoxyBiorhythmChart:()=>v});var j=globalThis,z=j.ShadowRoot&&(j.ShadyCSS===void 0||j.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,V=Symbol(),it=new WeakMap,C=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==V)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o,e=this.t;if(z&&t===void 0){let s=e!==void 0&&e.length===1;s&&(t=it.get(e)),t===void 0&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),s&&it.set(e,t))}return t}toString(){return this.cssText}},ot=i=>new C(typeof i=="string"?i:i+"",void 0,V),P=(i,...t)=>{let e=i.length===1?i[0]:t.reduce((s,r,o)=>s+(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.")})(r)+i[o+1],i[0]);return new C(e,i,V)},nt=(i,t)=>{if(z)i.adoptedStyleSheets=t.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let e of t){let s=document.createElement("style"),r=j.litNonce;r!==void 0&&s.setAttribute("nonce",r),s.textContent=e.cssText,i.appendChild(s)}},W=z?i=>i:i=>i instanceof CSSStyleSheet?(t=>{let e="";for(let s of t.cssRules)e+=s.cssText;return ot(e)})(i):i;var{is:Ut,defineProperty:kt,getOwnPropertyDescriptor:Rt,getOwnPropertyNames:Mt,getOwnPropertySymbols:Nt,getPrototypeOf:Tt}=Object,B=globalThis,at=B.trustedTypes,Ht=at?at.emptyScript:"",jt=B.reactiveElementPolyfillSupport,D=(i,t)=>i,O={toAttribute(i,t){switch(t){case Boolean:i=i?Ht:null;break;case Object:case Array:i=i==null?i:JSON.stringify(i)}return i},fromAttribute(i,t){let e=i;switch(t){case Boolean:e=i!==null;break;case Number:e=i===null?null:Number(i);break;case Object:case Array:try{e=JSON.parse(i)}catch{e=null}}return e}},L=(i,t)=>!Ut(i,t),ct={attribute:!0,type:String,converter:O,reflect:!1,useDefault:!1,hasChanged:L};Symbol.metadata??=Symbol("metadata"),B.litPropertyMetadata??=new WeakMap;var f=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=ct){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){let s=Symbol(),r=this.getPropertyDescriptor(t,s,e);r!==void 0&&kt(this.prototype,t,r)}}static getPropertyDescriptor(t,e,s){let{get:r,set:o}=Rt(this.prototype,t)??{get(){return this[e]},set(n){this[e]=n}};return{get:r,set(n){let c=r?.call(this);o?.call(this,n),this.requestUpdate(t,c,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??ct}static _$Ei(){if(this.hasOwnProperty(D("elementProperties")))return;let t=Tt(this);t.finalize(),t.l!==void 0&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(D("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(D("properties"))){let e=this.properties,s=[...Mt(e),...Nt(e)];for(let r of s)this.createProperty(r,e[r])}let t=this[Symbol.metadata];if(t!==null){let e=litPropertyMetadata.get(t);if(e!==void 0)for(let[s,r]of e)this.elementProperties.set(s,r)}this._$Eh=new Map;for(let[e,s]of this.elementProperties){let r=this._$Eu(e,s);r!==void 0&&this._$Eh.set(r,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){let e=[];if(Array.isArray(t)){let s=new Set(t.flat(1/0).reverse());for(let r of s)e.unshift(W(r))}else t!==void 0&&e.push(W(t));return e}static _$Eu(t,e){let s=e.attribute;return s===!1?void 0:typeof s=="string"?s:typeof t=="string"?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),this.renderRoot!==void 0&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){let t=new Map,e=this.constructor.elementProperties;for(let s of e.keys())this.hasOwnProperty(s)&&(t.set(s,this[s]),delete this[s]);t.size>0&&(this._$Ep=t)}createRenderRoot(){let t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return nt(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,s){this._$AK(t,s)}_$ET(t,e){let s=this.constructor.elementProperties.get(t),r=this.constructor._$Eu(t,s);if(r!==void 0&&s.reflect===!0){let o=(s.converter?.toAttribute!==void 0?s.converter:O).toAttribute(e,s.type);this._$Em=t,o==null?this.removeAttribute(r):this.setAttribute(r,o),this._$Em=null}}_$AK(t,e){let s=this.constructor,r=s._$Eh.get(t);if(r!==void 0&&this._$Em!==r){let o=s.getPropertyOptions(r),n=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:O;this._$Em=r;let c=n.fromAttribute(e,o.type);this[r]=c??this._$Ej?.get(r)??c,this._$Em=null}}requestUpdate(t,e,s,r=!1,o){if(t!==void 0){let n=this.constructor;if(r===!1&&(o=this[t]),s??=n.getPropertyOptions(t),!((s.hasChanged??L)(o,e)||s.useDefault&&s.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(n._$Eu(t,s))))return;this.C(t,e,s)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(t,e,{useDefault:s,reflect:r,wrapped:o},n){s&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,n??e??this[t]),o!==!0||n!==void 0)||(this._$AL.has(t)||(this.hasUpdated||s||(e=void 0),this._$AL.set(t,e)),r===!0&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let t=this.scheduleUpdate();return t!=null&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[r,o]of this._$Ep)this[r]=o;this._$Ep=void 0}let s=this.constructor.elementProperties;if(s.size>0)for(let[r,o]of s){let{wrapped:n}=o,c=this[r];n!==!0||this._$AL.has(r)||c===void 0||this.C(r,void 0,o,c)}}let t=!1,e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(s=>s.hostUpdate?.()),this.update(e)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(t){}firstUpdated(t){}};f.elementStyles=[],f.shadowRootOptions={mode:"open"},f[D("elementProperties")]=new Map,f[D("finalized")]=new Map,jt?.({ReactiveElement:f}),(B.reactiveElementVersions??=[]).push("2.1.2");var X=globalThis,lt=i=>i,q=X.trustedTypes,ht=q?q.createPolicy("lit-html",{createHTML:i=>i}):void 0,ft="$lit$",g=`lit$${Math.random().toFixed(9).slice(2)}$`,gt="?"+g,zt=`<${gt}>`,x=document,k=()=>x.createComment(""),R=i=>i===null||typeof i!="object"&&typeof i!="function",tt=Array.isArray,Bt=i=>tt(i)||typeof i?.[Symbol.iterator]=="function",K=`[
2
+ \f\r]`,U=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,dt=/-->/g,pt=/>/g,_=RegExp(`>|${K}(?:([^\\s"'>=/]+)(${K}*=${K}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),ut=/'/g,mt=/"/g,$t=/^(?:script|style|textarea|title)$/i,et=i=>(t,...e)=>({_$litType$:i,strings:t,values:e}),u=et(1),vt=et(2),Qt=et(3),A=Symbol.for("lit-noChange"),h=Symbol.for("lit-nothing"),yt=new WeakMap,b=x.createTreeWalker(x,129);function _t(i,t){if(!tt(i)||!i.hasOwnProperty("raw"))throw Error("invalid template strings array");return ht!==void 0?ht.createHTML(t):t}var Lt=(i,t)=>{let e=i.length-1,s=[],r,o=t===2?"<svg>":t===3?"<math>":"",n=U;for(let c=0;c<e;c++){let a=i[c],d,p,l=-1,m=0;for(;m<a.length&&(n.lastIndex=m,p=n.exec(a),p!==null);)m=n.lastIndex,n===U?p[1]==="!--"?n=dt:p[1]!==void 0?n=pt:p[2]!==void 0?($t.test(p[2])&&(r=RegExp("</"+p[2],"g")),n=_):p[3]!==void 0&&(n=_):n===_?p[0]===">"?(n=r??U,l=-1):p[1]===void 0?l=-2:(l=n.lastIndex-p[2].length,d=p[1],n=p[3]===void 0?_:p[3]==='"'?mt:ut):n===mt||n===ut?n=_:n===dt||n===pt?n=U:(n=_,r=void 0);let y=n===_&&i[c+1].startsWith("/>")?" ":"";o+=n===U?a+zt:l>=0?(s.push(d),a.slice(0,l)+ft+a.slice(l)+g+y):a+g+(l===-2?c:y)}return[_t(i,o+(i[e]||"<?>")+(t===2?"</svg>":t===3?"</math>":"")),s]},M=class i{constructor({strings:t,_$litType$:e},s){let r;this.parts=[];let o=0,n=0,c=t.length-1,a=this.parts,[d,p]=Lt(t,e);if(this.el=i.createElement(d,s),b.currentNode=this.el.content,e===2||e===3){let l=this.el.content.firstChild;l.replaceWith(...l.childNodes)}for(;(r=b.nextNode())!==null&&a.length<c;){if(r.nodeType===1){if(r.hasAttributes())for(let l of r.getAttributeNames())if(l.endsWith(ft)){let m=p[n++],y=r.getAttribute(l).split(g),S=/([.?@])?(.*)/.exec(m);a.push({type:1,index:o,name:S[2],strings:y,ctor:S[1]==="."?J:S[1]==="?"?Z:S[1]==="@"?G:w}),r.removeAttribute(l)}else l.startsWith(g)&&(a.push({type:6,index:o}),r.removeAttribute(l));if($t.test(r.tagName)){let l=r.textContent.split(g),m=l.length-1;if(m>0){r.textContent=q?q.emptyScript:"";for(let y=0;y<m;y++)r.append(l[y],k()),b.nextNode(),a.push({type:2,index:++o});r.append(l[m],k())}}}else if(r.nodeType===8)if(r.data===gt)a.push({type:2,index:o});else{let l=-1;for(;(l=r.data.indexOf(g,l+1))!==-1;)a.push({type:7,index:o}),l+=g.length-1}o++}}static createElement(t,e){let s=x.createElement("template");return s.innerHTML=t,s}};function E(i,t,e=i,s){if(t===A)return t;let r=s!==void 0?e._$Co?.[s]:e._$Cl,o=R(t)?void 0:t._$litDirective$;return r?.constructor!==o&&(r?._$AO?.(!1),o===void 0?r=void 0:(r=new o(i),r._$AT(i,e,s)),s!==void 0?(e._$Co??=[])[s]=r:e._$Cl=r),r!==void 0&&(t=E(i,r._$AS(i,t.values),r,s)),t}var Y=class{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){let{el:{content:e},parts:s}=this._$AD,r=(t?.creationScope??x).importNode(e,!0);b.currentNode=r;let o=b.nextNode(),n=0,c=0,a=s[0];for(;a!==void 0;){if(n===a.index){let d;a.type===2?d=new N(o,o.nextSibling,this,t):a.type===1?d=new a.ctor(o,a.name,a.strings,this,t):a.type===6&&(d=new Q(o,this,t)),this._$AV.push(d),a=s[++c]}n!==a?.index&&(o=b.nextNode(),n++)}return b.currentNode=x,r}p(t){let e=0;for(let s of this._$AV)s!==void 0&&(s.strings!==void 0?(s._$AI(t,s,e),e+=s.strings.length-2):s._$AI(t[e])),e++}},N=class i{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,s,r){this.type=2,this._$AH=h,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=s,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode,e=this._$AM;return e!==void 0&&t?.nodeType===11&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=E(this,t,e),R(t)?t===h||t==null||t===""?(this._$AH!==h&&this._$AR(),this._$AH=h):t!==this._$AH&&t!==A&&this._(t):t._$litType$!==void 0?this.$(t):t.nodeType!==void 0?this.T(t):Bt(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==h&&R(this._$AH)?this._$AA.nextSibling.data=t:this.T(x.createTextNode(t)),this._$AH=t}$(t){let{values:e,_$litType$:s}=t,r=typeof s=="number"?this._$AC(t):(s.el===void 0&&(s.el=M.createElement(_t(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(e);else{let o=new Y(r,this),n=o.u(this.options);o.p(e),this.T(n),this._$AH=o}}_$AC(t){let e=yt.get(t.strings);return e===void 0&&yt.set(t.strings,e=new M(t)),e}k(t){tt(this._$AH)||(this._$AH=[],this._$AR());let e=this._$AH,s,r=0;for(let o of t)r===e.length?e.push(s=new i(this.O(k()),this.O(k()),this,this.options)):s=e[r],s._$AI(o),r++;r<e.length&&(this._$AR(s&&s._$AB.nextSibling,r),e.length=r)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t!==this._$AB;){let s=lt(t).nextSibling;lt(t).remove(),t=s}}setConnected(t){this._$AM===void 0&&(this._$Cv=t,this._$AP?.(t))}},w=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,s,r,o){this.type=1,this._$AH=h,this._$AN=void 0,this.element=t,this.name=e,this._$AM=r,this.options=o,s.length>2||s[0]!==""||s[1]!==""?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=h}_$AI(t,e=this,s,r){let o=this.strings,n=!1;if(o===void 0)t=E(this,t,e,0),n=!R(t)||t!==this._$AH&&t!==A,n&&(this._$AH=t);else{let c=t,a,d;for(t=o[0],a=0;a<o.length-1;a++)d=E(this,c[s+a],e,a),d===A&&(d=this._$AH[a]),n||=!R(d)||d!==this._$AH[a],d===h?t=h:t!==h&&(t+=(d??"")+o[a+1]),this._$AH[a]=d}n&&!r&&this.j(t)}j(t){t===h?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}},J=class extends w{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===h?void 0:t}},Z=class extends w{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==h)}},G=class extends w{constructor(t,e,s,r,o){super(t,e,s,r,o),this.type=5}_$AI(t,e=this){if((t=E(this,t,e,0)??h)===A)return;let s=this._$AH,r=t===h&&s!==h||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,o=t!==h&&(s===h||r);r&&this.element.removeEventListener(this.name,this,s),o&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}},Q=class{constructor(t,e,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){E(this,t)}};var qt=X.litHtmlPolyfillSupport;qt?.(M,N),(X.litHtmlVersions??=[]).push("3.3.2");var bt=(i,t,e)=>{let s=e?.renderBefore??t,r=s._$litPart$;if(r===void 0){let o=e?.renderBefore??null;s._$litPart$=r=new N(t.insertBefore(k(),o),o,void 0,e??{})}return r._$AI(i),r};var st=globalThis,$=class extends f{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=bt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return A}};$._$litElement$=!0,$.finalized=!0,st.litElementHydrateSupport?.({LitElement:$});var It=st.litElementPolyfillSupport;It?.({LitElement:$});(st.litElementVersions??=[]).push("4.2.2");var xt=i=>(t,e)=>{e!==void 0?e.addInitializer(()=>{customElements.define(i,t)}):customElements.define(i,t)};var Ft={attribute:!0,type:String,converter:O,reflect:!1,hasChanged:L},Vt=(i=Ft,t,e)=>{let{kind:s,metadata:r}=e,o=globalThis.litPropertyMetadata.get(r);if(o===void 0&&globalThis.litPropertyMetadata.set(r,o=new Map),s==="setter"&&((i=Object.create(i)).wrapped=!0),o.set(e.name,i),s==="accessor"){let{name:n}=e;return{set(c){let a=t.get.call(this);t.set.call(this,c),this.requestUpdate(n,a,i,!0,c)},init(c){return c!==void 0&&this.C(n,void 0,i,c),c}}}if(s==="setter"){let{name:n}=e;return function(c){let a=this[n];t.call(this,c),this.requestUpdate(n,a,i,!0,c)}}throw Error("Unsupported decorator location: "+s)};function I(i){return(t,e)=>typeof e=="object"?Vt(i,t,e):((s,r,o)=>{let n=r.hasOwnProperty(o);return r.constructor.createProperty(o,s),n?Object.getOwnPropertyDescriptor(r,o):void 0})(i,t,e)}var At=P`
4
+ :host {
5
+ display: block;
6
+ container-type: inline-size;
7
+ font-family: var(
8
+ --roxy-font-sans,
9
+ system-ui,
10
+ -apple-system,
11
+ BlinkMacSystemFont,
12
+ 'Segoe UI',
13
+ Roboto,
14
+ sans-serif
15
+ );
16
+ color: var(--roxy-fg, #0a0a0a);
17
+ background: transparent;
18
+ font-size: var(--roxy-text-base, 1rem);
19
+ line-height: var(--roxy-leading-normal, 1.5);
20
+ animation: roxy-fade-in var(--roxy-motion-duration, 200ms)
21
+ var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1)) both;
22
+ }
23
+
24
+ *,
25
+ *::before,
26
+ *::after {
27
+ box-sizing: border-box;
28
+ }
29
+
30
+ @keyframes roxy-fade-in {
31
+ from {
32
+ opacity: 0;
33
+ transform: translateY(2px);
34
+ }
35
+ to {
36
+ opacity: 1;
37
+ transform: translateY(0);
38
+ }
39
+ }
40
+
41
+ @media (prefers-reduced-motion: reduce) {
42
+ :host {
43
+ animation: none;
44
+ }
45
+ }
46
+
47
+ .roxy-skeleton {
48
+ background: linear-gradient(
49
+ 90deg,
50
+ var(--roxy-border, #e4e4e7) 0%,
51
+ color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent) 50%,
52
+ var(--roxy-border, #e4e4e7) 100%
53
+ );
54
+ background-size: 200% 100%;
55
+ animation: roxy-shimmer 1.4s ease-in-out infinite;
56
+ border-radius: var(--roxy-radius-md, 8px);
57
+ }
58
+
59
+ @keyframes roxy-shimmer {
60
+ 0% {
61
+ background-position: 200% 0;
62
+ }
63
+ 100% {
64
+ background-position: -200% 0;
65
+ }
66
+ }
67
+
68
+ @media (prefers-reduced-motion: reduce) {
69
+ .roxy-skeleton {
70
+ animation: none;
71
+ }
72
+ }
73
+
74
+ .roxy-empty {
75
+ padding: var(--roxy-space-lg, 1.5rem);
76
+ color: var(--roxy-muted, #71717a);
77
+ text-align: center;
78
+ font-size: var(--roxy-text-sm, 0.875rem);
79
+ }
80
+
81
+ :host(:focus-within) .roxy-card {
82
+ outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
83
+ outline-offset: 2px;
84
+ }
85
+ `;var St={physical:"#dc2626",emotional:"#0284c7",intellectual:"#16a34a",intuitive:"#a855f7",aesthetic:"#f59e0b",awareness:"#ec4899",spiritual:"#14b8a6",passion:"#ef4444",mastery:"#6366f1",wisdom:"#475569"},v=class extends ${constructor(){super(...arguments);this.data=null;this.mode="daily"}render(){let e=this.data;return e?this.mode==="critical-days"&&e.criticalDays?.length?this.renderCritical(e):this.mode==="forecast"&&e.days?.length?this.renderForecast(e):this.renderDaily(e):u`<div class="roxy-empty" role="status">No biorhythm data</div>`}renderDaily(e){let s=e.cycles??{},r=Object.entries(s);return u`<section class="wrap" aria-label="Daily biorhythm">
86
+ <header class="head">
87
+ <h2 class="title">Biorhythm</h2>
88
+ ${typeof e.energyRating=="number"?u`<span class="energy">Energy ${e.energyRating}/10</span>`:h}
89
+ </header>
90
+ <div class="bars" role="list">
91
+ ${r.map(([o,n])=>{let c=typeof n=="number"?n:0,a=(c+1)/2*100,d=St[o]??"var(--roxy-accent, #f59e0b)";return u`<div class="bar" role="listitem">
92
+ <span style="text-transform: capitalize">${o}</span>
93
+ <span class="track">
94
+ <span
95
+ class="fill"
96
+ style="width: ${a}%; background: ${d}"
97
+ ></span>
98
+ </span>
99
+ <span class="value">${(c*100).toFixed(0)}%</span>
100
+ </div>`})}
101
+ </div>
102
+ ${e.interpretation?u`<p class="advice">${e.interpretation}</p>`:h}
103
+ ${e.advice?u`<p class="advice">${e.advice}</p>`:h}
104
+ ${e.criticalAlerts?.length?u`<div>
105
+ ${e.criticalAlerts.map(o=>u`<p class="alert">${o}</p>`)}
106
+ </div>`:h}
107
+ </section>`}renderForecast(e){let s=e.days??[];if(s.length===0)return u`<div class="roxy-empty" role="status">No forecast</div>`;let r=600,o=160,n=r/Math.max(s.length-1,1),c=Object.keys(s[0]?.cycles??{});return u`<section class="wrap" aria-label="Biorhythm forecast">
108
+ <header class="head">
109
+ <h2 class="title">Forecast</h2>
110
+ <span class="energy"
111
+ >${e.startDate??""} - ${e.endDate??""}</span
112
+ >
113
+ </header>
114
+ <svg
115
+ viewBox="0 0 ${r} ${o}"
116
+ role="img"
117
+ aria-label="Biorhythm cycle lines across the forecast window"
118
+ >
119
+ <title>Biorhythm forecast</title>
120
+ <line
121
+ x1="0"
122
+ y1=${o/2}
123
+ x2=${r}
124
+ y2=${o/2}
125
+ stroke="var(--roxy-border, #e4e4e7)"
126
+ stroke-width="1"
127
+ />
128
+ ${c.map(a=>{let d=s.map((l,m)=>{let y=l.cycles?.[a]??0,S=m*n,Et=o/2-y*(o/2-8);return`${S.toFixed(2)},${Et.toFixed(2)}`}).join(" "),p=St[a]??"#475569";return vt`<polyline points=${d} fill="none" stroke=${p} stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />`})}
129
+ </svg>
130
+ ${e.summary?.periodAdvice?u`<p class="advice">${e.summary.periodAdvice}</p>`:h}
131
+ </section>`}renderCritical(e){return u`<section class="wrap" aria-label="Critical days">
132
+ <header class="head">
133
+ <h2 class="title">Critical days</h2>
134
+ <span class="energy"
135
+ >${e.totalCriticalDays??e.criticalDays?.length??0} total</span
136
+ >
137
+ </header>
138
+ <div>
139
+ ${(e.criticalDays??[]).map(s=>u`<span class="crit"
140
+ >${s.date} · ${s.cycle??""} ${s.severity??""}</span
141
+ >`)}
142
+ </div>
143
+ </section>`}};v.styles=[At,P`
144
+ .wrap {
145
+ display: grid;
146
+ gap: var(--roxy-space-md, 1rem);
147
+ }
148
+ .head {
149
+ display: flex;
150
+ justify-content: space-between;
151
+ align-items: center;
152
+ flex-wrap: wrap;
153
+ gap: var(--roxy-space-sm, 0.5rem);
154
+ }
155
+ .title {
156
+ margin: 0;
157
+ font-size: var(--roxy-text-lg, 1.125rem);
158
+ font-weight: var(--roxy-weight-bold, 600);
159
+ }
160
+ .energy {
161
+ font-variant-numeric: tabular-nums;
162
+ color: var(--roxy-accent-fg, #b45309);
163
+ font-weight: var(--roxy-weight-bold, 600);
164
+ }
165
+ .bars {
166
+ display: grid;
167
+ gap: var(--roxy-space-xs, 0.25rem);
168
+ }
169
+ .bar {
170
+ display: grid;
171
+ grid-template-columns: 8rem 1fr 3.5rem;
172
+ gap: var(--roxy-space-sm, 0.5rem);
173
+ align-items: center;
174
+ font-size: var(--roxy-text-sm, 0.875rem);
175
+ }
176
+ .track {
177
+ height: 14px;
178
+ background: var(--roxy-border, #e4e4e7);
179
+ border-radius: var(--roxy-radius-full, 9999px);
180
+ overflow: hidden;
181
+ position: relative;
182
+ }
183
+ .fill {
184
+ display: block;
185
+ height: 100%;
186
+ transition:
187
+ width var(--roxy-motion-duration, 200ms)
188
+ var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1));
189
+ }
190
+ .value {
191
+ font-variant-numeric: tabular-nums;
192
+ text-align: right;
193
+ color: var(--roxy-muted, #71717a);
194
+ }
195
+ .advice {
196
+ color: var(--roxy-fg, #0a0a0a);
197
+ }
198
+ .alert {
199
+ background: color-mix(in srgb, var(--roxy-warning, #ea580c) 12%, transparent);
200
+ border: 1px solid color-mix(in srgb, var(--roxy-warning, #ea580c) 32%, transparent);
201
+ border-radius: var(--roxy-radius-md, 8px);
202
+ padding: var(--roxy-space-sm, 0.5rem);
203
+ font-size: var(--roxy-text-sm, 0.875rem);
204
+ margin: 0;
205
+ }
206
+ svg {
207
+ display: block;
208
+ width: 100%;
209
+ height: auto;
210
+ }
211
+ .crit {
212
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 12%, transparent);
213
+ border-radius: var(--roxy-radius-sm, 4px);
214
+ padding: 4px 8px;
215
+ font-size: var(--roxy-text-xs, 0.75rem);
216
+ display: inline-block;
217
+ margin: 2px;
218
+ }
219
+ `],H([I({attribute:!1})],v.prototype,"data",2),H([I({type:String,reflect:!0})],v.prototype,"mode",2),v=H([xt("roxy-biorhythm-chart")],v);return Ot(Wt);})();
220
+ /*! Bundled license information:
221
+
222
+ @lit/reactive-element/css-tag.js:
223
+ (**
224
+ * @license
225
+ * Copyright 2019 Google LLC
226
+ * SPDX-License-Identifier: BSD-3-Clause
227
+ *)
228
+
229
+ @lit/reactive-element/reactive-element.js:
230
+ lit-html/lit-html.js:
231
+ lit-element/lit-element.js:
232
+ @lit/reactive-element/decorators/custom-element.js:
233
+ @lit/reactive-element/decorators/property.js:
234
+ @lit/reactive-element/decorators/state.js:
235
+ @lit/reactive-element/decorators/event-options.js:
236
+ @lit/reactive-element/decorators/base.js:
237
+ @lit/reactive-element/decorators/query.js:
238
+ @lit/reactive-element/decorators/query-all.js:
239
+ @lit/reactive-element/decorators/query-async.js:
240
+ @lit/reactive-element/decorators/query-assigned-nodes.js:
241
+ (**
242
+ * @license
243
+ * Copyright 2017 Google LLC
244
+ * SPDX-License-Identifier: BSD-3-Clause
245
+ *)
246
+
247
+ lit-html/is-server.js:
248
+ (**
249
+ * @license
250
+ * Copyright 2022 Google LLC
251
+ * SPDX-License-Identifier: BSD-3-Clause
252
+ *)
253
+
254
+ @lit/reactive-element/decorators/query-assigned-elements.js:
255
+ (**
256
+ * @license
257
+ * Copyright 2021 Google LLC
258
+ * SPDX-License-Identifier: BSD-3-Clause
259
+ *)
260
+ */
261
+ //# sourceMappingURL=biorhythm-chart.js.map