@crowdlisten/harness 1.0.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 (109) hide show
  1. package/AGENTS.md +167 -0
  2. package/LICENSE +21 -0
  3. package/README.md +153 -0
  4. package/dist/agent-proxy.d.ts +24 -0
  5. package/dist/agent-proxy.js +140 -0
  6. package/dist/agent-tools.d.ts +736 -0
  7. package/dist/agent-tools.js +409 -0
  8. package/dist/context/api.d.ts +5 -0
  9. package/dist/context/api.js +164 -0
  10. package/dist/context/cli.d.ts +19 -0
  11. package/dist/context/cli.js +108 -0
  12. package/dist/context/extractor.d.ts +12 -0
  13. package/dist/context/extractor.js +43 -0
  14. package/dist/context/index.d.ts +12 -0
  15. package/dist/context/index.js +11 -0
  16. package/dist/context/matcher.d.ts +39 -0
  17. package/dist/context/matcher.js +246 -0
  18. package/dist/context/parser.d.ts +28 -0
  19. package/dist/context/parser.js +157 -0
  20. package/dist/context/pipeline.d.ts +26 -0
  21. package/dist/context/pipeline.js +56 -0
  22. package/dist/context/prompts.d.ts +6 -0
  23. package/dist/context/prompts.js +60 -0
  24. package/dist/context/providers.d.ts +6 -0
  25. package/dist/context/providers.js +106 -0
  26. package/dist/context/redactor.d.ts +10 -0
  27. package/dist/context/redactor.js +68 -0
  28. package/dist/context/server.d.ts +5 -0
  29. package/dist/context/server.js +134 -0
  30. package/dist/context/store.d.ts +12 -0
  31. package/dist/context/store.js +82 -0
  32. package/dist/context/types.d.ts +79 -0
  33. package/dist/context/types.js +4 -0
  34. package/dist/context/user-state.d.ts +40 -0
  35. package/dist/context/user-state.js +144 -0
  36. package/dist/index.d.ts +14 -0
  37. package/dist/index.js +385 -0
  38. package/dist/insights/browser/BrowserPool.d.ts +87 -0
  39. package/dist/insights/browser/BrowserPool.js +266 -0
  40. package/dist/insights/browser/RequestInterceptor.d.ts +46 -0
  41. package/dist/insights/browser/RequestInterceptor.js +115 -0
  42. package/dist/insights/cli.d.ts +8 -0
  43. package/dist/insights/cli.js +206 -0
  44. package/dist/insights/core/base/BaseAdapter.d.ts +37 -0
  45. package/dist/insights/core/base/BaseAdapter.js +123 -0
  46. package/dist/insights/core/health/HealthMonitor.d.ts +75 -0
  47. package/dist/insights/core/health/HealthMonitor.js +171 -0
  48. package/dist/insights/core/interfaces/SocialMediaPlatform.d.ts +125 -0
  49. package/dist/insights/core/interfaces/SocialMediaPlatform.js +42 -0
  50. package/dist/insights/core/utils/DataNormalizer.d.ts +53 -0
  51. package/dist/insights/core/utils/DataNormalizer.js +349 -0
  52. package/dist/insights/core/utils/InstagramUrlUtils.d.ts +11 -0
  53. package/dist/insights/core/utils/InstagramUrlUtils.js +60 -0
  54. package/dist/insights/core/utils/TikTokUrlUtils.d.ts +10 -0
  55. package/dist/insights/core/utils/TikTokUrlUtils.js +57 -0
  56. package/dist/insights/handlers.d.ts +157 -0
  57. package/dist/insights/handlers.js +246 -0
  58. package/dist/insights/index.d.ts +437 -0
  59. package/dist/insights/index.js +426 -0
  60. package/dist/insights/platforms/instagram/InstagramAdapter.d.ts +34 -0
  61. package/dist/insights/platforms/instagram/InstagramAdapter.js +342 -0
  62. package/dist/insights/platforms/moltbook/MoltbookAdapter.d.ts +31 -0
  63. package/dist/insights/platforms/moltbook/MoltbookAdapter.js +227 -0
  64. package/dist/insights/platforms/reddit/RedditAdapter.d.ts +21 -0
  65. package/dist/insights/platforms/reddit/RedditAdapter.js +212 -0
  66. package/dist/insights/platforms/tiktok/TikTokAdapter.d.ts +34 -0
  67. package/dist/insights/platforms/tiktok/TikTokAdapter.js +269 -0
  68. package/dist/insights/platforms/twitter/TwitterAdapter.d.ts +23 -0
  69. package/dist/insights/platforms/twitter/TwitterAdapter.js +211 -0
  70. package/dist/insights/platforms/xiaohongshu/XiaohongshuAdapter.d.ts +35 -0
  71. package/dist/insights/platforms/xiaohongshu/XiaohongshuAdapter.js +258 -0
  72. package/dist/insights/platforms/youtube/YouTubeAdapter.d.ts +22 -0
  73. package/dist/insights/platforms/youtube/YouTubeAdapter.js +254 -0
  74. package/dist/insights/service-config.d.ts +7 -0
  75. package/dist/insights/service-config.js +60 -0
  76. package/dist/insights/services/UnifiedSocialMediaService.d.ts +94 -0
  77. package/dist/insights/services/UnifiedSocialMediaService.js +259 -0
  78. package/dist/insights/vision/VisionExtractor.d.ts +46 -0
  79. package/dist/insights/vision/VisionExtractor.js +236 -0
  80. package/dist/learnings.d.ts +50 -0
  81. package/dist/learnings.js +130 -0
  82. package/dist/openapi.d.ts +29 -0
  83. package/dist/openapi.js +169 -0
  84. package/dist/server-factory.d.ts +20 -0
  85. package/dist/server-factory.js +41 -0
  86. package/dist/suggestions.d.ts +16 -0
  87. package/dist/suggestions.js +72 -0
  88. package/dist/telemetry.d.ts +44 -0
  89. package/dist/telemetry.js +93 -0
  90. package/dist/tools/registry.d.ts +65 -0
  91. package/dist/tools/registry.js +256 -0
  92. package/dist/tools.d.ts +2433 -0
  93. package/dist/tools.js +2294 -0
  94. package/dist/transport/http.d.ts +15 -0
  95. package/dist/transport/http.js +154 -0
  96. package/package.json +76 -0
  97. package/skills/catalog.json +272 -0
  98. package/skills/community-catalog.json +4202 -0
  99. package/skills/competitive-analysis/SKILL.md +174 -0
  100. package/skills/content-creator/SKILL.md +256 -0
  101. package/skills/content-strategy/SKILL.md +222 -0
  102. package/skills/data-storytelling/SKILL.md +248 -0
  103. package/skills/heuristic-evaluation/SKILL.md +201 -0
  104. package/skills/market-research-reports/SKILL.md +184 -0
  105. package/skills/user-stories/SKILL.md +178 -0
  106. package/skills/ux-researcher/SKILL.md +239 -0
  107. package/web-dist/assets/index-B1b25lNd.css +1 -0
  108. package/web-dist/assets/index-CDWHwHbl.js +64 -0
  109. package/web-dist/index.html +16 -0
