@nordsym/apiclaw 1.0.0 → 1.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.
- package/AGENTS.md +74 -0
- package/HEARTBEAT.md +4 -0
- package/IDENTITY.md +22 -0
- package/README.md +193 -202
- package/SOUL.md +36 -0
- package/STATUS.md +237 -0
- package/TOOLS.md +36 -0
- package/USER.md +17 -0
- package/{backend/convex → convex}/_generated/api.d.ts +12 -6
- package/convex/analytics.ts +90 -0
- package/convex/credits.ts +211 -0
- package/convex/http.ts +578 -0
- package/convex/providers.ts +516 -0
- package/convex/purchases.ts +183 -0
- package/convex/ratelimit.ts +104 -0
- package/convex/schema.ts +220 -0
- package/convex/telemetry.ts +81 -0
- package/convex.json +3 -0
- package/dist/credentials.d.ts +19 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +158 -0
- package/dist/credentials.js.map +1 -0
- package/dist/credits.d.ts +14 -11
- package/dist/credits.d.ts.map +1 -1
- package/dist/credits.js +151 -99
- package/dist/credits.js.map +1 -1
- package/dist/discovery.d.ts +7 -16
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +33 -40
- package/dist/discovery.js.map +1 -1
- package/dist/execute.d.ts +19 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +285 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.js +175 -31
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +6 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +19 -0
- package/dist/proxy.js.map +1 -0
- package/dist/registry/apis.json +95362 -202
- package/dist/registry/apis_expanded.json +100853 -0
- package/dist/stripe.d.ts +68 -0
- package/dist/stripe.d.ts.map +1 -0
- package/dist/stripe.js +196 -0
- package/dist/stripe.js.map +1 -0
- package/dist/telemetry.d.ts +28 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +50 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/test.d.ts +3 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +105 -75
- package/dist/test.js.map +1 -1
- package/dist/types.d.ts +0 -28
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook.d.ts +2 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +90 -0
- package/dist/webhook.js.map +1 -0
- package/landing/DESIGN.md +343 -0
- package/landing/package-lock.json +1196 -7
- package/landing/package.json +5 -1
- package/landing/public/android-chrome-192x192.png +0 -0
- package/landing/public/android-chrome-512x512.png +0 -0
- package/landing/public/apple-touch-icon.png +0 -0
- package/landing/public/demo.gif +0 -0
- package/landing/public/demo.mp4 +0 -0
- package/landing/public/favicon-16x16.png +0 -0
- package/landing/public/favicon-32x32.png +0 -0
- package/landing/public/favicon.ico +0 -0
- package/landing/public/favicon.svg +3 -0
- package/landing/public/icon.svg +47 -0
- package/landing/public/logo-mono.svg +37 -0
- package/landing/public/logo-simple.svg +45 -0
- package/landing/public/logo.svg +84 -0
- package/landing/public/og-template.html +184 -0
- package/landing/public/site.webmanifest +31 -0
- package/landing/scripts/generate-assets.js +284 -0
- package/landing/scripts/generate-pngs.js +48 -0
- package/landing/scripts/generate-stats.js +42 -0
- package/landing/src/app/admin/page.tsx +348 -0
- package/landing/src/app/api/auth/magic-link/route.ts +73 -0
- package/landing/src/app/api/auth/session/route.ts +38 -0
- package/landing/src/app/api/auth/verify/route.ts +43 -0
- package/landing/src/app/api/og/route.tsx +84 -0
- package/landing/src/app/globals.css +439 -100
- package/landing/src/app/layout.tsx +37 -7
- package/landing/src/app/page.tsx +627 -552
- package/landing/src/app/providers/dashboard/login/page.tsx +176 -0
- package/landing/src/app/providers/dashboard/page.tsx +589 -0
- package/landing/src/app/providers/dashboard/verify/page.tsx +106 -0
- package/landing/src/app/providers/layout.tsx +14 -0
- package/landing/src/app/providers/page.tsx +402 -0
- package/landing/src/app/providers/register/page.tsx +670 -0
- package/landing/src/components/ProviderDashboard.tsx +794 -0
- package/landing/src/hooks/useDashboardData.ts +99 -0
- package/landing/src/lib/apis.json +116054 -0
- package/landing/src/lib/convex-client.ts +106 -0
- package/landing/src/lib/mock-data.ts +285 -0
- package/landing/src/lib/stats.json +6 -0
- package/landing/tailwind.config.ts +12 -11
- package/landing/tsconfig.tsbuildinfo +1 -0
- package/package.json +21 -20
- package/scripts/SYMBOT-FIX.md +238 -0
- package/scripts/demo-simulation.py +177 -0
- package/scripts/expand-more.py +502 -0
- package/scripts/expand-registry.py +434 -0
- package/scripts/history-sanitizer.ts +272 -0
- package/scripts/mass-scrape.py +1308 -0
- package/scripts/sync-and-deploy.sh +36 -0
- package/src/credentials.ts +177 -0
- package/src/credits.ts +190 -122
- package/src/discovery.ts +45 -58
- package/src/execute.ts +350 -0
- package/src/index.ts +184 -32
- package/src/proxy.ts +24 -0
- package/src/registry/apis.json +95362 -202
- package/src/registry/apis_expanded.json +100853 -0
- package/src/stripe.ts +243 -0
- package/src/telemetry.ts +71 -0
- package/src/test.ts +127 -89
- package/src/types.ts +0 -34
- package/src/webhook.ts +107 -0
- package/.github/ISSUE_TEMPLATE/add-api.yml +0 -123
- package/BRIEFING.md +0 -30
- package/backend/convex/apiKeys.ts +0 -75
- package/backend/convex/purchases.ts +0 -74
- package/backend/convex/schema.ts +0 -45
- package/backend/convex/transactions.ts +0 -57
- package/backend/convex/users.ts +0 -94
- package/backend/package-lock.json +0 -521
- package/backend/package.json +0 -15
- package/dist/registry/parse_apis.py +0 -146
- package/dist/revenuecat.d.ts +0 -61
- package/dist/revenuecat.d.ts.map +0 -1
- package/dist/revenuecat.js +0 -166
- package/dist/revenuecat.js.map +0 -1
- package/dist/webhooks/revenuecat.d.ts +0 -48
- package/dist/webhooks/revenuecat.d.ts.map +0 -1
- package/dist/webhooks/revenuecat.js +0 -119
- package/dist/webhooks/revenuecat.js.map +0 -1
- package/docs/revenuecat-setup.md +0 -89
- package/landing/src/app/api/keys/route.ts +0 -71
- package/landing/src/app/api/log/route.ts +0 -37
- package/landing/src/app/api/stats/route.ts +0 -37
- package/landing/src/app/page.tsx.bak +0 -567
- package/landing/src/components/AddKeyModal.tsx +0 -159
- package/newsletter-template.html +0 -71
- package/outreach/OUTREACH-SYSTEM.md +0 -211
- package/outreach/email-template.html +0 -179
- package/outreach/targets.md +0 -133
- package/src/registry/parse_apis.py +0 -146
- package/src/revenuecat.ts +0 -239
- package/src/webhooks/revenuecat.ts +0 -187
- /package/{backend/convex → convex}/README.md +0 -0
- /package/{backend/convex → convex}/_generated/api.js +0 -0
- /package/{backend/convex → convex}/_generated/dataModel.d.ts +0 -0
- /package/{backend/convex → convex}/_generated/server.d.ts +0 -0
- /package/{backend/convex → convex}/_generated/server.js +0 -0
- /package/{backend/convex → convex}/tsconfig.json +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":""}
|
package/dist/webhook.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Stripe webhook handler for APIClaw
|
|
2
|
+
// Run as: npx ts-node src/webhook.ts
|
|
3
|
+
import { serve } from '@hono/node-server';
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
import { verifyWebhookSignature, processWebhookEvent, CREDIT_PACKAGES } from './stripe.js';
|
|
6
|
+
import { addCredits } from './credits.js';
|
|
7
|
+
import { config } from 'dotenv';
|
|
8
|
+
// Load environment
|
|
9
|
+
config({ path: '.env.local' });
|
|
10
|
+
const app = new Hono();
|
|
11
|
+
// Health check
|
|
12
|
+
app.get('/', (c) => {
|
|
13
|
+
return c.json({
|
|
14
|
+
service: 'APIClaw Webhook',
|
|
15
|
+
status: 'ok',
|
|
16
|
+
packages: Object.values(CREDIT_PACKAGES).map(p => ({
|
|
17
|
+
id: p.id,
|
|
18
|
+
price: `$${p.amountUsd}`,
|
|
19
|
+
credits: p.credits,
|
|
20
|
+
})),
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
// Stripe webhook endpoint
|
|
24
|
+
app.post('/webhook/stripe', async (c) => {
|
|
25
|
+
const signature = c.req.header('stripe-signature');
|
|
26
|
+
if (!signature) {
|
|
27
|
+
return c.json({ error: 'Missing stripe-signature header' }, 400);
|
|
28
|
+
}
|
|
29
|
+
// Get raw body
|
|
30
|
+
const rawBody = await c.req.text();
|
|
31
|
+
// Verify webhook signature
|
|
32
|
+
const event = verifyWebhookSignature(rawBody, signature);
|
|
33
|
+
if (!event) {
|
|
34
|
+
return c.json({ error: 'Invalid webhook signature' }, 400);
|
|
35
|
+
}
|
|
36
|
+
console.log(`[Webhook] Received: ${event.type}`);
|
|
37
|
+
// Process the event
|
|
38
|
+
const creditGrant = processWebhookEvent(event);
|
|
39
|
+
if (!creditGrant) {
|
|
40
|
+
// Not a credit-related event, acknowledge and move on
|
|
41
|
+
return c.json({ received: true, processed: false });
|
|
42
|
+
}
|
|
43
|
+
// Grant credits to the agent
|
|
44
|
+
try {
|
|
45
|
+
const credits = addCredits(creditGrant.agentId, creditGrant.credits);
|
|
46
|
+
console.log(`[Webhook] Granted ${creditGrant.credits} credits to ${creditGrant.agentId}`);
|
|
47
|
+
console.log(`[Webhook] New balance: $${credits.balance_usd.toFixed(2)}`);
|
|
48
|
+
return c.json({
|
|
49
|
+
received: true,
|
|
50
|
+
processed: true,
|
|
51
|
+
grant: {
|
|
52
|
+
agentId: creditGrant.agentId,
|
|
53
|
+
credits: creditGrant.credits,
|
|
54
|
+
newBalance: credits.balance_usd,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error('[Webhook] Error granting credits:', error);
|
|
60
|
+
return c.json({ error: 'Failed to grant credits' }, 500);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// Manual credit grant endpoint (for testing)
|
|
64
|
+
app.post('/admin/grant-credits', async (c) => {
|
|
65
|
+
const body = await c.req.json();
|
|
66
|
+
const { agentId, credits, adminKey } = body;
|
|
67
|
+
// Simple admin key check (use proper auth in production)
|
|
68
|
+
if (adminKey !== process.env.ADMIN_KEY && adminKey !== 'test-admin-key') {
|
|
69
|
+
return c.json({ error: 'Invalid admin key' }, 403);
|
|
70
|
+
}
|
|
71
|
+
if (!agentId || typeof credits !== 'number') {
|
|
72
|
+
return c.json({ error: 'Missing agentId or credits' }, 400);
|
|
73
|
+
}
|
|
74
|
+
const result = addCredits(agentId, credits);
|
|
75
|
+
return c.json({
|
|
76
|
+
success: true,
|
|
77
|
+
agentId,
|
|
78
|
+
creditsGranted: credits,
|
|
79
|
+
newBalance: result.balance_usd,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
// Start server
|
|
83
|
+
const port = parseInt(process.env.WEBHOOK_PORT || '3001', 10);
|
|
84
|
+
console.log(`[APIClaw] Webhook server starting on port ${port}`);
|
|
85
|
+
console.log(`[APIClaw] Endpoints:`);
|
|
86
|
+
console.log(` GET / - Health check`);
|
|
87
|
+
console.log(` POST /webhook/stripe - Stripe webhook`);
|
|
88
|
+
console.log(` POST /admin/grant-credits - Manual credit grant`);
|
|
89
|
+
serve({ fetch: app.fetch, port });
|
|
90
|
+
//# sourceMappingURL=webhook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,qCAAqC;AAErC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,mBAAmB;AACnB,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AAE/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAEvB,eAAe;AACf,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,iBAAiB;QAC1B,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACjD,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,KAAK,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE;YACxB,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC;KACJ,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,0BAA0B;AAC1B,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACtC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,eAAe;IACf,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAEnC,2BAA2B;IAC3B,MAAM,KAAK,GAAG,sBAAsB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjD,oBAAoB;IACpB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,sDAAsD;QACtD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,6BAA6B;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;QAErE,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,CAAC,OAAO,eAAe,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,2BAA2B,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAEzE,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,KAAK,EAAE;gBACL,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,UAAU,EAAE,OAAO,CAAC,WAAW;aAChC;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAC1D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,6CAA6C;AAC7C,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE5C,yDAAyD;IACzD,IAAI,QAAQ,KAAK,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QACxE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,IAAI;QACb,OAAO;QACP,cAAc,EAAE,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,WAAW;KAC/B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,eAAe;AACf,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAE9D,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;AACjE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACpC,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;AACrD,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AACvD,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;AAEjE,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# APIClaw Design System
|
|
2
|
+
|
|
3
|
+
> "If Jason Calacanis would see this, it should look like a $10M funded startup."
|
|
4
|
+
|
|
5
|
+
## Brand Identity
|
|
6
|
+
|
|
7
|
+
**APIClaw** — The API layer for AI agents. A lobster claw 🦞 represents precision, grip, and the ability to grab exactly what you need from the API ecosystem.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Logo
|
|
12
|
+
|
|
13
|
+
### Files
|
|
14
|
+
- `public/logo.svg` — Full gradient logo with details
|
|
15
|
+
- `public/logo-simple.svg` — Simplified gradient mark
|
|
16
|
+
- `public/logo-mono.svg` — Monochrome (uses `currentColor`)
|
|
17
|
+
- `public/icon.svg` — App icon with background
|
|
18
|
+
- `public/favicon.svg` — Favicon with rounded background
|
|
19
|
+
|
|
20
|
+
### Usage
|
|
21
|
+
- **Primary:** `logo-simple.svg` for most applications
|
|
22
|
+
- **Mono:** Use `logo-mono.svg` on colored backgrounds or when single-color is needed
|
|
23
|
+
- **Icon:** Use `icon.svg` for app stores, social profiles
|
|
24
|
+
|
|
25
|
+
### Clear Space
|
|
26
|
+
Maintain minimum clear space of 25% of logo width on all sides.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Color Palette
|
|
31
|
+
|
|
32
|
+
### Primary — Lobster Red
|
|
33
|
+
The signature color. Energetic, memorable, action-oriented.
|
|
34
|
+
|
|
35
|
+
| Name | Hex | RGB | Usage |
|
|
36
|
+
|------|-----|-----|-------|
|
|
37
|
+
| **Red 50** | `#fef2f2` | 254, 242, 242 | Subtle backgrounds |
|
|
38
|
+
| **Red 100** | `#fee2e2` | 254, 226, 226 | Hover states |
|
|
39
|
+
| **Red 200** | `#fecaca` | 254, 202, 202 | Borders, dividers |
|
|
40
|
+
| **Red 300** | `#fca5a5` | 252, 165, 165 | Light accents |
|
|
41
|
+
| **Red 400** | `#f87171` | 248, 113, 113 | **Primary light** |
|
|
42
|
+
| **Red 500** | `#ef4444` | 239, 68, 68 | **Primary** ⭐ |
|
|
43
|
+
| **Red 600** | `#dc2626` | 220, 38, 38 | **Primary dark** |
|
|
44
|
+
| **Red 700** | `#b91c1c` | 185, 28, 28 | Pressed states |
|
|
45
|
+
| **Red 800** | `#991b1b` | 153, 27, 27 | Deep accents |
|
|
46
|
+
| **Red 900** | `#7f1d1d` | 127, 29, 29 | Darkest red |
|
|
47
|
+
|
|
48
|
+
### Neutrals — Refined Dark
|
|
49
|
+
Premium dark palette inspired by Vercel and Linear.
|
|
50
|
+
|
|
51
|
+
| Name | Hex | RGB | Usage |
|
|
52
|
+
|------|-----|-----|-------|
|
|
53
|
+
| **Neutral 950** | `#0a0a0a` | 10, 10, 10 | **Background** (dark mode) |
|
|
54
|
+
| **Neutral 900** | `#171717` | 23, 23, 23 | **Surface** |
|
|
55
|
+
| **Neutral 800** | `#1f1f1f` | 31, 31, 31 | **Surface elevated** |
|
|
56
|
+
| **Neutral 700** | `#262626` | 38, 38, 38 | Cards, modals |
|
|
57
|
+
| **Neutral 600** | `#404040` | 64, 64, 64 | **Borders** |
|
|
58
|
+
| **Neutral 500** | `#525252` | 82, 82, 82 | Icons inactive |
|
|
59
|
+
| **Neutral 400** | `#737373` | 115, 115, 115 | **Text muted** |
|
|
60
|
+
| **Neutral 300** | `#a3a3a3` | 163, 163, 163 | **Text secondary** |
|
|
61
|
+
| **Neutral 200** | `#d4d4d4` | 212, 212, 212 | Text normal |
|
|
62
|
+
| **Neutral 100** | `#e5e5e5` | 229, 229, 229 | Borders (light mode) |
|
|
63
|
+
| **Neutral 50** | `#f5f5f5` | 245, 245, 245 | Background (light mode) |
|
|
64
|
+
| **White** | `#fafafa` | 250, 250, 250 | **Text primary** (dark) |
|
|
65
|
+
|
|
66
|
+
### Semantic Colors
|
|
67
|
+
|
|
68
|
+
| Name | Hex | Usage |
|
|
69
|
+
|------|-----|-------|
|
|
70
|
+
| **Success** | `#22c55e` | Confirmations, positive states |
|
|
71
|
+
| **Warning** | `#f59e0b` | Caution, pending states |
|
|
72
|
+
| **Error** | `#ef4444` | Errors (same as primary) |
|
|
73
|
+
| **Info** | `#3b82f6` | Informational, links |
|
|
74
|
+
|
|
75
|
+
### Gradients
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
/* Primary gradient - for CTAs and hero elements */
|
|
79
|
+
background: linear-gradient(135deg, #f87171 0%, #ef4444 50%, #dc2626 100%);
|
|
80
|
+
|
|
81
|
+
/* Subtle glow effect */
|
|
82
|
+
box-shadow: 0 0 80px rgba(239, 68, 68, 0.2);
|
|
83
|
+
|
|
84
|
+
/* Text gradient animation */
|
|
85
|
+
background: linear-gradient(135deg, #ef4444 0%, #f87171 50%, #fca5a5 100%);
|
|
86
|
+
background-size: 200% 200%;
|
|
87
|
+
animation: gradient 5s ease infinite;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Typography
|
|
93
|
+
|
|
94
|
+
### Font Stack
|
|
95
|
+
|
|
96
|
+
```css
|
|
97
|
+
/* Headlines & Body */
|
|
98
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
99
|
+
|
|
100
|
+
/* Code & Terminal */
|
|
101
|
+
font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', monospace;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Type Scale
|
|
105
|
+
|
|
106
|
+
| Element | Size | Weight | Letter Spacing | Line Height |
|
|
107
|
+
|---------|------|--------|----------------|-------------|
|
|
108
|
+
| **H1** | 4.5rem (72px) | 800 | -0.03em | 1.1 |
|
|
109
|
+
| **H2** | 2.25rem (36px) | 700 | -0.02em | 1.2 |
|
|
110
|
+
| **H3** | 1.5rem (24px) | 600 | -0.01em | 1.3 |
|
|
111
|
+
| **Body** | 1rem (16px) | 400 | 0 | 1.6 |
|
|
112
|
+
| **Body Large** | 1.25rem (20px) | 400 | 0 | 1.5 |
|
|
113
|
+
| **Small** | 0.875rem (14px) | 400 | 0 | 1.5 |
|
|
114
|
+
| **Label** | 0.75rem (12px) | 600 | 0.15em | 1.4 |
|
|
115
|
+
| **Code** | 0.875rem (14px) | 400 | 0 | 1.6 |
|
|
116
|
+
|
|
117
|
+
### OpenType Features
|
|
118
|
+
```css
|
|
119
|
+
font-feature-settings: "cv11", "ss01";
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Components
|
|
125
|
+
|
|
126
|
+
### Buttons
|
|
127
|
+
|
|
128
|
+
```css
|
|
129
|
+
/* Primary CTA */
|
|
130
|
+
.btn-primary {
|
|
131
|
+
padding: 12px 24px;
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
border-radius: 12px;
|
|
134
|
+
background: #ef4444;
|
|
135
|
+
color: #0a0a0a;
|
|
136
|
+
transition: all 0.2s ease;
|
|
137
|
+
}
|
|
138
|
+
.btn-primary:hover {
|
|
139
|
+
background: #dc2626;
|
|
140
|
+
transform: translateY(-1px);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Secondary */
|
|
144
|
+
.btn-secondary {
|
|
145
|
+
padding: 12px 24px;
|
|
146
|
+
font-weight: 500;
|
|
147
|
+
border-radius: 12px;
|
|
148
|
+
background: var(--surface);
|
|
149
|
+
border: 1px solid var(--border);
|
|
150
|
+
color: var(--text-primary);
|
|
151
|
+
}
|
|
152
|
+
.btn-secondary:hover {
|
|
153
|
+
border-color: #ef4444;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Cards
|
|
158
|
+
|
|
159
|
+
```css
|
|
160
|
+
.card {
|
|
161
|
+
background: var(--surface-elevated);
|
|
162
|
+
border: 1px solid var(--border);
|
|
163
|
+
border-radius: 16px;
|
|
164
|
+
padding: 24px;
|
|
165
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
166
|
+
}
|
|
167
|
+
.card:hover {
|
|
168
|
+
transform: translateY(-4px);
|
|
169
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
170
|
+
box-shadow: 0 12px 40px rgba(239, 68, 68, 0.1);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Terminal
|
|
175
|
+
|
|
176
|
+
```css
|
|
177
|
+
.terminal {
|
|
178
|
+
background: var(--surface);
|
|
179
|
+
border: 1px solid var(--border);
|
|
180
|
+
border-radius: 12px;
|
|
181
|
+
overflow: hidden;
|
|
182
|
+
}
|
|
183
|
+
.terminal-header {
|
|
184
|
+
display: flex;
|
|
185
|
+
gap: 6px;
|
|
186
|
+
padding: 12px 16px;
|
|
187
|
+
border-bottom: 1px solid var(--border);
|
|
188
|
+
background: var(--surface-elevated);
|
|
189
|
+
}
|
|
190
|
+
.terminal-dot { width: 12px; height: 12px; border-radius: 50%; }
|
|
191
|
+
.terminal-dot-red { background: #ff5f57; }
|
|
192
|
+
.terminal-dot-yellow { background: #febc2e; }
|
|
193
|
+
.terminal-dot-green { background: #28c840; }
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Badges
|
|
197
|
+
|
|
198
|
+
```css
|
|
199
|
+
.badge {
|
|
200
|
+
display: inline-flex;
|
|
201
|
+
align-items: center;
|
|
202
|
+
gap: 6px;
|
|
203
|
+
padding: 4px 12px;
|
|
204
|
+
font-size: 12px;
|
|
205
|
+
font-weight: 500;
|
|
206
|
+
border-radius: 9999px;
|
|
207
|
+
background: rgba(239, 68, 68, 0.1);
|
|
208
|
+
border: 1px solid rgba(239, 68, 68, 0.2);
|
|
209
|
+
color: #ef4444;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Spacing
|
|
216
|
+
|
|
217
|
+
Base unit: **4px**
|
|
218
|
+
|
|
219
|
+
| Name | Value | Usage |
|
|
220
|
+
|------|-------|-------|
|
|
221
|
+
| xs | 4px | Tight gaps |
|
|
222
|
+
| sm | 8px | Icon spacing |
|
|
223
|
+
| md | 16px | Component padding |
|
|
224
|
+
| lg | 24px | Section gaps |
|
|
225
|
+
| xl | 32px | Card padding |
|
|
226
|
+
| 2xl | 48px | Section margins |
|
|
227
|
+
| 3xl | 64px | Large sections |
|
|
228
|
+
| 4xl | 96px | Hero spacing |
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Border Radius
|
|
233
|
+
|
|
234
|
+
| Name | Value | Usage |
|
|
235
|
+
|------|-------|-------|
|
|
236
|
+
| sm | 6px | Inputs, small elements |
|
|
237
|
+
| md | 8px | Badges, chips |
|
|
238
|
+
| lg | 12px | Buttons, cards |
|
|
239
|
+
| xl | 16px | Modals, large cards |
|
|
240
|
+
| 2xl | 24px | Hero elements |
|
|
241
|
+
| full | 9999px | Pills, avatars |
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Shadows
|
|
246
|
+
|
|
247
|
+
```css
|
|
248
|
+
/* Subtle */
|
|
249
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
250
|
+
|
|
251
|
+
/* Default */
|
|
252
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
253
|
+
|
|
254
|
+
/* Medium */
|
|
255
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
256
|
+
|
|
257
|
+
/* Large */
|
|
258
|
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
|
|
259
|
+
|
|
260
|
+
/* Glow (accent) */
|
|
261
|
+
box-shadow: 0 0 80px rgba(239, 68, 68, 0.2);
|
|
262
|
+
|
|
263
|
+
/* Glow subtle */
|
|
264
|
+
box-shadow: 0 0 40px rgba(239, 68, 68, 0.1);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Animation
|
|
270
|
+
|
|
271
|
+
### Timing Functions
|
|
272
|
+
```css
|
|
273
|
+
/* Default ease */
|
|
274
|
+
transition: all 0.2s ease;
|
|
275
|
+
|
|
276
|
+
/* Smooth bounce */
|
|
277
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
278
|
+
|
|
279
|
+
/* Spring */
|
|
280
|
+
transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Keyframes
|
|
284
|
+
```css
|
|
285
|
+
@keyframes gradient {
|
|
286
|
+
0%, 100% { background-position: 0% 50%; }
|
|
287
|
+
50% { background-position: 100% 50%; }
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@keyframes pulse {
|
|
291
|
+
0%, 100% { opacity: 1; }
|
|
292
|
+
50% { opacity: 0.5; }
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@keyframes fadeIn {
|
|
296
|
+
from { opacity: 0; transform: translateY(10px); }
|
|
297
|
+
to { opacity: 1; transform: translateY(0); }
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Assets Checklist
|
|
304
|
+
|
|
305
|
+
- [x] `public/logo.svg` — Full gradient logo
|
|
306
|
+
- [x] `public/logo-simple.svg` — Simplified mark
|
|
307
|
+
- [x] `public/logo-mono.svg` — Monochrome version
|
|
308
|
+
- [x] `public/icon.svg` — App icon with background
|
|
309
|
+
- [x] `public/favicon.svg` — SVG favicon
|
|
310
|
+
- [ ] `public/favicon.ico` — ICO format (generated)
|
|
311
|
+
- [ ] `public/favicon-16x16.png` — 16px PNG
|
|
312
|
+
- [ ] `public/favicon-32x32.png` — 32px PNG
|
|
313
|
+
- [ ] `public/apple-touch-icon.png` — 180px for iOS
|
|
314
|
+
- [ ] `public/og-image.png` — 1200x630 social sharing
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Implementation Notes
|
|
319
|
+
|
|
320
|
+
### Next.js Head
|
|
321
|
+
```tsx
|
|
322
|
+
<Head>
|
|
323
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
324
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
325
|
+
<meta property="og:image" content="https://apiclaw.com/og-image.png" />
|
|
326
|
+
</Head>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Tailwind Config
|
|
330
|
+
Colors are defined in `tailwind.config.ts` and CSS variables in `globals.css`.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Inspiration Sources
|
|
335
|
+
|
|
336
|
+
- **Stripe** — Clean typography, professional feel
|
|
337
|
+
- **Vercel** — Dark mode excellence, premium polish
|
|
338
|
+
- **Linear** — Refined interactions, attention to detail
|
|
339
|
+
- **Raycast** — Developer-focused, crisp design
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
*Design System v1.0 — APIClaw by NordSym*
|