bref-ui 0.0.3 → 0.0.5

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.
@@ -0,0 +1,160 @@
1
+ # Button Component Styling Patterns
2
+
3
+ This document describes the CSS architecture and patterns used in the Button component.
4
+
5
+ ## CSS Variable Naming Convention
6
+
7
+ ### Internal vs External Variables
8
+
9
+ | Prefix | Meaning | Example |
10
+ |--------|---------|---------|
11
+ | `--color-*`, `--spacing`, `--border-radius` | **External/Theme tokens** – global design system variables | `--color-primary`, `--spacing` |
12
+ | `--internal-*` | **Internal/Private** – component-scoped variables, implementation details | `--internal-btn-hover-mix` |
13
+
14
+ The `--internal-` prefix signals that these variables are not part of the public API and should not be overridden by consumers.
15
+
16
+ ---
17
+
18
+ ## Pattern 1: Centralized Interaction Variables
19
+
20
+ All magic numbers for interactions are defined once in the base `button` selector:
21
+
22
+ ```css
23
+ button {
24
+ --internal-btn-transition-bg: 0.15s;
25
+ --internal-btn-transition-transform: 0.08s;
26
+ --internal-btn-scale-active: 0.98;
27
+ --internal-btn-disabled-opacity: 0.5;
28
+ }
29
+ ```
30
+
31
+ **Benefits:**
32
+ - Single source of truth for timing/effects
33
+ - Easy to tweak all hover/active states at once
34
+ - Self-documenting variable names
35
+
36
+ ---
37
+
38
+ ## Pattern 2: Color Mix Percentages as Variables
39
+
40
+ Instead of hardcoding percentages in `color-mix()`, they're stored as variables:
41
+
42
+ ```css
43
+ button {
44
+ --internal-btn-hover-mix: 85%;
45
+ --internal-btn-active-mix: 70%;
46
+ --internal-btn-ghost-hover-opacity: 10%;
47
+ --internal-btn-ghost-active-opacity: 25%;
48
+ }
49
+ ```
50
+
51
+ **Usage:**
52
+ ```css
53
+ .filled:not(:disabled):hover {
54
+ background-color: color-mix(in oklch, var(--internal-current-color) var(--internal-btn-hover-mix), black);
55
+ }
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Pattern 3: Size Variants via Variable Overrides
61
+
62
+ Instead of repeating `padding`, `font-size`, `border-radius` in each size class, we override internal variables:
63
+
64
+ ```css
65
+ /* Defaults set in button {} */
66
+ --internal-btn-padding-y: calc(var(--spacing) * 0.5);
67
+ --internal-btn-padding-x: calc(var(--spacing) * 1);
68
+ --internal-btn-font-size: 1rem;
69
+ --internal-btn-radius: calc(var(--border-radius) * 1.25);
70
+
71
+ /* Size classes only override the variables */
72
+ .x-small {
73
+ --internal-btn-padding-y: calc(var(--spacing) * 0.25);
74
+ --internal-btn-padding-x: calc(var(--spacing) * 0.5);
75
+ --internal-btn-font-size: 0.75rem;
76
+ --internal-btn-radius: calc(var(--border-radius) * 0.75);
77
+ }
78
+ ```
79
+
80
+ The actual properties are applied once in the base selector:
81
+ ```css
82
+ button {
83
+ padding: var(--internal-btn-padding-y) var(--internal-btn-padding-x);
84
+ font-size: var(--internal-btn-font-size);
85
+ border-radius: var(--internal-btn-radius);
86
+ }
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Pattern 4: Dynamic Color Mapping
92
+
93
+ Color classes map theme tokens to "current" internal variables:
94
+
95
+ ```css
96
+ .primary {
97
+ --internal-current-color: var(--color-primary);
98
+ --internal-current-color-soft: var(--color-primary-soft);
99
+ --internal-current-contrast: var(--color-primary-contrast);
100
+ }
101
+
102
+ .danger {
103
+ --internal-current-color: var(--color-danger);
104
+ --internal-current-color-soft: var(--color-danger-soft);
105
+ --internal-current-contrast: var(--color-danger-contrast);
106
+ }
107
+ ```
108
+
109
+ Variants then use these generic variables:
110
+
111
+ ```css
112
+ .filled {
113
+ background-color: var(--internal-current-color);
114
+ color: var(--internal-current-contrast);
115
+ }
116
+
117
+ .soft {
118
+ background-color: var(--internal-current-color-soft);
119
+ color: var(--internal-current-color);
120
+ }
121
+
122
+ .ghost {
123
+ background-color: transparent;
124
+ color: var(--internal-current-color);
125
+ }
126
+ ```
127
+
128
+ **Benefits:**
129
+ - Adding a new color = 1 small block (3 lines)
130
+ - Variants are color-agnostic (DRY)
131
+ - ~270 lines → ~180 lines
132
+
133
+ ---
134
+
135
+ ## Pattern 5: Consistent Color Spaces
136
+
137
+ | Variant | Color Space | Reason |
138
+ |---------|-------------|--------|
139
+ | `filled`, `soft` | `oklch` | Perceptually uniform darkening with black |
140
+ | `ghost` | `srgb` | Mixing with `transparent` works better in srgb |
141
+
142
+ ```css
143
+ /* Filled/Soft: darken with black */
144
+ color-mix(in oklch, var(--internal-current-color) 85%, black)
145
+
146
+ /* Ghost: fade to transparent */
147
+ color-mix(in srgb, var(--internal-current-color-soft) 10%, transparent)
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Summary
153
+
154
+ | Pattern | What It Solves |
155
+ |---------|----------------|
156
+ | Internal prefix (`--internal-*`) | Signals private implementation details |
157
+ | Centralized interaction vars | No scattered magic numbers |
158
+ | Color mix percentages as vars | Adjust hover/active intensity in one place |
159
+ | Size via variable overrides | Sizes don't repeat property declarations |
160
+ | Dynamic color mapping | Variants are color-agnostic; adding colors is trivial |
@@ -32,6 +32,24 @@
32
32
 
33
33
  <style>
34
34
  button {
35
+ /* Button interaction variables */
36
+ --internal-btn-transition-bg: 0.15s;
37
+ --internal-btn-transition-transform: 0.08s;
38
+ --internal-btn-scale-active: 0.98;
39
+ --internal-btn-disabled-opacity: 0.5;
40
+
41
+ /* Color mix percentages */
42
+ --internal-btn-hover-mix: 85%;
43
+ --internal-btn-active-mix: 70%;
44
+ --internal-btn-ghost-hover-opacity: 10%;
45
+ --internal-btn-ghost-active-opacity: 25%;
46
+
47
+ /* Size defaults (medium) */
48
+ --internal-btn-padding-y: calc(var(--spacing) * 0.5);
49
+ --internal-btn-padding-x: calc(var(--spacing) * 1);
50
+ --internal-btn-font-size: 1rem;
51
+ --internal-btn-radius: calc(var(--border-radius) * 1.25);
52
+
35
53
  display: inline-flex;
36
54
  align-items: center;
37
55
  justify-content: center;
@@ -39,10 +57,14 @@
39
57
  border: none;
40
58
  cursor: pointer;
41
59
  font-weight: 500;
60
+ padding: var(--internal-btn-padding-y) var(--internal-btn-padding-x);
61
+ font-size: var(--internal-btn-font-size);
62
+ border-radius: var(--internal-btn-radius);
42
63
  transition:
43
- background-color 0.15s ease,
44
- transform 0.08s cubic-bezier(0.34, 1.56, 0.64, 1);
64
+ background-color var(--internal-btn-transition-bg) ease,
65
+ transform var(--internal-btn-transition-transform) cubic-bezier(0.34, 1.56, 0.64, 1);
45
66
  }
67
+
46
68
  span {
47
69
  cursor: inherit;
48
70
  color: inherit;
@@ -50,12 +72,12 @@
50
72
  }
51
73
 
52
74
  button:disabled {
53
- opacity: 0.5;
75
+ opacity: var(--internal-btn-disabled-opacity);
54
76
  cursor: not-allowed;
55
77
  }
56
78
 
57
79
  button:not(:disabled):active {
58
- transform: scale(0.98);
80
+ transform: scale(var(--internal-btn-scale-active));
59
81
  }
60
82
 
61
83
  .wide {
@@ -64,269 +86,144 @@
64
86
 
65
87
  /* Sizes */
66
88
  .x-small {
67
- padding: 0.25rem 0.5rem;
68
- font-size: 0.75rem;
69
- border-radius: calc(var(--border-radius) * 0.75);
89
+ --internal-btn-padding-y: calc(var(--spacing) * 0.25);
90
+ --internal-btn-padding-x: calc(var(--spacing) * 0.5);
91
+ --internal-btn-font-size: 0.75rem;
92
+ --internal-btn-radius: calc(var(--border-radius) * 0.75);
70
93
  }
94
+
71
95
  .small {
72
- padding: 0.375rem 0.75rem;
73
- font-size: 0.875rem;
74
- border-radius: calc(var(--border-radius));
96
+ --internal-btn-padding-y: calc(var(--spacing) * 0.375);
97
+ --internal-btn-padding-x: calc(var(--spacing) * 0.75);
98
+ --internal-btn-font-size: 0.875rem;
99
+ --internal-btn-radius: var(--border-radius);
75
100
  }
101
+
76
102
  .medium {
77
- padding: 0.5rem 1rem;
78
- font-size: 1rem;
79
- border-radius: calc(var(--border-radius) * 1.25);
103
+ --internal-btn-padding-y: calc(var(--spacing) * 0.5);
104
+ --internal-btn-padding-x: calc(var(--spacing) * 1);
105
+ --internal-btn-font-size: 1rem;
106
+ --internal-btn-radius: calc(var(--border-radius) * 1.25);
80
107
  }
108
+
81
109
  .large {
82
- padding: 0.625rem 1.25rem;
83
- font-size: 1.125rem;
84
- border-radius: calc(var(--border-radius) * 1.5);
110
+ --internal-btn-padding-y: calc(var(--spacing) * 0.625);
111
+ --internal-btn-padding-x: calc(var(--spacing) * 1.25);
112
+ --internal-btn-font-size: 1.125rem;
113
+ --internal-btn-radius: calc(var(--border-radius) * 1.5);
85
114
  }
115
+
86
116
  .x-large {
87
- padding: 0.75rem 1.5rem;
88
- font-size: 1.25rem;
89
- border-radius: calc(var(--border-radius) * 2);
117
+ --internal-btn-padding-y: calc(var(--spacing) * 0.75);
118
+ --internal-btn-padding-x: calc(var(--spacing) * 1.5);
119
+ --internal-btn-font-size: 1.25rem;
120
+ --internal-btn-radius: calc(var(--border-radius) * 2);
90
121
  }
91
122
 
92
- /* Filled variant */
93
- .filled.primary {
94
- background-color: var(--color-primary);
95
- color: var(--color-primary-contrast);
96
- }
97
- .filled.primary:not(:disabled):hover {
98
- background-color: color-mix(in oklch, var(--color-primary) 85%, var(--hover-mix));
99
- }
100
- .filled.primary:not(:disabled):active {
101
- background-color: color-mix(in oklch, var(--color-primary) 70%, var(--hover-mix));
102
- }
103
- .filled.secondary {
104
- background-color: var(--color-secondary);
105
- color: var(--color-secondary-contrast);
106
- }
107
- .filled.secondary:not(:disabled):hover {
108
- background-color: color-mix(in oklch, var(--color-secondary) 85%, var(--hover-mix));
109
- }
110
- .filled.secondary:not(:disabled):active {
111
- background-color: color-mix(in oklch, var(--color-secondary) 70%, var(--hover-mix));
112
- }
113
- .filled.success {
114
- background-color: var(--color-success);
115
- color: var(--color-success-contrast);
116
- }
117
- .filled.success:not(:disabled):hover {
118
- background-color: color-mix(in oklch, var(--color-success) 85%, var(--hover-mix));
119
- }
120
- .filled.success:not(:disabled):active {
121
- background-color: color-mix(in oklch, var(--color-success) 70%, var(--hover-mix));
122
- }
123
- .filled.warning {
124
- background-color: var(--color-warning);
125
- color: var(--color-warning-contrast);
126
- }
127
- .filled.warning:not(:disabled):hover {
128
- background-color: color-mix(in oklch, var(--color-warning) 85%, var(--hover-mix));
129
- }
130
- .filled.warning:not(:disabled):active {
131
- background-color: color-mix(in oklch, var(--color-warning) 70%, var(--hover-mix));
123
+ /* Color mappings - set current color variables per color class */
124
+ .primary {
125
+ --internal-current-color: var(--color-primary);
126
+ --internal-current-color-soft: var(--color-primary-soft);
127
+ --internal-current-contrast: var(--color-primary-contrast);
132
128
  }
133
- .filled.danger {
134
- background-color: var(--color-danger);
135
- color: var(--color-danger-contrast);
136
- }
137
- .filled.danger:not(:disabled):hover {
138
- background-color: color-mix(in oklch, var(--color-danger) 85%, var(--hover-mix));
139
- }
140
- .filled.danger:not(:disabled):active {
141
- background-color: color-mix(in oklch, var(--color-danger) 70%, var(--hover-mix));
129
+
130
+ .secondary {
131
+ --internal-current-color: var(--color-secondary);
132
+ --internal-current-color-soft: var(--color-secondary-soft);
133
+ --internal-current-contrast: var(--color-secondary-contrast);
142
134
  }
143
- .filled.info {
144
- background-color: var(--color-info);
145
- color: var(--color-info-contrast);
135
+
136
+ .success {
137
+ --internal-current-color: var(--color-success);
138
+ --internal-current-color-soft: var(--color-success-soft);
139
+ --internal-current-contrast: var(--color-success-contrast);
146
140
  }
147
- .filled.info:not(:disabled):hover {
148
- background-color: color-mix(in oklch, var(--color-info) 85%, var(--hover-mix));
141
+
142
+ .warning {
143
+ --internal-current-color: var(--color-warning);
144
+ --internal-current-color-soft: var(--color-warning-soft);
145
+ --internal-current-contrast: var(--color-warning-contrast);
149
146
  }
150
- .filled.info:not(:disabled):active {
151
- background-color: color-mix(in oklch, var(--color-info) 70%, var(--hover-mix));
147
+
148
+ .danger {
149
+ --internal-current-color: var(--color-danger);
150
+ --internal-current-color-soft: var(--color-danger-soft);
151
+ --internal-current-contrast: var(--color-danger-contrast);
152
152
  }
153
- .filled.foreground {
154
- background-color: var(--color-foreground);
155
- color: var(--color-background);
153
+
154
+ .info {
155
+ --internal-current-color: var(--color-info);
156
+ --internal-current-color-soft: var(--color-info-soft);
157
+ --internal-current-contrast: var(--color-info-contrast);
156
158
  }
157
- .filled.foreground:not(:disabled):hover {
158
- background-color: color-mix(in oklch, var(--color-foreground) 85%, var(--hover-mix));
159
+
160
+ .foreground {
161
+ --internal-current-color: var(--color-foreground);
162
+ --internal-current-color-soft: var(--color-foreground-soft);
163
+ --internal-current-contrast: var(--color-background);
159
164
  }
160
- .filled.foreground:not(:disabled):active {
161
- background-color: color-mix(in oklch, var(--color-foreground) 70%, var(--hover-mix));
165
+
166
+ .background {
167
+ --internal-current-color: var(--color-background);
168
+ --internal-current-color-soft: var(--color-background-soft);
169
+ --internal-current-contrast: var(--color-foreground);
162
170
  }
163
- .filled.background {
164
- background-color: var(--color-background);
165
- color: var(--color-foreground);
171
+
172
+ /* Filled variant */
173
+ .filled {
174
+ background-color: var(--internal-current-color);
175
+ color: var(--internal-current-contrast);
166
176
  }
167
- .filled.background:not(:disabled):hover {
168
- background-color: color-mix(in oklch, var(--color-background) 85%, var(--hover-mix));
177
+
178
+ .filled:not(:disabled):hover {
179
+ background-color: color-mix(in oklch, var(--internal-current-color) var(--internal-btn-hover-mix), black);
169
180
  }
170
- .filled.background:not(:disabled):active {
171
- background-color: color-mix(in oklch, var(--color-background) 70%, var(--hover-mix));
181
+
182
+ .filled:not(:disabled):active {
183
+ background-color: color-mix(in oklch, var(--internal-current-color) var(--internal-btn-active-mix), black);
172
184
  }
173
185
 
174
186
  /* Soft variant */
175
- .soft.primary {
176
- background-color: var(--color-primary-soft);
177
- color: var(--color-primary);
178
- }
179
- .soft.primary:not(:disabled):hover {
180
- background-color: color-mix(in oklch, var(--color-primary-soft) 85%, var(--hover-mix));
181
- }
182
- .soft.primary:not(:disabled):active {
183
- background-color: color-mix(in oklch, var(--color-primary-soft) 70%, var(--hover-mix));
184
- }
185
- .soft.secondary {
186
- background-color: var(--color-secondary-soft);
187
- color: var(--color-secondary);
188
- }
189
- .soft.secondary:not(:disabled):hover {
190
- background-color: color-mix(in oklch, var(--color-secondary-soft) 85%, var(--hover-mix));
191
- }
192
- .soft.secondary:not(:disabled):active {
193
- background-color: color-mix(in oklch, var(--color-secondary-soft) 70%, var(--hover-mix));
194
- }
195
- .soft.success {
196
- background-color: var(--color-success-soft);
197
- color: var(--color-success);
198
- }
199
- .soft.success:not(:disabled):hover {
200
- background-color: color-mix(in oklch, var(--color-success-soft) 85%, var(--hover-mix));
187
+ .soft {
188
+ background-color: var(--internal-current-color-soft);
189
+ color: var(--internal-current-color);
201
190
  }
202
- .soft.success:not(:disabled):active {
203
- background-color: color-mix(in oklch, var(--color-success-soft) 70%, var(--hover-mix));
204
- }
205
- .soft.warning {
206
- background-color: var(--color-warning-soft);
207
- color: var(--color-warning);
208
- }
209
- .soft.warning:not(:disabled):hover {
210
- background-color: color-mix(in oklch, var(--color-warning-soft) 85%, var(--hover-mix));
211
- }
212
- .soft.warning:not(:disabled):active {
213
- background-color: color-mix(in oklch, var(--color-warning-soft) 70%, var(--hover-mix));
214
- }
215
- .soft.danger {
216
- background-color: var(--color-danger-soft);
217
- color: var(--color-danger);
218
- }
219
- .soft.danger:not(:disabled):hover {
220
- background-color: color-mix(in oklch, var(--color-danger-soft) 85%, var(--hover-mix));
221
- }
222
- .soft.danger:not(:disabled):active {
223
- background-color: color-mix(in oklch, var(--color-danger-soft) 70%, var(--hover-mix));
224
- }
225
- .soft.info {
226
- background-color: var(--color-info-soft);
227
- color: var(--color-info);
228
- }
229
- .soft.info:not(:disabled):hover {
230
- background-color: color-mix(in oklch, var(--color-info-soft) 85%, var(--hover-mix));
231
- }
232
- .soft.info:not(:disabled):active {
233
- background-color: color-mix(in oklch, var(--color-info-soft) 70%, var(--hover-mix));
234
- }
235
- .soft.foreground {
236
- background-color: var(--color-foreground-soft);
237
- color: var(--color-foreground);
238
- }
239
- .soft.foreground:not(:disabled):hover {
240
- background-color: color-mix(in oklch, var(--color-foreground-soft) 85%, var(--hover-mix));
241
- }
242
- .soft.foreground:not(:disabled):active {
243
- background-color: color-mix(in oklch, var(--color-foreground-soft) 70%, var(--hover-mix));
244
- }
245
- .soft.background {
246
- background-color: var(--color-background-soft);
247
- color: var(--color-background);
248
- }
249
- .soft.background:not(:disabled):hover {
250
- background-color: color-mix(in oklch, var(--color-background-soft) 85%, var(--hover-mix));
191
+
192
+ .soft:not(:disabled):hover {
193
+ background-color: color-mix(
194
+ in oklch,
195
+ var(--internal-current-color-soft) var(--internal-btn-hover-mix),
196
+ var(--internal-current-color)
197
+ );
251
198
  }
252
- .soft.background:not(:disabled):active {
253
- background-color: color-mix(in oklch, var(--color-background-soft) 70%, var(--hover-mix));
199
+
200
+ .soft:not(:disabled):active {
201
+ background-color: color-mix(
202
+ in oklch,
203
+ var(--internal-current-color-soft) var(--internal-btn-active-mix),
204
+ var(--internal-current-color)
205
+ );
254
206
  }
255
207
 
256
208
  /* Ghost variant */
257
209
  .ghost {
258
210
  background-color: transparent;
211
+ color: var(--internal-current-color);
259
212
  }
260
- .ghost.primary {
261
- color: var(--color-primary);
262
- }
263
- .ghost.primary:not(:disabled):hover {
264
- background-color: color-mix(in srgb, var(--color-primary-soft) 50%, transparent);
265
- }
266
- .ghost.primary:not(:disabled):active {
267
- background-color: var(--color-primary-soft);
268
- }
269
- .ghost.secondary {
270
- color: var(--color-secondary);
271
- }
272
- .ghost.secondary:not(:disabled):hover {
273
- background-color: color-mix(in srgb, var(--color-secondary-soft) 50%, transparent);
274
- }
275
- .ghost.secondary:not(:disabled):active {
276
- background-color: var(--color-secondary-soft);
277
- }
278
- .ghost.success {
279
- color: var(--color-success);
280
- }
281
- .ghost.success:not(:disabled):hover {
282
- background-color: color-mix(in srgb, var(--color-success-soft) 50%, transparent);
283
- }
284
- .ghost.success:not(:disabled):active {
285
- background-color: var(--color-success-soft);
286
- }
287
- .ghost.warning {
288
- color: var(--color-warning);
289
- }
290
- .ghost.warning:not(:disabled):hover {
291
- background-color: color-mix(in srgb, var(--color-warning-soft) 50%, transparent);
292
- }
293
- .ghost.warning:not(:disabled):active {
294
- background-color: var(--color-warning-soft);
295
- }
296
- .ghost.danger {
297
- color: var(--color-danger);
298
- }
299
- .ghost.danger:not(:disabled):hover {
300
- background-color: color-mix(in srgb, var(--color-danger-soft) 50%, transparent);
301
- }
302
- .ghost.danger:not(:disabled):active {
303
- background-color: var(--color-danger-soft);
304
- }
305
- .ghost.info {
306
- color: var(--color-info);
307
- }
308
- .ghost.info:not(:disabled):hover {
309
- background-color: color-mix(in srgb, var(--color-info-soft) 50%, transparent);
310
- }
311
- .ghost.info:not(:disabled):active {
312
- background-color: var(--color-info-soft);
313
- }
314
- .ghost.foreground {
315
- color: var(--color-foreground);
316
- }
317
- .ghost.foreground:not(:disabled):hover {
318
- background-color: color-mix(in srgb, var(--color-foreground-soft) 50%, transparent);
319
- }
320
- .ghost.foreground:not(:disabled):active {
321
- background-color: var(--color-foreground-soft);
322
- }
323
- .ghost.background {
324
- color: var(--color-background);
325
- }
326
- .ghost.background:not(:disabled):hover {
327
- background-color: color-mix(in srgb, var(--color-background-soft) 50%, transparent);
213
+
214
+ .ghost:not(:disabled):hover {
215
+ background-color: color-mix(
216
+ in srgb,
217
+ var(--internal-current-color) var(--internal-btn-ghost-hover-opacity),
218
+ var(--color-background)
219
+ );
328
220
  }
329
- .ghost.background:not(:disabled):active {
330
- background-color: var(--color-background-soft);
221
+
222
+ .ghost:not(:disabled):active {
223
+ background-color: color-mix(
224
+ in srgb,
225
+ var(--internal-current-color) var(--internal-btn-ghost-active-opacity),
226
+ var(--color-background)
227
+ );
331
228
  }
332
229
  </style>
@@ -23,294 +23,186 @@
23
23
 
24
24
  <style>
25
25
  button {
26
+ /* Button interaction variables */
27
+ --internal-btn-transition-bg: 0.15s;
28
+ --internal-btn-transition-transform: 0.08s;
29
+ --internal-btn-scale-active: 0.95;
30
+ --internal-btn-disabled-opacity: 0.5;
31
+
32
+ /* Color mix percentages */
33
+ --internal-btn-hover-mix: 85%;
34
+ --internal-btn-active-mix: 70%;
35
+ --internal-btn-ghost-hover-opacity: 10%;
36
+ --internal-btn-ghost-active-opacity: 25%;
37
+
38
+ /* Size defaults (medium) */
39
+ --internal-btn-size: calc(var(--spacing) * 2.5);
40
+ --internal-btn-radius: calc(var(--border-radius) * 1.25);
41
+
26
42
  display: inline-flex;
27
43
  align-items: center;
28
44
  justify-content: center;
29
45
  border: none;
30
46
  cursor: pointer;
47
+ width: var(--internal-btn-size);
48
+ height: var(--internal-btn-size);
49
+ border-radius: var(--internal-btn-radius);
31
50
  transition:
32
- background-color 0.15s ease,
33
- transform 0.08s cubic-bezier(0.34, 1.56, 0.64, 1);
51
+ background-color var(--internal-btn-transition-bg) ease,
52
+ transform var(--internal-btn-transition-transform) cubic-bezier(0.34, 1.56, 0.64, 1);
34
53
  }
35
54
 
36
55
  button:disabled {
37
- opacity: 0.5;
56
+ opacity: var(--internal-btn-disabled-opacity);
38
57
  cursor: not-allowed;
39
58
  }
40
59
 
41
60
  button:not(:disabled):active {
42
- transform: scale(0.95);
61
+ transform: scale(var(--internal-btn-scale-active));
43
62
  }
44
63
 
45
64
  /* Sizes */
46
65
  .x-small {
47
- width: 1.5rem;
48
- height: 1.5rem;
49
- border-radius: calc(var(--border-radius) * 0.75);
66
+ --internal-btn-size: calc(var(--spacing) * 1.5);
67
+ --internal-btn-radius: calc(var(--border-radius) * 0.75);
50
68
  }
69
+
51
70
  .small {
52
- width: 2rem;
53
- height: 2rem;
54
- border-radius: calc(var(--border-radius));
71
+ --internal-btn-size: calc(var(--spacing) * 2);
72
+ --internal-btn-radius: var(--border-radius);
55
73
  }
74
+
56
75
  .medium {
57
- width: 2.5rem;
58
- height: 2.5rem;
59
- border-radius: calc(var(--border-radius) * 1.25);
76
+ --internal-btn-size: calc(var(--spacing) * 2.5);
77
+ --internal-btn-radius: calc(var(--border-radius) * 1.25);
60
78
  }
79
+
61
80
  .large {
62
- width: 3rem;
63
- height: 3rem;
64
- border-radius: calc(var(--border-radius) * 1.5);
81
+ --internal-btn-size: calc(var(--spacing) * 3);
82
+ --internal-btn-radius: calc(var(--border-radius) * 1.5);
65
83
  }
84
+
66
85
  .x-large {
67
- width: 4rem;
68
- height: 4rem;
69
- border-radius: calc(var(--border-radius) * 2);
86
+ --internal-btn-size: calc(var(--spacing) * 4);
87
+ --internal-btn-radius: calc(var(--border-radius) * 2);
70
88
  }
71
89
 
72
90
  .rounded {
73
91
  border-radius: 50%;
74
92
  }
75
93
 
76
- /* Filled variant */
77
- .filled.primary {
78
- background-color: var(--color-primary);
79
- color: var(--color-primary-contrast);
80
- }
81
- .filled.primary:not(:disabled):hover {
82
- background-color: color-mix(in oklch, var(--color-primary) 85%, var(--hover-mix));
83
- }
84
- .filled.primary:not(:disabled):active {
85
- background-color: color-mix(in oklch, var(--color-primary) 70%, var(--hover-mix));
86
- }
87
- .filled.secondary {
88
- background-color: var(--color-secondary);
89
- color: var(--color-secondary-contrast);
90
- }
91
- .filled.secondary:not(:disabled):hover {
92
- background-color: color-mix(in oklch, var(--color-secondary) 85%, var(--hover-mix));
93
- }
94
- .filled.secondary:not(:disabled):active {
95
- background-color: color-mix(in oklch, var(--color-secondary) 70%, var(--hover-mix));
96
- }
97
- .filled.success {
98
- background-color: var(--color-success);
99
- color: var(--color-success-contrast);
100
- }
101
- .filled.success:not(:disabled):hover {
102
- background-color: color-mix(in oklch, var(--color-success) 85%, var(--hover-mix));
103
- }
104
- .filled.success:not(:disabled):active {
105
- background-color: color-mix(in oklch, var(--color-success) 70%, var(--hover-mix));
106
- }
107
- .filled.warning {
108
- background-color: var(--color-warning);
109
- color: var(--color-warning-contrast);
110
- }
111
- .filled.warning:not(:disabled):hover {
112
- background-color: color-mix(in oklch, var(--color-warning) 85%, var(--hover-mix));
113
- }
114
- .filled.warning:not(:disabled):active {
115
- background-color: color-mix(in oklch, var(--color-warning) 70%, var(--hover-mix));
116
- }
117
- .filled.danger {
118
- background-color: var(--color-danger);
119
- color: var(--color-danger-contrast);
94
+ /* Color mappings - set current color variables per color class */
95
+ .primary {
96
+ --internal-current-color: var(--color-primary);
97
+ --internal-current-color-soft: var(--color-primary-soft);
98
+ --internal-current-contrast: var(--color-primary-contrast);
120
99
  }
121
- .filled.danger:not(:disabled):hover {
122
- background-color: color-mix(in oklch, var(--color-danger) 85%, var(--hover-mix));
123
- }
124
- .filled.danger:not(:disabled):active {
125
- background-color: color-mix(in oklch, var(--color-danger) 70%, var(--hover-mix));
100
+
101
+ .secondary {
102
+ --internal-current-color: var(--color-secondary);
103
+ --internal-current-color-soft: var(--color-secondary-soft);
104
+ --internal-current-contrast: var(--color-secondary-contrast);
126
105
  }
127
- .filled.info {
128
- background-color: var(--color-info);
129
- color: var(--color-info-contrast);
106
+
107
+ .success {
108
+ --internal-current-color: var(--color-success);
109
+ --internal-current-color-soft: var(--color-success-soft);
110
+ --internal-current-contrast: var(--color-success-contrast);
130
111
  }
131
- .filled.info:not(:disabled):hover {
132
- background-color: color-mix(in oklch, var(--color-info) 85%, var(--hover-mix));
112
+
113
+ .warning {
114
+ --internal-current-color: var(--color-warning);
115
+ --internal-current-color-soft: var(--color-warning-soft);
116
+ --internal-current-contrast: var(--color-warning-contrast);
133
117
  }
134
- .filled.info:not(:disabled):active {
135
- background-color: color-mix(in oklch, var(--color-info) 70%, var(--hover-mix));
118
+
119
+ .danger {
120
+ --internal-current-color: var(--color-danger);
121
+ --internal-current-color-soft: var(--color-danger-soft);
122
+ --internal-current-contrast: var(--color-danger-contrast);
136
123
  }
137
- .filled.foreground {
138
- background-color: var(--color-foreground);
139
- color: var(--color-background);
124
+
125
+ .info {
126
+ --internal-current-color: var(--color-info);
127
+ --internal-current-color-soft: var(--color-info-soft);
128
+ --internal-current-contrast: var(--color-info-contrast);
140
129
  }
141
- .filled.foreground:not(:disabled):hover {
142
- background-color: color-mix(in oklch, var(--color-foreground) 85%, var(--hover-mix));
130
+
131
+ .foreground {
132
+ --internal-current-color: var(--color-foreground);
133
+ --internal-current-color-soft: var(--color-foreground-soft);
134
+ --internal-current-contrast: var(--color-background);
143
135
  }
144
- .filled.foreground:not(:disabled):active {
145
- background-color: color-mix(in oklch, var(--color-foreground) 70%, var(--hover-mix));
136
+
137
+ .background {
138
+ --internal-current-color: var(--color-background);
139
+ --internal-current-color-soft: var(--color-background-soft);
140
+ --internal-current-contrast: var(--color-foreground);
146
141
  }
147
- .filled.background {
148
- background-color: var(--color-background);
149
- color: var(--color-foreground);
142
+
143
+ /* Filled variant */
144
+ .filled {
145
+ background-color: var(--internal-current-color);
146
+ color: var(--internal-current-contrast);
150
147
  }
151
- .filled.background:not(:disabled):hover {
152
- background-color: color-mix(in oklch, var(--color-background) 85%, var(--hover-mix));
148
+
149
+ .filled:not(:disabled):hover {
150
+ background-color: color-mix(
151
+ in oklch,
152
+ var(--internal-current-color) var(--internal-btn-hover-mix),
153
+ black
154
+ );
153
155
  }
154
- .filled.background:not(:disabled):active {
155
- background-color: color-mix(in oklch, var(--color-background) 70%, var(--hover-mix));
156
+
157
+ .filled:not(:disabled):active {
158
+ background-color: color-mix(
159
+ in oklch,
160
+ var(--internal-current-color) var(--internal-btn-active-mix),
161
+ black
162
+ );
156
163
  }
157
164
 
158
165
  /* Soft variant */
159
- .soft.primary {
160
- background-color: var(--color-primary-soft);
161
- color: var(--color-primary);
162
- }
163
- .soft.primary:not(:disabled):hover {
164
- background-color: color-mix(in oklch, var(--color-primary-soft) 85%, var(--hover-mix));
165
- }
166
- .soft.primary:not(:disabled):active {
167
- background-color: color-mix(in oklch, var(--color-primary-soft) 70%, var(--hover-mix));
168
- }
169
- .soft.secondary {
170
- background-color: var(--color-secondary-soft);
171
- color: var(--color-secondary);
172
- }
173
- .soft.secondary:not(:disabled):hover {
174
- background-color: color-mix(in oklch, var(--color-secondary-soft) 85%, var(--hover-mix));
175
- }
176
- .soft.secondary:not(:disabled):active {
177
- background-color: color-mix(in oklch, var(--color-secondary-soft) 70%, var(--hover-mix));
178
- }
179
- .soft.success {
180
- background-color: var(--color-success-soft);
181
- color: var(--color-success);
182
- }
183
- .soft.success:not(:disabled):hover {
184
- background-color: color-mix(in oklch, var(--color-success-soft) 85%, var(--hover-mix));
185
- }
186
- .soft.success:not(:disabled):active {
187
- background-color: color-mix(in oklch, var(--color-success-soft) 70%, var(--hover-mix));
166
+ .soft {
167
+ background-color: var(--internal-current-color-soft);
168
+ color: var(--internal-current-color);
188
169
  }
189
- .soft.warning {
190
- background-color: var(--color-warning-soft);
191
- color: var(--color-warning);
192
- }
193
- .soft.warning:not(:disabled):hover {
194
- background-color: color-mix(in oklch, var(--color-warning-soft) 85%, var(--hover-mix));
195
- }
196
- .soft.warning:not(:disabled):active {
197
- background-color: color-mix(in oklch, var(--color-warning-soft) 70%, var(--hover-mix));
198
- }
199
- .soft.danger {
200
- background-color: var(--color-danger-soft);
201
- color: var(--color-danger);
202
- }
203
- .soft.danger:not(:disabled):hover {
204
- background-color: color-mix(in oklch, var(--color-danger-soft) 85%, var(--hover-mix));
205
- }
206
- .soft.danger:not(:disabled):active {
207
- background-color: color-mix(in oklch, var(--color-danger-soft) 70%, var(--hover-mix));
208
- }
209
- .soft.info {
210
- background-color: var(--color-info-soft);
211
- color: var(--color-info);
212
- }
213
- .soft.info:not(:disabled):hover {
214
- background-color: color-mix(in oklch, var(--color-info-soft) 85%, var(--hover-mix));
215
- }
216
- .soft.info:not(:disabled):active {
217
- background-color: color-mix(in oklch, var(--color-info-soft) 70%, var(--hover-mix));
218
- }
219
- .soft.foreground {
220
- background-color: var(--color-foreground-soft);
221
- color: var(--color-foreground);
222
- }
223
- .soft.foreground:not(:disabled):hover {
224
- background-color: color-mix(in oklch, var(--color-foreground-soft) 85%, var(--hover-mix));
225
- }
226
- .soft.foreground:not(:disabled):active {
227
- background-color: color-mix(in oklch, var(--color-foreground-soft) 70%, var(--hover-mix));
228
- }
229
- .soft.background {
230
- background-color: var(--color-background-soft);
231
- color: var(--color-background);
232
- }
233
- .soft.background:not(:disabled):hover {
234
- background-color: color-mix(in oklch, var(--color-background-soft) 85%, var(--hover-mix));
170
+
171
+ .soft:not(:disabled):hover {
172
+ background-color: color-mix(
173
+ in oklch,
174
+ var(--internal-current-color-soft) var(--internal-btn-hover-mix),
175
+ var(--internal-current-color)
176
+ );
235
177
  }
236
- .soft.background:not(:disabled):active {
237
- background-color: color-mix(in oklch, var(--color-background-soft) 70%, var(--hover-mix));
178
+
179
+ .soft:not(:disabled):active {
180
+ background-color: color-mix(
181
+ in oklch,
182
+ var(--internal-current-color-soft) var(--internal-btn-active-mix),
183
+ var(--internal-current-color)
184
+ );
238
185
  }
239
186
 
240
187
  /* Ghost variant */
241
188
  .ghost {
242
189
  background-color: transparent;
190
+ color: var(--internal-current-color);
243
191
  }
244
- .ghost.primary {
245
- color: var(--color-primary);
246
- }
247
- .ghost.primary:not(:disabled):hover {
248
- background-color: color-mix(in srgb, var(--color-primary-soft) 50%, transparent);
249
- }
250
- .ghost.primary:not(:disabled):active {
251
- background-color: var(--color-primary-soft);
252
- }
253
- .ghost.secondary {
254
- color: var(--color-secondary);
255
- }
256
- .ghost.secondary:not(:disabled):hover {
257
- background-color: color-mix(in srgb, var(--color-secondary-soft) 50%, transparent);
258
- }
259
- .ghost.secondary:not(:disabled):active {
260
- background-color: var(--color-secondary-soft);
261
- }
262
- .ghost.success {
263
- color: var(--color-success);
264
- }
265
- .ghost.success:not(:disabled):hover {
266
- background-color: color-mix(in srgb, var(--color-success-soft) 50%, transparent);
267
- }
268
- .ghost.success:not(:disabled):active {
269
- background-color: var(--color-success-soft);
270
- }
271
- .ghost.warning {
272
- color: var(--color-warning);
273
- }
274
- .ghost.warning:not(:disabled):hover {
275
- background-color: color-mix(in srgb, var(--color-warning-soft) 50%, transparent);
276
- }
277
- .ghost.warning:not(:disabled):active {
278
- background-color: var(--color-warning-soft);
279
- }
280
- .ghost.danger {
281
- color: var(--color-danger);
282
- }
283
- .ghost.danger:not(:disabled):hover {
284
- background-color: color-mix(in srgb, var(--color-danger-soft) 50%, transparent);
285
- }
286
- .ghost.danger:not(:disabled):active {
287
- background-color: var(--color-danger-soft);
288
- }
289
- .ghost.info {
290
- color: var(--color-info);
291
- }
292
- .ghost.info:not(:disabled):hover {
293
- background-color: color-mix(in srgb, var(--color-info-soft) 50%, transparent);
294
- }
295
- .ghost.info:not(:disabled):active {
296
- background-color: var(--color-info-soft);
297
- }
298
- .ghost.foreground {
299
- color: var(--color-foreground);
300
- }
301
- .ghost.foreground:not(:disabled):hover {
302
- background-color: color-mix(in srgb, var(--color-foreground-soft) 50%, transparent);
303
- }
304
- .ghost.foreground:not(:disabled):active {
305
- background-color: var(--color-foreground-soft);
306
- }
307
- .ghost.background {
308
- color: var(--color-background);
309
- }
310
- .ghost.background:not(:disabled):hover {
311
- background-color: color-mix(in srgb, var(--color-background-soft) 50%, transparent);
192
+
193
+ .ghost:not(:disabled):hover {
194
+ background-color: color-mix(
195
+ in srgb,
196
+ var(--internal-current-color) var(--internal-btn-ghost-hover-opacity),
197
+ var(--color-background)
198
+ );
312
199
  }
313
- .ghost.background:not(:disabled):active {
314
- background-color: var(--color-background-soft);
200
+
201
+ .ghost:not(:disabled):active {
202
+ background-color: color-mix(
203
+ in srgb,
204
+ var(--internal-current-color) var(--internal-btn-ghost-active-opacity),
205
+ var(--color-background)
206
+ );
315
207
  }
316
208
  </style>
@@ -37,7 +37,6 @@
37
37
  :global(:root),
38
38
  :global(:root[data-theme='light']) {
39
39
  color-scheme: light;
40
- --hover-mix: var(--color-foreground);
41
40
  --color-background: var(--color-light-background);
42
41
  --color-background-soft: var(--color-light-background-soft);
43
42
  --color-background-saturated: var(--color-light-background-saturated);
@@ -63,7 +62,6 @@
63
62
 
64
63
  :global(:root[data-theme='dark']) {
65
64
  color-scheme: dark;
66
- --hover-mix: var(--color-foreground);
67
65
  --color-background: var(--color-dark-background);
68
66
  --color-background-soft: var(--color-dark-background-soft);
69
67
  --color-background-saturated: var(--color-dark-background-saturated);
@@ -77,7 +75,6 @@
77
75
  @media (prefers-color-scheme: dark) {
78
76
  :global(:root:not([data-theme='light'])) {
79
77
  color-scheme: dark;
80
- --hover-mix: var(--color-foreground);
81
78
  --color-background: var(--color-dark-background);
82
79
  --color-background-soft: var(--color-dark-background-soft);
83
80
  --color-background-saturated: var(--color-dark-background-saturated);
@@ -53,15 +53,13 @@
53
53
  />`;
