tailwind-to-style 2.8.0 → 2.8.2

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/README.md CHANGED
@@ -488,16 +488,14 @@ This will automatically log warnings for operations taking longer than 5ms and p
488
488
 
489
489
  # Build-Time Plugins: Vite & Webpack
490
490
 
491
- ### Otomatisasi Generate CSS Modular
492
-
493
491
  ### Automated Modular CSS Generation
494
492
 
495
- 1. Save your modular styles in the `src/twsx/` folder as JSON files (e.g., `card.json`, `button.json`).
493
+ 1. Save your modular styles in the `src/twsx/` folder as JS files (e.g., `card.js`, `button.js`).
496
494
  2. Use the Vite/Webpack plugin from the `plugins/` folder to automatically generate CSS on every build/rebuild.
497
495
  3. All generated CSS files will be merged into a single `twsx.css` file inside `node_modules/tailwind-to-style/`.
498
496
  4. In React, simply import this file in your entry point: `import 'tailwind-to-style/twsx.css'`.
499
497
 
500
- #### Contoh Penggunaan Plugin Vite
498
+ #### Vite Plugin Usage Example
501
499
 
502
500
  Add the plugin to your `vite.config.js`:
503
501
  ```js
@@ -520,7 +518,7 @@ Import in React:
520
518
  import 'tailwind-to-style/twsx.css';
521
519
  ```
522
520
 
523
- #### Contoh Penggunaan Plugin Webpack
521
+ #### Webpack Plugin Usage Example
524
522
 
525
523
  Add the plugin to your `webpack.config.js`:
526
524
  ```js
@@ -543,6 +541,53 @@ Import in React:
543
541
  import 'tailwind-to-style/twsx.css';
544
542
  ```
545
543
 
544
+ ## Build-Time CSS Generation via Script
545
+
546
+ In addition to using the Vite/Webpack plugin, you can also use a Node.js script to generate a CSS file from the `src/twsx` folder manually or as part of your build workflow.
547
+
548
+ ### Script: lib/build-twsx.js
549
+
550
+ This script will read all JS files in `src/twsx`, generate CSS using the `twsx` function, and write the result to `node_modules/tailwind-to-style/twsx.css`.
551
+
552
+ #### How to Use
553
+
554
+ 1. Make sure your JS files containing style objects are in `src/twsx`.
555
+ 2. Run the script with the following command:
556
+
557
+ ```bash
558
+ node lib/build-twsx.js
559
+ ```
560
+ 3. After running, the combined CSS file will be available at:
561
+
562
+ ```
563
+ node_modules/tailwind-to-style/twsx.css
564
+ ```
565
+ 4. Import this CSS file in your React entry point:
566
+
567
+ ```js
568
+ import 'tailwind-to-style/twsx.css';
569
+ ```
570
+
571
+ #### Automatic Integration
572
+
573
+ You can add this script to the build section in your `package.json`:
574
+
575
+ ```json
576
+ {
577
+ "scripts": {
578
+ "build-css": "node lib/build-twsx.js"
579
+ }
580
+ }
581
+ ```
582
+
583
+ Then run:
584
+
585
+ ```bash
586
+ npm run build-css
587
+ ```
588
+
589
+ This script is suitable for CI/CD workflows, pre-build steps, or manually generating CSS without a bundler plugin.
590
+
546
591
  ## License
547
592
 