@@ -0,0 +1,178 @@
1
+ ---
2
+ name: crowdlisten:user-stories
3
+ description: Turn social listening data into product decisions. JTBD extraction, feature demand scoring, persona generation, user story generation from real audience data. Requires CROWDLISTEN_API_KEY.
4
+ user-invocable: true
5
+ allowed-tools: Bash, Read, Write, WebFetch, Grep
6
+ metadata:
7
+ openclaw:
8
+ category: research
9
+ tags: [user-stories, jtbd, feature-demand, persona-generation]
10
+ requires_api_key: true
11
+ ---
12
+
13
+ # User Stories
14
+
15
+ Turn crowd signals into product decisions using CrowdListen audience intelligence.
16
+
17
+ Consolidates: product-signals (JTBD, feature demand), audience-discovery (persona generation)
18
+
19
+ ## Before You Start
20
+
21
+ Ask your human for business context — this skill produces significantly better output when grounded in specifics:
22
+
23
+ - **Target market**: Who are the customers? What industry/segment?
24
+ - **Key competitors**: Which brands or products to compare against?
25
+ - **Constraints**: Budget, timeline, geographic focus?
26
+ - **Decision context**: What decisions will this analysis inform? (roadmap, funding, positioning, hiring?)
27
+ - **Existing data**: Any prior research, internal metrics, or hypotheses to validate?
28
+
29
+ ## When to Use This Skill
30
+
31
+ - Product planning and roadmap prioritization
32
+ - JTBD extraction from real user discussions
33
+ - Feature request analysis and demand scoring
34
+ - User story and persona generation from audience data
35
+ - Early-stage idea validation against real audience data
36
+
37
+ ## Foundation: CrowdListen Tools
38
+
39
+ This skill builds on CrowdListen's core capabilities:
40
+ - `search_content` — Find relevant social discussions across platforms
41
+ - `analyze_content` — Extract themes, sentiment, key opinions
42
+ - `cluster_opinions` — Group similar opinions into demand clusters
43
+ - `sentiment_evolution_tracker` — Track how feature sentiment changes over time
44
+ - `get_content_comments` — Deep-dive into specific discussion threads
45
+
46
+ ## Workflows
47
+
48
+ ### 1. Jobs-to-Be-Done (JTBD) Extraction
49
+
50
+ Search for discussions where users describe problems, workarounds, or desired outcomes.
51
+
52
+ **Process**:
53
+ 1. Search for "[product/category] + frustrating/wish/workaround/alternative/hack"
54
+ 2. Cluster the results by underlying job (not surface-level complaint)
55
+ 3. Score each job by: frequency, intensity (sentiment strength), recency (trending up/down)
56
+
57
+ **Output Template**:
58
+ ```markdown
59
+ ## JTBD Canvas
60
+
61
+ ### Job: [Functional job statement]
62
+ **When I** [situation/trigger]
63
+ **I want to** [desired outcome]
64
+ **So I can** [underlying motivation]
65
+
66
+ **Evidence**:
67
+ - Volume: X discussions across Y platforms
68
+ - Sentiment intensity: [score]
69
+ - Trend: [rising/stable/declining]
70
+ - Representative quotes:
71
+ > "[Direct user quote with source link]"
72
+
73
+ ### Current Solutions (Hired/Fired)
74
+ | Solution | Hired For | Fired Because |
75
+ |----------|-----------|---------------|
76
+ | [Product A] | [reason] | [shortcoming] |
77
+ | [Workaround B] | [reason] | [friction] |
78
+ ```
79
+
80
+ ### 2. Feature Demand Scoring
81
+
82
+ Quantify which features your audience wants most.
83
+
84
+ **Process**:
85
+ 1. Search for feature requests, wishlists, and comparison discussions
86
+ 2. Normalize mentions across platforms (Reddit post = 1, comment with 50+ upvotes = 3, etc.)
87
+ 3. Score using: `demand_score = (volume * 0.4) + (sentiment_intensity * 0.3) + (recency * 0.3)`
88
+
89
+ **Output Template**:
90
+ ```markdown
91
+ ## Feature Demand Matrix
92
+
93
+ | Rank | Feature | Demand Score | Volume | Sentiment | Trend | Action |
94
+ |------|---------|-------------|--------|-----------|-------|--------|
95
+ | 1 | [Feature] | [score] | [count] | [+/-] | [up/down] | Build |
96
+ | 2 | [Feature] | [score] | [count] | [+/-] | [up/down] | Investigate |
97
+
98
+ ### Top Feature Deep-Dive: [#1 Feature]
99
+ - **User stories** (from actual discussions):
100
+ - As a [role], I need [feature] because [reason]
101
+ - **Competitive context**: [Who offers this? How do users feel about their implementation?]
102
+ ```
103
+
104
+ ### 3. Persona Generation
105
+
106
+ Create data-driven personas from real social discussions.
107
+
108
+ **Process**:
109
+ 1. Search for your product category across platforms
110
+ 2. Analyze discussants' language, concerns, goals, and context clues
111
+ 3. Cluster into distinct persona groups by behavior patterns
112
+ 4. Validate against engagement patterns
113
+
114
+ **Output Template**:
115
+ ```markdown
116
+ ## Audience Personas — [Category]
117
+
118
+ ### Persona 1: [Name] — "[One-line description]"
119
+ **Archetype**: [Role/behavior archetype]
120
+ **Estimated segment size**: [% of audience]
121
+
122
+ **Demographics (inferred)**:
123
+ - Professional context: [industry, role level]
124
+ - Technical sophistication: [low/medium/high]
125
+ - Decision authority: [end-user/influencer/buyer]
126
+
127
+ **Goals**:
128
+ 1. [Primary goal with evidence from social discussions]
129
+
130
+ **Pain Points**:
131
+ 1. [Frustration with evidence]
132
+
133
+ **How to Reach Them**:
134
+ - Channel: [Best platforms/communities]
135
+ - Message: [What resonates based on their language]
136
+ - Trigger: [What makes them search for solutions]
137
+ ```
138
+
139
+ ### 4. User Story Generation
140
+
141
+ Produce implementation-ready user stories grounded in audience evidence.
142
+
143
+ **Process**:
144
+ 1. Combine JTBD extraction + feature demand + persona insights
145
+ 2. Generate user stories with acceptance criteria
146
+ 3. Attach evidence links to every story
147
+ 4. Prioritize by demand score
148
+
149
+ **Output Template**:
150
+ ```markdown
151
+ ## User Stories — [Product/Feature Area]
152
+
153
+ ### Story 1 (Priority: High, Demand Score: [X])
154
+ **As a** [persona name from persona generation]
155
+ **I want to** [capability derived from JTBD]
156
+ **So that** [outcome from audience discussions]
157
+
158
+ **Acceptance Criteria**:
159
+ - [ ] [Criterion derived from user expectations]
160
+ - [ ] [Criterion derived from competitor benchmarks]
161
+
162
+ **Evidence**:
163
+ - [X] discussions mention this need
164
+ - Platforms: [where demand is strongest]
165
+ - Key quote: > "[user quote]"
166
+
167
+ ### Story 2 (Priority: Medium, Demand Score: [X])
168
+ [Same structure]
169
+ ```
170
+
171
+ ## Integration with CrowdListen
172
+
173
+ This skill enhances CrowdListen analyses by:
174
+ - Transforming raw sentiment data into structured product decisions
175
+ - Providing PM-ready deliverables from social listening data
176
+ - Generating evidence-backed user stories and personas
177
+ - Enabling evidence-based roadmap prioritization
178
+ - Tracking feature demand trends over time
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: crowdlisten:ux-research
3
+ description: UX research synthesis — user personas, journey maps, heuristic evaluation (Nielsen's 10), design recommendations. Use when analyzing user behavior or designing experiences.
4
+ user-invocable: true
5
+ allowed-tools: Bash, Read, Write, WebFetch, Grep
6
+ metadata:
7
+ openclaw:
8
+ category: design
9
+ tags: [ux-research, user-personas, journey-maps, heuristic-evaluation]
10
+ requires_api_key: false
11
+ ---
12
+
13
+ # UX Researcher & Designer
14
+
15
+ Comprehensive UX research and design skill for user-centered analysis and design deliverables.
16
+
17
+ ## Before You Start
18
+
19
+ Ask your human for business context — this skill produces significantly better output when grounded in specifics:
20
+
21
+ - **Target market**: Who are the customers? What industry/segment?
22
+ - **Key competitors**: Which brands or products to compare against?
23
+ - **Constraints**: Budget, timeline, geographic focus?
24
+ - **Decision context**: What decisions will this analysis inform? (roadmap, funding, positioning, hiring?)
25
+ - **Existing data**: Any prior research, internal metrics, or hypotheses to validate?
26
+
27
+ ## Capabilities
28
+
29
+ This skill enables:
30
+ - **Persona Generation**: Research-based user persona creation
31
+ - **Journey Mapping**: End-to-end customer journey visualization
32
+ - **Usability Analysis**: Heuristic evaluation and UX audits
33
+ - **Research Synthesis**: Converting user data into actionable insights
34
+ - **Design Recommendations**: Evidence-based UX improvement suggestions
35
+
36
+ ## Core Methods
37
+
38
+ ### User Persona Generation
39
+
40
+ Create detailed, research-backed user personas:
41
+
42
+ ```markdown
43
+ ## [Persona Name]
44
+ **Role**: Primary/Secondary User Type
45
+
46
+ ### Demographics
47
+ - Age, location, occupation
48
+ - Technical proficiency
49
+ - Relevant background
50
+
51
+ ### Goals & Motivations
52
+ - Primary objectives
53
+ - Success metrics
54
+ - Underlying motivations
55
+
56
+ ### Pain Points & Frustrations
57
+ - Current challenges
58
+ - Unmet needs
59
+ - Friction points
60
+
61
+ ### Behaviors & Patterns
62
+ - Usage frequency
63
+ - Preferred channels
64
+ - Decision-making process
65
+
66
+ ### Quote
67
+ > "Representative voice that captures their perspective"
68
+
69
+ ### Scenario
70
+ A day-in-the-life narrative showing how they interact with the product/service.
71
+ ```
72
+
73
+ ### Journey Mapping
74
+
75
+ Map the complete user experience:
76
+
77
+ | Stage | Awareness | Consideration | Decision | Onboarding | Usage | Advocacy |
78
+ |-------|-----------|---------------|----------|------------|-------|----------|
79
+ | **Actions** | What they do | | | | | |
80
+ | **Touchpoints** | Where they interact | | | | | |
81
+ | **Emotions** | How they feel | | | | | |
82
+ | **Pain Points** | Frustrations | | | | | |
83
+ | **Opportunities** | Improvements | | | | | |
84
+
85
+ ### Heuristic Evaluation
86
+
87
+ Apply Nielsen's 10 Usability Heuristics:
88
+
89
+ 1. **Visibility of System Status**
90
+ 2. **Match Between System and Real World**
91
+ 3. **User Control and Freedom**
92
+ 4. **Consistency and Standards**
93
+ 5. **Error Prevention**
94
+ 6. **Recognition Rather Than Recall**
95
+ 7. **Flexibility and Efficiency of Use**
96
+ 8. **Aesthetic and Minimalist Design**
97
+ 9. **Help Users Recognize, Diagnose, and Recover from Errors**
98
+ 10. **Help and Documentation**
99
+
100
+ ## Usage
101
+
102
+ ### Generate User Persona
103
+
104
+ ```python
105
+ # Example: Create persona from research data
106
+ await generate_persona(
107
+ research_data=user_interview_transcripts,
108
+ persona_type="primary",
109
+ include_scenarios=True,
110
+ format="detailed" # detailed | summary | visual
111
+ )
112
+ ```
113
+
114
+ ### Create Journey Map
115
+
116
+ ```python
117
+ # Example: Map user journey
118
+ await create_journey_map(
119
+ persona="Tech-Savvy Startup Founder",
120
+ product="CrowdListen",
121
+ stages=["discovery", "evaluation", "purchase", "onboarding", "daily_use"],
122
+ include_emotions=True,
123
+ identify_moments_of_truth=True
124
+ )
125
+ ```
126
+
127
+ ### Conduct Usability Audit
128
+
129
+ ```python
130
+ # Example: Heuristic evaluation
131
+ await usability_audit(
132
+ product_screenshots=image_urls,
133
+ user_flows=["signup", "first_analysis", "export_results"],
134
+ heuristics="nielsen_10",
135
+ severity_ratings=True
136
+ )
137
+ ```
138
+
139
+ ### Synthesize Research
140
+
141
+ ```python
142
+ # Example: Synthesize user research
143
+ await synthesize_research(
144
+ data_sources=[
145
+ {"type": "interviews", "count": 12, "data": transcripts},
146
+ {"type": "surveys", "count": 150, "data": survey_results},
147
+ {"type": "analytics", "data": behavioral_data}
148
+ ],
149
+ outputs=["personas", "journey_map", "opportunity_areas"]
150
+ )
151
+ ```
152
+
153
+ ## Deliverable Templates
154
+
155
+ ### Persona Document
156
+ ```markdown
157
+ # [Name] - [Role]
158
+
159
+ ![Persona Photo Placeholder]
160
+
161
+ ## At a Glance
162
+ - **Age**:
163
+ - **Location**:
164
+ - **Occupation**:
165
+ - **Tech Savviness**: [1-5 scale]
166
+
167
+ ## Background
168
+ [2-3 sentence background]
169
+
170
+ ## Goals
171
+ 1.
172
+ 2.
173
+ 3.
174
+
175
+ ## Frustrations
176
+ 1.
177
+ 2.
178
+ 3.
179
+
180
+ ## Motivations
181
+ -
182
+ -
183
+
184
+ ## Preferred Channels
185
+ -
186
+ -
187
+
188
+ ## Brand Affinities
189
+ -
190
+ -
191
+
192
+ ## A Day in Their Life
193
+ [Narrative scenario]
194
+
195
+ ## Key Quote
196
+ > ""
197
+ ```
198
+
199
+ ### Journey Map Template
200
+ ```markdown
201
+ # Customer Journey Map: [Persona] using [Product]
202
+
203
+ ## Journey Overview
204
+ **Goal**:
205
+ **Timeline**:
206
+ **Channels**:
207
+
208
+ ## Stage-by-Stage Breakdown
209
+
210
+ ### Stage 1: [Name]
211
+ - **User Goal**:
212
+ - **Actions**:
213
+ - **Touchpoints**:
214
+ - **Thoughts**:
215
+ - **Emotions**: [happy/neutral/frustrated]
216
+ - **Pain Points**:
217
+ - **Opportunities**:
218
+
219
+ [Repeat for each stage]
220
+
221
+ ## Key Insights
222
+ 1.
223
+ 2.
224
+ 3.
225
+
226
+ ## Priority Opportunities
227
+ | Opportunity | Impact | Effort | Priority |
228
+ |-------------|--------|--------|----------|
229
+ | | | | |
230
+ ```
231
+
232
+ ## Integration with CrowdListen
233
+
234
+ This skill enhances CrowdListen by:
235
+ - Creating personas from social listening data
236
+ - Mapping user journeys based on community feedback
237
+ - Identifying UX pain points from user discussions
238
+ - Validating design decisions with community sentiment
239
+ - Generating research-backed user experience improvements
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-white:#fff;--spacing:.25rem;--container-xl:36rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-snug:1.375;--leading-relaxed:1.625;--radius-xs:.125rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.top-1\/2{top:50%}.left-1\/2{left:50%}.z-40{z-index:40}.z-50{z-index:50}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-7{margin-left:calc(var(--spacing) * 7)}.ml-9{margin-left:calc(var(--spacing) * 9)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.min-h-screen{min-height:100vh}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-full{width:100%}.max-w-6xl{max-width:var(--container-6xl)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.border{border-style:var(--tw-border-style);border-width:1px}.p-6{padding:calc(var(--spacing) * 6)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.text-center{text-align:center}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-pre-wrap{white-space:pre-wrap}.text-white{color:var(--color-white)}.underline{text-decoration-line:underline}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}:root{--brand-coral:#d97d55;--brand-cream:#f4e9d7;--brand-sage:#b8c4a9;--brand-teal:#6fa4af;--cl-bg:#f7f3ee;--cl-bg-card:#faf8f5;--cl-fg:#4a5956;--cl-fg-muted:#6f8582;--cl-border:#b0c4b6;--cl-border-light:#d3ded6;--cl-accent:#f4e0d7;--cl-positive-bg:#def7e4;--cl-positive-fg:#23903c;--cl-positive-border:#8ce3a0;--cl-negative-bg:#fddede;--cl-negative-fg:#eb1414;--cl-info-bg:#dcebfe;--cl-info-fg:#1368d8;--cl-warning-bg:#fdf3d3;--cl-warning-fg:#a57f0d;--radius-xs:4px;--radius-s:8px;--radius-m:12px;--radius-lg:20px;--radius-xl:28px;--radius-pill:9999px}body{background:var(--cl-bg);color:var(--cl-fg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,system-ui,-apple-system,sans-serif}h1,h2,h3{font-family:Playfair Display,Georgia,serif}.glass-card{-webkit-backdrop-filter:blur(12px);border:1px solid var(--cl-border-light);border-radius:var(--radius-m);background:#ffffffeb;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4px 16px #0000000f,0 1px 4px #0000000a}.glass-card:hover{box-shadow:0 8px 24px #00000014,0 2px 8px #0000000d}.glass-header{-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--cl-border-light);background:#fffffff2;box-shadow:0 1px 4px #0000000a}.btn-primary{background:var(--brand-teal);color:#fff;border-radius:var(--radius-s);cursor:pointer;border:none;padding:8px 20px;font-family:Inter,system-ui,sans-serif;font-size:14px;font-weight:500;transition:all .2s cubic-bezier(.4,0,.2,1)}.btn-primary:hover{background:var(--brand-coral);transform:translateY(-1px);box-shadow:0 4px 12px #d97d554d}.btn-primary:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.btn-secondary{color:var(--cl-fg);border:1px solid var(--cl-border);border-radius:var(--radius-s);cursor:pointer;background:0 0;padding:6px 16px;font-family:Inter,system-ui,sans-serif;font-size:13px;font-weight:500;transition:all .2s}.btn-secondary:hover{background:var(--cl-bg-card);border-color:var(--brand-teal);color:var(--brand-teal)}.btn-secondary:disabled{opacity:.5;cursor:not-allowed}.input-field{border:1px solid var(--cl-border-light);border-radius:var(--radius-s);width:100%;color:var(--cl-fg);background:#fff;padding:8px 12px;font-family:Inter,system-ui,sans-serif;font-size:14px;transition:all .2s}.input-field:focus{border-color:var(--brand-teal);outline:none;box-shadow:0 0 0 3px #6fa4af26}.input-field::placeholder{color:var(--cl-fg-muted)}.select-field{border:1px solid var(--cl-border-light);border-radius:var(--radius-s);width:100%;color:var(--cl-fg);cursor:pointer;background:#fff;padding:8px 12px;font-family:Inter,system-ui,sans-serif;font-size:14px;transition:border-color .2s}.select-field:focus{border-color:var(--brand-teal);outline:none;box-shadow:0 0 0 3px #6fa4af26}.pill{border-radius:var(--radius-pill);align-items:center;padding:2px 10px;font-family:Inter,system-ui,sans-serif;font-size:12px;font-weight:500;display:inline-flex}.pill-teal{color:var(--brand-teal);background:#6fa4af26}.pill-coral{color:var(--brand-coral);background:#d97d5526}.pill-sage{color:#586a67;background:#b8c4a940}.pill-positive{background:var(--cl-positive-bg);color:var(--cl-positive-fg)}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}.animate-float{animation:3s ease-in-out infinite float}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}.loading-shimmer{background:linear-gradient(90deg,var(--cl-bg) 25%,var(--cl-bg-card) 50%,var(--cl-bg) 75%);background-size:200px 100%;animation:1.5s infinite shimmer}@keyframes pulse-soft{0%,to{opacity:1}50%{opacity:.6}}.pulse-soft{animation:2s ease-in-out infinite pulse-soft}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}