54
54
  </script>
55
55
 
56
- {#snippet colorCard(name: string, isSurface: boolean = false)}
56
+ {#snippet colorCard(name: string)}
57
57
  <div class="color-card">
58
58
  <div class="color-header">{name}</div>
59
59
  <div class="color-variants">
60
60
  {#each ['base', 'soft', 'saturated', 'contrast'] as variant}
61
61
  {@const cssVar = variant === 'base' ? `--color-${name}` : `--color-${name}-${variant}`}
62
- {@const contrastVar =
63
- variant === 'contrast' ? `--color-${name}` : `--color-${name}-contrast`}
64
- <div class="color-swatch" style="background: var({cssVar}); color: var({contrastVar})">
62
+ <div class="color-swatch" style:background={`var(${cssVar})`}>
65
63
  <span class="swatch-label">{variant}</span>
66
64
  </div>
67
65
  {/each}
@@ -70,90 +68,33 @@
70
68
  {/snippet}
71
69
 
72
70
  <DemoSection title="Theming" id="theming">
73
- <p class="intro">
74
- The theme system provides a flexible, token-based approach to styling with automatic light/dark
75
- mode support.
76
- </p>
77
-
78
- <!-- Theme Mode Toggle -->
79
-
80
71
  <h3>Theme Mode</h3>
81
- <p class="description">
72
+ <p>
82
73
  Toggle between light and dark modes. The system respects <code>prefers-color-scheme</code> by default
83
74
  and persists your choice in localStorage.
84
75
  </p>
85
76
  <Button
86
77
  icon={{ name: themeMode === 'dark' ? 'light_mode' : 'dark_mode' }}
87
- label="Toggle to {themeMode === 'dark' ? 'light' : 'dark'}"
78
+ label="Toggle {themeMode === 'dark' ? 'light' : 'dark'}"
88
79
  onClick={onThemeToggle}
89
80
  />
90
81
 
91
- <!-- Palette Colors -->
92
-
93
- <h3>Palette Colors</h3>
94
- <p class="description">
95
- Semantic colors that remain consistent across light and dark modes. Each color generates three
96
- variants: <strong>soft</strong>, <strong>saturated</strong>, and
97
- <strong>contrast</strong>.
82
+ <h3>Colors</h3>
83
+ <p>
84
+ Semantic palette colors and surface colors. Each generates <strong>soft</strong>,
85
+ <strong>saturated</strong>, and <strong>contrast</strong> variants.
98
86
  </p>
99
87
  <div class="color-grid">
100
88
  {#each paletteColors as [name]}
101
89
  {@render colorCard(name)}
102
90
  {/each}
103
- </div>
104
-
105
- <!-- Surface Colors -->
106
-
107
- <h3>Surface Colors</h3>
108
- <p class="description">
109
- Background and foreground colors that automatically swap between light and dark modes. These
110
- define the base canvas and text colors.
111
- </p>
112
- <div class="color-grid surface-grid">
113
91
  {#each surfaceColors as name}
114
- {@render colorCard(name, true)}
92
+ {@render colorCard(name)}
115
93
  {/each}
116
94
  </div>
117
95
 
118
- <!-- Token Generation Logic -->
119
-
120
- <h3>Token Generation Logic</h3>
121
- <ul class="bullet-list">
122
- <li>
123
- <strong>Soft:</strong> <code>lighten(25%) + desaturate(10%)</code> — A lighter, muted variant ideal
124
- for backgrounds when using the base as foreground.
125
- </li>
126
- <li>
127
- <strong>Saturated:</strong> <code>darken(15%) + saturate(10%)</code> — A deeper, more intense shade
128
- for emphasis or active states.
129
- </li>
130
- <li>
131
- <strong>Contrast:</strong> <code>isDark() ? white : black</code> — Automatically picks black or
132
- white for text/icons ensuring WCAG compliance.
133
- </li>
134
- </ul>
135
-
136
- <!-- Architecture Overview -->
137
-
138
- <h3>Architecture</h3>
139
- <ul class="bullet-list">
140
- <li>
141
- All tokens are exposed as <code>--color-*</code> custom properties on <code>:root</code>.
142
- </li>
143
- <li>
144
- Surface colors use <code>data-theme</code> attribute with automatic fallback to
145
- <code>prefers-color-scheme</code>.
146
- </li>
147
- <li>User preference is persisted in <code>localStorage</code>.</li>
148
- <li>
149
- Hover states are delegated to components using <code>color-mix()</code> for context-aware derivation.
150
- </li>
151
- </ul>
152
-
153
- <!-- Usage -->
154
-
155
96
  <h3>Usage</h3>
156
- <p class="description">
97
+ <p>
157
98
  Add the Theme component at the root of your app. It generates CSS custom properties and handles
158
99
  light/dark mode switching.
159
100
  </p>
@@ -161,13 +102,6 @@
161
102
  </DemoSection>
162
103
 
163
104
  <style>
164
- .intro {
165
- text-align: center;
166
- font-size: 1.1rem;
167
- max-width: 40rem;
168
- opacity: 0.8;
169
- }
170
-
171
105
  h3 {
172
106
  font-size: 1.4rem;
173
107
  margin-top: 1.5rem;
@@ -176,7 +110,7 @@
176
110
  text-align: center;
177
111
  }
178
112
 
179
- .description {
113
+ p {
180
114
  text-align: center;
181
115
  max-width: 36rem;
182
116
  opacity: 0.7;
@@ -191,7 +125,6 @@
191
125
  font-size: 0.85em;
192
126
  }
193
127
 
194
- /* Color Grid */
195
128
  .color-grid {
196
129
  display: grid;
197
130
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
@@ -199,10 +132,6 @@
199
132
  width: 100%;
200
133
  }
201
134
 
202
- .surface-grid {
203
- max-width: 320px;
204
- }
205
-
206
135
  .color-card {
207
136
  display: flex;
208
137
  flex-direction: column;
@@ -232,26 +161,13 @@
232
161
  padding: 0.6rem 0.75rem;
233
162
  font-size: 0.75rem;
234
163
  }
235
-
164
+
236
165
  .swatch-label {
166
+ color: var(--color-foreground);
167
+ padding: 0.15rem 0.4rem;
168
+ text-transform: capitalize ;
169
+ background: color-mix(in srgb, var(--color-background) 50%, transparent);
170
+ border-radius: 0.25rem;
237
171
  font-weight: 500;
238
172
  }
239
-
240
- /* Bullet Lists */
241
- .bullet-list {
242
- list-style: disc;
243
- padding-left: 1.5rem;
244
- max-width: 40rem;
245
- text-align: left;
246
- }
247
-
248
- .bullet-list li {
249
- margin-bottom: 0.5rem;
250
- font-size: 0.9rem;
251
- line-height: 1.5;
252
- }
253
-
254
- .bullet-list li:last-child {
255
- margin-bottom: 0;
256
- }
257
173
  </style>
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "bref-ui",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "A truly Svelte-esque UI component library - minimal, flexible, pure CSS, no Tailwind",
5
5
  "license": "MIT",
6
6
  "author": "feuerstein",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/f-euer/bref.git"
9
+ "url": "git+https://github.com/feuersteiner/bref.git"
10
10
  },
11
- "homepage": "https://github.com/f-euer/bref#readme",
11
+ "homepage": "https://github.com/feuersteiner/bref#readme",
12
12
  "bugs": {
13
- "url": "https://github.com/f-euer/bref/issues"
13
+ "url": "https://github.com/feuersteiner/bref/issues"
14
14
  },
15
15
  "scripts": {
16
16
  "dev": "vite dev",