@cwcss/crosswind 0.1.4

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 (64) hide show
  1. package/PLUGIN.md +235 -0
  2. package/benchmark/framework-comparison.bench.ts +850 -0
  3. package/bin/cli.ts +365 -0
  4. package/bin/crosswind +0 -0
  5. package/bin/headwind +0 -0
  6. package/build.ts +8 -0
  7. package/crosswind.config.ts +9 -0
  8. package/example/comprehensive.html +70 -0
  9. package/example/index.html +21 -0
  10. package/example/output.css +236 -0
  11. package/examples/plugin/README.md +112 -0
  12. package/examples/plugin/build.ts +32 -0
  13. package/examples/plugin/src/index.html +34 -0
  14. package/examples/plugin/src/index.ts +7 -0
  15. package/headwind +2 -0
  16. package/package.json +92 -0
  17. package/src/build.ts +101 -0
  18. package/src/config.ts +529 -0
  19. package/src/generator.ts +2173 -0
  20. package/src/index.ts +10 -0
  21. package/src/parser.ts +1471 -0
  22. package/src/plugin.ts +118 -0
  23. package/src/preflight-forms.ts +229 -0
  24. package/src/preflight.ts +388 -0
  25. package/src/rules-advanced.ts +477 -0
  26. package/src/rules-effects.ts +457 -0
  27. package/src/rules-forms.ts +103 -0
  28. package/src/rules-grid.ts +241 -0
  29. package/src/rules-interactivity.ts +525 -0
  30. package/src/rules-layout.ts +385 -0
  31. package/src/rules-transforms.ts +412 -0
  32. package/src/rules-typography.ts +486 -0
  33. package/src/rules.ts +805 -0
  34. package/src/scanner.ts +84 -0
  35. package/src/transformer-compile-class.ts +275 -0
  36. package/src/types.ts +197 -0
  37. package/test/advanced-features.test.ts +911 -0
  38. package/test/arbitrary.test.ts +396 -0
  39. package/test/attributify.test.ts +592 -0
  40. package/test/bracket-syntax.test.ts +1133 -0
  41. package/test/build.test.ts +99 -0
  42. package/test/colors.test.ts +934 -0
  43. package/test/flexbox.test.ts +669 -0
  44. package/test/generator.test.ts +597 -0
  45. package/test/grid.test.ts +584 -0
  46. package/test/layout.test.ts +404 -0
  47. package/test/modifiers.test.ts +417 -0
  48. package/test/parser.test.ts +564 -0
  49. package/test/performance-regression.test.ts +376 -0
  50. package/test/performance.test.ts +568 -0
  51. package/test/plugin.test.ts +160 -0
  52. package/test/scanner.test.ts +94 -0
  53. package/test/sizing.test.ts +481 -0
  54. package/test/spacing.test.ts +394 -0
  55. package/test/transformer-compile-class.test.ts +287 -0
  56. package/test/transforms.test.ts +448 -0
  57. package/test/typography.test.ts +632 -0
  58. package/test/variants-form-states.test.ts +225 -0
  59. package/test/variants-group-peer.test.ts +66 -0
  60. package/test/variants-media.test.ts +213 -0
  61. package/test/variants-positional.test.ts +58 -0
  62. package/test/variants-pseudo-elements.test.ts +47 -0
  63. package/test/variants-state.test.ts +62 -0
  64. package/tsconfig.json +18 -0
