create-edhor-stack 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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/STACK.md +1086 -0
  4. package/dist/index.js +3181 -0
  5. package/package.json +44 -0
  6. package/templates/apps/api-elysia/package.json +21 -0
  7. package/templates/apps/api-elysia/src/index.ts +59 -0
  8. package/templates/apps/api-elysia/src/lib/eden.ts +25 -0
  9. package/templates/apps/api-elysia/src/lib/env.ts +18 -0
  10. package/templates/apps/api-elysia/src/routes/health.ts +13 -0
  11. package/templates/apps/api-elysia/src/routes/users.ts +117 -0
  12. package/templates/apps/api-elysia/tsconfig.json +15 -0
  13. package/templates/apps/api-hono/package.json +20 -0
  14. package/templates/apps/api-hono/src/index.ts +66 -0
  15. package/templates/apps/api-hono/src/lib/env.ts +18 -0
  16. package/templates/apps/api-hono/src/routes/health.ts +20 -0
  17. package/templates/apps/api-hono/src/routes/users.ts +110 -0
  18. package/templates/apps/api-hono/tsconfig.json +15 -0
  19. package/templates/apps/mobile/.env.example +9 -0
  20. package/templates/apps/mobile/app/_layout.tsx +16 -0
  21. package/templates/apps/mobile/app/index.tsx +39 -0
  22. package/templates/apps/mobile/app.json +37 -0
  23. package/templates/apps/mobile/assets/adaptive-icon.png +0 -0
  24. package/templates/apps/mobile/assets/favicon.png +0 -0
  25. package/templates/apps/mobile/assets/icon.png +0 -0
  26. package/templates/apps/mobile/assets/splash-icon.png +0 -0
  27. package/templates/apps/mobile/package.json +39 -0
  28. package/templates/apps/mobile/src/api/client.ts +51 -0
  29. package/templates/apps/mobile/src/api/index.ts +3 -0
  30. package/templates/apps/mobile/src/api/queries.ts +24 -0
  31. package/templates/apps/mobile/src/api/schemas.ts +32 -0
  32. package/templates/apps/mobile/src/lib/env.ts +40 -0
  33. package/templates/apps/mobile/src/lib/query-client.ts +28 -0
  34. package/templates/apps/mobile/src/lib/result.ts +45 -0
  35. package/templates/apps/mobile/src/lib/store.ts +63 -0
  36. package/templates/apps/mobile/tsconfig.json +10 -0
  37. package/templates/apps/web/.env.example +11 -0
  38. package/templates/apps/web/package.json +29 -0
  39. package/templates/apps/web/src/lib/env.ts +52 -0
  40. package/templates/apps/web/src/lib/queries.ts +27 -0
  41. package/templates/apps/web/src/lib/query-client.ts +11 -0
  42. package/templates/apps/web/src/router.tsx +17 -0
  43. package/templates/apps/web/src/routes/__root.tsx +32 -0
  44. package/templates/apps/web/src/routes/index.tsx +16 -0
  45. package/templates/apps/web/src/styles.css +26 -0
  46. package/templates/apps/web/tsconfig.json +10 -0
  47. package/templates/apps/web/vite.config.ts +21 -0
  48. package/templates/base/.claude/settings.json +33 -0
  49. package/templates/base/.claude/skills/add-api-endpoint.md +137 -0
  50. package/templates/base/.claude/skills/add-component.md +79 -0
  51. package/templates/base/.claude/skills/add-route.md +134 -0
  52. package/templates/base/.claude/skills/add-store.md +158 -0
  53. package/templates/base/.husky/pre-commit +1 -0
  54. package/templates/base/.lintstagedrc +4 -0
  55. package/templates/base/.node-version +1 -0
  56. package/templates/base/AGENTS.md +135 -0
  57. package/templates/base/CLAUDE.md.hbs +139 -0
  58. package/templates/base/Dockerfile +32 -0
  59. package/templates/base/biome.json +52 -0
  60. package/templates/base/fly.toml.hbs +20 -0
  61. package/templates/base/gitignore +36 -0
  62. package/templates/base/package.json.hbs +22 -0
  63. package/templates/base/tsconfig.json +14 -0
  64. package/templates/base/turbo.json +22 -0
  65. package/templates/packages/shared/package.json +17 -0
  66. package/templates/packages/shared/src/index.ts +4 -0
  67. package/templates/packages/shared/src/schemas.ts +50 -0
  68. package/templates/packages/shared/src/types.ts +47 -0
  69. package/templates/packages/shared/src/utils.ts +87 -0
  70. package/templates/packages/shared/tsconfig.json +14 -0
  71. package/templates/packages/stripe/package.json +18 -0
  72. package/templates/packages/stripe/src/client.ts +110 -0
  73. package/templates/packages/stripe/src/index.ts +3 -0
  74. package/templates/packages/stripe/src/schemas.ts +65 -0
  75. package/templates/packages/stripe/src/webhooks.ts +91 -0
  76. package/templates/packages/stripe/tsconfig.json +14 -0
  77. package/templates/packages/ui/components.json +19 -0
  78. package/templates/packages/ui/package.json +29 -0
  79. package/templates/packages/ui/src/components/button.tsx +58 -0
  80. package/templates/packages/ui/src/index.ts +5 -0
  81. package/templates/packages/ui/src/lib/utils.ts +6 -0
  82. package/templates/packages/ui/src/styles.css +120 -0
  83. package/templates/packages/ui/tsconfig.json +10 -0
