@katlux/preset-modern 0.1.0-beta.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present, The Katlux Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # Modern Template - Component Summary
2
+
3
+ The modern template provides a fresh, contemporary design for KatluxToolkit components with gradients, smooth animations, and enhanced visual feedback.
4
+
5
+ ## Supported Components
6
+
7
+ ### ✅ KButton
8
+ - Gradient backgrounds for all button types
9
+ - Smooth hover lift animation
10
+ - Enhanced shadows for depth
11
+ - Icon slot support
12
+ - Custom animated loading spinner
13
+
14
+ ### ✅ KCheckbox
15
+ - Gradient-filled checkmark on selection
16
+ - Smooth check animation with pop effect
17
+ - Hover glow effect
18
+ - Rounded corners
19
+ - Disabled state styling
20
+
21
+ ### ✅ KTextbox
22
+ - Clean, minimal design
23
+ - Focus ring with brand color
24
+ - Animated clear button
25
+ - Smooth transitions
26
+ - Enhanced placeholder styling
27
+
28
+ ### ✅ KTextarea
29
+ - Consistent styling with KTextbox
30
+ - Focus ring animation
31
+ - Smooth border transitions
32
+ - Comfortable padding
33
+ - Disabled state support
34
+
35
+ ## Design Features
36
+
37
+ ### Color Palette
38
+ - Primary: `#667eea` → `#764ba2` (gradient)
39
+ - Focus ring: `rgba(102, 126, 234, 0.1)`
40
+ - Borders: `#e5e7eb` (default), `#667eea` (focus)
41
+ - Text: `#1f2937` (primary), `#9ca3af` (placeholder)
42
+
43
+ ### Animations
44
+ - Cubic-bezier easing: `cubic-bezier(0.4, 0, 0.2, 1)`
45
+ - Transition duration: `0.3s` (standard), `0.2s` (quick)
46
+ - Transform effects: lift, scale, pop
47
+
48
+ ### Spacing
49
+ - Border radius: `10-14px` (depending on component)
50
+ - Padding: `12-16px`
51
+ - Focus ring: `3px` offset
52
+ - Gaps: `8-12px`
53
+
54
+ ## Usage Examples
55
+
56
+ ### KButton with Icon
57
+ ```vue
58
+ <KButton type="primary">
59
+ <template #icon>
60
+ <Icon name="mdi:check" />
61
+ </template>
62
+ Save Changes
63
+ </KButton>
64
+ ```
65
+
66
+ ### KCheckbox
67
+ ```vue
68
+ <KCheckbox v-model="accepted">
69
+ I accept the terms and conditions
70
+ </KCheckbox>
71
+ ```
72
+
73
+ ### KTextbox with Clear
74
+ ```vue
75
+ <KTextbox
76
+ v-model="searchQuery"
77
+ placeholder="Search..."
78
+ :showClear="true"
79
+ />
80
+ ```
81
+
82
+ ### KTextarea
83
+ ```vue
84
+ <KTextarea
85
+ v-model="description"
86
+ placeholder="Enter description..."
87
+ :rows="6"
88
+ />
89
+ ```
90
+
91
+ ## Installation
92
+
93
+ Katlux is a zero-configuration Nuxt module. When you install this preset, the core `@katlux/toolkit` is automatically provisioned for you.
94
+
95
+ ### Option 1: Using Nuxt CLI (Recommended)
96
+ ```bash
97
+ npx nuxi module add @katlux/preset-modern
98
+ ```
99
+ This single command installs the package and adds it to your `nuxt.config.ts`.
100
+
101
+ ### Option 2: Manual Installation
102
+ 1. Install via NPM:
103
+ ```bash
104
+ npm install @katlux/preset-modern
105
+ ```
106
+
107
+ 2. Register the module in `nuxt.config.ts`:
108
+ ```ts
109
+ export default defineNuxtConfig({
110
+ modules: [
111
+ '@katlux/preset-modern'
112
+ ]
113
+ })
114
+ ```
115
+
116
+ That's all! Start using Katlux components like `<KButton>` in your Vue files immediately. No imports required.
117
+
118
+ ## Next Components
119
+
120
+ Coming soon:
121
+ - KRadiobox
122
+ - KCombobox
123
+ - KDatatable
124
+ - KModal
125
+ - KPanel
126
+ - And more...
127
+
128
+ ## Trademark Policy
129
+
130
+ The code in this repository is completely free and open-source under the MIT License.
131
+ However, **Katlux™** and the Katlux logo are unregistered trademarks of the Katlux project.
132
+
133
+ To protect our users from fraud, you may not use the "Katlux" name or logo to brand your own modified forks, derivative works, or malicious distributions without explicit permission. You are, however, completely free to state "Built with Katlux" in your projects!
@@ -0,0 +1,3 @@
1
+ export default {
2
+ failOnWarn: false
3
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@katlux/preset-modern",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "Modern default design preset and styling variables for Katlux components",
5
+ "author": "Katlux",
6
+ "license": "MIT",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "main": "./dist/module.mjs",
11
+ "scripts": {
12
+ "build": "nuxt-module-build build",
13
+ "dev": "nuxt-module-build build --stub"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/module.mjs"
18
+ },
19
+ "./dist/runtime/assets/*": "./dist/runtime/assets/*"
20
+ },
21
+ "dependencies": {
22
+ "@katlux/toolkit": "*",
23
+ "@nuxt/kit": "^3.20.1"
24
+ }
25
+ }
package/src/module.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { defineNuxtModule, addComponentsDir, createResolver, installModule } from '@nuxt/kit'
2
+ import { createRequire } from 'node:module'
3
+
4
+ export default defineNuxtModule({
5
+ meta: {
6
+ name: '@katlux/preset-modern',
7
+ configKey: 'katluxTemplateModern'
8
+ },
9
+ async setup(options, nuxt) {
10
+ const { resolve } = createResolver(import.meta.url)
11
+ const _require = createRequire(import.meta.url)
12
+
13
+ // 0. Auto-install the base toolkit dependency!
14
+ await installModule('@katlux/toolkit')
15
+
16
+ // 1. Auto-import components
17
+ addComponentsDir({
18
+ path: resolve('./runtime/components'),
19
+ pathPrefix: false,
20
+ extensions: ['vue'],
21
+ global: true
22
+ })
23
+
24
+ // 2. Inject SCSS variables globally via Vite
25
+ nuxt.options.vite.css = nuxt.options.vite.css || {}
26
+ nuxt.options.vite.css.preprocessorOptions = nuxt.options.vite.css.preprocessorOptions || {}
27
+ nuxt.options.vite.css.preprocessorOptions.scss = nuxt.options.vite.css.preprocessorOptions.scss || {}
28
+
29
+ const currentAdditionalData = nuxt.options.vite.css.preprocessorOptions.scss.additionalData || ''
30
+
31
+ // Resolve toolkit SCSS: find package root via package.json (exposed in exports)
32
+ const toolkitPkgJson = _require.resolve('@katlux/toolkit/package.json')
33
+ const toolkitPkgDir = toolkitPkgJson.replace(/[\\/]package\.json$/, '')
34
+
35
+ const toolkitScssPath = nuxt.options.dev
36
+ ? `${toolkitPkgDir}/src/runtime/presets/default/assets/scss/index.scss`
37
+ : `${toolkitPkgDir}/dist/runtime/presets/default/assets/scss/index.css`
38
+
39
+ const presetScssPath = nuxt.options.dev
40
+ ? resolve('./runtime/assets/scss/index.scss')
41
+ : resolve('../dist/runtime/assets/scss/index.css')
42
+
43
+ const toolkitScss = `@use "${toolkitScssPath}" as *;`
44
+ const presetScssImport = `@use "${presetScssPath}" as *;`
45
+
46
+ nuxt.options.vite.css.preprocessorOptions.scss.additionalData = `${toolkitScss}\n${presetScssImport}\n${currentAdditionalData}`
47
+ }
48
+ })
@@ -0,0 +1,175 @@
1
+ // Modern Template - CSS Custom Properties
2
+ // Vibrant gradients and modern aesthetics
3
+ // Applied when data-template="modern" is set on the root element
4
+
5
+ [data-template="modern"] {
6
+ // Primary Colors - Purple-blue gradient palette
7
+ --primary-100: #ede9fe;
8
+ --primary-300: #c4b5fd;
9
+ --primary-500: #8b5cf6;
10
+ --primary-700: #7c3aed;
11
+ --primary-900: #5b21b6;
12
+
13
+ // Accent Colors - Cyan/teal
14
+ --accent-100: #cffafe;
15
+ --accent-300: #67e8f9;
16
+ --accent-500: #06b6d4;
17
+ --accent-700: #0891b2;
18
+ --accent-900: #155e75;
19
+
20
+ // Neutral Colors - Slate tones
21
+ --neutral-50: #f8fafc;
22
+ --neutral-100: #f1f5f9;
23
+ --neutral-200: #e2e8f0;
24
+ --neutral-300: #cbd5e1;
25
+ --neutral-400: #94a3b8;
26
+ --neutral-500: #64748b;
27
+ --neutral-600: #475569;
28
+ --neutral-700: #334155;
29
+ --neutral-800: #1e293b;
30
+ --neutral-900: #0f172a;
31
+
32
+ // Semantic Colors
33
+ --success-color: #10b981;
34
+ --success-color-light: #ecfdf5;
35
+ --warning-color: #f59e0b;
36
+ --warning-color-light: #fffbeb;
37
+ --error-color: #ef4444;
38
+ --error-color-light: #fef2f2;
39
+ --info-color: #3b82f6;
40
+ --info-color-light: #eff6ff;
41
+
42
+ // Font Colors
43
+ --font-color-primary: var(--neutral-700);
44
+ --font-color-secondary: var(--neutral-500);
45
+ --font-color-heading: var(--neutral-900);
46
+ --font-color-light: #ffffff;
47
+
48
+ // Background Colors
49
+ --background-color: #ffffff;
50
+ --background-color-light: var(--neutral-50);
51
+ --background-color-medium: var(--neutral-100);
52
+ --background-color-dark: var(--neutral-800);
53
+
54
+ // Border Colors
55
+ --border-color-light: var(--neutral-200);
56
+ --border-color-medium: var(--neutral-300);
57
+ --border-color-dark: var(--neutral-500);
58
+
59
+ // Spacing
60
+ --gap-sm: 8px;
61
+ --gap-md: 16px;
62
+ --gap-lg: 24px;
63
+ --gap-xl: 32px;
64
+
65
+ // Border Radius - More rounded for modern look
66
+ --border-radius-sm: 8px;
67
+ --border-radius-md: 12px;
68
+ --border-radius-lg: 16px;
69
+ --border-radius-xl: 24px;
70
+ --border-radius-full: 9999px;
71
+
72
+ // Shadows - Modern elevated shadows
73
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
74
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
75
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
76
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
77
+
78
+ // Glow shadows for buttons
79
+ --shadow-glow-primary: 0 10px 15px -3px rgba(102, 126, 234, 0.4), 0 4px 6px -2px rgba(102, 126, 234, 0.2);
80
+ --shadow-glow-danger: 0 10px 15px -3px rgba(245, 87, 108, 0.4), 0 4px 6px -2px rgba(245, 87, 108, 0.2);
81
+ --shadow-glow-success: 0 10px 15px -3px rgba(79, 172, 254, 0.4), 0 4px 6px -2px rgba(79, 172, 254, 0.2);
82
+
83
+ // Typography
84
+ --font-size-xs: 12px;
85
+ --font-size-sm: 14px;
86
+ --font-size-md: 16px;
87
+ --font-size-lg: 18px;
88
+ --font-size-xl: 20px;
89
+ --font-weight-normal: 400;
90
+ --font-weight-medium: 500;
91
+ --font-weight-semibold: 600;
92
+ --font-weight-bold: 700;
93
+ --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
94
+ --font-family-mono: 'Fira Code', 'Roboto Mono', monospace;
95
+
96
+ // Transitions
97
+ --transition-fast: 0.15s ease;
98
+ --transition-normal: 0.3s ease;
99
+ --transition-slow: 0.5s ease;
100
+ --transition-bounce: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
101
+
102
+ // Button-specific
103
+ --button-border-radius: var(--border-radius-md);
104
+ --button-font-size-sm: var(--font-size-sm);
105
+ --button-font-size-md: var(--font-size-md);
106
+ --button-font-size-lg: var(--font-size-lg);
107
+
108
+ // Button Gradients
109
+ --button-gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
110
+ --button-gradient-danger: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
111
+ --button-gradient-success: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
112
+ --button-gradient-warning: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
113
+ --button-gradient-info: linear-gradient(135deg, #30cfd0 0%, #330867 100%);
114
+ --button-gradient-light: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%);
115
+ --button-gradient-dark: linear-gradient(135deg, #434343 0%, #000000 100%);
116
+
117
+ // Button Colors (using gradients as backgrounds)
118
+ --button-bg-default: var(--button-gradient-primary);
119
+ --button-text-default: var(--font-color-light);
120
+ --button-hover-bg-default: var(--button-gradient-primary);
121
+
122
+ --button-bg-primary: var(--button-gradient-primary);
123
+ --button-text-primary: var(--font-color-light);
124
+ --button-hover-bg-primary: var(--button-gradient-primary);
125
+
126
+ --button-bg-success: var(--button-gradient-success);
127
+ --button-text-success: var(--font-color-light);
128
+ --button-hover-bg-success: var(--button-gradient-success);
129
+
130
+ --button-bg-warning: var(--button-gradient-warning);
131
+ --button-text-warning: var(--neutral-800);
132
+ --button-hover-bg-warning: var(--button-gradient-warning);
133
+
134
+ --button-bg-danger: var(--button-gradient-danger);
135
+ --button-text-danger: var(--font-color-light);
136
+ --button-hover-bg-danger: var(--button-gradient-danger);
137
+
138
+ --button-bg-info: var(--button-gradient-info);
139
+ --button-text-info: var(--font-color-light);
140
+ --button-hover-bg-info: var(--button-gradient-info);
141
+
142
+ --button-bg-light: var(--button-gradient-light);
143
+ --button-text-light: var(--neutral-800);
144
+ --button-hover-bg-light: var(--button-gradient-light);
145
+
146
+ --button-bg-dark: var(--button-gradient-dark);
147
+ --button-text-dark: var(--font-color-light);
148
+ --button-hover-bg-dark: var(--button-gradient-dark);
149
+
150
+ // Input
151
+ --input-border-radius: var(--border-radius-sm);
152
+ --input-border-color: var(--border-color-medium);
153
+ --input-focus-border-color: var(--primary-500);
154
+ --input-focus-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
155
+
156
+ // Table
157
+ --table-header-bg: var(--neutral-100);
158
+ --table-header-color: var(--neutral-600);
159
+ --table-border-color: var(--neutral-200);
160
+ --table-row-hover: var(--neutral-100);
161
+ --table-row-selected: #eff6ff;
162
+
163
+ // Checkbox
164
+ --checkbox-bg: var(--background-color);
165
+ --checkbox-checked-bg: var(--button-gradient-primary);
166
+ --checkbox-border-color: var(--neutral-400);
167
+ --modal-overlay-bg: rgba(15, 23, 42, 0.6);
168
+
169
+ // Layout Variables
170
+ --layout-header-height: 70px;
171
+ --layout-header-bg: var(--background-color);
172
+ --layout-sidebar-width: 240px;
173
+ --layout-sidebar-bg: var(--neutral-50);
174
+ --layout-content-bg: #ffffff;
175
+ }
@@ -0,0 +1,3 @@
1
+ @use "css-variables";
2
+ // Documentation styles are globally included via default template for now
3
+ // but using common theme variables
@@ -0,0 +1,72 @@
1
+ <template lang="pug">
2
+ .k-bulk-actions-modern
3
+ .actions-wrapper
4
+ //- Display actions as buttons if few, or dropdown if many
5
+ template(v-if="bulkActions.length > 3")
6
+ KCombobox(
7
+ :dataProvider="dp"
8
+ v-model="selected"
9
+ labelField="label"
10
+ closeOnSelect
11
+ :disabled="selectedRows.length === 0"
12
+ placeholder="Select Action"
13
+ class="action-select"
14
+ )
15
+ KButton(
16
+ @click="doAction(selected)"
17
+ size="small"
18
+ :disabled="selectedRows.length === 0 || selected == undefined"
19
+ class="execute-btn"
20
+ ) Go
21
+
22
+ template(v-else v-for="action in bulkActions" :key="action.label")
23
+ KButton(
24
+ @click="doAction(action)"
25
+ size="small"
26
+ variant="outline"
27
+ class="action-btn"
28
+ ) {{ action.label }}
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ import { CFlatClientDataProvider } from '@katlux/providers'
33
+ import type { IKDatatableAction } from '@katlux/providers'
34
+
35
+ // Use defineModel for simpler two-way binding
36
+ const selected = defineModel<any>('selected')
37
+
38
+ defineProps<{
39
+ bulkActions: IKDatatableAction[]
40
+ selectedRows: any[]
41
+ selectAll: boolean
42
+ dp: CFlatClientDataProvider
43
+ doAction: (action: any) => void
44
+ }>()
45
+ </script>
46
+
47
+ <style lang="scss" scoped>
48
+ .k-bulk-actions-modern {
49
+ display: flex;
50
+ align-items: center;
51
+
52
+ .actions-wrapper {
53
+ display: flex;
54
+ gap: var(--gap-sm);
55
+ align-items: center;
56
+ }
57
+
58
+ .action-btn {
59
+ border-radius: var(--border-radius-sm);
60
+ font-weight: var(--font-weight-medium);
61
+ transition: all var(--transition-fast);
62
+
63
+ &:hover {
64
+ transform: translateY(-1px);
65
+ }
66
+ }
67
+
68
+ .execute-btn {
69
+ border-radius: var(--border-radius-sm);
70
+ }
71
+ }
72
+ </style>
@@ -0,0 +1,227 @@
1
+ <template lang="pug">
2
+ NuxtLink.KButton.modern-button(v-if="isLink" :to="href" @click.prevent="onClick" :class="buttonClasses")
3
+ .button-content
4
+ .button-icon(v-if="$slots.icon")
5
+ slot(name="icon")
6
+ .button-text
7
+ slot
8
+ .button-loader(v-if="loading")
9
+ .spinner
10
+ button.KButton.modern-button(v-else @click="onClick" :class="buttonClasses" :disabled="isDisabled")
11
+ .button-content
12
+ .button-icon(v-if="$slots.icon")
13
+ slot(name="icon")
14
+ .button-text
15
+ slot
16
+ .button-loader(v-if="loading")
17
+ .spinner
18
+ </template>
19
+
20
+ <script lang="ts" setup>
21
+ // Modern template for KButton
22
+ defineProps<{
23
+ isLink: boolean
24
+ isDisabled: boolean
25
+ buttonClasses: any
26
+ onClick: () => void
27
+ href?: string
28
+ loading?: boolean
29
+ }>()
30
+ </script>
31
+
32
+ <style lang="scss" scoped>
33
+ .KButton.modern-button {
34
+ border-radius: var(--button-border-radius);
35
+ font-weight: var(--font-weight-semibold);
36
+ cursor: pointer;
37
+ transition: all var(--transition-bounce);
38
+ border: 2px solid transparent;
39
+ position: relative;
40
+ overflow: hidden;
41
+ text-decoration: none;
42
+ box-shadow: var(--shadow-md);
43
+
44
+ .button-content {
45
+ display: flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ gap: var(--gap-sm);
49
+ position: relative;
50
+ z-index: 1;
51
+ }
52
+
53
+ .button-icon {
54
+ display: flex;
55
+ align-items: center;
56
+ font-size: 1.2em;
57
+ }
58
+
59
+ .button-text {
60
+ display: flex;
61
+ align-items: center;
62
+ }
63
+
64
+ .button-loader {
65
+ position: absolute;
66
+ right: 12px;
67
+ top: 50%;
68
+ transform: translateY(-50%);
69
+
70
+ .spinner {
71
+ width: 16px;
72
+ height: 16px;
73
+ border: 2px solid rgba(255, 255, 255, 0.3);
74
+ border-top-color: white;
75
+ border-radius: 50%;
76
+ animation: spin 0.6s linear infinite;
77
+ }
78
+ }
79
+
80
+ &::before {
81
+ content: '';
82
+ position: absolute;
83
+ top: 0;
84
+ left: 0;
85
+ right: 0;
86
+ bottom: 0;
87
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
88
+ opacity: 0;
89
+ transition: opacity var(--transition-normal);
90
+ }
91
+
92
+ &:hover::before {
93
+ opacity: 1;
94
+ }
95
+
96
+ &:disabled {
97
+ opacity: 0.6;
98
+ cursor: not-allowed;
99
+ pointer-events: none;
100
+ box-shadow: none;
101
+ }
102
+
103
+ // Color variants
104
+ &.default, &.primary {
105
+ background: var(--button-bg-primary);
106
+ color: var(--button-text-primary);
107
+
108
+ &:hover {
109
+ transform: translateY(-2px);
110
+ box-shadow: var(--shadow-glow-primary, var(--shadow-lg));
111
+ }
112
+ }
113
+
114
+ &.danger {
115
+ background: var(--button-bg-danger);
116
+ color: var(--button-text-danger);
117
+
118
+ &:hover {
119
+ transform: translateY(-2px);
120
+ box-shadow: var(--shadow-glow-danger, var(--shadow-lg));
121
+ }
122
+ }
123
+
124
+ &.success {
125
+ background: var(--button-bg-success);
126
+ color: var(--button-text-success);
127
+
128
+ &:hover {
129
+ transform: translateY(-2px);
130
+ box-shadow: var(--shadow-glow-success, var(--shadow-lg));
131
+ }
132
+ }
133
+
134
+ &.warning {
135
+ background: var(--button-bg-warning);
136
+ color: var(--button-text-warning);
137
+
138
+ &:hover {
139
+ transform: translateY(-2px);
140
+ box-shadow: var(--shadow-lg);
141
+ }
142
+
143
+ .spinner {
144
+ border-color: rgba(51, 51, 51, 0.3);
145
+ border-top-color: #333;
146
+ }
147
+ }
148
+
149
+ &.info {
150
+ background: var(--button-bg-info);
151
+ color: var(--button-text-info);
152
+
153
+ &:hover {
154
+ transform: translateY(-2px);
155
+ box-shadow: var(--shadow-lg);
156
+ }
157
+ }
158
+
159
+ &.light {
160
+ background: var(--button-bg-light);
161
+ color: var(--button-text-light);
162
+ border-color: var(--border-color-medium);
163
+
164
+ &:hover {
165
+ transform: translateY(-2px);
166
+ box-shadow: var(--shadow-lg);
167
+ }
168
+
169
+ .spinner {
170
+ border-color: rgba(51, 51, 51, 0.3);
171
+ border-top-color: #333;
172
+ }
173
+ }
174
+
175
+ &.dark {
176
+ background: var(--button-bg-dark);
177
+ color: var(--button-text-dark);
178
+
179
+ &:hover {
180
+ transform: translateY(-2px);
181
+ box-shadow: var(--shadow-lg);
182
+ }
183
+ }
184
+
185
+ // Size variants
186
+ &.large {
187
+ font-size: var(--font-size-lg);
188
+ padding: var(--gap-md) var(--gap-xl);
189
+ border-radius: var(--border-radius-lg);
190
+
191
+ .button-icon {
192
+ font-size: 1.3em;
193
+ }
194
+ }
195
+
196
+ &.medium {
197
+ font-size: var(--font-size-md);
198
+ padding: var(--gap-sm) var(--gap-lg);
199
+ border-radius: var(--button-border-radius);
200
+ }
201
+
202
+ &.small {
203
+ font-size: var(--font-size-sm);
204
+ padding: var(--gap-sm) var(--gap-md);
205
+ border-radius: var(--border-radius-sm);
206
+
207
+ .button-icon {
208
+ font-size: 1.1em;
209
+ }
210
+
211
+ .spinner {
212
+ width: 12px;
213
+ height: 12px;
214
+ }
215
+ }
216
+
217
+ &:active {
218
+ transform: translateY(0);
219
+ }
220
+ }
221
+
222
+ @keyframes spin {
223
+ to {
224
+ transform: rotate(360deg);
225
+ }
226
+ }
227
+ </style>