548
593
  ## Contributing
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.0
2
+ * tailwind-to-style v2.8.2
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.0
2
+ * tailwind-to-style v2.8.2
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.0
2
+ * tailwind-to-style v2.8.2
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
@@ -0,0 +1,60 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { pathToFileURL } from "url";
4
+ import { twsx } from "tailwind-to-style";
5
+
6
+ function findTwsxFiles(dir, files = []) {
7
+ const items = fs.readdirSync(dir);
8
+ for (const item of items) {
9
+ const fullPath = path.join(dir, item);
10
+ const stat = fs.statSync(fullPath);
11
+ if (stat.isDirectory()) {
12
+ findTwsxFiles(fullPath, files);
13
+ } else if (item.startsWith("twsx.") && item.endsWith(".js")) {
14
+ files.push(fullPath);
15
+ }
16
+ }
17
+ return files;
18
+ }
19
+
20
+ async function buildTwsx(inputDir, outputDir) {
21
+ try {
22
+ const twsxFiles = findTwsxFiles(inputDir);
23
+ for (const filePath of twsxFiles) {
24
+ try {
25
+ const styleModule = await import(
26
+ pathToFileURL(filePath).href + `?update=${Date.now()}`
27
+ );
28
+ const styleObj = styleModule.default || styleModule;
29
+ const css = twsx(styleObj, { inject: false });
30
+ const fileName = path.basename(filePath).replace(/\.js$/, ".css");
31
+ const cssFilePath = path.join(outputDir, fileName);
32
+ fs.writeFileSync(cssFilePath, css);
33
+ console.log(`[build-twsx] CSS written to ${cssFilePath}`);
34
+ } catch (err) {
35
+ console.error(
36
+ `[build-twsx] Error importing or processing ${filePath}:`,
37
+ err
38
+ );
39
+ }
40
+ }
41
+ } catch (err) {
42
+ console.error("[build-twsx] Error scanning for twsx files:", err);
43
+ }
44
+ }
45
+
46
+ const inputDir =
47
+ process.env.TWSX_INPUT_DIR || path.resolve(process.cwd(), "src");
48
+ const outputDir =
49
+ process.env.TWSX_OUTPUT_DIR || path.resolve(process.cwd(), "src/styles");
50
+ if (!fs.existsSync(outputDir)) {
51
+ fs.mkdirSync(outputDir, { recursive: true });
52
+ }
53
+
54
+ (async () => {
55
+ try {
56
+ await buildTwsx(inputDir, outputDir);
57
+ } catch (err) {
58
+ console.error("[build-twsx] Error writing CSS:", err);
59
+ }
60
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwind-to-style",
3
- "version": "2.8.0",
3
+ "version": "2.8.2",
4
4
  "description": "Convert tailwind classes to inline style",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -11,7 +11,9 @@
11
11
  "preflight.css",
12
12
  "README.md",
13
13
  "LICENSE",
14
- "plugins"
14
+ "plugins",
15
+ "lib",
16
+ "twsx.css"
15
17
  ],
16
18
  "scripts": {
17
19
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --passWithNoTests",
@@ -1,40 +1,72 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { twsx } = require("tailwind-to-style");
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { pathToFileURL } from "url";
4
+ import { twsx } from "tailwind-to-style";
4
5
 
5
- function buildTwsx(twsxDir, outDir) {
6
- let allCss = "";
7
- fs.readdirSync(twsxDir).forEach((file) => {
8
- if (file.endsWith(".json")) {
9
- const json = JSON.parse(
10
- fs.readFileSync(path.join(twsxDir, file), "utf8")
11
- );
12
- const css = twsx(json, { inject: false });
13
- const outFile = path.join(outDir, file.replace(".json", ".css"));
14
- fs.writeFileSync(outFile, css);
15
- allCss += css + "\n";
6
+ function findTwsxFiles(dir, files = []) {
7
+ const items = fs.readdirSync(dir);
8
+ for (const item of items) {
9
+ const fullPath = path.join(dir, item);
10
+ const stat = fs.statSync(fullPath);
11
+ if (stat.isDirectory()) {
12
+ findTwsxFiles(fullPath, files);
13
+ } else if (item.startsWith("twsx.") && item.endsWith(".js")) {
14
+ files.push(fullPath);
16
15
  }
17
- });
18
- return allCss;
16
+ }
17
+ return files;
19
18
  }
20
19
 
21
- module.exports = function twsxPlugin(options = {}) {
22
- const twsxDir = options.twsxDir || path.resolve(process.cwd(), "src/twsx");
23
- const outDir = options.outDir || path.resolve(process.cwd(), "dist");
24
- const cssFile = path.resolve(
25
- process.cwd(),
26
- "node_modules/tailwind-to-style/twsx.css"
27
- );
20
+ async function buildTwsx(inputDir, outputDir) {
21
+ try {
22
+ const twsxFiles = findTwsxFiles(inputDir);
23
+ for (const filePath of twsxFiles) {
24
+ try {
25
+ const styleModule = await import(
26
+ pathToFileURL(filePath).href + `?update=${Date.now()}`
27
+ );
28
+ const styleObj = styleModule.default || styleModule;
29
+ const css = twsx(styleObj, { inject: false });
30
+ const fileName = path.basename(filePath).replace(/\.js$/, ".css");
31
+ const cssFilePath = path.join(outputDir, fileName);
32
+ fs.writeFileSync(cssFilePath, css);
33
+ } catch (err) {
34
+ console.error(
35
+ `[vite-twsx] Error importing or processing ${filePath}:`,
36
+ err
37
+ );
38
+ }
39
+ }
40
+ } catch (err) {
41
+ console.error("[vite-twsx] Error scanning for twsx files:", err);
42
+ }
43
+ return null;
44
+ }
45
+
46
+ export default function twsxPlugin(options = {}) {
47
+ const inputDir = options.inputDir || path.resolve(process.cwd(), "src");
48
+ const outputDir =
49
+ options.outputDir || path.resolve(process.cwd(), "src/styles");
50
+
51
+ if (!fs.existsSync(outputDir)) {
52
+ fs.mkdirSync(outputDir, { recursive: true });
53
+ }
28
54
 
29
55
  return {
30
56
  name: "vite-twsx",
31
- buildStart() {
32
- const allCss = buildTwsx(twsxDir, outDir);
33
- fs.writeFileSync(cssFile, allCss);
57
+ async buildStart() {
58
+ try {
59
+ await buildTwsx(inputDir, outputDir);
60
+ } catch (err) {
61
+ console.error("[vite-twsx] Error writing CSS:", err);
62
+ }
34
63
  },
35
- handleHotUpdate() {
36
- const allCss = buildTwsx(twsxDir, outDir);
37
- fs.writeFileSync(cssFile, allCss);
64
+ async handleHotUpdate() {
65
+ try {
66
+ await buildTwsx(inputDir, outputDir);
67
+ } catch (err) {
68
+ console.error("[vite-twsx] Error updating CSS:", err);
69
+ }
38
70
  },
39
71
  };
40
- };
72
+ }
@@ -1,43 +1,73 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { twsx } = require("tailwind-to-style");
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { pathToFileURL } from "url";
4
+ import { twsx } from "tailwind-to-style";
4
5
 
5
- class TwsxPlugin {
6
- constructor(options = {}) {
7
- this.twsxDir = options.twsxDir || path.resolve(process.cwd(), "src/twsx");
8
- this.outDir = options.outDir || path.resolve(process.cwd(), "dist");
6
+ function findTwsxFiles(dir, files = []) {
7
+ const items = fs.readdirSync(dir);
8
+ for (const item of items) {
9
+ const fullPath = path.join(dir, item);
10
+ const stat = fs.statSync(fullPath);
11
+ if (stat.isDirectory()) {
12
+ findTwsxFiles(fullPath, files);
13
+ } else if (item.startsWith("twsx.") && item.endsWith(".js")) {
14
+ files.push(fullPath);
15
+ }
9
16
  }
17
+ return files;
18
+ }
10
19
 
11
- buildTwsx() {
12
- let allCss = "";
13
- fs.readdirSync(this.twsxDir).forEach((file) => {
14
- if (file.endsWith(".json")) {
15
- const json = JSON.parse(
16
- fs.readFileSync(path.join(this.twsxDir, file), "utf8")
20
+ async function buildTwsx(inputDir, outputDir) {
21
+ try {
22
+ const twsxFiles = findTwsxFiles(inputDir);
23
+ for (const filePath of twsxFiles) {
24
+ try {
25
+ const styleModule = await import(
26
+ pathToFileURL(filePath).href + `?update=${Date.now()}`
27
+ );
28
+ const styleObj = styleModule.default || styleModule;
29
+ const css = twsx(styleObj, { inject: false });
30
+ const fileName = path.basename(filePath).replace(/\.js$/, ".css");
31
+ const cssFilePath = path.join(outputDir, fileName);
32
+ fs.writeFileSync(cssFilePath, css);
33
+ } catch (err) {
34
+ console.error(
35
+ `[webpack-twsx] Error importing or processing ${filePath}:`,
36
+ err
17
37
  );
18
- const css = twsx(json, { inject: false });
19
- const outFile = path.join(this.outDir, file.replace(".json", ".css"));
20
- fs.writeFileSync(outFile, css);
21
- allCss += css + "\n";
22
38
  }
23
- });
24
- return allCss;
39
+ }
40
+ } catch (err) {
41
+ console.error("[webpack-twsx] Error scanning for twsx files:", err);
42
+ }
43
+ }
44
+
45
+ class TwsxPlugin {
46
+ constructor(options = {}) {
47
+ this.inputDir = options.inputDir || path.resolve(process.cwd(), "src");
48
+ this.outputDir =
49
+ options.outputDir || path.resolve(process.cwd(), "src/styles");
50
+ if (!fs.existsSync(this.outputDir)) {
51
+ fs.mkdirSync(this.outputDir, { recursive: true });
52
+ }
25
53
  }
26
54
 
27
55
  apply(compiler) {
28
- const cssFile = path.resolve(
29
- process.cwd(),
30
- "node_modules/tailwind-to-style/twsx.css"
31
- );
32
- compiler.hooks.beforeCompile.tap("TwsxPlugin", () => {
33
- const allCss = this.buildTwsx();
34
- fs.writeFileSync(cssFile, allCss);
56
+ compiler.hooks.beforeCompile.tapPromise("TwsxPlugin", async () => {
57
+ try {
58
+ await buildTwsx(this.inputDir, this.outputDir);
59
+ } catch (err) {
60
+ console.error("[webpack-twsx] Error writing CSS:", err);
61
+ }
35
62
  });
36
- compiler.hooks.watchRun.tap("TwsxPlugin", () => {
37
- const allCss = this.buildTwsx();
38
- fs.writeFileSync(cssFile, allCss);
63
+ compiler.hooks.watchRun.tapPromise("TwsxPlugin", async () => {
64
+ try {
65
+ await buildTwsx(this.inputDir, this.outputDir);
66
+ } catch (err) {
67
+ console.error("[webpack-twsx] Error updating CSS:", err);
68
+ }
39
69
  });
40
70
  }
41
71
  }
42
72
 
43
- module.exports = TwsxPlugin;
73
+ export default TwsxPlugin;
package/twsx.css ADDED
File without changes
@@ -1,336 +0,0 @@
1
-
2
- /* Component Styles */
3
- /* btn Component */
4
- .btn {
5
- display: inline-block;
6
- padding: 0.5rem 1rem;
7
- border-radius: 0.25rem;
8
- font-weight: 500;
9
- text-align: center;
10
- text-decoration: none;
11
- cursor: pointer;
12
- transition: all 0.2s ease-in-out;
13
- }
14
- .btn--primary {
15
- background-color: #3b82f6;
16
- color: #ffffff;
17
- }
18
- .btn--secondary {
19
- background-color: #6b7280;
20
- color: #ffffff;
21
- }
22
- .btn--success {
23
- background-color: #10b981;
24
- color: #ffffff;
25
- }
26
- .btn--danger {
27
- background-color: #ef4444;
28
- color: #ffffff;
29
- }
30
- .btn:hover {
31
- opacity: 0.9;
32
- transform: translateY(-1px);
33
- }
34
- .btn:focus {
35
- outline: 2px solid #3b82f6;
36
- outline-offset: 2px;
37
- }
38
- .btn:active {
39
- transform: translateY(0);
40
- }
41
- /* card Component */
42
- .card {
43
- background-color: #ffffff;
44
- border-radius: 0.5rem;
45
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
46
- padding: 1.5rem;
47
- }
48
- .card--elevated {
49
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
50
- }
51
- .card--bordered {
52
- border: 1px solid #e5e7eb;
53
- box-shadow: none;
54
- }
55
- /* input Component */
56
- .input {
57
- display: block;
58
- width: 100%;
59
- padding: 0.5rem 0.75rem;
60
- border: 1px solid #d1d5db;
61
- border-radius: 0.375rem;
62
- font-size: 1rem;
63
- line-height: 1.5;
64
- }
65
- .input:focus {
66
- outline: none;
67
- border-color: #3b82f6;
68
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
69
- }
70
- .input:disabled {
71
- background-color: #f3f4f6;
72
- opacity: 0.6;
73
- cursor: not-allowed;
74
- }
75
- /* Utility Styles */
76
- /* Background Color utilities */
77
- .bg-primary { background-color: #3b82f6; }
78
- .bg-secondary { background-color: #6b7280; }
79
- .bg-success { background-color: #10b981; }
80
- .bg-warning { background-color: #f59e0b; }
81
- .bg-error { background-color: #ef4444; }
82
- .bg-white { background-color: #ffffff; }
83
- .bg-black { background-color: #000000; }
84
- .bg-gray-100 { background-color: #f3f4f6; }
85
- .bg-gray-200 { background-color: #e5e7eb; }
86
- .bg-gray-300 { background-color: #d1d5db; }
87
- .bg-gray-400 { background-color: #9ca3af; }
88
- .bg-gray-500 { background-color: #6b7280; }
89
- .bg-gray-600 { background-color: #4b5563; }
90
- .bg-gray-700 { background-color: #374151; }
91
- .bg-gray-800 { background-color: #1f2937; }
92
- .bg-gray-900 { background-color: #111827; }
93
- /* Text Color utilities */
94
- .text-primary { color: #3b82f6; }
95
- .text-secondary { color: #6b7280; }
96
- .text-success { color: #10b981; }
97
- .text-warning { color: #f59e0b; }
98
- .text-error { color: #ef4444; }
99
- .text-white { color: #ffffff; }
100
- .text-black { color: #000000; }
101
- .text-gray-100 { color: #f3f4f6; }
102
- .text-gray-200 { color: #e5e7eb; }
103
- .text-gray-300 { color: #d1d5db; }
104
- .text-gray-400 { color: #9ca3af; }
105
- .text-gray-500 { color: #6b7280; }
106
- .text-gray-600 { color: #4b5563; }
107
- .text-gray-700 { color: #374151; }
108
- .text-gray-800 { color: #1f2937; }
109
- .text-gray-900 { color: #111827; }
110
- /* Padding utilities */
111
- .p-0 { padding: 0; }
112
- .px-0 { padding-left: 0; padding-right: 0; }
113
- .py-0 { padding-top: 0; padding-bottom: 0; }
114
- .pt-0 { padding-top: 0; }
115
- .pr-0 { padding-right: 0; }
116
- .pb-0 { padding-bottom: 0; }
117
- .pl-0 { padding-left: 0; }
118
- .p-1 { padding: 0.25rem; }
119
- .px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
120
- .py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
121
- .pt-1 { padding-top: 0.25rem; }
122
- .pr-1 { padding-right: 0.25rem; }
123
- .pb-1 { padding-bottom: 0.25rem; }
124
- .pl-1 { padding-left: 0.25rem; }
125
- .p-2 { padding: 0.5rem; }
126
- .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
127
- .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
128
- .pt-2 { padding-top: 0.5rem; }
129
- .pr-2 { padding-right: 0.5rem; }
130
- .pb-2 { padding-bottom: 0.5rem; }
131
- .pl-2 { padding-left: 0.5rem; }
132
- .p-3 { padding: 0.75rem; }
133
- .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
134
- .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
135
- .pt-3 { padding-top: 0.75rem; }
136
- .pr-3 { padding-right: 0.75rem; }
137
- .pb-3 { padding-bottom: 0.75rem; }
138
- .pl-3 { padding-left: 0.75rem; }
139
- .p-4 { padding: 1rem; }
140
- .px-4 { padding-left: 1rem; padding-right: 1rem; }
141
- .py-4 { padding-top: 1rem; padding-bottom: 1rem; }
142
- .pt-4 { padding-top: 1rem; }
143
- .pr-4 { padding-right: 1rem; }
144
- .pb-4 { padding-bottom: 1rem; }
145
- .pl-4 { padding-left: 1rem; }
146
- .p-5 { padding: 1.25rem; }
147
- .px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
148
- .py-5 { padding-top: 1.25rem; padding-bottom: 1.25rem; }
149
- .pt-5 { padding-top: 1.25rem; }
150
- .pr-5 { padding-right: 1.25rem; }
151
- .pb-5 { padding-bottom: 1.25rem; }
152
- .pl-5 { padding-left: 1.25rem; }
153
- .p-6 { padding: 1.5rem; }
154
- .px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
155
- .py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
156
- .pt-6 { padding-top: 1.5rem; }
157
- .pr-6 { padding-right: 1.5rem; }
158
- .pb-6 { padding-bottom: 1.5rem; }
159
- .pl-6 { padding-left: 1.5rem; }
160
- .p-8 { padding: 2rem; }
161
- .px-8 { padding-left: 2rem; padding-right: 2rem; }
162
- .py-8 { padding-top: 2rem; padding-bottom: 2rem; }
163
- .pt-8 { padding-top: 2rem; }
164
- .pr-8 { padding-right: 2rem; }
165
- .pb-8 { padding-bottom: 2rem; }
166
- .pl-8 { padding-left: 2rem; }
167
- .p-10 { padding: 2.5rem; }
168
- .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; }
169
- .py-10 { padding-top: 2.5rem; padding-bottom: 2.5rem; }
170
- .pt-10 { padding-top: 2.5rem; }
171
- .pr-10 { padding-right: 2.5rem; }
172
- .pb-10 { padding-bottom: 2.5rem; }
173
- .pl-10 { padding-left: 2.5rem; }
174
- .p-12 { padding: 3rem; }
175
- .px-12 { padding-left: 3rem; padding-right: 3rem; }
176
- .py-12 { padding-top: 3rem; padding-bottom: 3rem; }
177
- .pt-12 { padding-top: 3rem; }
178
- .pr-12 { padding-right: 3rem; }
179
- .pb-12 { padding-bottom: 3rem; }
180
- .pl-12 { padding-left: 3rem; }
181
- .p-16 { padding: 4rem; }
182
- .px-16 { padding-left: 4rem; padding-right: 4rem; }
183
- .py-16 { padding-top: 4rem; padding-bottom: 4rem; }
184
- .pt-16 { padding-top: 4rem; }
185
- .pr-16 { padding-right: 4rem; }
186
- .pb-16 { padding-bottom: 4rem; }
187
- .pl-16 { padding-left: 4rem; }
188
- .p-20 { padding: 5rem; }
189
- .px-20 { padding-left: 5rem; padding-right: 5rem; }
190
- .py-20 { padding-top: 5rem; padding-bottom: 5rem; }
191
- .pt-20 { padding-top: 5rem; }
192
- .pr-20 { padding-right: 5rem; }
193
- .pb-20 { padding-bottom: 5rem; }
194
- .pl-20 { padding-left: 5rem; }
195
- .p-24 { padding: 6rem; }
196
- .px-24 { padding-left: 6rem; padding-right: 6rem; }
197
- .py-24 { padding-top: 6rem; padding-bottom: 6rem; }
198
- .pt-24 { padding-top: 6rem; }
199
- .pr-24 { padding-right: 6rem; }
200
- .pb-24 { padding-bottom: 6rem; }
201
- .pl-24 { padding-left: 6rem; }
202
- .p-32 { padding: 8rem; }
203
- .px-32 { padding-left: 8rem; padding-right: 8rem; }
204
- .py-32 { padding-top: 8rem; padding-bottom: 8rem; }
205
- .pt-32 { padding-top: 8rem; }
206
- .pr-32 { padding-right: 8rem; }
207
- .pb-32 { padding-bottom: 8rem; }
208
- .pl-32 { padding-left: 8rem; }
209
- /* Margin utilities */
210
- .m-0 { margin: 0; }
211
- .mx-0 { margin-left: 0; margin-right: 0; }
212
- .my-0 { margin-top: 0; margin-bottom: 0; }
213
- .mt-0 { margin-top: 0; }
214
- .mr-0 { margin-right: 0; }
215
- .mb-0 { margin-bottom: 0; }
216
- .ml-0 { margin-left: 0; }
217
- .m-1 { margin: 0.25rem; }
218
- .mx-1 { margin-left: 0.25rem; margin-right: 0.25rem; }
219
- .my-1 { margin-top: 0.25rem; margin-bottom: 0.25rem; }
220
- .mt-1 { margin-top: 0.25rem; }
221
- .mr-1 { margin-right: 0.25rem; }
222
- .mb-1 { margin-bottom: 0.25rem; }
223
- .ml-1 { margin-left: 0.25rem; }
224
- .m-2 { margin: 0.5rem; }
225
- .mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
226
- .my-2 { margin-top: 0.5rem; margin-bottom: 0.5rem; }
227
- .mt-2 { margin-top: 0.5rem; }
228
- .mr-2 { margin-right: 0.5rem; }
229
- .mb-2 { margin-bottom: 0.5rem; }
230
- .ml-2 { margin-left: 0.5rem; }
231
- .m-3 { margin: 0.75rem; }
232
- .mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; }
233
- .my-3 { margin-top: 0.75rem; margin-bottom: 0.75rem; }
234
- .mt-3 { margin-top: 0.75rem; }
235
- .mr-3 { margin-right: 0.75rem; }
236
- .mb-3 { margin-bottom: 0.75rem; }
237
- .ml-3 { margin-left: 0.75rem; }
238
- .m-4 { margin: 1rem; }
239
- .mx-4 { margin-left: 1rem; margin-right: 1rem; }
240
- .my-4 { margin-top: 1rem; margin-bottom: 1rem; }
241
- .mt-4 { margin-top: 1rem; }
242
- .mr-4 { margin-right: 1rem; }
243
- .mb-4 { margin-bottom: 1rem; }
244
- .ml-4 { margin-left: 1rem; }
245
- .m-5 { margin: 1.25rem; }
246
- .mx-5 { margin-left: 1.25rem; margin-right: 1.25rem; }
247
- .my-5 { margin-top: 1.25rem; margin-bottom: 1.25rem; }
248
- .mt-5 { margin-top: 1.25rem; }
249
- .mr-5 { margin-right: 1.25rem; }
250
- .mb-5 { margin-bottom: 1.25rem; }
251
- .ml-5 { margin-left: 1.25rem; }
252
- .m-6 { margin: 1.5rem; }
253
- .mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; }
254
- .my-6 { margin-top: 1.5rem; margin-bottom: 1.5rem; }
255
- .mt-6 { margin-top: 1.5rem; }
256
- .mr-6 { margin-right: 1.5rem; }
257
- .mb-6 { margin-bottom: 1.5rem; }
258
- .ml-6 { margin-left: 1.5rem; }
259
- .m-8 { margin: 2rem; }
260
- .mx-8 { margin-left: 2rem; margin-right: 2rem; }
261
- .my-8 { margin-top: 2rem; margin-bottom: 2rem; }
262
- .mt-8 { margin-top: 2rem; }
263
- .mr-8 { margin-right: 2rem; }
264
- .mb-8 { margin-bottom: 2rem; }
265
- .ml-8 { margin-left: 2rem; }
266
- .m-10 { margin: 2.5rem; }
267
- .mx-10 { margin-left: 2.5rem; margin-right: 2.5rem; }
268
- .my-10 { margin-top: 2.5rem; margin-bottom: 2.5rem; }
269
- .mt-10 { margin-top: 2.5rem; }
270
- .mr-10 { margin-right: 2.5rem; }
271
- .mb-10 { margin-bottom: 2.5rem; }
272
- .ml-10 { margin-left: 2.5rem; }
273
- .m-12 { margin: 3rem; }
274
- .mx-12 { margin-left: 3rem; margin-right: 3rem; }
275
- .my-12 { margin-top: 3rem; margin-bottom: 3rem; }
276
- .mt-12 { margin-top: 3rem; }
277
- .mr-12 { margin-right: 3rem; }
278
- .mb-12 { margin-bottom: 3rem; }
279
- .ml-12 { margin-left: 3rem; }
280
- .m-16 { margin: 4rem; }
281
- .mx-16 { margin-left: 4rem; margin-right: 4rem; }
282
- .my-16 { margin-top: 4rem; margin-bottom: 4rem; }
283
- .mt-16 { margin-top: 4rem; }
284
- .mr-16 { margin-right: 4rem; }
285
- .mb-16 { margin-bottom: 4rem; }
286
- .ml-16 { margin-left: 4rem; }
287
- .m-20 { margin: 5rem; }
288
- .mx-20 { margin-left: 5rem; margin-right: 5rem; }
289
- .my-20 { margin-top: 5rem; margin-bottom: 5rem; }
290
- .mt-20 { margin-top: 5rem; }
291
- .mr-20 { margin-right: 5rem; }
292
- .mb-20 { margin-bottom: 5rem; }
293
- .ml-20 { margin-left: 5rem; }
294
- .m-24 { margin: 6rem; }
295
- .mx-24 { margin-left: 6rem; margin-right: 6rem; }
296
- .my-24 { margin-top: 6rem; margin-bottom: 6rem; }
297
- .mt-24 { margin-top: 6rem; }
298
- .mr-24 { margin-right: 6rem; }
299
- .mb-24 { margin-bottom: 6rem; }
300
- .ml-24 { margin-left: 6rem; }
301
- .m-32 { margin: 8rem; }
302
- .mx-32 { margin-left: 8rem; margin-right: 8rem; }
303
- .my-32 { margin-top: 8rem; margin-bottom: 8rem; }
304
- .mt-32 { margin-top: 8rem; }
305
- .mr-32 { margin-right: 8rem; }
306
- .mb-32 { margin-bottom: 8rem; }
307
- .ml-32 { margin-left: 8rem; }
308
- /* Font Size utilities */
309
- .text-xs { font-size: 0.75rem; }
310
- .text-sm { font-size: 0.875rem; }
311
- .text-base { font-size: 1rem; }
312
- .text-lg { font-size: 1.125rem; }
313
- .text-xl { font-size: 1.25rem; }
314
- .text-2xl { font-size: 1.5rem; }
315
- .text-3xl { font-size: 1.875rem; }
316
- .text-4xl { font-size: 2.25rem; }
317
- /* Border Radius utilities */
318
- .rounded-none { border-radius: 0; }
319
- .rounded-sm { border-radius: 0.125rem; }
320
- .rounded { border-radius: 0.25rem; }
321
- .rounded-md { border-radius: 0.375rem; }
322
- .rounded-lg { border-radius: 0.5rem; }
323
- .rounded-xl { border-radius: 0.75rem; }
324
- .rounded-2xl { border-radius: 1rem; }
325
- .rounded-full { border-radius: 9999px; }
326
- /* Custom Styles */
327
- .container {
328
- max-width: 1200px;
329
- margin: 0 auto;
330
- padding: 0 1rem;
331
- }
332
- .flex-center {
333
- display: flex;
334
- align-items: center;
335
- justify-content: center;
336
- }