package/src/plugin.ts ADDED
@@ -0,0 +1,118 @@
1
+ import type { BunPlugin } from 'bun'
2
+ import type { CrosswindConfig, CrosswindOptions } from './types'
3
+ import { loadConfig } from 'bunfig'
4
+ import { defaultConfig } from './config'
5
+ import { CSSGenerator } from './generator'
6
+ import { extractClasses } from './parser'
7
+
8
+ export interface CrosswindPluginOptions {
9
+ /**
10
+ * Custom config to override default config
11
+ */
12
+ config?: CrosswindOptions
13
+ /**
14
+ * Include preflight CSS
15
+ * @default true
16
+ */
17
+ includePreflight?: boolean
18
+ }
19
+
20
+ /**
21
+ * Crosswind Bun plugin for processing HTML files
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { plugin } from '@cwcss/crosswind'
26
+ *
27
+ * await Bun.build({
28
+ * entrypoints: ['./src/index.ts'],
29
+ * outdir: './dist',
30
+ * plugins: [plugin()],
31
+ * })
32
+ * ```
33
+ */
34
+ export function plugin(options: CrosswindPluginOptions = {}): BunPlugin {
35
+ return {
36
+ name: 'bun-plugin-crosswind',
37
+ async setup(build) {
38
+ // Load configuration from crosswind.config.ts or use defaults
39
+ const loadedConfig = await loadConfig<CrosswindConfig>({
40
+ name: 'crosswind',
41
+ defaultConfig,
42
+ })
43
+
44
+ // Merge with provided options
45
+ const config = {
46
+ ...loadedConfig,
47
+ ...options.config,
48
+ theme: {
49
+ ...loadedConfig.theme,
50
+ ...options.config?.theme,
51
+ },
52
+ shortcuts: {
53
+ ...loadedConfig.shortcuts,
54
+ ...options.config?.shortcuts,
55
+ },
56
+ rules: [
57
+ ...(loadedConfig.rules || []),
58
+ ...(options.config?.rules || []),
59
+ ],
60
+ variants: {
61
+ ...loadedConfig.variants,
62
+ ...options.config?.variants,
63
+ },
64
+ safelist: [
65
+ ...(loadedConfig.safelist || []),
66
+ ...(options.config?.safelist || []),
67
+ ],
68
+ blocklist: [
69
+ ...(loadedConfig.blocklist || []),
70
+ ...(options.config?.blocklist || []),
71
+ ],
72
+ preflights: [
73
+ ...(loadedConfig.preflights || []),
74
+ ...(options.config?.preflights || []),
75
+ ],
76
+ presets: [
77
+ ...(loadedConfig.presets || []),
78
+ ...(options.config?.presets || []),
79
+ ],
80
+ } as CrosswindConfig
81
+
82
+ const includePreflight = options.includePreflight ?? true
83
+
84
+ // Process HTML files
85
+ build.onLoad({ filter: /\.html?$/ }, async ({ path }) => {
86
+ const html = await Bun.file(path).text()
87
+
88
+ // Extract utility classes from HTML
89
+ const classes = extractClasses(html)
90
+
91
+ // Add safelist classes
92
+ for (const cls of config.safelist) {
93
+ classes.add(cls)
94
+ }
95
+
96
+ // Generate CSS
97
+ const generator = new CSSGenerator(config)
98
+
99
+ for (const className of classes) {
100
+ generator.generate(className)
101
+ }
102
+
103
+ // Generate CSS output
104
+ const css = generator.toCSS(includePreflight, config.minify)
105
+
106
+ // Inject CSS into HTML
107
+ const contents = html.replace('</head>', `<style>${css}</style>\n</head>`)
108
+
109
+ return {
110
+ contents,
111
+ loader: 'text',
112
+ }
113
+ })
114
+ },
115
+ }
116
+ }
117
+
118
+ export default plugin
@@ -0,0 +1,229 @@
1
+ import type { Preflight } from './types'
2
+
3
+ /**
4
+ * Tailwind Forms preflight styles
5
+ * Provides default styling for form elements to make them easy to customize with utilities
6
+ */
7
+ export const tailwindFormsPreflight: Preflight = {
8
+ getCSS: () => `
9
+ /* Tailwind Forms */
10
+
11
+ [type='text'],
12
+ [type='email'],
13
+ [type='url'],
14
+ [type='password'],
15
+ [type='number'],
16
+ [type='date'],
17
+ [type='datetime-local'],
18
+ [type='month'],
19
+ [type='search'],
20
+ [type='tel'],
21
+ [type='time'],
22
+ [type='week'],
23
+ textarea,
24
+ select {
25
+ appearance: none;
26
+ background-color: #fff;
27
+ border-color: #6b7280;
28
+ border-width: 1px;
29
+ border-radius: 0px;
30
+ padding-top: 0.5rem;
31
+ padding-right: 0.75rem;
32
+ padding-bottom: 0.5rem;
33
+ padding-left: 0.75rem;
34
+ font-size: 1rem;
35
+ line-height: 1.5rem;
36
+ --hw-shadow: 0 0 #0000;
37
+ }
38
+
39
+ [type='text']:focus,
40
+ [type='email']:focus,
41
+ [type='url']:focus,
42
+ [type='password']:focus,
43
+ [type='number']:focus,
44
+ [type='date']:focus,
45
+ [type='datetime-local']:focus,
46
+ [type='month']:focus,
47
+ [type='search']:focus,
48
+ [type='tel']:focus,
49
+ [type='time']:focus,
50
+ [type='week']:focus,
51
+ textarea:focus,
52
+ select:focus {
53
+ outline: 2px solid transparent;
54
+ outline-offset: 2px;
55
+ --hw-ring-inset: var(--hw-empty,/*!*/ /*!*/);
56
+ --hw-ring-offset-width: 0px;
57
+ --hw-ring-offset-color: #fff;
58
+ --hw-ring-color: #2563eb;
59
+ --hw-ring-offset-shadow: var(--hw-ring-inset) 0 0 0 var(--hw-ring-offset-width) var(--hw-ring-offset-color);
60
+ --hw-ring-shadow: var(--hw-ring-inset) 0 0 0 calc(1px + var(--hw-ring-offset-width)) var(--hw-ring-color);
61
+ box-shadow: var(--hw-ring-offset-shadow), var(--hw-ring-shadow), var(--hw-shadow);
62
+ border-color: #2563eb;
63
+ }
64
+
65
+ input::placeholder,
66
+ textarea::placeholder {
67
+ color: #6b7280;
68
+ opacity: 1;
69
+ }
70
+
71
+ ::-webkit-datetime-edit-fields-wrapper {
72
+ padding: 0;
73
+ }
74
+
75
+ ::-webkit-date-and-time-value {
76
+ min-height: 1.5em;
77
+ text-align: inherit;
78
+ }
79
+
80
+ ::-webkit-datetime-edit {
81
+ display: inline-flex;
82
+ }
83
+
84
+ ::-webkit-datetime-edit,
85
+ ::-webkit-datetime-edit-year-field,
86
+ ::-webkit-datetime-edit-month-field,
87
+ ::-webkit-datetime-edit-day-field,
88
+ ::-webkit-datetime-edit-hour-field,
89
+ ::-webkit-datetime-edit-minute-field,
90
+ ::-webkit-datetime-edit-second-field,
91
+ ::-webkit-datetime-edit-millisecond-field,
92
+ ::-webkit-datetime-edit-meridiem-field {
93
+ padding-top: 0;
94
+ padding-bottom: 0;
95
+ }
96
+
97
+ select {
98
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
99
+ background-position: right 0.5rem center;
100
+ background-repeat: no-repeat;
101
+ background-size: 1.5em 1.5em;
102
+ padding-right: 2.5rem;
103
+ print-color-adjust: exact;
104
+ }
105
+
106
+ select[multiple],
107
+ select[size]:where([size]:not([size="1"])) {
108
+ background-image: initial;
109
+ background-position: initial;
110
+ background-repeat: unset;
111
+ background-size: initial;
112
+ padding-right: 0.75rem;
113
+ print-color-adjust: unset;
114
+ }
115
+
116
+ [type='checkbox'],
117
+ [type='radio'] {
118
+ appearance: none;
119
+ padding: 0;
120
+ print-color-adjust: exact;
121
+ display: inline-block;
122
+ vertical-align: middle;
123
+ background-origin: border-box;
124
+ user-select: none;
125
+ flex-shrink: 0;
126
+ height: 1rem;
127
+ width: 1rem;
128
+ color: #2563eb;
129
+ background-color: #fff;
130
+ border-color: #6b7280;
131
+ border-width: 1px;
132
+ --hw-shadow: 0 0 #0000;
133
+ }
134
+
135
+ [type='checkbox'] {
136
+ border-radius: 0px;
137
+ }
138
+
139
+ [type='radio'] {
140
+ border-radius: 100%;
141
+ }
142
+
143
+ [type='checkbox']:focus,
144
+ [type='radio']:focus {
145
+ outline: 2px solid transparent;
146
+ outline-offset: 2px;
147
+ --hw-ring-inset: var(--hw-empty,/*!*/ /*!*/);
148
+ --hw-ring-offset-width: 2px;
149
+ --hw-ring-offset-color: #fff;
150
+ --hw-ring-color: #2563eb;
151
+ --hw-ring-offset-shadow: var(--hw-ring-inset) 0 0 0 var(--hw-ring-offset-width) var(--hw-ring-offset-color);
152
+ --hw-ring-shadow: var(--hw-ring-inset) 0 0 0 calc(2px + var(--hw-ring-offset-width)) var(--hw-ring-color);
153
+ box-shadow: var(--hw-ring-offset-shadow), var(--hw-ring-shadow), var(--hw-shadow);
154
+ }
155
+
156
+ [type='checkbox']:checked,
157
+ [type='radio']:checked {
158
+ border-color: transparent;
159
+ background-color: currentColor;
160
+ background-size: 100% 100%;
161
+ background-position: center;
162
+ background-repeat: no-repeat;
163
+ }
164
+
165
+ [type='checkbox']:checked {
166
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
167
+ }
168
+
169
+ @media (forced-colors: active) {
170
+ [type='checkbox']:checked {
171
+ appearance: auto;
172
+ }
173
+ }
174
+
175
+ [type='radio']:checked {
176
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
177
+ }
178
+
179
+ @media (forced-colors: active) {
180
+ [type='radio']:checked {
181
+ appearance: auto;
182
+ }
183
+ }
184
+
185
+ [type='checkbox']:checked:hover,
186
+ [type='checkbox']:checked:focus,
187
+ [type='radio']:checked:hover,
188
+ [type='radio']:checked:focus {
189
+ border-color: transparent;
190
+ background-color: currentColor;
191
+ }
192
+
193
+ [type='checkbox']:indeterminate {
194
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
195
+ border-color: transparent;
196
+ background-color: currentColor;
197
+ background-size: 100% 100%;
198
+ background-position: center;
199
+ background-repeat: no-repeat;
200
+ }
201
+
202
+ @media (forced-colors: active) {
203
+ [type='checkbox']:indeterminate {
204
+ appearance: auto;
205
+ }
206
+ }
207
+
208
+ [type='checkbox']:indeterminate:hover,
209
+ [type='checkbox']:indeterminate:focus {
210
+ border-color: transparent;
211
+ background-color: currentColor;
212
+ }
213
+
214
+ [type='file'] {
215
+ background: unset;
216
+ border-color: inherit;
217
+ border-width: 0;
218
+ border-radius: 0;
219
+ padding: 0;
220
+ font-size: unset;
221
+ line-height: inherit;
222
+ }
223
+
224
+ [type='file']:focus {
225
+ outline: 1px solid ButtonText;
226
+ outline: 1px auto -webkit-focus-ring-color;
227
+ }
228
+ `,
229
+ }
@@ -0,0 +1,388 @@
1
+ import type { Preflight } from './types'
2
+
3
+ export const modernNormalize: Preflight = {
4
+ getCSS: () => `
5
+ /*
6
+ ! Modern Normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize
7
+ */
8
+
9
+ *,
10
+ ::before,
11
+ ::after {
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ html {
16
+ -webkit-text-size-adjust: 100%;
17
+ tab-size: 4;
18
+ }
19
+
20
+ body {
21
+ margin: 0;
22
+ font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
23
+ }
24
+
25
+ hr {
26
+ height: 0;
27
+ color: inherit;
28
+ }
29
+
30
+ abbr[title] {
31
+ text-decoration: underline dotted;
32
+ }
33
+
34
+ b,
35
+ strong {
36
+ font-weight: bolder;
37
+ }
38
+
39
+ code,
40
+ kbd,
41
+ samp,
42
+ pre {
43
+ font-family: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
44
+ font-size: 1em;
45
+ }
46
+
47
+ small {
48
+ font-size: 80%;
49
+ }
50
+
51
+ sub,
52
+ sup {
53
+ font-size: 75%;
54
+ line-height: 0;
55
+ position: relative;
56
+ vertical-align: baseline;
57
+ }
58
+
59
+ sub {
60
+ bottom: -0.25em;
61
+ }
62
+
63
+ sup {
64
+ top: -0.5em;
65
+ }
66
+
67
+ table {
68
+ text-indent: 0;
69
+ border-color: inherit;
70
+ }
71
+
72
+ button,
73
+ input,
74
+ optgroup,
75
+ select,
76
+ textarea {
77
+ font-family: inherit;
78
+ font-size: 100%;
79
+ line-height: 1.15;
80
+ margin: 0;
81
+ }
82
+
83
+ button,
84
+ select {
85
+ text-transform: none;
86
+ }
87
+
88
+ button,
89
+ [type='button'],
90
+ [type='reset'],
91
+ [type='submit'] {
92
+ -webkit-appearance: button;
93
+ }
94
+
95
+ ::-moz-focus-inner {
96
+ border-style: none;
97
+ padding: 0;
98
+ }
99
+
100
+ :-moz-focusring {
101
+ outline: 1px dotted ButtonText;
102
+ }
103
+
104
+ :-moz-ui-invalid {
105
+ box-shadow: none;
106
+ }
107
+
108
+ legend {
109
+ padding: 0;
110
+ }
111
+
112
+ progress {
113
+ vertical-align: baseline;
114
+ }
115
+
116
+ ::-webkit-inner-spin-button,
117
+ ::-webkit-outer-spin-button {
118
+ height: auto;
119
+ }
120
+
121
+ [type='search'] {
122
+ -webkit-appearance: textfield;
123
+ outline-offset: -2px;
124
+ }
125
+
126
+ ::-webkit-search-decoration {
127
+ -webkit-appearance: none;
128
+ }
129
+
130
+ ::-webkit-file-upload-button {
131
+ -webkit-appearance: button;
132
+ font: inherit;
133
+ }
134
+
135
+ summary {
136
+ display: list-item;
137
+ }
138
+ `.trim(),
139
+ }
140
+
141
+ export const tailwindPreflight: Preflight = {
142
+ getCSS: () => `
143
+ /*
144
+ ! Tailwind CSS Preflight | MIT License | https://tailwindcss.com
145
+ */
146
+
147
+ *,
148
+ ::before,
149
+ ::after {
150
+ box-sizing: border-box;
151
+ border-width: 0;
152
+ border-style: solid;
153
+ border-color: var(--border-color, currentColor);
154
+ }
155
+
156
+ ::before,
157
+ ::after {
158
+ --hw-content: '';
159
+ }
160
+
161
+ html,
162
+ :host {
163
+ line-height: 1.5;
164
+ -webkit-text-size-adjust: 100%;
165
+ -moz-tab-size: 4;
166
+ tab-size: 4;
167
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
168
+ font-feature-settings: normal;
169
+ font-variation-settings: normal;
170
+ -webkit-tap-highlight-color: transparent;
171
+ }
172
+
173
+ body {
174
+ margin: 0;
175
+ line-height: inherit;
176
+ }
177
+
178
+ hr {
179
+ height: 0;
180
+ color: inherit;
181
+ border-top-width: 1px;
182
+ }
183
+
184
+ abbr:where([title]) {
185
+ text-decoration: underline dotted;
186
+ }
187
+
188
+ h1,
189
+ h2,
190
+ h3,
191
+ h4,
192
+ h5,
193
+ h6 {
194
+ font-size: inherit;
195
+ font-weight: inherit;
196
+ }
197
+
198
+ a {
199
+ color: inherit;
200
+ text-decoration: inherit;
201
+ }
202
+
203
+ b,
204
+ strong {
205
+ font-weight: bolder;
206
+ }
207
+
208
+ code,
209
+ kbd,
210
+ samp,
211
+ pre {
212
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
213
+ font-feature-settings: normal;
214
+ font-variation-settings: normal;
215
+ font-size: 1em;
216
+ }
217
+
218
+ small {
219
+ font-size: 80%;
220
+ }
221
+
222
+ sub,
223
+ sup {
224
+ font-size: 75%;
225
+ line-height: 0;
226
+ position: relative;
227
+ vertical-align: baseline;
228
+ }
229
+
230
+ sub {
231
+ bottom: -0.25em;
232
+ }
233
+
234
+ sup {
235
+ top: -0.5em;
236
+ }
237
+
238
+ table {
239
+ text-indent: 0;
240
+ border-color: var(--border-color, inherit);
241
+ border-collapse: collapse;
242
+ }
243
+
244
+ button,
245
+ input,
246
+ optgroup,
247
+ select,
248
+ textarea {
249
+ font-family: inherit;
250
+ font-feature-settings: inherit;
251
+ font-variation-settings: inherit;
252
+ font-size: 100%;
253
+ font-weight: inherit;
254
+ line-height: inherit;
255
+ letter-spacing: inherit;
256
+ color: inherit;
257
+ margin: 0;
258
+ padding: 0;
259
+ }
260
+
261
+ button,
262
+ select {
263
+ text-transform: none;
264
+ }
265
+
266
+ button,
267
+ input:where([type='button']),
268
+ input:where([type='reset']),
269
+ input:where([type='submit']) {
270
+ -webkit-appearance: button;
271
+ background-color: transparent;
272
+ background-image: none;
273
+ }
274
+
275
+ :-moz-focusring {
276
+ outline: auto;
277
+ }
278
+
279
+ :-moz-ui-invalid {
280
+ box-shadow: none;
281
+ }
282
+
283
+ progress {
284
+ vertical-align: baseline;
285
+ }
286
+
287
+ ::-webkit-inner-spin-button,
288
+ ::-webkit-outer-spin-button {
289
+ height: auto;
290
+ }
291
+
292
+ [type='search'] {
293
+ -webkit-appearance: textfield;
294
+ outline-offset: -2px;
295
+ }
296
+
297
+ ::-webkit-search-decoration {
298
+ -webkit-appearance: none;
299
+ }
300
+
301
+ ::-webkit-file-upload-button {
302
+ -webkit-appearance: button;
303
+ font: inherit;
304
+ }
305
+
306
+ summary {
307
+ display: list-item;
308
+ }
309
+
310
+ blockquote,
311
+ dl,
312
+ dd,
313
+ h1,
314
+ h2,
315
+ h3,
316
+ h4,
317
+ h5,
318
+ h6,
319
+ hr,
320
+ figure,
321
+ p,
322
+ pre {
323
+ margin: 0;
324
+ }
325
+
326
+ fieldset {
327
+ margin: 0;
328
+ padding: 0;
329
+ }
330
+
331
+ legend {
332
+ padding: 0;
333
+ }
334
+
335
+ ol,
336
+ ul,
337
+ menu {
338
+ list-style: none;
339
+ margin: 0;
340
+ padding: 0;
341
+ }
342
+
343
+ dialog {
344
+ padding: 0;
345
+ }
346
+
347
+ textarea {
348
+ resize: vertical;
349
+ }
350
+
351
+ input::placeholder,
352
+ textarea::placeholder {
353
+ opacity: 1;
354
+ color: #9ca3af;
355
+ }
356
+
357
+ button,
358
+ [role="button"] {
359
+ cursor: pointer;
360
+ }
361
+
362
+ :disabled {
363
+ cursor: default;
364
+ }
365
+
366
+ img,
367
+ svg,
368
+ video,
369
+ canvas,
370
+ audio,
371
+ iframe,
372
+ embed,
373
+ object {
374
+ display: block;
375
+ vertical-align: middle;
376
+ }
377
+
378
+ img,
379
+ video {
380
+ max-width: 100%;
381
+ height: auto;
382
+ }
383
+
384
+ [hidden] {
385
+ display: none;
386
+ }
387
+ `.trim(),
388
+ }