gea-lib 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +100 -0
  2. package/bin/index.js +214 -0
  3. package/package.json +38 -0
  4. package/templates/js/README.md +39 -0
  5. package/templates/js/_gitignore +42 -0
  6. package/templates/js/package.json +32 -0
  7. package/templates/js/playground/app.jsx +80 -0
  8. package/templates/js/playground/index.html +15 -0
  9. package/templates/js/playground/main.js +5 -0
  10. package/templates/js/playground/style.css +49 -0
  11. package/templates/js/src/components/Button.css +74 -0
  12. package/templates/js/src/components/Button.jsx +20 -0
  13. package/templates/js/src/components/Card.css +44 -0
  14. package/templates/js/src/components/Card.jsx +27 -0
  15. package/templates/js/src/index.js +3 -0
  16. package/templates/js/src/stores/counter.js +21 -0
  17. package/templates/js/vite.config.js +23 -0
  18. package/templates/ts/README.md +40 -0
  19. package/templates/ts/_gitignore +42 -0
  20. package/templates/ts/package.json +35 -0
  21. package/templates/ts/playground/app.tsx +80 -0
  22. package/templates/ts/playground/index.html +15 -0
  23. package/templates/ts/playground/main.ts +5 -0
  24. package/templates/ts/playground/style.css +49 -0
  25. package/templates/ts/src/components/Button.css +74 -0
  26. package/templates/ts/src/components/Button.tsx +26 -0
  27. package/templates/ts/src/components/Card.css +44 -0
  28. package/templates/ts/src/components/Card.tsx +32 -0
  29. package/templates/ts/src/index.ts +3 -0
  30. package/templates/ts/src/stores/counter.ts +21 -0
  31. package/templates/ts/tsconfig.build.json +10 -0
  32. package/templates/ts/tsconfig.json +21 -0
  33. package/templates/ts/vite.config.ts +23 -0
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # GeaJS Library Scaffolder (`gea-lib`)
2
+
3
+ ⚡ A fast, flexible, and interactive scaffolding tool to easily bootstrap modern, reactive libraries for GeaJS. With this tool, you can set up a new GeaJS library in seconds with TypeScript or JavaScript, complete with automatic git initialization and dependency installation.
4
+
5
+ ## Features
6
+
7
+ - 📦 **Pre-configured Templates:** Ready-to-go templates for both JavaScript (`js`) and TypeScript (`ts`).
8
+ - ⚙️ **Interactive CLI:** Step-by-step prompts to select your project name, language, and initial setup preferences.
9
+ - 🚀 **Silent Mode (Non-Interactive):** Fast creation using CLI flags to skip prompts.
10
+ - 🛠️ **Auto-configuration:** Automatic Git initialization and dependency installation using your active package manager (`npm`, `yarn`, `pnpm`, `bun`).
11
+
12
+ ---
13
+
14
+ ## Usage
15
+
16
+ You can run this tool remotely using `npx` (recommended), or run it locally during development.
17
+
18
+ ### 1. Remote Execution (Recommended)
19
+
20
+ Since the package is published on npm, you can generate a new GeaJS library anywhere without installing it globally:
21
+
22
+ ```bash
23
+ # Using npx (runs interactively by default)
24
+ npx gea-lib
25
+ ```
26
+
27
+ ---
28
+
29
+ ### 2. Command Line Options
30
+
31
+ You can skip or pre-configure choices by passing arguments to the command:
32
+
33
+ ```bash
34
+ npx gea-lib <project-name> [options]
35
+ ```
36
+
37
+ #### Available Options:
38
+
39
+ | Option | Description |
40
+ | :--- | :--- |
41
+ | `<project-name>` | The name of the project/directory to create (e.g., `my-awesome-lib`). |
42
+ | `--ts` / `--typescript` | Use the TypeScript template. |
43
+ | `--js` / `--javascript` | Use the JavaScript template. |
44
+ | `--git` | Automatically initialize a git repository. |
45
+ | `--no-git` | Skip initializing a git repository. |
46
+ | `--install` | Automatically install dependencies. |
47
+ | `--no-install` | Skip installing dependencies. |
48
+ | `-y` / `--yes` | Use default choices for all prompts (creates `gea-library` in TypeScript with git and install). |
49
+
50
+ #### Examples:
51
+
52
+ **Create a TypeScript project with git and installed dependencies silently:**
53
+ ```bash
54
+ npx gea-lib my-ts-lib -y
55
+ ```
56
+
57
+ **Create a JavaScript project and skip dependency installation:**
58
+ ```bash
59
+ npx gea-lib my-js-lib --js --no-install
60
+ ```
61
+
62
+ ---
63
+
64
+ ### 3. Local Development & Installation
65
+
66
+ If you are developing this scaffolder tool locally, you can use these methods:
67
+
68
+ #### Run locally:
69
+ ```bash
70
+ # In the scaffolder root directory
71
+ node ./bin/index.js
72
+ # Or:
73
+ npm start
74
+ ```
75
+
76
+ #### Link locally for testing:
77
+ ```bash
78
+ # Create a global symlink of the package
79
+ npm link
80
+
81
+ # Run it from anywhere on your machine:
82
+ gea-lib my-library
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Developing Your New Library
88
+
89
+ Once your project is created, navigate into the directory and run these commands to start developing:
90
+
91
+ ```bash
92
+ # Go to the project directory
93
+ cd <project-name>
94
+
95
+ # Start the interactive sandbox demo environment
96
+ npm run dev
97
+
98
+ # Build the library for NPM distribution
99
+ npm run build
100
+ ```
package/bin/index.js ADDED
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { promises as fs } from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import { spawn } from 'child_process';
7
+ import prompts from 'prompts';
8
+ import pc from 'picocolors';
9
+
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+
12
+ // Helper: Run a command in a child process
13
+ function runCommand(command, args, options = {}) {
14
+ return new Promise((resolve, reject) => {
15
+ const process = spawn(command, args, { stdio: 'inherit', shell: true, ...options });
16
+ process.on('close', (code) => {
17
+ if (code === 0) {
18
+ resolve();
19
+ } else {
20
+ reject(new Error(`Command failed with exit code ${code}`));
21
+ }
22
+ });
23
+ process.on('error', (err) => {
24
+ reject(err);
25
+ });
26
+ });
27
+ }
28
+
29
+ // Helper: Convert project-name to CamelCase library name
30
+ function toCamelCase(str) {
31
+ return str
32
+ .replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase())
33
+ .replace(/[^a-zA-Z0-9]/g, '');
34
+ }
35
+
36
+ // Helper: Recursively copy directory and replace placeholders
37
+ async function copyDir(src, dest, replacements) {
38
+ const stat = await fs.lstat(src);
39
+ if (stat.isDirectory()) {
40
+ await fs.mkdir(dest, { recursive: true });
41
+ const entries = await fs.readdir(src);
42
+ for (const entry of entries) {
43
+ const srcPath = path.join(src, entry);
44
+ let destEntryName = entry;
45
+ // Rename _gitignore to .gitignore
46
+ if (entry === '_gitignore') {
47
+ destEntryName = '.gitignore';
48
+ }
49
+ const destPath = path.join(dest, destEntryName);
50
+ await copyDir(srcPath, destPath, replacements);
51
+ }
52
+ } else {
53
+ // Read file, replace templates, write to dest
54
+ let content = await fs.readFile(src, 'utf8');
55
+ for (const [key, value] of Object.entries(replacements)) {
56
+ const regex = new RegExp(`<%\\s*${key}\\s*%>`, 'g');
57
+ content = content.replace(regex, value);
58
+ }
59
+ await fs.writeFile(dest, content, 'utf8');
60
+ }
61
+ }
62
+
63
+ // Helper: Detect the active package manager
64
+ function detectPackageManager() {
65
+ const userAgent = process.env.npm_config_user_agent || '';
66
+ if (userAgent.includes('yarn')) return 'yarn';
67
+ if (userAgent.includes('pnpm')) return 'pnpm';
68
+ if (userAgent.includes('bun')) return 'bun';
69
+ return 'npm';
70
+ }
71
+
72
+ async function main() {
73
+ console.log('\n' + pc.cyan(pc.bold('⚡ GeaJS Library Scaffolder ⚡')) + '\n');
74
+
75
+ const args = process.argv.slice(2);
76
+ const cliOptions = {
77
+ projectName: args.find(a => !a.startsWith('-')),
78
+ language: args.includes('--ts') || args.includes('--typescript') ? 'ts' : (args.includes('--js') || args.includes('--javascript') ? 'js' : null),
79
+ gitInit: args.includes('--no-git') ? false : (args.includes('--git') ? true : null),
80
+ installDeps: args.includes('--no-install') ? false : (args.includes('--install') ? true : null),
81
+ yes: args.includes('-y') || args.includes('--yes')
82
+ };
83
+
84
+ let projectName = cliOptions.projectName;
85
+ let language = cliOptions.language;
86
+ let gitInit = cliOptions.gitInit;
87
+ let installDeps = cliOptions.installDeps;
88
+
89
+ if (cliOptions.yes) {
90
+ if (!projectName) projectName = 'gea-library';
91
+ if (!language) language = 'ts';
92
+ if (gitInit === null) gitInit = true;
93
+ if (installDeps === null) installDeps = true;
94
+ } else {
95
+ const questions = [];
96
+
97
+ if (!projectName) {
98
+ questions.push({
99
+ type: 'text',
100
+ name: 'projectName',
101
+ message: 'Project name:',
102
+ initial: 'gea-library',
103
+ validate: (value) => (value.trim().length > 0 ? true : 'Please enter a project name')
104
+ });
105
+ }
106
+
107
+ if (!language) {
108
+ questions.push({
109
+ type: 'select',
110
+ name: 'language',
111
+ message: 'Select programming language:',
112
+ choices: [
113
+ { title: pc.blue('TypeScript'), value: 'ts' },
114
+ { title: pc.yellow('JavaScript'), value: 'js' }
115
+ ],
116
+ initial: 0
117
+ });
118
+ }
119
+
120
+ if (gitInit === null) {
121
+ questions.push({
122
+ type: 'confirm',
123
+ name: 'gitInit',
124
+ message: 'Initialize a git repository?',
125
+ initial: true
126
+ });
127
+ }
128
+
129
+ if (installDeps === null) {
130
+ questions.push({
131
+ type: 'confirm',
132
+ name: 'installDeps',
133
+ message: 'Install dependencies automatically?',
134
+ initial: true
135
+ });
136
+ }
137
+
138
+ if (questions.length > 0) {
139
+ const response = await prompts(questions, {
140
+ onCancel: () => {
141
+ console.log(pc.red('\n✖ Scaffolding cancelled.'));
142
+ process.exit(1);
143
+ }
144
+ });
145
+
146
+ if (!projectName) projectName = response.projectName;
147
+ if (!language) language = response.language;
148
+ if (gitInit === null) gitInit = response.gitInit;
149
+ if (installDeps === null) installDeps = response.installDeps;
150
+ }
151
+ }
152
+
153
+ const projectDir = path.resolve(process.cwd(), projectName);
154
+ const pkgName = path.basename(projectName).toLowerCase().replace(/[^a-z0-9-_]/g, '');
155
+ const libraryName = toCamelCase(pkgName);
156
+
157
+ console.log(`\nCreating GeaJS library in ${pc.green(projectDir)}...\n`);
158
+
159
+ // Source template path
160
+ const templatePath = path.resolve(__dirname, '../templates', language);
161
+
162
+ try {
163
+ // Copy template files
164
+ await copyDir(templatePath, projectDir, {
165
+ projectName: pkgName,
166
+ libraryName: libraryName
167
+ });
168
+
169
+ // Git initialization
170
+ if (gitInit) {
171
+ console.log(pc.dim('Initializing git repository...'));
172
+ try {
173
+ await runCommand('git', ['init'], { cwd: projectDir });
174
+ } catch (err) {
175
+ console.warn(pc.yellow('⚠ Could not initialize git repository: ' + err.message));
176
+ }
177
+ }
178
+
179
+ // Dependency installation
180
+ const pkgManager = detectPackageManager();
181
+ if (installDeps) {
182
+ console.log(pc.dim(`Installing dependencies using ${pkgManager}...`));
183
+ try {
184
+ const installArgs = pkgManager === 'yarn' ? [] : ['install'];
185
+ await runCommand(pkgManager, installArgs, { cwd: projectDir });
186
+ console.log(pc.green('\n✔ Dependencies installed successfully!'));
187
+ } catch (err) {
188
+ console.error(pc.red(`\n✖ Failed to install dependencies: ${err.message}`));
189
+ }
190
+ }
191
+
192
+ // Success Screen
193
+ console.log('\n' + pc.green(pc.bold('🎉 Project created successfully!')) + '\n');
194
+ console.log('To get started:');
195
+
196
+ if (path.resolve(process.cwd()) !== projectDir) {
197
+ console.log(` ${pc.cyan(`cd ${projectName}`)}`);
198
+ }
199
+
200
+ if (!installDeps) {
201
+ console.log(` ${pc.cyan(`${pkgManager} install`)}`);
202
+ }
203
+
204
+ console.log(` ${pc.cyan(`${pkgManager} run dev`)} ${pc.dim('# Starts interactive demo sandbox')}`);
205
+ console.log(` ${pc.cyan(`${pkgManager} run build`)} ${pc.dim('# Builds library for NPM distribution')}`);
206
+ console.log('\nHappy coding with GeaJS!\n');
207
+
208
+ } catch (error) {
209
+ console.error(pc.red(`\n✖ Scaffolding failed: ${error.message}`));
210
+ process.exit(1);
211
+ }
212
+ }
213
+
214
+ main();
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "gea-lib",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold a modern, reactive library for GeaJS",
5
+ "type": "module",
6
+ "bin": {
7
+ "gea-lib": "./bin/index.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "templates"
12
+ ],
13
+ "scripts": {
14
+ "start": "node ./bin/index.js"
15
+ },
16
+ "keywords": [
17
+ "geajs",
18
+ "gea",
19
+ "reactive",
20
+ "library",
21
+ "scaffolder",
22
+ "create"
23
+ ],
24
+ "author": "Mehmet Fıskındal",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/mehmetfiskindal/gea-lib.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/mehmetfiskindal/gea-lib/issues"
32
+ },
33
+ "homepage": "https://github.com/mehmetfiskindal/gea-lib#readme",
34
+ "dependencies": {
35
+ "picocolors": "^1.1.1",
36
+ "prompts": "^2.4.2"
37
+ }
38
+ }
@@ -0,0 +1,39 @@
1
+ # <% projectName %>
2
+
3
+ A modern, high-performance, and reactive component library for **GeaJS**.
4
+
5
+ Built with compiler-first reactivity, proxy-based state management, and modern glassmorphic designs.
6
+
7
+ ## Features
8
+
9
+ - ⚡ **No Virtual DOM**: Built on GeaJS, compile-time JSX transformations for surgical DOM patching.
10
+ - 🎨 **Premium Styling**: Pre-configured responsive styles, micro-animations, and glassmorphic designs.
11
+ - 🛠️ **Playground Included**: An interactive visual sandbox to test and showcase your components in real-time.
12
+
13
+ ## Development
14
+
15
+ To start the interactive playground:
16
+
17
+ ```bash
18
+ npm install
19
+ npm run dev
20
+ ```
21
+
22
+ ## Production Build
23
+
24
+ To build your library for distribution:
25
+
26
+ ```bash
27
+ npm run build
28
+ ```
29
+
30
+ The build process bundles your components into `dist/index.js` (ES Modules).
31
+
32
+ ## Usage
33
+
34
+ Register components in your main application:
35
+
36
+ ```javascript
37
+ import { Button, Card, counterStore } from '<% projectName %>';
38
+ import '<% projectName %>/style.css';
39
+ ```
@@ -0,0 +1,42 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ # Dependency directories
11
+ node_modules/
12
+ jspm_packages/
13
+
14
+ # Compiler outputs
15
+ dist/
16
+ tmp/
17
+ out/
18
+ .docusaurus/
19
+
20
+ # IDEs and editors
21
+ .idea/
22
+ .vscode/
23
+ *.suo
24
+ *.ntvs*
25
+ *.njsproj
26
+ *.sln
27
+ *.sw?
28
+
29
+ # OS files
30
+ .DS_Store
31
+ Thumbs.db
32
+
33
+ # Test coverage
34
+ coverage/
35
+ .nyc_output/
36
+
37
+ # Build environment
38
+ .env
39
+ .env.local
40
+ .env.development.local
41
+ .env.test.local
42
+ .env.production.local
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "<% projectName %>",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./style.css": "./dist/style.css"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "dev": "vite",
18
+ "build": "vite build",
19
+ "preview": "vite preview",
20
+ "test": "vitest run"
21
+ },
22
+ "peerDependencies": {
23
+ "@geajs/core": "^1.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@geajs/core": "^1.0.0",
27
+ "@geajs/vite-plugin": "^1.0.0",
28
+ "vite": "^8.0.0",
29
+ "vitest": "^2.0.0",
30
+ "jsdom": "^24.1.0"
31
+ }
32
+ }
@@ -0,0 +1,80 @@
1
+ import { Component } from '@geajs/core';
2
+ import { Button, Card, counterStore } from '../src';
3
+
4
+ export default class App extends Component {
5
+ template() {
6
+ return (
7
+ <div style="max-width: 800px; width: 100%; padding: 2rem;">
8
+ <div style="text-align: center; margin-bottom: 3rem;">
9
+ <h1 style="font-size: 3rem; font-weight: 800; background: linear-gradient(135deg, #a78bfa 0%, #ec4899 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 0.5rem; letter-spacing: -0.05em;">
10
+ GeaJS Library Playground
11
+ </h1>
12
+ <p style="color: var(--text-secondary); font-size: 1.1rem;">
13
+ Interactive sandbox demonstrating your reactive components
14
+ </p>
15
+ </div>
16
+
17
+ <div style="display: grid; grid-template-columns: 1fr; gap: 2rem;">
18
+
19
+ {/* Reactive Counter Card */}
20
+ <Card
21
+ title="Reactive State Demo"
22
+ footer={
23
+ <Button variant="glass" click={() => counterStore.reset()}>
24
+ Reset Counter
25
+ </Button>
26
+ }
27
+ >
28
+ <p style="margin-bottom: 1.5rem;">
29
+ GeaJS utilizes deep proxies to surgically update the DOM. Click the buttons below to see the reactivity in action.
30
+ </p>
31
+
32
+ <div style="display: flex; align-items: center; justify-content: center; gap: 2rem; margin: 2rem 0; padding: 1.5rem; background: rgba(255,255,255,0.02); border-radius: 16px; border: 1px dashed rgba(255,255,255,0.08);">
33
+ <Button variant="secondary" click={() => counterStore.decrement()}>-</Button>
34
+ <span style="font-family: var(--font-mono); font-size: 3rem; font-weight: bold; min-width: 80px; text-align: center; color: #ffffff;">
35
+ {counterStore.count}
36
+ </span>
37
+ <Button variant="primary" click={() => counterStore.increment()}>+</Button>
38
+ </div>
39
+ </Card>
40
+
41
+ {/* Button Variant Showcase */}
42
+ <Card title="Button Variants">
43
+ <p style="margin-bottom: 1.5rem;">
44
+ Beautiful styled buttons with hover glows and tap micro-animations.
45
+ </p>
46
+
47
+ <div style="display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center;">
48
+ <Button variant="primary" click={() => alert('Primary clicked!')}>
49
+ Primary Glow
50
+ </Button>
51
+ <Button variant="secondary" click={() => alert('Secondary clicked!')}>
52
+ Secondary Glow
53
+ </Button>
54
+ <Button variant="glass" click={() => alert('Glass clicked!')}>
55
+ Glassmorphic
56
+ </Button>
57
+ <Button variant="primary" disabled={true}>
58
+ Disabled
59
+ </Button>
60
+ </div>
61
+ </Card>
62
+
63
+ {/* Integration Guide */}
64
+ <Card title="How to Import">
65
+ <p style="margin-bottom: 1rem;">Import components directly into your GeaJS project:</p>
66
+ <pre style="background: rgba(0,0,0,0.3); padding: 1rem; border-radius: 12px; border: 1px solid rgba(255,255,255,0.05); font-family: var(--font-mono); font-size: 0.9rem; color: #a78bfa; overflow-x: auto; white-space: pre-wrap;">
67
+ {`import { Button, Card } from 'your-library-name';
68
+
69
+ // In template:
70
+ <Card title="My Card">
71
+ <Button click={() => doSomething()}>Click Me</Button>
72
+ </Card>`}
73
+ </pre>
74
+ </Card>
75
+
76
+ </div>
77
+ </div>
78
+ );
79
+ }
80
+ }
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title><% projectName %> - Component Library Playground</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
10
+ </head>
11
+ <body>
12
+ <div id="app"></div>
13
+ <script type="module" src="/playground/main.js"></script>
14
+ </body>
15
+ </html>
@@ -0,0 +1,5 @@
1
+ import App from './app';
2
+ import './style.css';
3
+
4
+ const app = new App();
5
+ app.render(document.getElementById('app'));
@@ -0,0 +1,49 @@
1
+ :root {
2
+ --bg-color: #030014;
3
+ --panel-bg: rgba(255, 255, 255, 0.03);
4
+ --panel-border: rgba(255, 255, 255, 0.08);
5
+ --primary-color: #7c3aed;
6
+ --primary-glow: rgba(124, 58, 237, 0.3);
7
+ --secondary-color: #06b6d4;
8
+ --secondary-glow: rgba(6, 182, 212, 0.3);
9
+ --accent-color: #ec4899;
10
+ --text-primary: #f3f4f6;
11
+ --text-secondary: #9ca3af;
12
+ --font-sans: 'Outfit', sans-serif;
13
+ --font-mono: 'JetBrains Mono', monospace;
14
+ }
15
+
16
+ * {
17
+ box-sizing: border-box;
18
+ margin: 0;
19
+ padding: 0;
20
+ }
21
+
22
+ body {
23
+ background-color: var(--bg-color);
24
+ color: var(--text-primary);
25
+ font-family: var(--font-sans);
26
+ min-height: 100vh;
27
+ display: flex;
28
+ justify-content: center;
29
+ align-items: center;
30
+ overflow-x: hidden;
31
+ background-image:
32
+ radial-gradient(circle at 10% 20%, rgba(124, 58, 237, 0.15) 0%, transparent 40%),
33
+ radial-gradient(circle at 90% 80%, rgba(6, 182, 212, 0.15) 0%, transparent 40%);
34
+ }
35
+
36
+ /* Scrollbar styles */
37
+ ::-webkit-scrollbar {
38
+ width: 8px;
39
+ }
40
+ ::-webkit-scrollbar-track {
41
+ background: var(--bg-color);
42
+ }
43
+ ::-webkit-scrollbar-thumb {
44
+ background: var(--panel-border);
45
+ border-radius: 4px;
46
+ }
47
+ ::-webkit-scrollbar-thumb:hover {
48
+ background: var(--primary-color);
49
+ }
@@ -0,0 +1,74 @@
1
+ .gea-btn {
2
+ font-family: var(--font-sans, 'Outfit', sans-serif);
3
+ font-weight: 600;
4
+ font-size: 0.95rem;
5
+ padding: 0.75rem 1.5rem;
6
+ border-radius: 12px;
7
+ border: 1px solid transparent;
8
+ cursor: pointer;
9
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ gap: 0.5rem;
14
+ position: relative;
15
+ overflow: hidden;
16
+ color: #ffffff;
17
+ }
18
+
19
+ .gea-btn::after {
20
+ content: '';
21
+ position: absolute;
22
+ inset: 0;
23
+ background: rgba(255, 255, 255, 0.1);
24
+ opacity: 0;
25
+ transition: opacity 0.2s ease;
26
+ }
27
+
28
+ .gea-btn:hover::after {
29
+ opacity: 1;
30
+ }
31
+
32
+ .gea-btn:active {
33
+ transform: scale(0.97);
34
+ }
35
+
36
+ .gea-btn:disabled {
37
+ opacity: 0.5;
38
+ cursor: not-allowed;
39
+ transform: none;
40
+ }
41
+
42
+ /* Variants */
43
+ .gea-btn-primary {
44
+ background: linear-gradient(135deg, var(--primary-color, #7c3aed) 0%, #6d28d9 100%);
45
+ box-shadow: 0 4px 15px var(--primary-glow, rgba(124, 58, 237, 0.3));
46
+ }
47
+
48
+ .gea-btn-primary:hover {
49
+ box-shadow: 0 6px 20px var(--primary-glow, rgba(124, 58, 237, 0.5));
50
+ transform: translateY(-1px);
51
+ }
52
+
53
+ .gea-btn-secondary {
54
+ background: linear-gradient(135deg, var(--secondary-color, #06b6d4) 0%, #0891b2 100%);
55
+ box-shadow: 0 4px 15px var(--secondary-glow, rgba(6, 182, 212, 0.3));
56
+ }
57
+
58
+ .gea-btn-secondary:hover {
59
+ box-shadow: 0 6px 20px var(--secondary-glow, rgba(6, 182, 212, 0.5));
60
+ transform: translateY(-1px);
61
+ }
62
+
63
+ .gea-btn-glass {
64
+ background: rgba(255, 255, 255, 0.05);
65
+ border: 1px solid rgba(255, 255, 255, 0.1);
66
+ backdrop-filter: blur(10px);
67
+ -webkit-backdrop-filter: blur(10px);
68
+ }
69
+
70
+ .gea-btn-glass:hover {
71
+ background: rgba(255, 255, 255, 0.1);
72
+ border-color: rgba(255, 255, 255, 0.2);
73
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
74
+ }