@zapatran/paper-ember-theme 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.
package/src/forms.css ADDED
@@ -0,0 +1,333 @@
1
+ /* =====================================================================
2
+ FORMS
3
+ ===================================================================== */
4
+
5
+ .field {
6
+ display: flex;
7
+ flex-direction: column;
8
+ }
9
+
10
+ .field__label {
11
+ color: var(--color-paper-800);
12
+ margin-bottom: 0.375rem;
13
+ display: block;
14
+ font-size: 13px;
15
+ font-weight: 600;
16
+
17
+ &:where(.dark, .dark *) {
18
+ color: var(--color-paper-200);
19
+ }
20
+ }
21
+
22
+ .field__helper {
23
+ color: var(--color-paper-600);
24
+ margin-top: 0.375rem;
25
+ font-size: 12px;
26
+
27
+ &:where(.dark, .dark *) {
28
+ color: var(--color-paper-400);
29
+ }
30
+ }
31
+
32
+ .field__error {
33
+ margin-top: 0.375rem;
34
+ font-size: 12px;
35
+ font-weight: 600;
36
+ color: var(--color-rose-700);
37
+
38
+ &:where(.dark, .dark *) {
39
+ color: var(--color-rose-300);
40
+ }
41
+ }
42
+
43
+ .field__input-wrap {
44
+ position: relative;
45
+ }
46
+
47
+ .field__input-icon {
48
+ pointer-events: none;
49
+ position: absolute;
50
+ top: 50%;
51
+ right: 0.75rem;
52
+ transform: translateY(-50%);
53
+ }
54
+
55
+ .input {
56
+ background-color: var(--color-paper-50);
57
+ border: 1px solid var(--color-paper-300);
58
+ color: var(--color-paper-900);
59
+ height: 2.75rem;
60
+ width: 100%;
61
+ border-radius: var(--radius-md);
62
+ padding-left: 0.875rem;
63
+ padding-right: 0.875rem;
64
+ font-family: var(--font-family-sans);
65
+ font-size: 14px;
66
+ transition:
67
+ color 150ms ease-in-out,
68
+ background-color 150ms ease-in-out,
69
+ border-color 150ms ease-in-out;
70
+ outline: none;
71
+
72
+ &:focus {
73
+ border-color: var(--color-ember-400);
74
+ box-shadow: 0 0 0 2px var(--color-ember-200);
75
+ }
76
+
77
+ &:where(.dark, .dark *) {
78
+ background-color: var(--color-paper-900);
79
+ border-color: var(--color-paper-700);
80
+ color: var(--color-paper-50);
81
+ &:focus {
82
+ box-shadow: 0 0 0 2px var(--color-ember-800);
83
+ }
84
+ }
85
+ }
86
+
87
+ .input--error {
88
+ border-color: var(--color-rose-400);
89
+ background-color: var(--color-rose-50);
90
+
91
+ &:where(.dark, .dark *) {
92
+ background-color: var(--color-paper-900);
93
+ border-color: var(--color-rose-500);
94
+ }
95
+ }
96
+
97
+ .select-wrap {
98
+ position: relative;
99
+ }
100
+
101
+ .select-wrap__arrow {
102
+ color: var(--color-paper-600);
103
+ pointer-events: none;
104
+ position: absolute;
105
+ top: 50%;
106
+ right: 0.75rem;
107
+ height: 1rem;
108
+ width: 1rem;
109
+ transform: translateY(-50%);
110
+
111
+ &:where(.dark, .dark *) {
112
+ color: var(--color-paper-400);
113
+ }
114
+ }
115
+
116
+ .select {
117
+ background-color: var(--color-paper-50);
118
+ border: 1px solid var(--color-paper-300);
119
+ color: var(--color-paper-900);
120
+ height: 2.75rem;
121
+ width: 100%;
122
+ appearance: none;
123
+ border-radius: var(--radius-md);
124
+ padding-right: 2.5rem;
125
+ padding-left: 0.875rem;
126
+ font-family: var(--font-family-sans);
127
+ font-size: 14px;
128
+ transition:
129
+ color 150ms ease-in-out,
130
+ background-color 150ms ease-in-out,
131
+ border-color 150ms ease-in-out;
132
+ outline: none;
133
+
134
+ &:focus {
135
+ border-color: var(--color-ember-400);
136
+ box-shadow: 0 0 0 2px var(--color-ember-200);
137
+ }
138
+
139
+ &:where(.dark, .dark *) {
140
+ background-color: var(--color-paper-900);
141
+ border-color: var(--color-paper-700);
142
+ color: var(--color-paper-50);
143
+ &:focus {
144
+ box-shadow: 0 0 0 2px var(--color-ember-800);
145
+ }
146
+ }
147
+ }
148
+
149
+ .textarea {
150
+ background-color: var(--color-paper-50);
151
+ border: 1px solid var(--color-paper-300);
152
+ color: var(--color-paper-900);
153
+ width: 100%;
154
+ resize: vertical;
155
+ border-radius: var(--radius-md);
156
+ padding-left: 0.875rem;
157
+ padding-right: 0.875rem;
158
+ padding-top: 0.625rem;
159
+ padding-bottom: 0.625rem;
160
+ font-family: var(--font-family-sans);
161
+ font-size: 14px;
162
+ transition:
163
+ color 150ms ease-in-out,
164
+ background-color 150ms ease-in-out,
165
+ border-color 150ms ease-in-out;
166
+ outline: none;
167
+
168
+ &:focus {
169
+ border-color: var(--color-ember-400);
170
+ box-shadow: 0 0 0 2px var(--color-ember-200);
171
+ }
172
+
173
+ &:where(.dark, .dark *) {
174
+ background-color: var(--color-paper-900);
175
+ border-color: var(--color-paper-700);
176
+ color: var(--color-paper-50);
177
+ &:focus {
178
+ box-shadow: 0 0 0 2px var(--color-ember-800);
179
+ }
180
+ }
181
+ }
182
+
183
+ .checkbox {
184
+ display: flex;
185
+ cursor: pointer;
186
+ align-items: flex-start;
187
+ gap: 0.75rem;
188
+ user-select: none;
189
+ }
190
+
191
+ .checkbox__box {
192
+ border: 1px solid var(--color-paper-400);
193
+ background-color: var(--color-paper-50);
194
+ margin-top: 0.125rem;
195
+ display: inline-flex;
196
+ height: 1.25rem;
197
+ width: 1.25rem;
198
+ flex-shrink: 0;
199
+ align-items: center;
200
+ justify-content: center;
201
+ border-radius: var(--radius-sm);
202
+ transition:
203
+ color 150ms ease-in-out,
204
+ background-color 150ms ease-in-out,
205
+ border-color 150ms ease-in-out;
206
+
207
+ &:where(.dark, .dark *) {
208
+ border-color: var(--color-paper-600);
209
+ background-color: var(--color-paper-900);
210
+ }
211
+ }
212
+
213
+ .checkbox__box--checked {
214
+ background-color: var(--color-ember-500);
215
+ border-color: var(--color-ember-600);
216
+
217
+ &:where(.dark, .dark *) {
218
+ background-color: var(--color-ember-500);
219
+ border-color: var(--color-ember-400);
220
+ }
221
+ }
222
+
223
+ .checkbox__check {
224
+ height: 0.75rem;
225
+ width: 0.75rem;
226
+ fill: none;
227
+ stroke: currentColor;
228
+ color: white;
229
+
230
+ &:where(.dark, .dark *) {
231
+ color: var(--color-paper-950);
232
+ }
233
+ }
234
+
235
+ .checkbox__label {
236
+ color: var(--color-paper-900);
237
+ font-size: 14px;
238
+
239
+ &:where(.dark, .dark *) {
240
+ color: var(--color-paper-100);
241
+ }
242
+ }
243
+
244
+ .radio {
245
+ display: flex;
246
+ cursor: pointer;
247
+ align-items: center;
248
+ gap: 0.5rem;
249
+ user-select: none;
250
+ }
251
+
252
+ .radio__circle {
253
+ border: 1px solid var(--color-paper-400);
254
+ background-color: var(--color-paper-50);
255
+ height: 1rem;
256
+ width: 1rem;
257
+ flex-shrink: 0;
258
+ border-radius: 9999px;
259
+ transition:
260
+ color 150ms ease-in-out,
261
+ background-color 150ms ease-in-out,
262
+ border-color 150ms ease-in-out;
263
+
264
+ &:where(.dark, .dark *) {
265
+ border-color: var(--color-paper-600);
266
+ background-color: var(--color-paper-900);
267
+ }
268
+ }
269
+
270
+ .radio__circle--selected {
271
+ border-color: var(--color-ember-500);
272
+ background-color: var(--color-paper-50);
273
+ border-width: 5px;
274
+
275
+ &:where(.dark, .dark *) {
276
+ background-color: var(--color-paper-900);
277
+ }
278
+ }
279
+
280
+ .radio__label {
281
+ color: var(--color-paper-900);
282
+ font-size: 14px;
283
+
284
+ &:where(.dark, .dark *) {
285
+ color: var(--color-paper-100);
286
+ }
287
+ }
288
+
289
+ .switch {
290
+ background-color: var(--color-paper-300);
291
+ position: relative;
292
+ height: 1.5rem;
293
+ width: 2.5rem;
294
+ flex-shrink: 0;
295
+ cursor: pointer;
296
+ border-radius: 9999px;
297
+ border: 0;
298
+ transition: background-color 150ms ease-in-out;
299
+
300
+ &:where(.dark, .dark *) {
301
+ background-color: var(--color-paper-700);
302
+ }
303
+ }
304
+
305
+ .switch--on {
306
+ background-color: var(--color-ember-500);
307
+
308
+ & .switch__thumb {
309
+ left: 18px;
310
+ }
311
+
312
+ &:where(.dark, .dark *) {
313
+ & .switch__thumb {
314
+ background-color: var(--color-paper-950);
315
+ }
316
+ }
317
+ }
318
+
319
+ .switch__thumb {
320
+ box-shadow: var(--shadow-paper-1);
321
+ position: absolute;
322
+ top: 0.125rem;
323
+ left: 0.125rem;
324
+ height: 1.25rem;
325
+ width: 1.25rem;
326
+ border-radius: 9999px;
327
+ background-color: white;
328
+ transition: left 0.15s ease;
329
+
330
+ &:where(.dark, .dark *) {
331
+ background-color: var(--color-paper-300);
332
+ }
333
+ }
package/src/index.css ADDED
@@ -0,0 +1,9 @@
1
+ @import './vars.css';
2
+ @import './tokens.css';
3
+ @import './components.css';
4
+ @import './buttons.css';
5
+ @import './badges.css';
6
+ @import './forms.css';
7
+ @import './cards.css';
8
+ @import './alerts.css';
9
+ @import './tables.css';
package/src/index.ts ADDED
@@ -0,0 +1,140 @@
1
+ export type BtnVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'info'
2
+ export type BtnSize = 'sm' | 'md' | 'lg' | 'xl'
3
+ export type BtnModifier = 'icon' | 'block' | 'loading'
4
+
5
+ export type BadgeVariant = 'neutral' | 'ember' | 'success' | 'warning' | 'danger' | 'info'
6
+ export type BadgeStyle = 'soft' | 'solid' | 'outline'
7
+ export type BadgeSize = 'xs' | 'sm' | 'md'
8
+ export type BadgeShape = 'pill' | 'square'
9
+ export type BadgeModifier = 'pill' | 'square' | 'removable' | 'count'
10
+
11
+ export type AlertVariant = 'info' | 'success' | 'warning' | 'danger' | 'banner'
12
+
13
+ export type CardTrendDirection = 'up' | 'down'
14
+
15
+ export type ThAlign = 'left' | 'right'
16
+
17
+ export const classes = {
18
+ btn: {
19
+ root: (variant: BtnVariant, size: BtnSize, modifiers: BtnModifier[] = []) => {
20
+ const base = `btn btn--${variant} btn--${size}`
21
+ const mods = modifiers.map((m) => `btn--${m}`).join(' ')
22
+ return mods ? `${base} ${mods}` : base
23
+ },
24
+ elements: {
25
+ label: 'btn__label',
26
+ spinner: 'btn__spinner',
27
+ icon: 'btn__icon',
28
+ kbd: 'btn__kbd',
29
+ },
30
+ },
31
+
32
+ badge: {
33
+ root: (
34
+ variant: BadgeVariant,
35
+ appearance: BadgeStyle = 'soft',
36
+ size: BadgeSize = 'sm',
37
+ modifiers: BadgeModifier[] = [],
38
+ ) => {
39
+ const base = `badge badge--${appearance} badge--${variant} badge--${size}`
40
+ const mods = modifiers.map((m) => `badge--${m}`).join(' ')
41
+ return mods ? `${base} ${mods}` : base
42
+ },
43
+ elements: {
44
+ dot: 'badge__dot',
45
+ icon: 'badge__icon',
46
+ label: 'badge__label',
47
+ count: 'badge__count',
48
+ close: 'badge__close',
49
+ },
50
+ },
51
+
52
+ alert: {
53
+ root: (variant: AlertVariant) => `alert alert--${variant}`,
54
+ elements: {
55
+ icon: 'alert__icon',
56
+ body: 'alert__body',
57
+ title: 'alert__title',
58
+ text: 'alert__text',
59
+ close: 'alert__close',
60
+ action: 'alert__action',
61
+ },
62
+ },
63
+
64
+ card: {
65
+ root: 'card',
66
+ elements: {
67
+ header: 'card__header',
68
+ title: 'card__title',
69
+ meta: 'card__meta',
70
+ kpi: 'card__kpi',
71
+ trend: (direction: CardTrendDirection) => `card__trend card__trend--${direction}`,
72
+ chart: 'card__chart',
73
+ avatar: 'card__avatar',
74
+ },
75
+ },
76
+
77
+ table: {
78
+ wrap: 'table-wrap',
79
+ root: (stripe?: boolean) => (stripe ? 'table table--stripe' : 'table'),
80
+ elements: {
81
+ th: (align?: ThAlign) => (align === 'right' ? 'table__th table__th--right' : 'table__th'),
82
+ td: 'table__td',
83
+ tdFoot: 'table__td--foot',
84
+ tdNum: 'table__td--num',
85
+ },
86
+ },
87
+
88
+ field: {
89
+ root: 'field',
90
+ elements: {
91
+ label: 'field__label',
92
+ helper: 'field__helper',
93
+ error: 'field__error',
94
+ inputWrap: 'field__input-wrap',
95
+ inputIcon: 'field__input-icon',
96
+ },
97
+ },
98
+
99
+ input: {
100
+ root: (error?: boolean) => (error ? 'input input--error' : 'input'),
101
+ },
102
+
103
+ textarea: {
104
+ root: 'textarea',
105
+ },
106
+
107
+ select: {
108
+ wrap: 'select-wrap',
109
+ root: 'select',
110
+ elements: {
111
+ arrow: 'select-wrap__arrow',
112
+ },
113
+ },
114
+
115
+ checkbox: {
116
+ root: 'checkbox',
117
+ elements: {
118
+ box: (checked?: boolean) =>
119
+ checked ? 'checkbox__box checkbox__box--checked' : 'checkbox__box',
120
+ check: 'checkbox__check',
121
+ label: 'checkbox__label',
122
+ },
123
+ },
124
+
125
+ radio: {
126
+ root: 'radio',
127
+ elements: {
128
+ circle: (selected?: boolean) =>
129
+ selected ? 'radio__circle radio__circle--selected' : 'radio__circle',
130
+ label: 'radio__label',
131
+ },
132
+ },
133
+
134
+ switch: {
135
+ root: (on?: boolean) => (on ? 'switch switch--on' : 'switch'),
136
+ elements: {
137
+ thumb: 'switch__thumb',
138
+ },
139
+ },
140
+ }
package/src/tables.css ADDED
@@ -0,0 +1,96 @@
1
+ /* =====================================================================
2
+ TABLES
3
+ ===================================================================== */
4
+
5
+ .table-wrap {
6
+ width: 100%;
7
+ overflow-x: auto;
8
+ }
9
+
10
+ .table {
11
+ width: 100%;
12
+ font-size: 13px;
13
+
14
+ & thead tr {
15
+ color: var(--color-paper-600);
16
+ font-family: var(--font-family-mono);
17
+ font-size: 10px;
18
+ letter-spacing: 0.1em;
19
+ text-transform: uppercase;
20
+ }
21
+
22
+ & tbody tr {
23
+ color: var(--color-paper-900);
24
+ }
25
+
26
+ & tfoot tr {
27
+ color: var(--color-paper-950);
28
+ border-color: var(--color-paper-300);
29
+ border-top-width: 2px;
30
+ font-weight: 600;
31
+ }
32
+
33
+ &:where(.dark, .dark *) {
34
+ & thead tr {
35
+ color: var(--color-paper-400);
36
+ }
37
+ & tbody tr {
38
+ color: var(--color-paper-100);
39
+ }
40
+ & tfoot tr {
41
+ color: var(--color-paper-50);
42
+ border-color: var(--color-paper-700);
43
+ }
44
+ }
45
+ }
46
+
47
+ .table__th {
48
+ border-bottom: 1px solid var(--color-paper-200);
49
+ padding-left: 0.75rem;
50
+ padding-right: 0.75rem;
51
+ padding-top: 0.5rem;
52
+ padding-bottom: 0.5rem;
53
+ text-align: left;
54
+ font-weight: 600;
55
+ white-space: nowrap;
56
+
57
+ &:where(.dark, .dark *) {
58
+ border-color: var(--color-paper-800);
59
+ }
60
+ }
61
+
62
+ .table__th--right {
63
+ text-align: right;
64
+ }
65
+
66
+ .table__td {
67
+ padding-left: 0.75rem;
68
+ padding-right: 0.75rem;
69
+ padding-top: 0.625rem;
70
+ padding-bottom: 0.625rem;
71
+ }
72
+
73
+ .table__td--num {
74
+ text-align: right;
75
+ font-family: var(--font-family-mono);
76
+ font-variant-numeric: tabular-nums;
77
+ }
78
+
79
+ .table__td--foot {
80
+ padding-left: 0.75rem;
81
+ padding-right: 0.75rem;
82
+ padding-top: 0.75rem;
83
+ padding-bottom: 0.75rem;
84
+ }
85
+
86
+ .table--stripe {
87
+ & tbody tr:nth-child(odd) td {
88
+ background-color: var(--color-paper-100);
89
+ }
90
+
91
+ &:where(.dark, .dark *) {
92
+ & tbody tr:nth-child(odd) td {
93
+ background-color: #2a2018;
94
+ }
95
+ }
96
+ }
package/src/tokens.css ADDED
@@ -0,0 +1,99 @@
1
+ @theme {
2
+ /* ── Paper ── */
3
+ --color-paper-50: #faf7f1;
4
+ --color-paper-100: #f4ede0;
5
+ --color-paper-200: #e9dcc2;
6
+ --color-paper-300: #dcc69d;
7
+ --color-paper-400: #c9aa78;
8
+ --color-paper-500: #b08e5b;
9
+ --color-paper-600: #92744a;
10
+ --color-paper-700: #735a3c;
11
+ --color-paper-800: #544231;
12
+ --color-paper-900: #382c22;
13
+ --color-paper-950: #1f1812;
14
+
15
+ /* ── Ember ── */
16
+ --color-ember-50: #fdf4ee;
17
+ --color-ember-100: #fae5d6;
18
+ --color-ember-200: #f4c9a7;
19
+ --color-ember-300: #eda472;
20
+ --color-ember-400: #e37f47;
21
+ --color-ember-500: #d5612f;
22
+ --color-ember-600: #bd4a23;
23
+ --color-ember-700: #9d3a20;
24
+ --color-ember-800: #7e2f1f;
25
+ --color-ember-900: #65271c;
26
+ --color-ember-950: #37120d;
27
+
28
+ /* ── Leaf ── */
29
+ --color-leaf-50: #f3f7ed;
30
+ --color-leaf-100: #e3eed5;
31
+ --color-leaf-200: #c8dcaf;
32
+ --color-leaf-300: #a4c382;
33
+ --color-leaf-400: #82a85e;
34
+ --color-leaf-500: #658c44;
35
+ --color-leaf-600: #4e6f33;
36
+ --color-leaf-700: #3e572b;
37
+ --color-leaf-800: #324624;
38
+ --color-leaf-900: #2a3b1f;
39
+
40
+ /* ── Honey ── */
41
+ --color-honey-50: #fdf8ec;
42
+ --color-honey-100: #fbedc7;
43
+ --color-honey-200: #f7d98c;
44
+ --color-honey-300: #f2c054;
45
+ --color-honey-400: #eda82b;
46
+ --color-honey-500: #d18a19;
47
+ --color-honey-600: #a86813;
48
+ --color-honey-700: #7e4d12;
49
+ --color-honey-800: #5c3a10;
50
+ --color-honey-900: #3f2a0d;
51
+
52
+ /* ── Rose ── */
53
+ --color-rose-50: #fdf2f0;
54
+ --color-rose-100: #fbdcd7;
55
+ --color-rose-200: #f6b6ad;
56
+ --color-rose-300: #ef8676;
57
+ --color-rose-400: #e25b46;
58
+ --color-rose-500: #c93f29;
59
+ --color-rose-600: #a82d1b;
60
+ --color-rose-700: #822417;
61
+ --color-rose-800: #5f1d14;
62
+ --color-rose-900: #3d1410;
63
+
64
+ /* ── Ink ── */
65
+ --color-ink-50: #eef3f8;
66
+ --color-ink-100: #d8e3ee;
67
+ --color-ink-200: #b1c5dc;
68
+ --color-ink-300: #83a4c6;
69
+ --color-ink-400: #5a85ad;
70
+ --color-ink-500: #3b6a92;
71
+ --color-ink-600: #2e5477;
72
+ --color-ink-700: #26425d;
73
+ --color-ink-800: #1f3447;
74
+ --color-ink-900: #172734;
75
+
76
+ /* ── Typography ── */
77
+ --font-family-sans: 'Figtree', ui-sans-serif, system-ui, sans-serif;
78
+ --font-family-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
79
+
80
+ /* ── Border Radius ── */
81
+ --radius-xs: 2px;
82
+ --radius-sm: 4px;
83
+ --radius-md: 8px;
84
+ --radius-lg: 12px;
85
+ --radius-xl: 16px;
86
+ --radius-2xl: 20px;
87
+ --radius-3xl: 28px;
88
+
89
+ /* ── Shadows ── */
90
+ --shadow-paper-1: 0 1px 2px rgba(56, 44, 34, 0.06), 0 1px 1px rgba(56, 44, 34, 0.04);
91
+ --shadow-paper-2: 0 2px 4px rgba(56, 44, 34, 0.06), 0 4px 8px rgba(56, 44, 34, 0.05);
92
+ --shadow-paper-3: 0 4px 8px rgba(56, 44, 34, 0.06), 0 12px 24px rgba(56, 44, 34, 0.07);
93
+ --shadow-paper-4: 0 8px 16px rgba(56, 44, 34, 0.08), 0 24px 48px rgba(56, 44, 34, 0.1);
94
+ --shadow-ember-glow: 0 6px 24px -8px rgba(213, 97, 47, 0.55);
95
+
96
+ /* ── Letter Spacing ── */
97
+ --tracking-tightish: -0.012em;
98
+ --tracking-tighter2: -0.022em;
99
+ }