@@ -0,0 +1,110 @@
1
+ import Stripe from 'stripe';
2
+
3
+ if (!process.env.STRIPE_SECRET_KEY) {
4
+ throw new Error('STRIPE_SECRET_KEY is not set');
5
+ }
6
+
7
+ export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
8
+ apiVersion: '2024-12-18.acacia',
9
+ typescript: true,
10
+ });
11
+
12
+ // ============================================================================
13
+ // CUSTOMERS
14
+ // ============================================================================
15
+
16
+ export async function createCustomer(params: {
17
+ email: string;
18
+ name?: string;
19
+ metadata?: Record<string, string>;
20
+ }) {
21
+ return stripe.customers.create({
22
+ email: params.email,
23
+ name: params.name,
24
+ metadata: params.metadata,
25
+ });
26
+ }
27
+
28
+ export async function getCustomer(customerId: string) {
29
+ return stripe.customers.retrieve(customerId);
30
+ }
31
+
32
+ export async function getCustomerByEmail(email: string) {
33
+ const customers = await stripe.customers.list({ email, limit: 1 });
34
+ return customers.data[0] ?? null;
35
+ }
36
+
37
+ // ============================================================================
38
+ // CHECKOUT SESSIONS
39
+ // ============================================================================
40
+
41
+ export async function createCheckoutSession(params: {
42
+ customerId?: string;
43
+ customerEmail?: string;
44
+ priceId: string;
45
+ successUrl: string;
46
+ cancelUrl: string;
47
+ metadata?: Record<string, string>;
48
+ }) {
49
+ return stripe.checkout.sessions.create({
50
+ customer: params.customerId,
51
+ customer_email: params.customerId ? undefined : params.customerEmail,
52
+ mode: 'subscription',
53
+ line_items: [{ price: params.priceId, quantity: 1 }],
54
+ success_url: params.successUrl,
55
+ cancel_url: params.cancelUrl,
56
+ metadata: params.metadata,
57
+ });
58
+ }
59
+
60
+ export async function createOneTimeCheckoutSession(params: {
61
+ customerId?: string;
62
+ customerEmail?: string;
63
+ priceId: string;
64
+ successUrl: string;
65
+ cancelUrl: string;
66
+ metadata?: Record<string, string>;
67
+ }) {
68
+ return stripe.checkout.sessions.create({
69
+ customer: params.customerId,
70
+ customer_email: params.customerId ? undefined : params.customerEmail,
71
+ mode: 'payment',
72
+ line_items: [{ price: params.priceId, quantity: 1 }],
73
+ success_url: params.successUrl,
74
+ cancel_url: params.cancelUrl,
75
+ metadata: params.metadata,
76
+ });
77
+ }
78
+
79
+ // ============================================================================
80
+ // SUBSCRIPTIONS
81
+ // ============================================================================
82
+
83
+ export async function getSubscription(subscriptionId: string) {
84
+ return stripe.subscriptions.retrieve(subscriptionId);
85
+ }
86
+
87
+ export async function cancelSubscription(subscriptionId: string) {
88
+ return stripe.subscriptions.cancel(subscriptionId);
89
+ }
90
+
91
+ export async function getCustomerSubscriptions(customerId: string) {
92
+ return stripe.subscriptions.list({
93
+ customer: customerId,
94
+ status: 'all',
95
+ });
96
+ }
97
+
98
+ // ============================================================================
99
+ // BILLING PORTAL
100
+ // ============================================================================
101
+
102
+ export async function createBillingPortalSession(params: {
103
+ customerId: string;
104
+ returnUrl: string;
105
+ }) {
106
+ return stripe.billingPortal.sessions.create({
107
+ customer: params.customerId,
108
+ return_url: params.returnUrl,
109
+ });
110
+ }
@@ -0,0 +1,3 @@
1
+ export { stripe } from './client';
2
+ export * from './schemas';
3
+ export * from './webhooks';
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod';
2
+
3
+ // ============================================================================
4
+ // CHECKOUT SCHEMAS
5
+ // ============================================================================
6
+
7
+ export const CreateCheckoutSchema = z.object({
8
+ priceId: z.string().startsWith('price_'),
9
+ successUrl: z.string().url(),
10
+ cancelUrl: z.string().url(),
11
+ });
12
+
13
+ export const CheckoutSessionSchema = z.object({
14
+ id: z.string().startsWith('cs_'),
15
+ url: z.string().url().nullable(),
16
+ status: z.enum(['open', 'complete', 'expired']),
17
+ customer: z.string().nullable(),
18
+ subscription: z.string().nullable(),
19
+ });
20
+
21
+ // ============================================================================
22
+ // SUBSCRIPTION SCHEMAS
23
+ // ============================================================================
24
+
25
+ export const SubscriptionStatusSchema = z.enum([
26
+ 'active',
27
+ 'canceled',
28
+ 'incomplete',
29
+ 'incomplete_expired',
30
+ 'past_due',
31
+ 'paused',
32
+ 'trialing',
33
+ 'unpaid',
34
+ ]);
35
+
36
+ export const SubscriptionSchema = z.object({
37
+ id: z.string().startsWith('sub_'),
38
+ status: SubscriptionStatusSchema,
39
+ currentPeriodStart: z.number(),
40
+ currentPeriodEnd: z.number(),
41
+ cancelAtPeriodEnd: z.boolean(),
42
+ priceId: z.string(),
43
+ });
44
+
45
+ // ============================================================================
46
+ // WEBHOOK SCHEMAS
47
+ // ============================================================================
48
+
49
+ export const WebhookEventSchema = z.object({
50
+ id: z.string().startsWith('evt_'),
51
+ type: z.string(),
52
+ data: z.object({
53
+ object: z.record(z.unknown()),
54
+ }),
55
+ });
56
+
57
+ // ============================================================================
58
+ // TYPES
59
+ // ============================================================================
60
+
61
+ export type CreateCheckout = z.infer<typeof CreateCheckoutSchema>;
62
+ export type CheckoutSession = z.infer<typeof CheckoutSessionSchema>;
63
+ export type SubscriptionStatus = z.infer<typeof SubscriptionStatusSchema>;
64
+ export type Subscription = z.infer<typeof SubscriptionSchema>;
65
+ export type WebhookEvent = z.infer<typeof WebhookEventSchema>;
@@ -0,0 +1,91 @@
1
+ import type Stripe from 'stripe';
2
+ import { stripe } from './client';
3
+
4
+ if (!process.env.STRIPE_WEBHOOK_SECRET) {
5
+ console.warn('STRIPE_WEBHOOK_SECRET is not set - webhooks will not be verified');
6
+ }
7
+
8
+ // ============================================================================
9
+ // WEBHOOK VERIFICATION
10
+ // ============================================================================
11
+
12
+ export function constructWebhookEvent(
13
+ payload: string | Buffer,
14
+ signature: string
15
+ ): Stripe.Event {
16
+ if (!process.env.STRIPE_WEBHOOK_SECRET) {
17
+ throw new Error('STRIPE_WEBHOOK_SECRET is not set');
18
+ }
19
+
20
+ return stripe.webhooks.constructEvent(
21
+ payload,
22
+ signature,
23
+ process.env.STRIPE_WEBHOOK_SECRET
24
+ );
25
+ }
26
+
27
+ // ============================================================================
28
+ // WEBHOOK HANDLER TYPES
29
+ // ============================================================================
30
+
31
+ export type WebhookHandler<T = unknown> = (data: T) => Promise<void>;
32
+
33
+ export interface WebhookHandlers {
34
+ 'checkout.session.completed'?: WebhookHandler<Stripe.Checkout.Session>;
35
+ 'customer.subscription.created'?: WebhookHandler<Stripe.Subscription>;
36
+ 'customer.subscription.updated'?: WebhookHandler<Stripe.Subscription>;
37
+ 'customer.subscription.deleted'?: WebhookHandler<Stripe.Subscription>;
38
+ 'invoice.payment_succeeded'?: WebhookHandler<Stripe.Invoice>;
39
+ 'invoice.payment_failed'?: WebhookHandler<Stripe.Invoice>;
40
+ }
41
+
42
+ // ============================================================================
43
+ // WEBHOOK PROCESSOR
44
+ // ============================================================================
45
+
46
+ export async function processWebhook(
47
+ event: Stripe.Event,
48
+ handlers: WebhookHandlers
49
+ ): Promise<void> {
50
+ const handler = handlers[event.type as keyof WebhookHandlers];
51
+
52
+ if (handler) {
53
+ await handler(event.data.object);
54
+ } else {
55
+ console.log(`Unhandled webhook event: ${event.type}`);
56
+ }
57
+ }
58
+
59
+ // ============================================================================
60
+ // EXAMPLE USAGE
61
+ // ============================================================================
62
+ /*
63
+ // In your API route (e.g., /api/webhooks/stripe):
64
+
65
+ import { constructWebhookEvent, processWebhook } from '@your-app/stripe/webhooks';
66
+
67
+ export async function POST(request: Request) {
68
+ const payload = await request.text();
69
+ const signature = request.headers.get('stripe-signature')!;
70
+
71
+ try {
72
+ const event = constructWebhookEvent(payload, signature);
73
+
74
+ await processWebhook(event, {
75
+ 'checkout.session.completed': async (session) => {
76
+ // Handle successful checkout
77
+ console.log('Checkout completed:', session.id);
78
+ },
79
+ 'customer.subscription.updated': async (subscription) => {
80
+ // Handle subscription update
81
+ console.log('Subscription updated:', subscription.id);
82
+ },
83
+ });
84
+
85
+ return new Response('OK', { status: 200 });
86
+ } catch (error) {
87
+ console.error('Webhook error:', error);
88
+ return new Response('Webhook Error', { status: 400 });
89
+ }
90
+ }
91
+ */
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "composite": true
12
+ },
13
+ "include": ["src/**/*"]
14
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": false,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "",
8
+ "css": "src/styles.css",
9
+ "baseColor": "zinc",
10
+ "cssVariables": true
11
+ },
12
+ "aliases": {
13
+ "components": "src/components",
14
+ "utils": "src/lib/utils",
15
+ "ui": "src/components",
16
+ "lib": "src/lib"
17
+ },
18
+ "iconLibrary": "lucide"
19
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@{{name}}/ui",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/index.ts",
8
+ "./components/*": "./src/components/*.tsx",
9
+ "./lib/*": "./src/lib/*.ts",
10
+ "./styles.css": "./src/styles.css"
11
+ },
12
+ "scripts": {
13
+ "ui:add": "bunx shadcn@latest add"
14
+ },
15
+ "dependencies": {
16
+ "@radix-ui/react-slot": "^1.1.0",
17
+ "class-variance-authority": "^0.7.1",
18
+ "clsx": "^2.1.1",
19
+ "tailwind-merge": "^3.0.0",
20
+ "lucide-react": "^0.460.0"
21
+ },
22
+ "devDependencies": {
23
+ "tailwindcss": "^4.0.0",
24
+ "@types/react": "^19.0.0"
25
+ },
26
+ "peerDependencies": {
27
+ "react": "^19.0.0"
28
+ }
29
+ }
@@ -0,0 +1,58 @@
1
+ import * as React from 'react';
2
+ import { Slot } from '@radix-ui/react-slot';
3
+ import { cva, type VariantProps } from 'class-variance-authority';
4
+
5
+ import { cn } from '../lib/utils';
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
14
+ destructive:
15
+ 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
16
+ outline:
17
+ 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground',
18
+ secondary:
19
+ 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
20
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
21
+ link: 'text-primary underline-offset-4 hover:underline',
22
+ },
23
+ size: {
24
+ default: 'h-9 px-4 py-2 has-[>svg]:px-3',
25
+ sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
26
+ lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
27
+ icon: 'size-9',
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ variant: 'default',
32
+ size: 'default',
33
+ },
34
+ }
35
+ );
36
+
37
+ function Button({
38
+ className,
39
+ variant,
40
+ size,
41
+ asChild = false,
42
+ ...props
43
+ }: React.ComponentProps<'button'> &
44
+ VariantProps<typeof buttonVariants> & {
45
+ asChild?: boolean;
46
+ }) {
47
+ const Comp = asChild ? Slot : 'button';
48
+
49
+ return (
50
+ <Comp
51
+ data-slot="button"
52
+ className={cn(buttonVariants({ variant, size, className }))}
53
+ {...props}
54
+ />
55
+ );
56
+ }
57
+
58
+ export { Button, buttonVariants };
@@ -0,0 +1,5 @@
1
+ // Components
2
+ export * from './components/button';
3
+
4
+ // Utilities
5
+ export * from './lib/utils';
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,120 @@
1
+ @import "tailwindcss";
2
+
3
+ @theme inline {
4
+ --color-background: var(--background);
5
+ --color-foreground: var(--foreground);
6
+ --color-card: var(--card);
7
+ --color-card-foreground: var(--card-foreground);
8
+ --color-popover: var(--popover);
9
+ --color-popover-foreground: var(--popover-foreground);
10
+ --color-primary: var(--primary);
11
+ --color-primary-foreground: var(--primary-foreground);
12
+ --color-secondary: var(--secondary);
13
+ --color-secondary-foreground: var(--secondary-foreground);
14
+ --color-muted: var(--muted);
15
+ --color-muted-foreground: var(--muted-foreground);
16
+ --color-accent: var(--accent);
17
+ --color-accent-foreground: var(--accent-foreground);
18
+ --color-destructive: var(--destructive);
19
+ --color-destructive-foreground: var(--destructive-foreground);
20
+ --color-border: var(--border);
21
+ --color-input: var(--input);
22
+ --color-ring: var(--ring);
23
+ --color-chart-1: var(--chart-1);
24
+ --color-chart-2: var(--chart-2);
25
+ --color-chart-3: var(--chart-3);
26
+ --color-chart-4: var(--chart-4);
27
+ --color-chart-5: var(--chart-5);
28
+ --color-sidebar: var(--sidebar);
29
+ --color-sidebar-foreground: var(--sidebar-foreground);
30
+ --color-sidebar-primary: var(--sidebar-primary);
31
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
32
+ --color-sidebar-accent: var(--sidebar-accent);
33
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
34
+ --color-sidebar-border: var(--sidebar-border);
35
+ --color-sidebar-ring: var(--sidebar-ring);
36
+ --radius-sm: calc(var(--radius) - 4px);
37
+ --radius-md: calc(var(--radius) - 2px);
38
+ --radius-lg: var(--radius);
39
+ --radius-xl: calc(var(--radius) + 4px);
40
+ }
41
+
42
+ :root {
43
+ --radius: 0.625rem;
44
+ --background: oklch(1 0 0);
45
+ --foreground: oklch(0.145 0 0);
46
+ --card: oklch(1 0 0);
47
+ --card-foreground: oklch(0.145 0 0);
48
+ --popover: oklch(1 0 0);
49
+ --popover-foreground: oklch(0.145 0 0);
50
+ --primary: oklch(0.205 0 0);
51
+ --primary-foreground: oklch(0.985 0 0);
52
+ --secondary: oklch(0.97 0 0);
53
+ --secondary-foreground: oklch(0.205 0 0);
54
+ --muted: oklch(0.97 0 0);
55
+ --muted-foreground: oklch(0.556 0 0);
56
+ --accent: oklch(0.97 0 0);
57
+ --accent-foreground: oklch(0.205 0 0);
58
+ --destructive: oklch(0.577 0.245 27.325);
59
+ --destructive-foreground: oklch(0.577 0.245 27.325);
60
+ --border: oklch(0.922 0 0);
61
+ --input: oklch(0.922 0 0);
62
+ --ring: oklch(0.708 0 0);
63
+ --chart-1: oklch(0.646 0.222 41.116);
64
+ --chart-2: oklch(0.6 0.118 184.704);
65
+ --chart-3: oklch(0.398 0.07 227.392);
66
+ --chart-4: oklch(0.828 0.189 84.429);
67
+ --chart-5: oklch(0.769 0.188 70.08);
68
+ --sidebar: oklch(0.985 0 0);
69
+ --sidebar-foreground: oklch(0.145 0 0);
70
+ --sidebar-primary: oklch(0.205 0 0);
71
+ --sidebar-primary-foreground: oklch(0.985 0 0);
72
+ --sidebar-accent: oklch(0.97 0 0);
73
+ --sidebar-accent-foreground: oklch(0.205 0 0);
74
+ --sidebar-border: oklch(0.922 0 0);
75
+ --sidebar-ring: oklch(0.708 0 0);
76
+ }
77
+
78
+ .dark {
79
+ --background: oklch(0.145 0 0);
80
+ --foreground: oklch(0.985 0 0);
81
+ --card: oklch(0.145 0 0);
82
+ --card-foreground: oklch(0.985 0 0);
83
+ --popover: oklch(0.145 0 0);
84
+ --popover-foreground: oklch(0.985 0 0);
85
+ --primary: oklch(0.985 0 0);
86
+ --primary-foreground: oklch(0.205 0 0);
87
+ --secondary: oklch(0.269 0 0);
88
+ --secondary-foreground: oklch(0.985 0 0);
89
+ --muted: oklch(0.269 0 0);
90
+ --muted-foreground: oklch(0.708 0 0);
91
+ --accent: oklch(0.269 0 0);
92
+ --accent-foreground: oklch(0.985 0 0);
93
+ --destructive: oklch(0.396 0.141 25.723);
94
+ --destructive-foreground: oklch(0.637 0.237 25.331);
95
+ --border: oklch(0.269 0 0);
96
+ --input: oklch(0.269 0 0);
97
+ --ring: oklch(0.439 0 0);
98
+ --chart-1: oklch(0.488 0.243 264.376);
99
+ --chart-2: oklch(0.696 0.17 162.48);
100
+ --chart-3: oklch(0.769 0.188 70.08);
101
+ --chart-4: oklch(0.627 0.265 303.9);
102
+ --chart-5: oklch(0.645 0.246 16.439);
103
+ --sidebar: oklch(0.205 0 0);
104
+ --sidebar-foreground: oklch(0.985 0 0);
105
+ --sidebar-primary: oklch(0.488 0.243 264.376);
106
+ --sidebar-primary-foreground: oklch(0.985 0 0);
107
+ --sidebar-accent: oklch(0.269 0 0);
108
+ --sidebar-accent-foreground: oklch(0.985 0 0);
109
+ --sidebar-border: oklch(0.269 0 0);
110
+ --sidebar-ring: oklch(0.439 0 0);
111
+ }
112
+
113
+ @layer base {
114
+ * {
115
+ @apply border-border;
116
+ }
117
+ body {
118
+ @apply bg-background text-foreground;
119
+ }
120
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "jsx": "react-jsx",
5
+ "paths": {
6
+ "@/*": ["./src/*"]
7
+ }
8
+ },
9
+ "include": ["src"]
10
+ }