rampkit-mcp-server 0.1.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.
- package/README.md +160 -0
- package/dist/api/rampkit.d.ts +96 -0
- package/dist/api/rampkit.d.ts.map +1 -0
- package/dist/api/rampkit.js +391 -0
- package/dist/api/rampkit.js.map +1 -0
- package/dist/detection/platform.d.ts +11 -0
- package/dist/detection/platform.d.ts.map +1 -0
- package/dist/detection/platform.js +420 -0
- package/dist/detection/platform.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +24 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +183 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/authoring-guide.d.ts +9 -0
- package/dist/resources/authoring-guide.d.ts.map +1 -0
- package/dist/resources/authoring-guide.js +487 -0
- package/dist/resources/authoring-guide.js.map +1 -0
- package/dist/resources/best-practices.d.ts +8 -0
- package/dist/resources/best-practices.d.ts.map +1 -0
- package/dist/resources/best-practices.js +92 -0
- package/dist/resources/best-practices.js.map +1 -0
- package/dist/resources/index.d.ts +19 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +236 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/schema.d.ts +42 -0
- package/dist/resources/schema.d.ts.map +1 -0
- package/dist/resources/schema.js +239 -0
- package/dist/resources/schema.js.map +1 -0
- package/dist/resources/sdk-guide.d.ts +7 -0
- package/dist/resources/sdk-guide.d.ts.map +1 -0
- package/dist/resources/sdk-guide.js +368 -0
- package/dist/resources/sdk-guide.js.map +1 -0
- package/dist/resources/templates.d.ts +9 -0
- package/dist/resources/templates.d.ts.map +1 -0
- package/dist/resources/templates.js +874 -0
- package/dist/resources/templates.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +109 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/instructions.d.ts +23 -0
- package/dist/tools/instructions.d.ts.map +1 -0
- package/dist/tools/instructions.js +74 -0
- package/dist/tools/instructions.js.map +1 -0
- package/dist/tools/onboarding.d.ts +211 -0
- package/dist/tools/onboarding.d.ts.map +1 -0
- package/dist/tools/onboarding.js +452 -0
- package/dist/tools/onboarding.js.map +1 -0
- package/dist/tools/setup.d.ts +61 -0
- package/dist/tools/setup.d.ts.map +1 -0
- package/dist/tools/setup.js +543 -0
- package/dist/tools/setup.js.map +1 -0
- package/dist/types.d.ts +280 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,UAAU,UAAU;IACxB,OAAO;QACL;YACE,IAAI,EAAE,sBAAsB;YAC5B,WAAW,EACT,8FAA8F;YAChG,SAAS,EAAE;gBACT;oBACE,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,mFAAmF;oBAChG,QAAQ,EAAE,KAAK;iBAChB;aACF;SACF;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EACT,oEAAoE;YACtE,SAAS,EAAE;gBACT;oBACE,IAAI,EAAE,MAAM;oBACZ,WAAW,EAAE,6CAA6C;oBAC1D,QAAQ,EAAE,KAAK;iBAChB;aACF;SACF;QACD;YACE,IAAI,EAAE,qBAAqB;YAC3B,WAAW,EACT,8DAA8D;YAChE,SAAS,EAAE;gBACT;oBACE,IAAI,EAAE,cAAc;oBACpB,WAAW,EAAE,kCAAkC;oBAC/C,QAAQ,EAAE,IAAI;iBACf;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,sBAAsB;YACzB,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC;yBAC/C;qBACF;iBACF;aACF,CAAC;QAEJ,KAAK,oBAAoB;YACvB,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,0BAA0B,CAAC,IAAI,EAAE,IAAI,CAAC;yBAC7C;qBACF;iBACF;aACF,CAAC;QAEJ,KAAK,qBAAqB;YACxB,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,2BAA2B,CAAC,IAAI,EAAE,YAAY,CAAC;yBACtD;qBACF;iBACF;aACF,CAAC;QAEJ;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAc;IACjD,MAAM,YAAY,GAAG,KAAK;QACxB,CAAC,CAAC,mBAAmB,KAAK,+DAA+D,KAAK,IAAI;QAClG,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;iFA0BwE,YAAY,EAAE,CAAC;AAChG,CAAC;AAED,SAAS,0BAA0B,CAAC,QAAiB;IACnD,MAAM,WAAW,GAAG,QAAQ;QAC1B,CAAC,CAAC,sBAAsB,QAAQ,6DAA6D;QAC7F,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;gFAyBuE,WAAW,EAAE,CAAC;AAC9F,CAAC;AAED,SAAS,2BAA2B,CAAC,YAAqB;IACxD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;;8FAEmF,CAAC;IAC7F,CAAC;IAED,OAAO,wDAAwD,YAAY;;;8CAG/B,YAAY;;;;;;;;;;;;;;;;;;;;;;;;mFAwByB,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML Authoring Guide for RampKit Onboardings
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive guide for AI assistants to generate correct HTML screens.
|
|
5
|
+
* This mirrors the detail level of the Vibe Agent's system prompts but for HTML-first content.
|
|
6
|
+
*/
|
|
7
|
+
export declare const HTML_AUTHORING_GUIDE = "# RampKit HTML Screen Authoring Guide\n\nYou are generating HTML screens for mobile app onboarding flows. These screens render in a native WebView on iOS and Android.\n\n## Screen Structure\n\nEvery screen MUST follow this structure:\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n <style>\n /* CSS styles here */\n </style>\n</head>\n<body>\n <div class=\"screen\">\n <!-- Screen content -->\n </div>\n <script>\n // JavaScript here\n </script>\n</body>\n</html>\n```\n\n## Required CSS Reset\n\nAlways start with this reset:\n\n```css\n* { margin: 0; padding: 0; box-sizing: border-box; }\n:root {\n --ramp-primary: #007AFF;\n --ramp-background: #FFFFFF;\n --ramp-text: #1C1C1E;\n --ramp-text-secondary: #8E8E93;\n --ramp-safe-area-top: env(safe-area-inset-top, 44px);\n --ramp-safe-area-bottom: env(safe-area-inset-bottom, 34px);\n}\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro', sans-serif;\n background: var(--ramp-background);\n color: var(--ramp-text);\n min-height: 100vh;\n}\n```\n\n## Safe Areas (CRITICAL)\n\nMobile devices have notches and home indicators. ALWAYS respect safe areas:\n\n```css\n.screen {\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n /* Add safe area padding - REQUIRED */\n padding: calc(var(--ramp-safe-area-top) + 20px) 24px calc(var(--ramp-safe-area-bottom) + 20px);\n}\n```\n\nNever place interactive elements or text under the safe areas.\n\n## Data Attributes (REQUIRED)\n\nEvery editable element MUST have BOTH `data-ramp-id` AND `data-ramp-type`:\n\n### Valid Types\n- `text` - For headings, paragraphs, spans, labels\n- `button` - For clickable buttons (also requires `data-tap-dynamic`)\n- `image` - For images\n- `video` - For video players\n- `lottie` - For Lottie animations\n- `input` - For form inputs\n\n### Text Elements\n```html\n<h1 data-ramp-id=\"title\" data-ramp-type=\"text\">Welcome to AppName</h1>\n<p data-ramp-id=\"subtitle\" data-ramp-type=\"text\">Your journey starts here</p>\n<span data-ramp-id=\"label\" data-ramp-type=\"text\">Some label</span>\n```\n\n### Button Elements (require data-tap-dynamic for actions)\n```html\n<button data-ramp-id=\"cta\" data-ramp-type=\"button\" data-tap-dynamic='{\"action\":\"navigate\",\"target\":\"next\"}'>\n Continue\n</button>\n<button data-ramp-id=\"skip\" data-ramp-type=\"button\" data-tap-dynamic='{\"action\":\"dismiss\"}'>\n Skip\n</button>\n<button data-ramp-id=\"finish_btn\" data-ramp-type=\"button\" data-tap-dynamic='{\"action\":\"finish\"}'>\n Done\n</button>\n```\n\n### Image Elements\n```html\n<img data-ramp-id=\"hero_image\" data-ramp-type=\"image\" src=\"https://example.com/image.png\" alt=\"Hero\">\n```\n\n### data-tap-dynamic Actions\n```json\n{\"action\":\"navigate\",\"target\":\"next\"} // Go to next screen\n{\"action\":\"navigate\",\"target\":\"back\"} // Go to previous screen\n{\"action\":\"navigate\",\"target\":\"screen-id\"} // Go to specific screen\n{\"action\":\"dismiss\"} // Close onboarding\n{\"action\":\"finish\"} // Complete onboarding\n{\"action\":\"requestPermission\",\"permission\":\"notifications\"} // Request permission\n{\"action\":\"purchase\",\"productId\":\"annual\"} // Initiate purchase\n```\n\n## RampKit JavaScript API\n\nThe SDK injects a global `RampKit` object. Use these methods:\n\n### Navigation\n```javascript\nRampKit.navigate('next'); // Go to next screen\nRampKit.navigate('back'); // Go to previous screen\nRampKit.navigate('screen-id'); // Go to specific screen\nRampKit.dismiss(); // Close onboarding (user chose to skip)\nRampKit.finish(); // Complete onboarding successfully\n```\n\n### Permissions\n```javascript\nRampKit.requestPermission('notifications'); // Request push notifications\nRampKit.requestPermission('tracking'); // Request ATT (App Tracking Transparency)\nRampKit.requestPermission('location'); // Request location access\n```\n\n### Paywall & Purchases\n```javascript\nRampKit.showPaywall(); // Show paywall screen\nRampKit.purchase('product_id'); // Initiate purchase\nRampKit.restorePurchases(); // Restore previous purchases\n```\n\n### Analytics\n```javascript\nRampKit.track('event_name', { key: 'value' }); // Track custom event\nRampKit.setUserProperty('property', 'value'); // Set user attribute\n```\n\n### Variables\n```javascript\nRampKit.setVariable('name', value); // Set a state variable\nRampKit.getVariable('name'); // Get a state variable\n```\n\n### Context\n```javascript\n// Access device/user context\nconst context = RampKit.getContext();\n// context.device.platform, context.device.language, context.user.isNewUser, etc.\n```\n\n## Button Patterns\n\n### Primary CTA Button\n```html\n<button class=\"btn-primary\" onclick=\"RampKit.navigate('next')\">\n Continue\n</button>\n\n<style>\n.btn-primary {\n background: var(--ramp-primary);\n color: white;\n border: none;\n padding: 16px;\n border-radius: 14px;\n font-size: 17px;\n font-weight: 600;\n cursor: pointer;\n width: 100%;\n}\n</style>\n```\n\n### Secondary/Skip Button\n```html\n<button class=\"btn-secondary\" onclick=\"RampKit.dismiss()\">\n Skip for now\n</button>\n\n<style>\n.btn-secondary {\n background: transparent;\n color: var(--ramp-primary);\n border: none;\n padding: 12px;\n font-size: 15px;\n font-weight: 500;\n cursor: pointer;\n}\n</style>\n```\n\n### Close Button (X)\n```html\n<button class=\"close-btn\" onclick=\"RampKit.dismiss()\">\u2715</button>\n\n<style>\n.close-btn {\n position: absolute;\n top: calc(var(--ramp-safe-area-top) + 12px);\n right: 16px;\n width: 30px;\n height: 30px;\n border-radius: 50%;\n background: #E5E5EA;\n border: none;\n font-size: 18px;\n cursor: pointer;\n}\n</style>\n```\n\n## Screen Types & Patterns\n\n### Welcome Screen\n- Large icon or app logo (80-120px)\n- Bold title (font-size: 28px, weight: 700)\n- Subtitle with value proposition (font-size: 17px, secondary color)\n- Primary CTA button\n- Optional skip link\n\n### Features Screen\n- Title at top\n- 2-4 feature rows with icon + text\n- Each feature: icon (48px container) + title + description\n- Continue button at bottom\n\n### Permission Screen\n- Large icon representing the permission (80-100px)\n- Clear explanation of WHY you need the permission\n- List of benefits (checkmarks)\n- \"Enable\" primary button\n- \"Maybe Later\" secondary button\n\n### Personalization Screen\n- Question as title\n- Selectable options (cards or buttons)\n- Visual feedback for selection (border color change)\n- Continue button (disabled until selection)\n\n### Paywall Screen\n- Badge/tier indicator\n- Value proposition headline\n- List of benefits\n- Plan options (monthly/yearly cards)\n- Subscribe button\n- Terms/privacy links\n\n### Completion Screen\n- Success icon (checkmark)\n- Celebration message\n- Optional confetti animation\n- \"Let's Go\" finish button\n\n## Typography Scale\n\n| Use Case | Size | Weight |\n|----------|------|--------|\n| Hero title | 28-32px | 700 |\n| Section title | 24-26px | 700 |\n| Body title | 17-18px | 600 |\n| Body text | 16-17px | 400 |\n| Secondary text | 14-15px | 400 |\n| Caption | 12-13px | 400 |\n\n## Color Guidelines\n\nAlways use CSS variables for easy theming:\n\n```css\n:root {\n /* Primary brand color - customize per app */\n --ramp-primary: #007AFF;\n --ramp-primary-dark: #0056b3;\n\n /* Backgrounds */\n --ramp-background: #FFFFFF;\n --ramp-surface: #F2F2F7;\n\n /* Text */\n --ramp-text: #1C1C1E;\n --ramp-text-secondary: #8E8E93;\n\n /* Feedback */\n --ramp-success: #34C759;\n --ramp-warning: #FF9500;\n --ramp-error: #FF3B30;\n\n /* Borders */\n --ramp-border: #E5E5EA;\n}\n```\n\n## Interactive Elements\n\n### Option Selection\n```html\n<div class=\"option\" data-value=\"choice1\" onclick=\"selectOption(this)\">\n <span class=\"option-icon\">\uD83C\uDFE0</span>\n <div class=\"option-content\">\n <h3>Option Title</h3>\n <p>Option description</p>\n </div>\n <div class=\"option-check\">\u2713</div>\n</div>\n\n<script>\nlet selectedValue = null;\n\nfunction selectOption(el) {\n document.querySelectorAll('.option').forEach(o => o.classList.remove('selected'));\n el.classList.add('selected');\n selectedValue = el.dataset.value;\n document.querySelector('.btn-primary').disabled = false;\n}\n</script>\n\n<style>\n.option {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 16px;\n border: 2px solid var(--ramp-border);\n border-radius: 14px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.option.selected {\n border-color: var(--ramp-primary);\n background: rgba(0, 122, 255, 0.05);\n}\n.option-check {\n width: 24px;\n height: 24px;\n border-radius: 50%;\n border: 2px solid var(--ramp-border);\n display: flex;\n align-items: center;\n justify-content: center;\n color: transparent;\n}\n.option.selected .option-check {\n background: var(--ramp-primary);\n border-color: var(--ramp-primary);\n color: white;\n}\n</style>\n```\n\n### Plan Selection (Paywall)\n```html\n<div class=\"plans\">\n <div class=\"plan\" data-plan=\"monthly\" onclick=\"selectPlan(this)\">\n <div class=\"plan-period\">Monthly</div>\n <div class=\"plan-price\">$9.99<span>/mo</span></div>\n </div>\n <div class=\"plan popular selected\" data-plan=\"annual\" onclick=\"selectPlan(this)\">\n <div class=\"plan-period\">Annual</div>\n <div class=\"plan-price\">$4.99<span>/mo</span></div>\n <div class=\"plan-savings\">Save 50%</div>\n </div>\n</div>\n\n<script>\nlet selectedPlan = 'annual';\n\nfunction selectPlan(el) {\n document.querySelectorAll('.plan').forEach(p => p.classList.remove('selected'));\n el.classList.add('selected');\n selectedPlan = el.dataset.plan;\n}\n\nfunction subscribe() {\n RampKit.track('paywall_cta_clicked', { plan: selectedPlan });\n RampKit.purchase(selectedPlan);\n}\n</script>\n```\n\n## Animation Examples\n\n### Scale-in Animation\n```css\n@keyframes scaleIn {\n 0% { transform: scale(0); opacity: 0; }\n 50% { transform: scale(1.1); }\n 100% { transform: scale(1); opacity: 1; }\n}\n\n.animated-icon {\n animation: scaleIn 0.5s ease-out;\n}\n```\n\n### Confetti Effect\n```html\n<div class=\"confetti\" id=\"confetti\"></div>\n\n<style>\n.confetti {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n}\n.confetti-piece {\n position: absolute;\n width: 10px;\n height: 10px;\n animation: confetti-fall 3s linear forwards;\n}\n@keyframes confetti-fall {\n 0% { transform: translateY(-100%) rotate(0deg); opacity: 1; }\n 100% { transform: translateY(100vh) rotate(720deg); opacity: 0; }\n}\n</style>\n\n<script>\nconst colors = ['#FF3B30', '#FF9500', '#FFCC00', '#34C759', '#007AFF', '#5856D6'];\nconst container = document.getElementById('confetti');\n\nfor (let i = 0; i < 50; i++) {\n const piece = document.createElement('div');\n piece.className = 'confetti-piece';\n piece.style.left = Math.random() * 100 + '%';\n piece.style.background = colors[Math.floor(Math.random() * colors.length)];\n piece.style.animationDelay = Math.random() * 2 + 's';\n container.appendChild(piece);\n}\n</script>\n```\n\n## Important Rules\n\n1. **ALWAYS include safe area padding** - Never place content under notch or home indicator\n2. **ALWAYS use data-ramp-id** on text elements for tracking\n3. **ALWAYS use CSS variables** for colors - makes theming easy\n4. **Use system fonts** - `-apple-system, BlinkMacSystemFont` for native feel\n5. **Keep HTML self-contained** - All CSS and JS inline in the file\n6. **Minimum touch targets** - Buttons should be at least 44px tall\n7. **Consistent button placement** - CTAs at bottom, above safe area\n8. **Test on multiple sizes** - Works on iPhone SE and iPad\n9. **Never use emojis in production** - They render differently across devices. Use icons from a CDN if needed.\n10. **Keep screens focused** - One key message or action per screen\n";
|
|
8
|
+
export declare const SCREEN_ID_GUIDE = "## Screen ID Conventions\n\nUse descriptive, kebab-case IDs for screens:\n\n- `screen-welcome` - Welcome/intro screen\n- `screen-features` - Feature highlights\n- `screen-permissions-notifications` - Notification permission\n- `screen-permissions-tracking` - ATT permission\n- `screen-personalization` - User preference questions\n- `screen-paywall` - Subscription offer\n- `screen-complete` - Success/completion screen\n\nFor multi-step personalization:\n- `screen-personalization-1`\n- `screen-personalization-2`\n\nFor A/B test variants:\n- `screen-welcome-a`\n- `screen-welcome-b`\n";
|
|
9
|
+
//# sourceMappingURL=authoring-guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authoring-guide.d.ts","sourceRoot":"","sources":["../../src/resources/authoring-guide.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,oBAAoB,+/XA2chC,CAAC;AAEF,eAAO,MAAM,eAAe,+kBAmB3B,CAAC"}
|
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML Authoring Guide for RampKit Onboardings
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive guide for AI assistants to generate correct HTML screens.
|
|
5
|
+
* This mirrors the detail level of the Vibe Agent's system prompts but for HTML-first content.
|
|
6
|
+
*/
|
|
7
|
+
export const HTML_AUTHORING_GUIDE = `# RampKit HTML Screen Authoring Guide
|
|
8
|
+
|
|
9
|
+
You are generating HTML screens for mobile app onboarding flows. These screens render in a native WebView on iOS and Android.
|
|
10
|
+
|
|
11
|
+
## Screen Structure
|
|
12
|
+
|
|
13
|
+
Every screen MUST follow this structure:
|
|
14
|
+
|
|
15
|
+
\`\`\`html
|
|
16
|
+
<!DOCTYPE html>
|
|
17
|
+
<html>
|
|
18
|
+
<head>
|
|
19
|
+
<meta charset="utf-8">
|
|
20
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
21
|
+
<style>
|
|
22
|
+
/* CSS styles here */
|
|
23
|
+
</style>
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<div class="screen">
|
|
27
|
+
<!-- Screen content -->
|
|
28
|
+
</div>
|
|
29
|
+
<script>
|
|
30
|
+
// JavaScript here
|
|
31
|
+
</script>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
34
|
+
\`\`\`
|
|
35
|
+
|
|
36
|
+
## Required CSS Reset
|
|
37
|
+
|
|
38
|
+
Always start with this reset:
|
|
39
|
+
|
|
40
|
+
\`\`\`css
|
|
41
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
42
|
+
:root {
|
|
43
|
+
--ramp-primary: #007AFF;
|
|
44
|
+
--ramp-background: #FFFFFF;
|
|
45
|
+
--ramp-text: #1C1C1E;
|
|
46
|
+
--ramp-text-secondary: #8E8E93;
|
|
47
|
+
--ramp-safe-area-top: env(safe-area-inset-top, 44px);
|
|
48
|
+
--ramp-safe-area-bottom: env(safe-area-inset-bottom, 34px);
|
|
49
|
+
}
|
|
50
|
+
body {
|
|
51
|
+
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro', sans-serif;
|
|
52
|
+
background: var(--ramp-background);
|
|
53
|
+
color: var(--ramp-text);
|
|
54
|
+
min-height: 100vh;
|
|
55
|
+
}
|
|
56
|
+
\`\`\`
|
|
57
|
+
|
|
58
|
+
## Safe Areas (CRITICAL)
|
|
59
|
+
|
|
60
|
+
Mobile devices have notches and home indicators. ALWAYS respect safe areas:
|
|
61
|
+
|
|
62
|
+
\`\`\`css
|
|
63
|
+
.screen {
|
|
64
|
+
min-height: 100vh;
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: column;
|
|
67
|
+
/* Add safe area padding - REQUIRED */
|
|
68
|
+
padding: calc(var(--ramp-safe-area-top) + 20px) 24px calc(var(--ramp-safe-area-bottom) + 20px);
|
|
69
|
+
}
|
|
70
|
+
\`\`\`
|
|
71
|
+
|
|
72
|
+
Never place interactive elements or text under the safe areas.
|
|
73
|
+
|
|
74
|
+
## Data Attributes (REQUIRED)
|
|
75
|
+
|
|
76
|
+
Every editable element MUST have BOTH \`data-ramp-id\` AND \`data-ramp-type\`:
|
|
77
|
+
|
|
78
|
+
### Valid Types
|
|
79
|
+
- \`text\` - For headings, paragraphs, spans, labels
|
|
80
|
+
- \`button\` - For clickable buttons (also requires \`data-tap-dynamic\`)
|
|
81
|
+
- \`image\` - For images
|
|
82
|
+
- \`video\` - For video players
|
|
83
|
+
- \`lottie\` - For Lottie animations
|
|
84
|
+
- \`input\` - For form inputs
|
|
85
|
+
|
|
86
|
+
### Text Elements
|
|
87
|
+
\`\`\`html
|
|
88
|
+
<h1 data-ramp-id="title" data-ramp-type="text">Welcome to AppName</h1>
|
|
89
|
+
<p data-ramp-id="subtitle" data-ramp-type="text">Your journey starts here</p>
|
|
90
|
+
<span data-ramp-id="label" data-ramp-type="text">Some label</span>
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
### Button Elements (require data-tap-dynamic for actions)
|
|
94
|
+
\`\`\`html
|
|
95
|
+
<button data-ramp-id="cta" data-ramp-type="button" data-tap-dynamic='{"action":"navigate","target":"next"}'>
|
|
96
|
+
Continue
|
|
97
|
+
</button>
|
|
98
|
+
<button data-ramp-id="skip" data-ramp-type="button" data-tap-dynamic='{"action":"dismiss"}'>
|
|
99
|
+
Skip
|
|
100
|
+
</button>
|
|
101
|
+
<button data-ramp-id="finish_btn" data-ramp-type="button" data-tap-dynamic='{"action":"finish"}'>
|
|
102
|
+
Done
|
|
103
|
+
</button>
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
### Image Elements
|
|
107
|
+
\`\`\`html
|
|
108
|
+
<img data-ramp-id="hero_image" data-ramp-type="image" src="https://example.com/image.png" alt="Hero">
|
|
109
|
+
\`\`\`
|
|
110
|
+
|
|
111
|
+
### data-tap-dynamic Actions
|
|
112
|
+
\`\`\`json
|
|
113
|
+
{"action":"navigate","target":"next"} // Go to next screen
|
|
114
|
+
{"action":"navigate","target":"back"} // Go to previous screen
|
|
115
|
+
{"action":"navigate","target":"screen-id"} // Go to specific screen
|
|
116
|
+
{"action":"dismiss"} // Close onboarding
|
|
117
|
+
{"action":"finish"} // Complete onboarding
|
|
118
|
+
{"action":"requestPermission","permission":"notifications"} // Request permission
|
|
119
|
+
{"action":"purchase","productId":"annual"} // Initiate purchase
|
|
120
|
+
\`\`\`
|
|
121
|
+
|
|
122
|
+
## RampKit JavaScript API
|
|
123
|
+
|
|
124
|
+
The SDK injects a global \`RampKit\` object. Use these methods:
|
|
125
|
+
|
|
126
|
+
### Navigation
|
|
127
|
+
\`\`\`javascript
|
|
128
|
+
RampKit.navigate('next'); // Go to next screen
|
|
129
|
+
RampKit.navigate('back'); // Go to previous screen
|
|
130
|
+
RampKit.navigate('screen-id'); // Go to specific screen
|
|
131
|
+
RampKit.dismiss(); // Close onboarding (user chose to skip)
|
|
132
|
+
RampKit.finish(); // Complete onboarding successfully
|
|
133
|
+
\`\`\`
|
|
134
|
+
|
|
135
|
+
### Permissions
|
|
136
|
+
\`\`\`javascript
|
|
137
|
+
RampKit.requestPermission('notifications'); // Request push notifications
|
|
138
|
+
RampKit.requestPermission('tracking'); // Request ATT (App Tracking Transparency)
|
|
139
|
+
RampKit.requestPermission('location'); // Request location access
|
|
140
|
+
\`\`\`
|
|
141
|
+
|
|
142
|
+
### Paywall & Purchases
|
|
143
|
+
\`\`\`javascript
|
|
144
|
+
RampKit.showPaywall(); // Show paywall screen
|
|
145
|
+
RampKit.purchase('product_id'); // Initiate purchase
|
|
146
|
+
RampKit.restorePurchases(); // Restore previous purchases
|
|
147
|
+
\`\`\`
|
|
148
|
+
|
|
149
|
+
### Analytics
|
|
150
|
+
\`\`\`javascript
|
|
151
|
+
RampKit.track('event_name', { key: 'value' }); // Track custom event
|
|
152
|
+
RampKit.setUserProperty('property', 'value'); // Set user attribute
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
### Variables
|
|
156
|
+
\`\`\`javascript
|
|
157
|
+
RampKit.setVariable('name', value); // Set a state variable
|
|
158
|
+
RampKit.getVariable('name'); // Get a state variable
|
|
159
|
+
\`\`\`
|
|
160
|
+
|
|
161
|
+
### Context
|
|
162
|
+
\`\`\`javascript
|
|
163
|
+
// Access device/user context
|
|
164
|
+
const context = RampKit.getContext();
|
|
165
|
+
// context.device.platform, context.device.language, context.user.isNewUser, etc.
|
|
166
|
+
\`\`\`
|
|
167
|
+
|
|
168
|
+
## Button Patterns
|
|
169
|
+
|
|
170
|
+
### Primary CTA Button
|
|
171
|
+
\`\`\`html
|
|
172
|
+
<button class="btn-primary" onclick="RampKit.navigate('next')">
|
|
173
|
+
Continue
|
|
174
|
+
</button>
|
|
175
|
+
|
|
176
|
+
<style>
|
|
177
|
+
.btn-primary {
|
|
178
|
+
background: var(--ramp-primary);
|
|
179
|
+
color: white;
|
|
180
|
+
border: none;
|
|
181
|
+
padding: 16px;
|
|
182
|
+
border-radius: 14px;
|
|
183
|
+
font-size: 17px;
|
|
184
|
+
font-weight: 600;
|
|
185
|
+
cursor: pointer;
|
|
186
|
+
width: 100%;
|
|
187
|
+
}
|
|
188
|
+
</style>
|
|
189
|
+
\`\`\`
|
|
190
|
+
|
|
191
|
+
### Secondary/Skip Button
|
|
192
|
+
\`\`\`html
|
|
193
|
+
<button class="btn-secondary" onclick="RampKit.dismiss()">
|
|
194
|
+
Skip for now
|
|
195
|
+
</button>
|
|
196
|
+
|
|
197
|
+
<style>
|
|
198
|
+
.btn-secondary {
|
|
199
|
+
background: transparent;
|
|
200
|
+
color: var(--ramp-primary);
|
|
201
|
+
border: none;
|
|
202
|
+
padding: 12px;
|
|
203
|
+
font-size: 15px;
|
|
204
|
+
font-weight: 500;
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
}
|
|
207
|
+
</style>
|
|
208
|
+
\`\`\`
|
|
209
|
+
|
|
210
|
+
### Close Button (X)
|
|
211
|
+
\`\`\`html
|
|
212
|
+
<button class="close-btn" onclick="RampKit.dismiss()">✕</button>
|
|
213
|
+
|
|
214
|
+
<style>
|
|
215
|
+
.close-btn {
|
|
216
|
+
position: absolute;
|
|
217
|
+
top: calc(var(--ramp-safe-area-top) + 12px);
|
|
218
|
+
right: 16px;
|
|
219
|
+
width: 30px;
|
|
220
|
+
height: 30px;
|
|
221
|
+
border-radius: 50%;
|
|
222
|
+
background: #E5E5EA;
|
|
223
|
+
border: none;
|
|
224
|
+
font-size: 18px;
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
}
|
|
227
|
+
</style>
|
|
228
|
+
\`\`\`
|
|
229
|
+
|
|
230
|
+
## Screen Types & Patterns
|
|
231
|
+
|
|
232
|
+
### Welcome Screen
|
|
233
|
+
- Large icon or app logo (80-120px)
|
|
234
|
+
- Bold title (font-size: 28px, weight: 700)
|
|
235
|
+
- Subtitle with value proposition (font-size: 17px, secondary color)
|
|
236
|
+
- Primary CTA button
|
|
237
|
+
- Optional skip link
|
|
238
|
+
|
|
239
|
+
### Features Screen
|
|
240
|
+
- Title at top
|
|
241
|
+
- 2-4 feature rows with icon + text
|
|
242
|
+
- Each feature: icon (48px container) + title + description
|
|
243
|
+
- Continue button at bottom
|
|
244
|
+
|
|
245
|
+
### Permission Screen
|
|
246
|
+
- Large icon representing the permission (80-100px)
|
|
247
|
+
- Clear explanation of WHY you need the permission
|
|
248
|
+
- List of benefits (checkmarks)
|
|
249
|
+
- "Enable" primary button
|
|
250
|
+
- "Maybe Later" secondary button
|
|
251
|
+
|
|
252
|
+
### Personalization Screen
|
|
253
|
+
- Question as title
|
|
254
|
+
- Selectable options (cards or buttons)
|
|
255
|
+
- Visual feedback for selection (border color change)
|
|
256
|
+
- Continue button (disabled until selection)
|
|
257
|
+
|
|
258
|
+
### Paywall Screen
|
|
259
|
+
- Badge/tier indicator
|
|
260
|
+
- Value proposition headline
|
|
261
|
+
- List of benefits
|
|
262
|
+
- Plan options (monthly/yearly cards)
|
|
263
|
+
- Subscribe button
|
|
264
|
+
- Terms/privacy links
|
|
265
|
+
|
|
266
|
+
### Completion Screen
|
|
267
|
+
- Success icon (checkmark)
|
|
268
|
+
- Celebration message
|
|
269
|
+
- Optional confetti animation
|
|
270
|
+
- "Let's Go" finish button
|
|
271
|
+
|
|
272
|
+
## Typography Scale
|
|
273
|
+
|
|
274
|
+
| Use Case | Size | Weight |
|
|
275
|
+
|----------|------|--------|
|
|
276
|
+
| Hero title | 28-32px | 700 |
|
|
277
|
+
| Section title | 24-26px | 700 |
|
|
278
|
+
| Body title | 17-18px | 600 |
|
|
279
|
+
| Body text | 16-17px | 400 |
|
|
280
|
+
| Secondary text | 14-15px | 400 |
|
|
281
|
+
| Caption | 12-13px | 400 |
|
|
282
|
+
|
|
283
|
+
## Color Guidelines
|
|
284
|
+
|
|
285
|
+
Always use CSS variables for easy theming:
|
|
286
|
+
|
|
287
|
+
\`\`\`css
|
|
288
|
+
:root {
|
|
289
|
+
/* Primary brand color - customize per app */
|
|
290
|
+
--ramp-primary: #007AFF;
|
|
291
|
+
--ramp-primary-dark: #0056b3;
|
|
292
|
+
|
|
293
|
+
/* Backgrounds */
|
|
294
|
+
--ramp-background: #FFFFFF;
|
|
295
|
+
--ramp-surface: #F2F2F7;
|
|
296
|
+
|
|
297
|
+
/* Text */
|
|
298
|
+
--ramp-text: #1C1C1E;
|
|
299
|
+
--ramp-text-secondary: #8E8E93;
|
|
300
|
+
|
|
301
|
+
/* Feedback */
|
|
302
|
+
--ramp-success: #34C759;
|
|
303
|
+
--ramp-warning: #FF9500;
|
|
304
|
+
--ramp-error: #FF3B30;
|
|
305
|
+
|
|
306
|
+
/* Borders */
|
|
307
|
+
--ramp-border: #E5E5EA;
|
|
308
|
+
}
|
|
309
|
+
\`\`\`
|
|
310
|
+
|
|
311
|
+
## Interactive Elements
|
|
312
|
+
|
|
313
|
+
### Option Selection
|
|
314
|
+
\`\`\`html
|
|
315
|
+
<div class="option" data-value="choice1" onclick="selectOption(this)">
|
|
316
|
+
<span class="option-icon">🏠</span>
|
|
317
|
+
<div class="option-content">
|
|
318
|
+
<h3>Option Title</h3>
|
|
319
|
+
<p>Option description</p>
|
|
320
|
+
</div>
|
|
321
|
+
<div class="option-check">✓</div>
|
|
322
|
+
</div>
|
|
323
|
+
|
|
324
|
+
<script>
|
|
325
|
+
let selectedValue = null;
|
|
326
|
+
|
|
327
|
+
function selectOption(el) {
|
|
328
|
+
document.querySelectorAll('.option').forEach(o => o.classList.remove('selected'));
|
|
329
|
+
el.classList.add('selected');
|
|
330
|
+
selectedValue = el.dataset.value;
|
|
331
|
+
document.querySelector('.btn-primary').disabled = false;
|
|
332
|
+
}
|
|
333
|
+
</script>
|
|
334
|
+
|
|
335
|
+
<style>
|
|
336
|
+
.option {
|
|
337
|
+
display: flex;
|
|
338
|
+
align-items: center;
|
|
339
|
+
gap: 16px;
|
|
340
|
+
padding: 16px;
|
|
341
|
+
border: 2px solid var(--ramp-border);
|
|
342
|
+
border-radius: 14px;
|
|
343
|
+
cursor: pointer;
|
|
344
|
+
transition: all 0.2s;
|
|
345
|
+
}
|
|
346
|
+
.option.selected {
|
|
347
|
+
border-color: var(--ramp-primary);
|
|
348
|
+
background: rgba(0, 122, 255, 0.05);
|
|
349
|
+
}
|
|
350
|
+
.option-check {
|
|
351
|
+
width: 24px;
|
|
352
|
+
height: 24px;
|
|
353
|
+
border-radius: 50%;
|
|
354
|
+
border: 2px solid var(--ramp-border);
|
|
355
|
+
display: flex;
|
|
356
|
+
align-items: center;
|
|
357
|
+
justify-content: center;
|
|
358
|
+
color: transparent;
|
|
359
|
+
}
|
|
360
|
+
.option.selected .option-check {
|
|
361
|
+
background: var(--ramp-primary);
|
|
362
|
+
border-color: var(--ramp-primary);
|
|
363
|
+
color: white;
|
|
364
|
+
}
|
|
365
|
+
</style>
|
|
366
|
+
\`\`\`
|
|
367
|
+
|
|
368
|
+
### Plan Selection (Paywall)
|
|
369
|
+
\`\`\`html
|
|
370
|
+
<div class="plans">
|
|
371
|
+
<div class="plan" data-plan="monthly" onclick="selectPlan(this)">
|
|
372
|
+
<div class="plan-period">Monthly</div>
|
|
373
|
+
<div class="plan-price">$9.99<span>/mo</span></div>
|
|
374
|
+
</div>
|
|
375
|
+
<div class="plan popular selected" data-plan="annual" onclick="selectPlan(this)">
|
|
376
|
+
<div class="plan-period">Annual</div>
|
|
377
|
+
<div class="plan-price">$4.99<span>/mo</span></div>
|
|
378
|
+
<div class="plan-savings">Save 50%</div>
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
|
|
382
|
+
<script>
|
|
383
|
+
let selectedPlan = 'annual';
|
|
384
|
+
|
|
385
|
+
function selectPlan(el) {
|
|
386
|
+
document.querySelectorAll('.plan').forEach(p => p.classList.remove('selected'));
|
|
387
|
+
el.classList.add('selected');
|
|
388
|
+
selectedPlan = el.dataset.plan;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function subscribe() {
|
|
392
|
+
RampKit.track('paywall_cta_clicked', { plan: selectedPlan });
|
|
393
|
+
RampKit.purchase(selectedPlan);
|
|
394
|
+
}
|
|
395
|
+
</script>
|
|
396
|
+
\`\`\`
|
|
397
|
+
|
|
398
|
+
## Animation Examples
|
|
399
|
+
|
|
400
|
+
### Scale-in Animation
|
|
401
|
+
\`\`\`css
|
|
402
|
+
@keyframes scaleIn {
|
|
403
|
+
0% { transform: scale(0); opacity: 0; }
|
|
404
|
+
50% { transform: scale(1.1); }
|
|
405
|
+
100% { transform: scale(1); opacity: 1; }
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.animated-icon {
|
|
409
|
+
animation: scaleIn 0.5s ease-out;
|
|
410
|
+
}
|
|
411
|
+
\`\`\`
|
|
412
|
+
|
|
413
|
+
### Confetti Effect
|
|
414
|
+
\`\`\`html
|
|
415
|
+
<div class="confetti" id="confetti"></div>
|
|
416
|
+
|
|
417
|
+
<style>
|
|
418
|
+
.confetti {
|
|
419
|
+
position: fixed;
|
|
420
|
+
top: 0;
|
|
421
|
+
left: 0;
|
|
422
|
+
width: 100%;
|
|
423
|
+
height: 100%;
|
|
424
|
+
pointer-events: none;
|
|
425
|
+
overflow: hidden;
|
|
426
|
+
}
|
|
427
|
+
.confetti-piece {
|
|
428
|
+
position: absolute;
|
|
429
|
+
width: 10px;
|
|
430
|
+
height: 10px;
|
|
431
|
+
animation: confetti-fall 3s linear forwards;
|
|
432
|
+
}
|
|
433
|
+
@keyframes confetti-fall {
|
|
434
|
+
0% { transform: translateY(-100%) rotate(0deg); opacity: 1; }
|
|
435
|
+
100% { transform: translateY(100vh) rotate(720deg); opacity: 0; }
|
|
436
|
+
}
|
|
437
|
+
</style>
|
|
438
|
+
|
|
439
|
+
<script>
|
|
440
|
+
const colors = ['#FF3B30', '#FF9500', '#FFCC00', '#34C759', '#007AFF', '#5856D6'];
|
|
441
|
+
const container = document.getElementById('confetti');
|
|
442
|
+
|
|
443
|
+
for (let i = 0; i < 50; i++) {
|
|
444
|
+
const piece = document.createElement('div');
|
|
445
|
+
piece.className = 'confetti-piece';
|
|
446
|
+
piece.style.left = Math.random() * 100 + '%';
|
|
447
|
+
piece.style.background = colors[Math.floor(Math.random() * colors.length)];
|
|
448
|
+
piece.style.animationDelay = Math.random() * 2 + 's';
|
|
449
|
+
container.appendChild(piece);
|
|
450
|
+
}
|
|
451
|
+
</script>
|
|
452
|
+
\`\`\`
|
|
453
|
+
|
|
454
|
+
## Important Rules
|
|
455
|
+
|
|
456
|
+
1. **ALWAYS include safe area padding** - Never place content under notch or home indicator
|
|
457
|
+
2. **ALWAYS use data-ramp-id** on text elements for tracking
|
|
458
|
+
3. **ALWAYS use CSS variables** for colors - makes theming easy
|
|
459
|
+
4. **Use system fonts** - \`-apple-system, BlinkMacSystemFont\` for native feel
|
|
460
|
+
5. **Keep HTML self-contained** - All CSS and JS inline in the file
|
|
461
|
+
6. **Minimum touch targets** - Buttons should be at least 44px tall
|
|
462
|
+
7. **Consistent button placement** - CTAs at bottom, above safe area
|
|
463
|
+
8. **Test on multiple sizes** - Works on iPhone SE and iPad
|
|
464
|
+
9. **Never use emojis in production** - They render differently across devices. Use icons from a CDN if needed.
|
|
465
|
+
10. **Keep screens focused** - One key message or action per screen
|
|
466
|
+
`;
|
|
467
|
+
export const SCREEN_ID_GUIDE = `## Screen ID Conventions
|
|
468
|
+
|
|
469
|
+
Use descriptive, kebab-case IDs for screens:
|
|
470
|
+
|
|
471
|
+
- \`screen-welcome\` - Welcome/intro screen
|
|
472
|
+
- \`screen-features\` - Feature highlights
|
|
473
|
+
- \`screen-permissions-notifications\` - Notification permission
|
|
474
|
+
- \`screen-permissions-tracking\` - ATT permission
|
|
475
|
+
- \`screen-personalization\` - User preference questions
|
|
476
|
+
- \`screen-paywall\` - Subscription offer
|
|
477
|
+
- \`screen-complete\` - Success/completion screen
|
|
478
|
+
|
|
479
|
+
For multi-step personalization:
|
|
480
|
+
- \`screen-personalization-1\`
|
|
481
|
+
- \`screen-personalization-2\`
|
|
482
|
+
|
|
483
|
+
For A/B test variants:
|
|
484
|
+
- \`screen-welcome-a\`
|
|
485
|
+
- \`screen-welcome-b\`
|
|
486
|
+
`;
|
|
487
|
+
//# sourceMappingURL=authoring-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authoring-guide.js","sourceRoot":"","sources":["../../src/resources/authoring-guide.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2cnC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;CAmB9B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best Practices for Onboarding Design
|
|
3
|
+
*
|
|
4
|
+
* Guidelines and CSS variables for creating effective onboardings.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BEST_PRACTICES: string[];
|
|
7
|
+
export declare const CSS_VARIABLES: Record<string, string>;
|
|
8
|
+
//# sourceMappingURL=best-practices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.d.ts","sourceRoot":"","sources":["../../src/resources/best-practices.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,cAAc,EAAE,MAAM,EAmClC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAwGhD,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best Practices for Onboarding Design
|
|
3
|
+
*
|
|
4
|
+
* Guidelines and CSS variables for creating effective onboardings.
|
|
5
|
+
*/
|
|
6
|
+
export const BEST_PRACTICES = [
|
|
7
|
+
// Content Strategy
|
|
8
|
+
'Keep each screen focused on ONE key message or action. Users should immediately understand what to do.',
|
|
9
|
+
'Use the app\'s actual colors, fonts, and visual style to create a seamless experience.',
|
|
10
|
+
'Write copy that speaks directly to the user using "you" language. Avoid corporate jargon.',
|
|
11
|
+
'Show value before asking for permissions. Explain WHY you need notifications, location, etc.',
|
|
12
|
+
'Make progress visible with indicators or page dots. Users want to know how long the flow is.',
|
|
13
|
+
// Visual Design
|
|
14
|
+
'Use large, clear CTAs that are easy to tap. Minimum touch target is 44x44pt.',
|
|
15
|
+
'Maintain consistent button placement across screens (usually bottom, above safe area).',
|
|
16
|
+
'Use illustrations or icons to make abstract concepts concrete and memorable.',
|
|
17
|
+
'Ensure sufficient color contrast for accessibility (4.5:1 ratio for text).',
|
|
18
|
+
'Respect safe areas on notched devices - never place content under the notch or home indicator.',
|
|
19
|
+
// Screen Types
|
|
20
|
+
'Start with a warm welcome that sets expectations for the onboarding flow.',
|
|
21
|
+
'Highlight 2-4 key features - too many overwhelms users.',
|
|
22
|
+
'Permission screens should explain the benefit, not just ask for access.',
|
|
23
|
+
'Personalization questions (2-3 max) should meaningfully customize the experience.',
|
|
24
|
+
'End with a success/completion screen that celebrates and motivates action.',
|
|
25
|
+
// Technical
|
|
26
|
+
'Use data-ramp-id attributes on all text elements for easy content updates.',
|
|
27
|
+
'Use CSS variables (--ramp-primary, etc.) so colors can be customized without code changes.',
|
|
28
|
+
'Test on multiple device sizes - the layout should work on both iPhone SE and iPad.',
|
|
29
|
+
'Keep HTML files self-contained with inline CSS and JavaScript.',
|
|
30
|
+
'Use system fonts (-apple-system, BlinkMacSystemFont) for native feel.',
|
|
31
|
+
// Optimization
|
|
32
|
+
'Keep onboardings to 3-5 screens maximum. Every extra screen reduces completion rate.',
|
|
33
|
+
'Always include a skip option for users who want to explore immediately.',
|
|
34
|
+
'A/B test different copy, images, and screen order to optimize conversion.',
|
|
35
|
+
'Track screen views and drop-offs to identify where users are leaving.',
|
|
36
|
+
'Measure completion rate - aim for 60%+ for a good onboarding.',
|
|
37
|
+
];
|
|
38
|
+
export const CSS_VARIABLES = {
|
|
39
|
+
// Brand Colors
|
|
40
|
+
'--ramp-primary': 'Primary brand color for buttons and interactive elements. Default: #007AFF (iOS blue)',
|
|
41
|
+
'--ramp-primary-dark': 'Darker variant of primary for hover/pressed states. Default: #0056b3',
|
|
42
|
+
'--ramp-secondary': 'Secondary accent color for highlights. Default: #5856D6 (iOS purple)',
|
|
43
|
+
// Background & Surface
|
|
44
|
+
'--ramp-background': 'Main background color. Default: #FFFFFF (light) or #000000 (dark)',
|
|
45
|
+
'--ramp-surface': 'Card/panel background color. Default: #F2F2F7 (light) or #1C1C1E (dark)',
|
|
46
|
+
'--ramp-surface-elevated': 'Elevated surface (modals, dropdowns). Default: #FFFFFF',
|
|
47
|
+
// Text Colors
|
|
48
|
+
'--ramp-text': 'Primary text color. Default: #1C1C1E (light) or #FFFFFF (dark)',
|
|
49
|
+
'--ramp-text-secondary': 'Secondary/muted text. Default: #8E8E93',
|
|
50
|
+
'--ramp-text-tertiary': 'Tertiary/placeholder text. Default: #C7C7CC',
|
|
51
|
+
'--ramp-text-on-primary': 'Text color on primary background. Default: #FFFFFF',
|
|
52
|
+
// Feedback Colors
|
|
53
|
+
'--ramp-success': 'Success state color. Default: #34C759 (iOS green)',
|
|
54
|
+
'--ramp-warning': 'Warning state color. Default: #FF9500 (iOS orange)',
|
|
55
|
+
'--ramp-error': 'Error state color. Default: #FF3B30 (iOS red)',
|
|
56
|
+
'--ramp-info': 'Info state color. Default: #007AFF (iOS blue)',
|
|
57
|
+
// Borders & Dividers
|
|
58
|
+
'--ramp-border': 'Border color for inputs and cards. Default: #E5E5EA',
|
|
59
|
+
'--ramp-divider': 'Divider/separator color. Default: #C6C6C8',
|
|
60
|
+
// Safe Areas
|
|
61
|
+
'--ramp-safe-area-top': 'Safe area inset from top (notch, status bar). Automatically set by SDK.',
|
|
62
|
+
'--ramp-safe-area-bottom': 'Safe area inset from bottom (home indicator). Automatically set by SDK.',
|
|
63
|
+
'--ramp-safe-area-left': 'Safe area inset from left (landscape). Automatically set by SDK.',
|
|
64
|
+
'--ramp-safe-area-right': 'Safe area inset from right (landscape). Automatically set by SDK.',
|
|
65
|
+
// Layout
|
|
66
|
+
'--ramp-content-max-width': 'Maximum content width for readability. Default: 400px',
|
|
67
|
+
'--ramp-spacing-unit': 'Base spacing unit for consistent rhythm. Default: 8px',
|
|
68
|
+
// Typography
|
|
69
|
+
'--ramp-font-family': 'Font family stack. Default: -apple-system, BlinkMacSystemFont, "SF Pro", "Segoe UI", sans-serif',
|
|
70
|
+
'--ramp-font-size-xs': 'Extra small text. Default: 12px',
|
|
71
|
+
'--ramp-font-size-sm': 'Small text. Default: 14px',
|
|
72
|
+
'--ramp-font-size-base': 'Base/body text. Default: 16px',
|
|
73
|
+
'--ramp-font-size-lg': 'Large text. Default: 18px',
|
|
74
|
+
'--ramp-font-size-xl': 'Extra large text. Default: 20px',
|
|
75
|
+
'--ramp-font-size-2xl': 'Heading text. Default: 24px',
|
|
76
|
+
'--ramp-font-size-3xl': 'Large heading. Default: 28px',
|
|
77
|
+
// Animation
|
|
78
|
+
'--ramp-transition-fast': 'Fast transition duration. Default: 150ms',
|
|
79
|
+
'--ramp-transition-normal': 'Normal transition duration. Default: 250ms',
|
|
80
|
+
'--ramp-transition-slow': 'Slow transition duration. Default: 400ms',
|
|
81
|
+
// Shadows
|
|
82
|
+
'--ramp-shadow-sm': 'Small shadow for subtle elevation. Default: 0 1px 2px rgba(0,0,0,0.1)',
|
|
83
|
+
'--ramp-shadow-md': 'Medium shadow for cards. Default: 0 4px 6px rgba(0,0,0,0.1)',
|
|
84
|
+
'--ramp-shadow-lg': 'Large shadow for modals. Default: 0 10px 15px rgba(0,0,0,0.1)',
|
|
85
|
+
// Border Radius
|
|
86
|
+
'--ramp-radius-sm': 'Small border radius. Default: 6px',
|
|
87
|
+
'--ramp-radius-md': 'Medium border radius. Default: 12px',
|
|
88
|
+
'--ramp-radius-lg': 'Large border radius. Default: 16px',
|
|
89
|
+
'--ramp-radius-xl': 'Extra large border radius. Default: 24px',
|
|
90
|
+
'--ramp-radius-full': 'Full/pill border radius. Default: 9999px',
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=best-practices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.js","sourceRoot":"","sources":["../../src/resources/best-practices.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAa;IACtC,mBAAmB;IACnB,wGAAwG;IACxG,wFAAwF;IACxF,2FAA2F;IAC3F,8FAA8F;IAC9F,8FAA8F;IAE9F,gBAAgB;IAChB,8EAA8E;IAC9E,wFAAwF;IACxF,8EAA8E;IAC9E,4EAA4E;IAC5E,gGAAgG;IAEhG,eAAe;IACf,2EAA2E;IAC3E,yDAAyD;IACzD,yEAAyE;IACzE,mFAAmF;IACnF,4EAA4E;IAE5E,YAAY;IACZ,4EAA4E;IAC5E,4FAA4F;IAC5F,oFAAoF;IACpF,gEAAgE;IAChE,uEAAuE;IAEvE,eAAe;IACf,sFAAsF;IACtF,yEAAyE;IACzE,2EAA2E;IAC3E,uEAAuE;IACvE,+DAA+D;CAChE,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,eAAe;IACf,gBAAgB,EACd,uFAAuF;IACzF,qBAAqB,EACnB,sEAAsE;IACxE,kBAAkB,EAChB,sEAAsE;IAExE,uBAAuB;IACvB,mBAAmB,EACjB,mEAAmE;IACrE,gBAAgB,EACd,yEAAyE;IAC3E,yBAAyB,EACvB,wDAAwD;IAE1D,cAAc;IACd,aAAa,EACX,gEAAgE;IAClE,uBAAuB,EACrB,wCAAwC;IAC1C,sBAAsB,EACpB,6CAA6C;IAC/C,wBAAwB,EACtB,oDAAoD;IAEtD,kBAAkB;IAClB,gBAAgB,EACd,mDAAmD;IACrD,gBAAgB,EACd,oDAAoD;IACtD,cAAc,EACZ,+CAA+C;IACjD,aAAa,EACX,+CAA+C;IAEjD,qBAAqB;IACrB,eAAe,EACb,qDAAqD;IACvD,gBAAgB,EACd,2CAA2C;IAE7C,aAAa;IACb,sBAAsB,EACpB,yEAAyE;IAC3E,yBAAyB,EACvB,yEAAyE;IAC3E,uBAAuB,EACrB,kEAAkE;IACpE,wBAAwB,EACtB,mEAAmE;IAErE,SAAS;IACT,0BAA0B,EACxB,uDAAuD;IACzD,qBAAqB,EACnB,uDAAuD;IAEzD,aAAa;IACb,oBAAoB,EAClB,iGAAiG;IACnG,qBAAqB,EACnB,iCAAiC;IACnC,qBAAqB,EACnB,2BAA2B;IAC7B,uBAAuB,EACrB,+BAA+B;IACjC,qBAAqB,EACnB,2BAA2B;IAC7B,qBAAqB,EACnB,iCAAiC;IACnC,sBAAsB,EACpB,6BAA6B;IAC/B,sBAAsB,EACpB,8BAA8B;IAEhC,YAAY;IACZ,wBAAwB,EACtB,0CAA0C;IAC5C,0BAA0B,EACxB,4CAA4C;IAC9C,wBAAwB,EACtB,0CAA0C;IAE5C,UAAU;IACV,kBAAkB,EAChB,uEAAuE;IACzE,kBAAkB,EAChB,6DAA6D;IAC/D,kBAAkB,EAChB,+DAA+D;IAEjE,gBAAgB;IAChB,kBAAkB,EAChB,mCAAmC;IACrC,kBAAkB,EAChB,qCAAqC;IACvC,kBAAkB,EAChB,oCAAoC;IACtC,kBAAkB,EAChB,0CAA0C;IAC5C,oBAAoB,EAClB,0CAA0C;CAC7C,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resources
|
|
3
|
+
*
|
|
4
|
+
* Exposes RampKit schema, templates, and documentation as MCP resources.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getResources(): {
|
|
7
|
+
uri: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
mimeType: string;
|
|
11
|
+
}[];
|
|
12
|
+
export declare function readResource(uri: string): {
|
|
13
|
+
contents: Array<{
|
|
14
|
+
uri: string;
|
|
15
|
+
mimeType: string;
|
|
16
|
+
text: string;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,wBAAgB,YAAY;;;;;IA6F3B;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAiI9G"}
|