mcp-tailwindcss 1.0.0 → 1.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/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { createRequire } from 'node:module';
5
6
  import * as fs from 'fs';
6
7
  import * as path from 'path';
7
8
  import { fileURLToPath } from 'url';
@@ -9,6 +10,8 @@ import { AstParser, } from './ast-parser.js';
9
10
  import { checkAndUpdate, checkForUpdates, getRepositoryStatus, scheduleUpdateCheck, ensureRepository, } from './auto-updater.js';
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = path.dirname(__filename);
13
+ const require = createRequire(import.meta.url);
14
+ const APP_VERSION = require('../package.json').version ?? '0.0.0';
12
15
  let TAILWIND_SRC_PATH = process.env.TAILWIND_SRC_PATH || '';
13
16
  const CATEGORY_EMOJI = {
14
17
  interface: '📋',
@@ -32,7 +35,7 @@ const CATEGORY_LABELS = {
32
35
  };
33
36
  const mcpServer = new McpServer({
34
37
  name: 'mcp-tailwindcss',
35
- version: '1.0.0',
38
+ version: APP_VERSION,
36
39
  }, {
37
40
  capabilities: {
38
41
  tools: {},
@@ -420,6 +423,113 @@ mcpServer.server.setRequestHandler(ListToolsRequestSchema, async () => {
420
423
  required: ['framework'],
421
424
  },
422
425
  },
426
+ {
427
+ name: 'tailwind_utilities',
428
+ description: 'Lista completa de classes utilitárias do Tailwind CSS organizadas por categoria (layout, flexbox, grid, spacing, sizing, typography, backgrounds, borders, effects, filters, transitions, transforms). Inclui sintaxe e CSS gerado.',
429
+ inputSchema: {
430
+ type: 'object',
431
+ properties: {
432
+ categoria: {
433
+ type: 'string',
434
+ enum: ['layout', 'flexbox', 'grid', 'spacing', 'sizing', 'typography', 'backgrounds', 'borders', 'effects', 'filters', 'transitions', 'transforms', 'interactivity', 'svg', 'tables', 'accessibility'],
435
+ description: 'Categoria de utilities para listar. Se omitido, lista todas as categorias disponíveis.',
436
+ },
437
+ },
438
+ required: [],
439
+ },
440
+ },
441
+ {
442
+ name: 'tailwind_variants',
443
+ description: 'Lista completa de variants (modificadores) do Tailwind CSS: pseudo-classes (hover, focus, active), pseudo-elements (before, after), media queries (sm, md, lg), estados (disabled, checked), dark mode, e variants compostos (group-hover, peer-focus).',
444
+ inputSchema: {
445
+ type: 'object',
446
+ properties: {
447
+ tipo: {
448
+ type: 'string',
449
+ enum: ['pseudo-classes', 'pseudo-elements', 'responsive', 'dark-mode', 'state', 'compound', 'aria', 'data'],
450
+ description: 'Tipo de variant para listar. Se omitido, lista todos os tipos.',
451
+ },
452
+ },
453
+ required: [],
454
+ },
455
+ },
456
+ {
457
+ name: 'tailwind_cores',
458
+ description: 'Paleta completa de cores do Tailwind CSS v4 com valores em OKLCH e equivalentes hex. Inclui todas as escalas (50-950) para cada cor (slate, gray, red, orange, yellow, green, blue, indigo, purple, pink).',
459
+ inputSchema: {
460
+ type: 'object',
461
+ properties: {
462
+ cor: {
463
+ type: 'string',
464
+ description: 'Nome da cor específica (slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose). Se omitido, lista todas.',
465
+ },
466
+ },
467
+ required: [],
468
+ },
469
+ },
470
+ {
471
+ name: 'tailwind_spacing',
472
+ description: 'Escala completa de espaçamento do Tailwind CSS. Mostra todos os valores de spacing (0, 0.5, 1, 1.5, 2, ... 96, px) com seus valores em rem/px. Usado para margin, padding, gap, width, height, etc.',
473
+ inputSchema: {
474
+ type: 'object',
475
+ properties: {},
476
+ required: [],
477
+ },
478
+ },
479
+ {
480
+ name: 'tailwind_breakpoints',
481
+ description: 'Breakpoints responsivos do Tailwind CSS com valores e exemplos de uso. Mostra sm, md, lg, xl, 2xl e como usar min-*, max-* e container queries (@sm, @md, etc).',
482
+ inputSchema: {
483
+ type: 'object',
484
+ properties: {},
485
+ required: [],
486
+ },
487
+ },
488
+ {
489
+ name: 'tailwind_receitas',
490
+ description: 'Receitas e exemplos prontos de componentes comuns com Tailwind CSS: buttons, cards, forms, modals, navbars, footers, heroes, grids responsivos. Código HTML+classes pronto para copiar.',
491
+ inputSchema: {
492
+ type: 'object',
493
+ properties: {
494
+ componente: {
495
+ type: 'string',
496
+ enum: ['button', 'card', 'form', 'input', 'modal', 'navbar', 'footer', 'hero', 'grid', 'alert', 'badge', 'avatar', 'dropdown', 'tabs', 'breadcrumb', 'pagination', 'skeleton'],
497
+ description: 'Componente específico para ver a receita.',
498
+ },
499
+ },
500
+ required: ['componente'],
501
+ },
502
+ },
503
+ {
504
+ name: 'tailwind_migracao_v4',
505
+ description: 'Guia completo de migração do Tailwind CSS v3 para v4. Mudanças de sintaxe, novas features, breaking changes, e exemplos de código antes/depois.',
506
+ inputSchema: {
507
+ type: 'object',
508
+ properties: {
509
+ topico: {
510
+ type: 'string',
511
+ enum: ['overview', 'css-first', 'theme-config', 'utilities', 'variants', 'plugins', 'breaking-changes', 'postcss-vite'],
512
+ description: 'Tópico específico da migração. Se omitido, mostra overview completo.',
513
+ },
514
+ },
515
+ required: [],
516
+ },
517
+ },
518
+ {
519
+ name: 'tailwind_boas_praticas',
520
+ description: 'Boas práticas e dicas para usar Tailwind CSS de forma eficiente: organização de classes, extração de componentes, performance, acessibilidade, responsive design, dark mode.',
521
+ inputSchema: {
522
+ type: 'object',
523
+ properties: {
524
+ topico: {
525
+ type: 'string',
526
+ enum: ['organizacao', 'componentes', 'performance', 'acessibilidade', 'responsivo', 'dark-mode', 'animacoes', 'forms'],
527
+ description: 'Tópico específico. Se omitido, mostra dicas gerais.',
528
+ },
529
+ },
530
+ required: [],
531
+ },
532
+ },
423
533
  ],
424
534
  };
425
535
  });
@@ -744,19 +854,19 @@ mcpServer.server.setRequestHandler(CallToolRequestSchema, async (request) => {
744
854
  'Crie o CSS com @import "tailwindcss"',
745
855
  'Importe o CSS no entry (main.tsx/main.ts)',
746
856
  ],
747
- configSnippet: `// vite.config.ts
748
- import tailwindcss from '@tailwindcss/vite'
749
- import { defineConfig } from 'vite'
750
-
751
- export default defineConfig({
752
- plugins: [tailwindcss()]
857
+ configSnippet: `// vite.config.ts
858
+ import tailwindcss from '@tailwindcss/vite'
859
+ import { defineConfig } from 'vite'
860
+
861
+ export default defineConfig({
862
+ plugins: [tailwindcss()]
753
863
  })`,
754
- cssSnippet: `/* app.css */
755
- @import "tailwindcss";
756
-
757
- @theme {
758
- /* Customize theme variables */
759
- --color-brand: oklch(0.72 0.11 221.19);
864
+ cssSnippet: `/* app.css */
865
+ @import "tailwindcss";
866
+
867
+ @theme {
868
+ /* Customize theme variables */
869
+ --color-brand: oklch(0.72 0.11 221.19);
760
870
  }`,
761
871
  },
762
872
  v3: {
@@ -766,15 +876,15 @@ export default defineConfig({
766
876
  'Configure content no tailwind.config.js',
767
877
  'Crie CSS com diretivas @tailwind',
768
878
  ],
769
- configSnippet: `// tailwind.config.js
770
- module.exports = {
771
- content: ['./index.html', './src/**/*.{js,ts,jsx,tsx,vue,svelte}'],
772
- theme: { extend: {} },
773
- plugins: [],
879
+ configSnippet: `// tailwind.config.js
880
+ module.exports = {
881
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx,vue,svelte}'],
882
+ theme: { extend: {} },
883
+ plugins: [],
774
884
  }`,
775
- cssSnippet: `/* src/index.css */
776
- @tailwind base;
777
- @tailwind components;
885
+ cssSnippet: `/* src/index.css */
886
+ @tailwind base;
887
+ @tailwind components;
778
888
  @tailwind utilities;`,
779
889
  },
780
890
  contentGlob: './index.html, ./src/**/*.{js,ts,jsx,tsx,vue,svelte}',
@@ -788,17 +898,17 @@ module.exports = {
788
898
  'Crie app/globals.css com @import "tailwindcss"',
789
899
  'Importe em app/layout.tsx',
790
900
  ],
791
- configSnippet: `// postcss.config.mjs
792
- export default {
793
- plugins: {
794
- '@tailwindcss/postcss': {}
795
- }
901
+ configSnippet: `// postcss.config.mjs
902
+ export default {
903
+ plugins: {
904
+ '@tailwindcss/postcss': {}
905
+ }
796
906
  }`,
797
- cssSnippet: `/* app/globals.css */
798
- @import "tailwindcss";
799
-
800
- @theme {
801
- --color-primary: oklch(0.62 0.21 259.81);
907
+ cssSnippet: `/* app/globals.css */
908
+ @import "tailwindcss";
909
+
910
+ @theme {
911
+ --color-primary: oklch(0.62 0.21 259.81);
802
912
  }`,
803
913
  },
804
914
  v3: {
@@ -808,20 +918,20 @@ export default {
808
918
  'Configure content no tailwind.config.js',
809
919
  'Crie globals.css com diretivas @tailwind',
810
920
  ],
811
- configSnippet: `// tailwind.config.js
812
- module.exports = {
813
- content: [
814
- './app/**/*.{js,ts,jsx,tsx,mdx}',
815
- './pages/**/*.{js,ts,jsx,tsx}',
816
- './components/**/*.{js,ts,jsx,tsx}',
817
- './src/**/*.{js,ts,jsx,tsx,mdx}',
818
- ],
819
- theme: { extend: {} },
820
- plugins: [],
921
+ configSnippet: `// tailwind.config.js
922
+ module.exports = {
923
+ content: [
924
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
925
+ './pages/**/*.{js,ts,jsx,tsx}',
926
+ './components/**/*.{js,ts,jsx,tsx}',
927
+ './src/**/*.{js,ts,jsx,tsx,mdx}',
928
+ ],
929
+ theme: { extend: {} },
930
+ plugins: [],
821
931
  }`,
822
- cssSnippet: `/* app/globals.css */
823
- @tailwind base;
824
- @tailwind components;
932
+ cssSnippet: `/* app/globals.css */
933
+ @tailwind base;
934
+ @tailwind components;
825
935
  @tailwind utilities;`,
826
936
  },
827
937
  contentGlob: './app/**/*.{js,ts,jsx,tsx,mdx}, ./components/**/*.{js,ts,jsx,tsx}',
@@ -835,20 +945,20 @@ module.exports = {
835
945
  'Crie assets/css/main.css com @import "tailwindcss"',
836
946
  'Adicione o CSS ao nuxt.config.ts',
837
947
  ],
838
- configSnippet: `// nuxt.config.ts
839
- export default defineNuxtConfig({
840
- css: ['~/assets/css/main.css'],
841
- postcss: {
842
- plugins: {
843
- '@tailwindcss/postcss': {}
844
- }
845
- }
948
+ configSnippet: `// nuxt.config.ts
949
+ export default defineNuxtConfig({
950
+ css: ['~/assets/css/main.css'],
951
+ postcss: {
952
+ plugins: {
953
+ '@tailwindcss/postcss': {}
954
+ }
955
+ }
846
956
  })`,
847
- cssSnippet: `/* assets/css/main.css */
848
- @import "tailwindcss";
849
-
850
- @theme {
851
- --color-brand: oklch(0.69 0.17 162.48);
957
+ cssSnippet: `/* assets/css/main.css */
958
+ @import "tailwindcss";
959
+
960
+ @theme {
961
+ --color-brand: oklch(0.69 0.17 162.48);
852
962
  }`,
853
963
  },
854
964
  v3: {
@@ -857,21 +967,21 @@ export default defineNuxtConfig({
857
967
  'Gere config: npx tailwindcss init -p',
858
968
  'Configure content e adicione CSS ao nuxt.config.ts',
859
969
  ],
860
- configSnippet: `// tailwind.config.js
861
- module.exports = {
862
- content: [
863
- './components/**/*.{vue,js,ts}',
864
- './layouts/**/*.vue',
865
- './pages/**/*.vue',
866
- './app.vue',
867
- './plugins/**/*.{js,ts}',
868
- ],
869
- theme: { extend: {} },
870
- plugins: [],
970
+ configSnippet: `// tailwind.config.js
971
+ module.exports = {
972
+ content: [
973
+ './components/**/*.{vue,js,ts}',
974
+ './layouts/**/*.vue',
975
+ './pages/**/*.vue',
976
+ './app.vue',
977
+ './plugins/**/*.{js,ts}',
978
+ ],
979
+ theme: { extend: {} },
980
+ plugins: [],
871
981
  }`,
872
- cssSnippet: `/* assets/css/tailwind.css */
873
- @tailwind base;
874
- @tailwind components;
982
+ cssSnippet: `/* assets/css/tailwind.css */
983
+ @tailwind base;
984
+ @tailwind components;
875
985
  @tailwind utilities;`,
876
986
  },
877
987
  contentGlob: './components/**/*.{vue,js,ts}, ./pages/**/*.vue, ./app.vue',
@@ -885,15 +995,15 @@ module.exports = {
885
995
  'Crie src/app.css com @import "tailwindcss"',
886
996
  'Importe em src/routes/+layout.svelte',
887
997
  ],
888
- configSnippet: `// vite.config.ts
889
- import { sveltekit } from '@sveltejs/kit/vite'
890
- import tailwindcss from '@tailwindcss/vite'
891
- import { defineConfig } from 'vite'
892
-
893
- export default defineConfig({
894
- plugins: [tailwindcss(), sveltekit()]
998
+ configSnippet: `// vite.config.ts
999
+ import { sveltekit } from '@sveltejs/kit/vite'
1000
+ import tailwindcss from '@tailwindcss/vite'
1001
+ import { defineConfig } from 'vite'
1002
+
1003
+ export default defineConfig({
1004
+ plugins: [tailwindcss(), sveltekit()]
895
1005
  })`,
896
- cssSnippet: `/* src/app.css */
1006
+ cssSnippet: `/* src/app.css */
897
1007
  @import "tailwindcss";`,
898
1008
  },
899
1009
  v3: {
@@ -902,15 +1012,15 @@ export default defineConfig({
902
1012
  'Gere config: npx tailwindcss init -p',
903
1013
  'Crie src/app.css e importe em +layout.svelte',
904
1014
  ],
905
- configSnippet: `// tailwind.config.js
906
- module.exports = {
907
- content: ['./src/**/*.{html,js,svelte,ts}'],
908
- theme: { extend: {} },
909
- plugins: [],
1015
+ configSnippet: `// tailwind.config.js
1016
+ module.exports = {
1017
+ content: ['./src/**/*.{html,js,svelte,ts}'],
1018
+ theme: { extend: {} },
1019
+ plugins: [],
910
1020
  }`,
911
- cssSnippet: `/* src/app.css */
912
- @tailwind base;
913
- @tailwind components;
1021
+ cssSnippet: `/* src/app.css */
1022
+ @tailwind base;
1023
+ @tailwind components;
914
1024
  @tailwind utilities;`,
915
1025
  },
916
1026
  contentGlob: './src/**/*.{html,js,svelte,ts}',
@@ -924,16 +1034,16 @@ module.exports = {
924
1034
  'Crie src/styles/global.css com @import "tailwindcss"',
925
1035
  'Importe em layouts/Layout.astro',
926
1036
  ],
927
- configSnippet: `// astro.config.mjs
928
- import { defineConfig } from 'astro/config'
929
- import tailwindcss from '@tailwindcss/vite'
930
-
931
- export default defineConfig({
932
- vite: {
933
- plugins: [tailwindcss()]
934
- }
1037
+ configSnippet: `// astro.config.mjs
1038
+ import { defineConfig } from 'astro/config'
1039
+ import tailwindcss from '@tailwindcss/vite'
1040
+
1041
+ export default defineConfig({
1042
+ vite: {
1043
+ plugins: [tailwindcss()]
1044
+ }
935
1045
  })`,
936
- cssSnippet: `/* src/styles/global.css */
1046
+ cssSnippet: `/* src/styles/global.css */
937
1047
  @import "tailwindcss";`,
938
1048
  },
939
1049
  v3: {
@@ -941,15 +1051,15 @@ export default defineConfig({
941
1051
  'Use: npx astro add tailwind (recomendado)',
942
1052
  'Ou manual: npm install -D tailwindcss @astrojs/tailwind',
943
1053
  ],
944
- configSnippet: `// tailwind.config.js
945
- module.exports = {
946
- content: ['./src/**/*.{astro,html,js,jsx,ts,tsx,vue,svelte}'],
947
- theme: { extend: {} },
948
- plugins: [],
1054
+ configSnippet: `// tailwind.config.js
1055
+ module.exports = {
1056
+ content: ['./src/**/*.{astro,html,js,jsx,ts,tsx,vue,svelte}'],
1057
+ theme: { extend: {} },
1058
+ plugins: [],
949
1059
  }`,
950
- cssSnippet: `/* src/styles/global.css */
951
- @tailwind base;
952
- @tailwind components;
1060
+ cssSnippet: `/* src/styles/global.css */
1061
+ @tailwind base;
1062
+ @tailwind components;
953
1063
  @tailwind utilities;`,
954
1064
  },
955
1065
  contentGlob: './src/**/*.{astro,html,js,jsx,ts,tsx,vue,svelte}',
@@ -963,15 +1073,15 @@ module.exports = {
963
1073
  'Crie app/tailwind.css com @import "tailwindcss"',
964
1074
  'Importe em app/root.tsx via links()',
965
1075
  ],
966
- configSnippet: `// vite.config.ts
967
- import { vitePlugin as remix } from '@remix-run/dev'
968
- import tailwindcss from '@tailwindcss/vite'
969
- import { defineConfig } from 'vite'
970
-
971
- export default defineConfig({
972
- plugins: [tailwindcss(), remix()]
1076
+ configSnippet: `// vite.config.ts
1077
+ import { vitePlugin as remix } from '@remix-run/dev'
1078
+ import tailwindcss from '@tailwindcss/vite'
1079
+ import { defineConfig } from 'vite'
1080
+
1081
+ export default defineConfig({
1082
+ plugins: [tailwindcss(), remix()]
973
1083
  })`,
974
- cssSnippet: `/* app/tailwind.css */
1084
+ cssSnippet: `/* app/tailwind.css */
975
1085
  @import "tailwindcss";`,
976
1086
  },
977
1087
  v3: {
@@ -980,15 +1090,15 @@ export default defineConfig({
980
1090
  'Gere config: npx tailwindcss init -p',
981
1091
  'Crie app/tailwind.css e importe em root.tsx',
982
1092
  ],
983
- configSnippet: `// tailwind.config.js
984
- module.exports = {
985
- content: ['./app/**/*.{ts,tsx,js,jsx}'],
986
- theme: { extend: {} },
987
- plugins: [],
1093
+ configSnippet: `// tailwind.config.js
1094
+ module.exports = {
1095
+ content: ['./app/**/*.{ts,tsx,js,jsx}'],
1096
+ theme: { extend: {} },
1097
+ plugins: [],
988
1098
  }`,
989
- cssSnippet: `/* app/tailwind.css */
990
- @tailwind base;
991
- @tailwind components;
1099
+ cssSnippet: `/* app/tailwind.css */
1100
+ @tailwind base;
1101
+ @tailwind components;
992
1102
  @tailwind utilities;`,
993
1103
  },
994
1104
  contentGlob: './app/**/*.{ts,tsx,js,jsx}',
@@ -1002,15 +1112,15 @@ module.exports = {
1002
1112
  'Crie src/assets/main.css com @import "tailwindcss"',
1003
1113
  'Importe em src/main.ts',
1004
1114
  ],
1005
- configSnippet: `// vite.config.ts
1006
- import vue from '@vitejs/plugin-vue'
1007
- import tailwindcss from '@tailwindcss/vite'
1008
- import { defineConfig } from 'vite'
1009
-
1010
- export default defineConfig({
1011
- plugins: [vue(), tailwindcss()]
1115
+ configSnippet: `// vite.config.ts
1116
+ import vue from '@vitejs/plugin-vue'
1117
+ import tailwindcss from '@tailwindcss/vite'
1118
+ import { defineConfig } from 'vite'
1119
+
1120
+ export default defineConfig({
1121
+ plugins: [vue(), tailwindcss()]
1012
1122
  })`,
1013
- cssSnippet: `/* src/assets/main.css */
1123
+ cssSnippet: `/* src/assets/main.css */
1014
1124
  @import "tailwindcss";`,
1015
1125
  },
1016
1126
  v3: {
@@ -1019,15 +1129,15 @@ export default defineConfig({
1019
1129
  'Gere config: npx tailwindcss init -p',
1020
1130
  'Crie src/assets/tailwind.css e importe em main.ts',
1021
1131
  ],
1022
- configSnippet: `// tailwind.config.js
1023
- module.exports = {
1024
- content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
1025
- theme: { extend: {} },
1026
- plugins: [],
1132
+ configSnippet: `// tailwind.config.js
1133
+ module.exports = {
1134
+ content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
1135
+ theme: { extend: {} },
1136
+ plugins: [],
1027
1137
  }`,
1028
- cssSnippet: `/* src/assets/tailwind.css */
1029
- @tailwind base;
1030
- @tailwind components;
1138
+ cssSnippet: `/* src/assets/tailwind.css */
1139
+ @tailwind base;
1140
+ @tailwind components;
1031
1141
  @tailwind utilities;`,
1032
1142
  },
1033
1143
  contentGlob: './index.html, ./src/**/*.{vue,js,ts,jsx,tsx}',
@@ -1041,15 +1151,15 @@ module.exports = {
1041
1151
  'Crie src/index.css com @import "tailwindcss"',
1042
1152
  'Importe em src/main.tsx',
1043
1153
  ],
1044
- configSnippet: `// vite.config.ts
1045
- import react from '@vitejs/plugin-react'
1046
- import tailwindcss from '@tailwindcss/vite'
1047
- import { defineConfig } from 'vite'
1048
-
1049
- export default defineConfig({
1050
- plugins: [react(), tailwindcss()]
1154
+ configSnippet: `// vite.config.ts
1155
+ import react from '@vitejs/plugin-react'
1156
+ import tailwindcss from '@tailwindcss/vite'
1157
+ import { defineConfig } from 'vite'
1158
+
1159
+ export default defineConfig({
1160
+ plugins: [react(), tailwindcss()]
1051
1161
  })`,
1052
- cssSnippet: `/* src/index.css */
1162
+ cssSnippet: `/* src/index.css */
1053
1163
  @import "tailwindcss";`,
1054
1164
  },
1055
1165
  v3: {
@@ -1058,15 +1168,15 @@ export default defineConfig({
1058
1168
  'Gere config: npx tailwindcss init -p',
1059
1169
  'Crie src/index.css e importe em main.tsx/index.tsx',
1060
1170
  ],
1061
- configSnippet: `// tailwind.config.js
1062
- module.exports = {
1063
- content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
1064
- theme: { extend: {} },
1065
- plugins: [],
1171
+ configSnippet: `// tailwind.config.js
1172
+ module.exports = {
1173
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
1174
+ theme: { extend: {} },
1175
+ plugins: [],
1066
1176
  }`,
1067
- cssSnippet: `/* src/index.css */
1068
- @tailwind base;
1069
- @tailwind components;
1177
+ cssSnippet: `/* src/index.css */
1178
+ @tailwind base;
1179
+ @tailwind components;
1070
1180
  @tailwind utilities;`,
1071
1181
  },
1072
1182
  contentGlob: './index.html, ./src/**/*.{js,ts,jsx,tsx}',
@@ -1079,13 +1189,13 @@ module.exports = {
1079
1189
  'Configure postcss.config.js',
1080
1190
  'Crie CSS com @import "tailwindcss"',
1081
1191
  ],
1082
- configSnippet: `// postcss.config.js
1083
- export default {
1084
- plugins: {
1085
- '@tailwindcss/postcss': {}
1086
- }
1192
+ configSnippet: `// postcss.config.js
1193
+ export default {
1194
+ plugins: {
1195
+ '@tailwindcss/postcss': {}
1196
+ }
1087
1197
  }`,
1088
- cssSnippet: `/* styles.css */
1198
+ cssSnippet: `/* styles.css */
1089
1199
  @import "tailwindcss";`,
1090
1200
  },
1091
1201
  v3: {
@@ -1094,16 +1204,16 @@ export default {
1094
1204
  'Configure postcss.config.js',
1095
1205
  'Crie CSS com diretivas @tailwind',
1096
1206
  ],
1097
- configSnippet: `// postcss.config.js
1098
- module.exports = {
1099
- plugins: {
1100
- tailwindcss: {},
1101
- autoprefixer: {},
1102
- }
1207
+ configSnippet: `// postcss.config.js
1208
+ module.exports = {
1209
+ plugins: {
1210
+ tailwindcss: {},
1211
+ autoprefixer: {},
1212
+ }
1103
1213
  }`,
1104
- cssSnippet: `/* styles.css */
1105
- @tailwind base;
1106
- @tailwind components;
1214
+ cssSnippet: `/* styles.css */
1215
+ @tailwind base;
1216
+ @tailwind components;
1107
1217
  @tailwind utilities;`,
1108
1218
  },
1109
1219
  contentGlob: './src/**/*.{html,js,ts,jsx,tsx}',
@@ -1115,15 +1225,15 @@ module.exports = {
1115
1225
  'Instale: npm install tailwindcss @tailwindcss/cli',
1116
1226
  'Execute: npx @tailwindcss/cli -i input.css -o output.css --watch',
1117
1227
  ],
1118
- configSnippet: `# Comando para build
1119
- npx @tailwindcss/cli -i input.css -o output.css
1120
-
1121
- # Comando para watch
1122
- npx @tailwindcss/cli -i input.css -o output.css --watch
1123
-
1124
- # Minificado para produção
1228
+ configSnippet: `# Comando para build
1229
+ npx @tailwindcss/cli -i input.css -o output.css
1230
+
1231
+ # Comando para watch
1232
+ npx @tailwindcss/cli -i input.css -o output.css --watch
1233
+
1234
+ # Minificado para produção
1125
1235
  npx @tailwindcss/cli -i input.css -o output.css --minify`,
1126
- cssSnippet: `/* input.css */
1236
+ cssSnippet: `/* input.css */
1127
1237
  @import "tailwindcss";`,
1128
1238
  },
1129
1239
  v3: {
@@ -1132,14 +1242,14 @@ npx @tailwindcss/cli -i input.css -o output.css --minify`,
1132
1242
  'Gere config: npx tailwindcss init',
1133
1243
  'Execute: npx tailwindcss -i input.css -o output.css --watch',
1134
1244
  ],
1135
- configSnippet: `# Comando para watch
1136
- npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch
1137
-
1138
- # Minificado para produção
1245
+ configSnippet: `# Comando para watch
1246
+ npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch
1247
+
1248
+ # Minificado para produção
1139
1249
  npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify`,
1140
- cssSnippet: `/* input.css */
1141
- @tailwind base;
1142
- @tailwind components;
1250
+ cssSnippet: `/* input.css */
1251
+ @tailwind base;
1252
+ @tailwind components;
1143
1253
  @tailwind utilities;`,
1144
1254
  },
1145
1255
  contentGlob: './src/**/*.{html,js}',
@@ -1176,6 +1286,2417 @@ npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify`,
1176
1286
  content: [{ type: 'text', text: result }],
1177
1287
  };
1178
1288
  }
1289
+ case 'tailwind_utilities': {
1290
+ const categoria = args?.categoria;
1291
+ const utilities = {
1292
+ layout: {
1293
+ desc: 'Controle de layout e posicionamento',
1294
+ classes: [
1295
+ { class: 'block', css: 'display: block;' },
1296
+ { class: 'inline-block', css: 'display: inline-block;' },
1297
+ { class: 'inline', css: 'display: inline;' },
1298
+ { class: 'flex', css: 'display: flex;' },
1299
+ { class: 'inline-flex', css: 'display: inline-flex;' },
1300
+ { class: 'grid', css: 'display: grid;' },
1301
+ { class: 'inline-grid', css: 'display: inline-grid;' },
1302
+ { class: 'hidden', css: 'display: none;' },
1303
+ { class: 'container', css: 'width: 100%; max-width: breakpoint;' },
1304
+ { class: 'static', css: 'position: static;' },
1305
+ { class: 'fixed', css: 'position: fixed;' },
1306
+ { class: 'absolute', css: 'position: absolute;' },
1307
+ { class: 'relative', css: 'position: relative;' },
1308
+ { class: 'sticky', css: 'position: sticky;' },
1309
+ { class: 'inset-{n}', css: 'inset: {value};', desc: 'top, right, bottom, left' },
1310
+ { class: 'top-{n}', css: 'top: {value};' },
1311
+ { class: 'right-{n}', css: 'right: {value};' },
1312
+ { class: 'bottom-{n}', css: 'bottom: {value};' },
1313
+ { class: 'left-{n}', css: 'left: {value};' },
1314
+ { class: 'z-{n}', css: 'z-index: {n};', desc: '0, 10, 20, 30, 40, 50, auto' },
1315
+ { class: 'visible', css: 'visibility: visible;' },
1316
+ { class: 'invisible', css: 'visibility: hidden;' },
1317
+ { class: 'collapse', css: 'visibility: collapse;' },
1318
+ ],
1319
+ },
1320
+ flexbox: {
1321
+ desc: 'Flexbox utilities',
1322
+ classes: [
1323
+ { class: 'flex-row', css: 'flex-direction: row;' },
1324
+ { class: 'flex-row-reverse', css: 'flex-direction: row-reverse;' },
1325
+ { class: 'flex-col', css: 'flex-direction: column;' },
1326
+ { class: 'flex-col-reverse', css: 'flex-direction: column-reverse;' },
1327
+ { class: 'flex-wrap', css: 'flex-wrap: wrap;' },
1328
+ { class: 'flex-wrap-reverse', css: 'flex-wrap: wrap-reverse;' },
1329
+ { class: 'flex-nowrap', css: 'flex-wrap: nowrap;' },
1330
+ { class: 'flex-1', css: 'flex: 1 1 0%;' },
1331
+ { class: 'flex-auto', css: 'flex: 1 1 auto;' },
1332
+ { class: 'flex-initial', css: 'flex: 0 1 auto;' },
1333
+ { class: 'flex-none', css: 'flex: none;' },
1334
+ { class: 'grow', css: 'flex-grow: 1;' },
1335
+ { class: 'grow-0', css: 'flex-grow: 0;' },
1336
+ { class: 'shrink', css: 'flex-shrink: 1;' },
1337
+ { class: 'shrink-0', css: 'flex-shrink: 0;' },
1338
+ { class: 'basis-{n}', css: 'flex-basis: {value};' },
1339
+ { class: 'justify-start', css: 'justify-content: flex-start;' },
1340
+ { class: 'justify-end', css: 'justify-content: flex-end;' },
1341
+ { class: 'justify-center', css: 'justify-content: center;' },
1342
+ { class: 'justify-between', css: 'justify-content: space-between;' },
1343
+ { class: 'justify-around', css: 'justify-content: space-around;' },
1344
+ { class: 'justify-evenly', css: 'justify-content: space-evenly;' },
1345
+ { class: 'items-start', css: 'align-items: flex-start;' },
1346
+ { class: 'items-end', css: 'align-items: flex-end;' },
1347
+ { class: 'items-center', css: 'align-items: center;' },
1348
+ { class: 'items-baseline', css: 'align-items: baseline;' },
1349
+ { class: 'items-stretch', css: 'align-items: stretch;' },
1350
+ { class: 'gap-{n}', css: 'gap: {value};' },
1351
+ { class: 'gap-x-{n}', css: 'column-gap: {value};' },
1352
+ { class: 'gap-y-{n}', css: 'row-gap: {value};' },
1353
+ ],
1354
+ },
1355
+ grid: {
1356
+ desc: 'Grid utilities',
1357
+ classes: [
1358
+ { class: 'grid-cols-{n}', css: 'grid-template-columns: repeat({n}, minmax(0, 1fr));', desc: '1-12, none' },
1359
+ { class: 'grid-rows-{n}', css: 'grid-template-rows: repeat({n}, minmax(0, 1fr));', desc: '1-12, none' },
1360
+ { class: 'col-span-{n}', css: 'grid-column: span {n} / span {n};', desc: '1-12, full' },
1361
+ { class: 'col-start-{n}', css: 'grid-column-start: {n};' },
1362
+ { class: 'col-end-{n}', css: 'grid-column-end: {n};' },
1363
+ { class: 'row-span-{n}', css: 'grid-row: span {n} / span {n};' },
1364
+ { class: 'row-start-{n}', css: 'grid-row-start: {n};' },
1365
+ { class: 'row-end-{n}', css: 'grid-row-end: {n};' },
1366
+ { class: 'grid-flow-row', css: 'grid-auto-flow: row;' },
1367
+ { class: 'grid-flow-col', css: 'grid-auto-flow: column;' },
1368
+ { class: 'grid-flow-dense', css: 'grid-auto-flow: dense;' },
1369
+ { class: 'auto-cols-auto', css: 'grid-auto-columns: auto;' },
1370
+ { class: 'auto-cols-min', css: 'grid-auto-columns: min-content;' },
1371
+ { class: 'auto-cols-max', css: 'grid-auto-columns: max-content;' },
1372
+ { class: 'auto-cols-fr', css: 'grid-auto-columns: minmax(0, 1fr);' },
1373
+ { class: 'auto-rows-auto', css: 'grid-auto-rows: auto;' },
1374
+ { class: 'auto-rows-min', css: 'grid-auto-rows: min-content;' },
1375
+ { class: 'auto-rows-max', css: 'grid-auto-rows: max-content;' },
1376
+ { class: 'auto-rows-fr', css: 'grid-auto-rows: minmax(0, 1fr);' },
1377
+ ],
1378
+ },
1379
+ spacing: {
1380
+ desc: 'Margin e Padding',
1381
+ classes: [
1382
+ { class: 'p-{n}', css: 'padding: {value};', desc: '0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96, px' },
1383
+ { class: 'px-{n}', css: 'padding-left: {value}; padding-right: {value};' },
1384
+ { class: 'py-{n}', css: 'padding-top: {value}; padding-bottom: {value};' },
1385
+ { class: 'pt-{n}', css: 'padding-top: {value};' },
1386
+ { class: 'pr-{n}', css: 'padding-right: {value};' },
1387
+ { class: 'pb-{n}', css: 'padding-bottom: {value};' },
1388
+ { class: 'pl-{n}', css: 'padding-left: {value};' },
1389
+ { class: 'm-{n}', css: 'margin: {value};' },
1390
+ { class: 'mx-{n}', css: 'margin-left: {value}; margin-right: {value};' },
1391
+ { class: 'my-{n}', css: 'margin-top: {value}; margin-bottom: {value};' },
1392
+ { class: 'mt-{n}', css: 'margin-top: {value};' },
1393
+ { class: 'mr-{n}', css: 'margin-right: {value};' },
1394
+ { class: 'mb-{n}', css: 'margin-bottom: {value};' },
1395
+ { class: 'ml-{n}', css: 'margin-left: {value};' },
1396
+ { class: '-m-{n}', css: 'margin: -{value};', desc: 'Negative margin' },
1397
+ { class: 'space-x-{n}', css: '> * + * { margin-left: {value}; }' },
1398
+ { class: 'space-y-{n}', css: '> * + * { margin-top: {value}; }' },
1399
+ { class: 'space-x-reverse', css: '--tw-space-x-reverse: 1;' },
1400
+ { class: 'space-y-reverse', css: '--tw-space-y-reverse: 1;' },
1401
+ ],
1402
+ },
1403
+ sizing: {
1404
+ desc: 'Width e Height',
1405
+ classes: [
1406
+ { class: 'w-{n}', css: 'width: {value};', desc: '0-96, auto, full, screen, svw, lvw, dvw, min, max, fit' },
1407
+ { class: 'w-1/2', css: 'width: 50%;' },
1408
+ { class: 'w-1/3', css: 'width: 33.333333%;' },
1409
+ { class: 'w-2/3', css: 'width: 66.666667%;' },
1410
+ { class: 'w-1/4', css: 'width: 25%;' },
1411
+ { class: 'w-full', css: 'width: 100%;' },
1412
+ { class: 'w-screen', css: 'width: 100vw;' },
1413
+ { class: 'w-auto', css: 'width: auto;' },
1414
+ { class: 'min-w-{n}', css: 'min-width: {value};' },
1415
+ { class: 'max-w-{n}', css: 'max-width: {value};', desc: 'xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, full, prose, screen-sm, screen-md, screen-lg, screen-xl, screen-2xl' },
1416
+ { class: 'h-{n}', css: 'height: {value};' },
1417
+ { class: 'h-full', css: 'height: 100%;' },
1418
+ { class: 'h-screen', css: 'height: 100vh;' },
1419
+ { class: 'h-svh', css: 'height: 100svh;' },
1420
+ { class: 'h-lvh', css: 'height: 100lvh;' },
1421
+ { class: 'h-dvh', css: 'height: 100dvh;' },
1422
+ { class: 'min-h-{n}', css: 'min-height: {value};' },
1423
+ { class: 'min-h-screen', css: 'min-height: 100vh;' },
1424
+ { class: 'max-h-{n}', css: 'max-height: {value};' },
1425
+ { class: 'size-{n}', css: 'width: {value}; height: {value};', desc: 'v4: shorthand for w + h' },
1426
+ ],
1427
+ },
1428
+ typography: {
1429
+ desc: 'Tipografia e texto',
1430
+ classes: [
1431
+ { class: 'text-xs', css: 'font-size: 0.75rem; line-height: 1rem;' },
1432
+ { class: 'text-sm', css: 'font-size: 0.875rem; line-height: 1.25rem;' },
1433
+ { class: 'text-base', css: 'font-size: 1rem; line-height: 1.5rem;' },
1434
+ { class: 'text-lg', css: 'font-size: 1.125rem; line-height: 1.75rem;' },
1435
+ { class: 'text-xl', css: 'font-size: 1.25rem; line-height: 1.75rem;' },
1436
+ { class: 'text-2xl', css: 'font-size: 1.5rem; line-height: 2rem;' },
1437
+ { class: 'text-3xl', css: 'font-size: 1.875rem; line-height: 2.25rem;' },
1438
+ { class: 'text-4xl', css: 'font-size: 2.25rem; line-height: 2.5rem;' },
1439
+ { class: 'text-5xl', css: 'font-size: 3rem; line-height: 1;' },
1440
+ { class: 'text-6xl', css: 'font-size: 3.75rem; line-height: 1;' },
1441
+ { class: 'font-thin', css: 'font-weight: 100;' },
1442
+ { class: 'font-light', css: 'font-weight: 300;' },
1443
+ { class: 'font-normal', css: 'font-weight: 400;' },
1444
+ { class: 'font-medium', css: 'font-weight: 500;' },
1445
+ { class: 'font-semibold', css: 'font-weight: 600;' },
1446
+ { class: 'font-bold', css: 'font-weight: 700;' },
1447
+ { class: 'font-extrabold', css: 'font-weight: 800;' },
1448
+ { class: 'font-black', css: 'font-weight: 900;' },
1449
+ { class: 'italic', css: 'font-style: italic;' },
1450
+ { class: 'not-italic', css: 'font-style: normal;' },
1451
+ { class: 'text-left', css: 'text-align: left;' },
1452
+ { class: 'text-center', css: 'text-align: center;' },
1453
+ { class: 'text-right', css: 'text-align: right;' },
1454
+ { class: 'text-justify', css: 'text-align: justify;' },
1455
+ { class: 'underline', css: 'text-decoration-line: underline;' },
1456
+ { class: 'overline', css: 'text-decoration-line: overline;' },
1457
+ { class: 'line-through', css: 'text-decoration-line: line-through;' },
1458
+ { class: 'no-underline', css: 'text-decoration-line: none;' },
1459
+ { class: 'uppercase', css: 'text-transform: uppercase;' },
1460
+ { class: 'lowercase', css: 'text-transform: lowercase;' },
1461
+ { class: 'capitalize', css: 'text-transform: capitalize;' },
1462
+ { class: 'normal-case', css: 'text-transform: none;' },
1463
+ { class: 'truncate', css: 'overflow: hidden; text-overflow: ellipsis; white-space: nowrap;' },
1464
+ { class: 'leading-{n}', css: 'line-height: {value};', desc: '3-10, none, tight, snug, normal, relaxed, loose' },
1465
+ { class: 'tracking-{n}', css: 'letter-spacing: {value};', desc: 'tighter, tight, normal, wide, wider, widest' },
1466
+ ],
1467
+ },
1468
+ backgrounds: {
1469
+ desc: 'Backgrounds e gradientes',
1470
+ classes: [
1471
+ { class: 'bg-{color}', css: 'background-color: {color};', desc: 'Qualquer cor da paleta' },
1472
+ { class: 'bg-transparent', css: 'background-color: transparent;' },
1473
+ { class: 'bg-current', css: 'background-color: currentColor;' },
1474
+ { class: 'bg-inherit', css: 'background-color: inherit;' },
1475
+ { class: 'bg-gradient-to-{dir}', css: 'background-image: linear-gradient(to {dir}, ...);', desc: 't, tr, r, br, b, bl, l, tl' },
1476
+ { class: 'from-{color}', css: '--tw-gradient-from: {color};' },
1477
+ { class: 'via-{color}', css: '--tw-gradient-via: {color};' },
1478
+ { class: 'to-{color}', css: '--tw-gradient-to: {color};' },
1479
+ { class: 'bg-none', css: 'background-image: none;' },
1480
+ { class: 'bg-cover', css: 'background-size: cover;' },
1481
+ { class: 'bg-contain', css: 'background-size: contain;' },
1482
+ { class: 'bg-auto', css: 'background-size: auto;' },
1483
+ { class: 'bg-fixed', css: 'background-attachment: fixed;' },
1484
+ { class: 'bg-local', css: 'background-attachment: local;' },
1485
+ { class: 'bg-scroll', css: 'background-attachment: scroll;' },
1486
+ { class: 'bg-center', css: 'background-position: center;' },
1487
+ { class: 'bg-top', css: 'background-position: top;' },
1488
+ { class: 'bg-bottom', css: 'background-position: bottom;' },
1489
+ { class: 'bg-repeat', css: 'background-repeat: repeat;' },
1490
+ { class: 'bg-no-repeat', css: 'background-repeat: no-repeat;' },
1491
+ { class: 'bg-repeat-x', css: 'background-repeat: repeat-x;' },
1492
+ { class: 'bg-repeat-y', css: 'background-repeat: repeat-y;' },
1493
+ ],
1494
+ },
1495
+ borders: {
1496
+ desc: 'Borders e border-radius',
1497
+ classes: [
1498
+ { class: 'border', css: 'border-width: 1px;' },
1499
+ { class: 'border-0', css: 'border-width: 0px;' },
1500
+ { class: 'border-2', css: 'border-width: 2px;' },
1501
+ { class: 'border-4', css: 'border-width: 4px;' },
1502
+ { class: 'border-8', css: 'border-width: 8px;' },
1503
+ { class: 'border-t', css: 'border-top-width: 1px;' },
1504
+ { class: 'border-r', css: 'border-right-width: 1px;' },
1505
+ { class: 'border-b', css: 'border-bottom-width: 1px;' },
1506
+ { class: 'border-l', css: 'border-left-width: 1px;' },
1507
+ { class: 'border-{color}', css: 'border-color: {color};' },
1508
+ { class: 'border-solid', css: 'border-style: solid;' },
1509
+ { class: 'border-dashed', css: 'border-style: dashed;' },
1510
+ { class: 'border-dotted', css: 'border-style: dotted;' },
1511
+ { class: 'border-double', css: 'border-style: double;' },
1512
+ { class: 'border-hidden', css: 'border-style: hidden;' },
1513
+ { class: 'border-none', css: 'border-style: none;' },
1514
+ { class: 'rounded', css: 'border-radius: 0.25rem;' },
1515
+ { class: 'rounded-none', css: 'border-radius: 0px;' },
1516
+ { class: 'rounded-sm', css: 'border-radius: 0.125rem;' },
1517
+ { class: 'rounded-md', css: 'border-radius: 0.375rem;' },
1518
+ { class: 'rounded-lg', css: 'border-radius: 0.5rem;' },
1519
+ { class: 'rounded-xl', css: 'border-radius: 0.75rem;' },
1520
+ { class: 'rounded-2xl', css: 'border-radius: 1rem;' },
1521
+ { class: 'rounded-3xl', css: 'border-radius: 1.5rem;' },
1522
+ { class: 'rounded-full', css: 'border-radius: 9999px;' },
1523
+ { class: 'divide-x', css: '> * + * { border-left-width: 1px; }' },
1524
+ { class: 'divide-y', css: '> * + * { border-top-width: 1px; }' },
1525
+ { class: 'divide-{color}', css: '> * + * { border-color: {color}; }' },
1526
+ { class: 'ring-{n}', css: 'box-shadow: 0 0 0 {n}px ...;', desc: '0, 1, 2, 4, 8, inset' },
1527
+ { class: 'ring-{color}', css: '--tw-ring-color: {color};' },
1528
+ { class: 'outline', css: 'outline-style: solid;' },
1529
+ { class: 'outline-none', css: 'outline: 2px solid transparent; outline-offset: 2px;' },
1530
+ ],
1531
+ },
1532
+ effects: {
1533
+ desc: 'Sombras e opacidade',
1534
+ classes: [
1535
+ { class: 'shadow-sm', css: 'box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);' },
1536
+ { class: 'shadow', css: 'box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);' },
1537
+ { class: 'shadow-md', css: 'box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);' },
1538
+ { class: 'shadow-lg', css: 'box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);' },
1539
+ { class: 'shadow-xl', css: 'box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);' },
1540
+ { class: 'shadow-2xl', css: 'box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);' },
1541
+ { class: 'shadow-inner', css: 'box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);' },
1542
+ { class: 'shadow-none', css: 'box-shadow: 0 0 #0000;' },
1543
+ { class: 'shadow-{color}', css: '--tw-shadow-color: {color};' },
1544
+ { class: 'opacity-{n}', css: 'opacity: {n/100};', desc: '0, 5, 10, 15, 20, 25, 30, ..., 100' },
1545
+ { class: 'mix-blend-{mode}', css: 'mix-blend-mode: {mode};', desc: 'normal, multiply, screen, overlay, darken, lighten, etc.' },
1546
+ { class: 'bg-blend-{mode}', css: 'background-blend-mode: {mode};' },
1547
+ ],
1548
+ },
1549
+ filters: {
1550
+ desc: 'Filtros CSS',
1551
+ classes: [
1552
+ { class: 'blur', css: 'filter: blur(8px);' },
1553
+ { class: 'blur-sm', css: 'filter: blur(4px);' },
1554
+ { class: 'blur-md', css: 'filter: blur(12px);' },
1555
+ { class: 'blur-lg', css: 'filter: blur(16px);' },
1556
+ { class: 'blur-xl', css: 'filter: blur(24px);' },
1557
+ { class: 'blur-2xl', css: 'filter: blur(40px);' },
1558
+ { class: 'blur-3xl', css: 'filter: blur(64px);' },
1559
+ { class: 'blur-none', css: 'filter: blur(0);' },
1560
+ { class: 'brightness-{n}', css: 'filter: brightness({n/100});', desc: '0, 50, 75, 90, 95, 100, 105, 110, 125, 150, 200' },
1561
+ { class: 'contrast-{n}', css: 'filter: contrast({n/100});' },
1562
+ { class: 'grayscale', css: 'filter: grayscale(100%);' },
1563
+ { class: 'grayscale-0', css: 'filter: grayscale(0);' },
1564
+ { class: 'hue-rotate-{n}', css: 'filter: hue-rotate({n}deg);', desc: '0, 15, 30, 60, 90, 180' },
1565
+ { class: 'invert', css: 'filter: invert(100%);' },
1566
+ { class: 'invert-0', css: 'filter: invert(0);' },
1567
+ { class: 'saturate-{n}', css: 'filter: saturate({n/100});' },
1568
+ { class: 'sepia', css: 'filter: sepia(100%);' },
1569
+ { class: 'sepia-0', css: 'filter: sepia(0);' },
1570
+ { class: 'backdrop-blur-{n}', css: 'backdrop-filter: blur({value});' },
1571
+ { class: 'backdrop-brightness-{n}', css: 'backdrop-filter: brightness({n/100});' },
1572
+ { class: 'backdrop-contrast-{n}', css: 'backdrop-filter: contrast({n/100});' },
1573
+ { class: 'backdrop-grayscale', css: 'backdrop-filter: grayscale(100%);' },
1574
+ { class: 'backdrop-invert', css: 'backdrop-filter: invert(100%);' },
1575
+ { class: 'backdrop-opacity-{n}', css: 'backdrop-filter: opacity({n/100});' },
1576
+ { class: 'backdrop-saturate-{n}', css: 'backdrop-filter: saturate({n/100});' },
1577
+ { class: 'backdrop-sepia', css: 'backdrop-filter: sepia(100%);' },
1578
+ ],
1579
+ },
1580
+ transitions: {
1581
+ desc: 'Transições e animações',
1582
+ classes: [
1583
+ { class: 'transition', css: 'transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;' },
1584
+ { class: 'transition-none', css: 'transition-property: none;' },
1585
+ { class: 'transition-all', css: 'transition-property: all;' },
1586
+ { class: 'transition-colors', css: 'transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;' },
1587
+ { class: 'transition-opacity', css: 'transition-property: opacity;' },
1588
+ { class: 'transition-shadow', css: 'transition-property: box-shadow;' },
1589
+ { class: 'transition-transform', css: 'transition-property: transform;' },
1590
+ { class: 'duration-{n}', css: 'transition-duration: {n}ms;', desc: '0, 75, 100, 150, 200, 300, 500, 700, 1000' },
1591
+ { class: 'ease-linear', css: 'transition-timing-function: linear;' },
1592
+ { class: 'ease-in', css: 'transition-timing-function: cubic-bezier(0.4, 0, 1, 1);' },
1593
+ { class: 'ease-out', css: 'transition-timing-function: cubic-bezier(0, 0, 0.2, 1);' },
1594
+ { class: 'ease-in-out', css: 'transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);' },
1595
+ { class: 'delay-{n}', css: 'transition-delay: {n}ms;' },
1596
+ { class: 'animate-none', css: 'animation: none;' },
1597
+ { class: 'animate-spin', css: 'animation: spin 1s linear infinite;' },
1598
+ { class: 'animate-ping', css: 'animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;' },
1599
+ { class: 'animate-pulse', css: 'animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;' },
1600
+ { class: 'animate-bounce', css: 'animation: bounce 1s infinite;' },
1601
+ ],
1602
+ },
1603
+ transforms: {
1604
+ desc: 'Transformações CSS',
1605
+ classes: [
1606
+ { class: 'scale-{n}', css: 'transform: scale({n/100});', desc: '0, 50, 75, 90, 95, 100, 105, 110, 125, 150' },
1607
+ { class: 'scale-x-{n}', css: 'transform: scaleX({n/100});' },
1608
+ { class: 'scale-y-{n}', css: 'transform: scaleY({n/100});' },
1609
+ { class: 'rotate-{n}', css: 'transform: rotate({n}deg);', desc: '0, 1, 2, 3, 6, 12, 45, 90, 180' },
1610
+ { class: '-rotate-{n}', css: 'transform: rotate(-{n}deg);' },
1611
+ { class: 'translate-x-{n}', css: 'transform: translateX({value});' },
1612
+ { class: 'translate-y-{n}', css: 'transform: translateY({value});' },
1613
+ { class: '-translate-x-{n}', css: 'transform: translateX(-{value});' },
1614
+ { class: '-translate-y-{n}', css: 'transform: translateY(-{value});' },
1615
+ { class: 'skew-x-{n}', css: 'transform: skewX({n}deg);', desc: '0, 1, 2, 3, 6, 12' },
1616
+ { class: 'skew-y-{n}', css: 'transform: skewY({n}deg);' },
1617
+ { class: 'origin-center', css: 'transform-origin: center;' },
1618
+ { class: 'origin-top', css: 'transform-origin: top;' },
1619
+ { class: 'origin-top-right', css: 'transform-origin: top right;' },
1620
+ { class: 'origin-right', css: 'transform-origin: right;' },
1621
+ { class: 'origin-bottom-right', css: 'transform-origin: bottom right;' },
1622
+ { class: 'origin-bottom', css: 'transform-origin: bottom;' },
1623
+ { class: 'origin-bottom-left', css: 'transform-origin: bottom left;' },
1624
+ { class: 'origin-left', css: 'transform-origin: left;' },
1625
+ { class: 'origin-top-left', css: 'transform-origin: top left;' },
1626
+ ],
1627
+ },
1628
+ interactivity: {
1629
+ desc: 'Cursor, scroll, resize',
1630
+ classes: [
1631
+ { class: 'cursor-auto', css: 'cursor: auto;' },
1632
+ { class: 'cursor-default', css: 'cursor: default;' },
1633
+ { class: 'cursor-pointer', css: 'cursor: pointer;' },
1634
+ { class: 'cursor-wait', css: 'cursor: wait;' },
1635
+ { class: 'cursor-text', css: 'cursor: text;' },
1636
+ { class: 'cursor-move', css: 'cursor: move;' },
1637
+ { class: 'cursor-not-allowed', css: 'cursor: not-allowed;' },
1638
+ { class: 'cursor-grab', css: 'cursor: grab;' },
1639
+ { class: 'cursor-grabbing', css: 'cursor: grabbing;' },
1640
+ { class: 'select-none', css: 'user-select: none;' },
1641
+ { class: 'select-text', css: 'user-select: text;' },
1642
+ { class: 'select-all', css: 'user-select: all;' },
1643
+ { class: 'select-auto', css: 'user-select: auto;' },
1644
+ { class: 'resize-none', css: 'resize: none;' },
1645
+ { class: 'resize', css: 'resize: both;' },
1646
+ { class: 'resize-x', css: 'resize: horizontal;' },
1647
+ { class: 'resize-y', css: 'resize: vertical;' },
1648
+ { class: 'scroll-auto', css: 'scroll-behavior: auto;' },
1649
+ { class: 'scroll-smooth', css: 'scroll-behavior: smooth;' },
1650
+ { class: 'snap-start', css: 'scroll-snap-align: start;' },
1651
+ { class: 'snap-end', css: 'scroll-snap-align: end;' },
1652
+ { class: 'snap-center', css: 'scroll-snap-align: center;' },
1653
+ { class: 'snap-none', css: 'scroll-snap-type: none;' },
1654
+ { class: 'snap-x', css: 'scroll-snap-type: x var(--tw-scroll-snap-strictness);' },
1655
+ { class: 'snap-y', css: 'scroll-snap-type: y var(--tw-scroll-snap-strictness);' },
1656
+ { class: 'snap-mandatory', css: '--tw-scroll-snap-strictness: mandatory;' },
1657
+ { class: 'snap-proximity', css: '--tw-scroll-snap-strictness: proximity;' },
1658
+ { class: 'touch-auto', css: 'touch-action: auto;' },
1659
+ { class: 'touch-none', css: 'touch-action: none;' },
1660
+ { class: 'touch-manipulation', css: 'touch-action: manipulation;' },
1661
+ { class: 'pointer-events-none', css: 'pointer-events: none;' },
1662
+ { class: 'pointer-events-auto', css: 'pointer-events: auto;' },
1663
+ ],
1664
+ },
1665
+ svg: {
1666
+ desc: 'SVG fill e stroke',
1667
+ classes: [
1668
+ { class: 'fill-none', css: 'fill: none;' },
1669
+ { class: 'fill-inherit', css: 'fill: inherit;' },
1670
+ { class: 'fill-current', css: 'fill: currentColor;' },
1671
+ { class: 'fill-transparent', css: 'fill: transparent;' },
1672
+ { class: 'fill-{color}', css: 'fill: {color};' },
1673
+ { class: 'stroke-none', css: 'stroke: none;' },
1674
+ { class: 'stroke-inherit', css: 'stroke: inherit;' },
1675
+ { class: 'stroke-current', css: 'stroke: currentColor;' },
1676
+ { class: 'stroke-transparent', css: 'stroke: transparent;' },
1677
+ { class: 'stroke-{color}', css: 'stroke: {color};' },
1678
+ { class: 'stroke-{n}', css: 'stroke-width: {n};', desc: '0, 1, 2' },
1679
+ ],
1680
+ },
1681
+ tables: {
1682
+ desc: 'Tabelas',
1683
+ classes: [
1684
+ { class: 'border-collapse', css: 'border-collapse: collapse;' },
1685
+ { class: 'border-separate', css: 'border-collapse: separate;' },
1686
+ { class: 'border-spacing-{n}', css: 'border-spacing: {value};' },
1687
+ { class: 'border-spacing-x-{n}', css: 'border-spacing: {value} 0;' },
1688
+ { class: 'border-spacing-y-{n}', css: 'border-spacing: 0 {value};' },
1689
+ { class: 'table-auto', css: 'table-layout: auto;' },
1690
+ { class: 'table-fixed', css: 'table-layout: fixed;' },
1691
+ { class: 'caption-top', css: 'caption-side: top;' },
1692
+ { class: 'caption-bottom', css: 'caption-side: bottom;' },
1693
+ ],
1694
+ },
1695
+ accessibility: {
1696
+ desc: 'Acessibilidade',
1697
+ classes: [
1698
+ { class: 'sr-only', css: 'position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0;' },
1699
+ { class: 'not-sr-only', css: 'position: static; width: auto; height: auto; padding: 0; margin: 0; overflow: visible; clip: auto; white-space: normal;' },
1700
+ { class: 'forced-color-adjust-auto', css: 'forced-color-adjust: auto;' },
1701
+ { class: 'forced-color-adjust-none', css: 'forced-color-adjust: none;' },
1702
+ ],
1703
+ },
1704
+ };
1705
+ if (!categoria) {
1706
+ let result = '# 📚 Categorias de Utilities do Tailwind CSS\n\n';
1707
+ result += 'Use `tailwind_utilities` com uma categoria específica para ver as classes.\n\n';
1708
+ result += '| Categoria | Descrição | Classes |\n';
1709
+ result += '|-----------|-----------|--------|\n';
1710
+ for (const [key, value] of Object.entries(utilities)) {
1711
+ result += `| \`${key}\` | ${value.desc} | ${value.classes.length} |\n`;
1712
+ }
1713
+ result += '\n**Exemplo:** `tailwind_utilities({ categoria: "flexbox" })`\n';
1714
+ return { content: [{ type: 'text', text: result }] };
1715
+ }
1716
+ const cat = utilities[categoria];
1717
+ if (!cat) {
1718
+ return {
1719
+ content: [{ type: 'text', text: `❌ Categoria não encontrada: ${categoria}\n\nCategorias disponíveis: ${Object.keys(utilities).join(', ')}` }],
1720
+ isError: true,
1721
+ };
1722
+ }
1723
+ let result = `# 🎨 Utilities: ${categoria}\n\n`;
1724
+ result += `**${cat.desc}**\n\n`;
1725
+ result += '| Classe | CSS Gerado | Notas |\n';
1726
+ result += '|--------|------------|-------|\n';
1727
+ for (const u of cat.classes) {
1728
+ const notes = u.desc || '-';
1729
+ result += `| \`${u.class}\` | \`${u.css}\` | ${notes} |\n`;
1730
+ }
1731
+ result += `\n**Total:** ${cat.classes.length} classes\n`;
1732
+ return { content: [{ type: 'text', text: result }] };
1733
+ }
1734
+ case 'tailwind_variants': {
1735
+ const tipo = args?.tipo;
1736
+ const variants = {
1737
+ 'pseudo-classes': {
1738
+ desc: 'Estados interativos e de formulário',
1739
+ items: [
1740
+ { variant: 'hover', desc: 'Mouse sobre o elemento', example: 'hover:bg-blue-500' },
1741
+ { variant: 'focus', desc: 'Elemento focado', example: 'focus:ring-2' },
1742
+ { variant: 'focus-within', desc: 'Filho tem foco', example: 'focus-within:border-blue-500' },
1743
+ { variant: 'focus-visible', desc: 'Foco visível (teclado)', example: 'focus-visible:outline-2' },
1744
+ { variant: 'active', desc: 'Clique ativo', example: 'active:bg-blue-700' },
1745
+ { variant: 'visited', desc: 'Link visitado', example: 'visited:text-purple-500' },
1746
+ { variant: 'target', desc: 'Alvo de âncora', example: 'target:bg-yellow-200' },
1747
+ { variant: 'first', desc: 'Primeiro filho', example: 'first:mt-0' },
1748
+ { variant: 'last', desc: 'Último filho', example: 'last:mb-0' },
1749
+ { variant: 'only', desc: 'Filho único', example: 'only:mx-auto' },
1750
+ { variant: 'odd', desc: 'Filhos ímpares', example: 'odd:bg-gray-100' },
1751
+ { variant: 'even', desc: 'Filhos pares', example: 'even:bg-gray-50' },
1752
+ { variant: 'first-of-type', desc: 'Primeiro do tipo', example: 'first-of-type:pt-0' },
1753
+ { variant: 'last-of-type', desc: 'Último do tipo', example: 'last-of-type:pb-0' },
1754
+ { variant: 'only-of-type', desc: 'Único do tipo', example: 'only-of-type:mx-auto' },
1755
+ { variant: 'empty', desc: 'Sem filhos', example: 'empty:hidden' },
1756
+ { variant: 'enabled', desc: 'Input habilitado', example: 'enabled:cursor-pointer' },
1757
+ { variant: 'disabled', desc: 'Input desabilitado', example: 'disabled:opacity-50' },
1758
+ { variant: 'checked', desc: 'Checkbox/radio marcado', example: 'checked:bg-blue-500' },
1759
+ { variant: 'indeterminate', desc: 'Estado indeterminado', example: 'indeterminate:bg-gray-300' },
1760
+ { variant: 'default', desc: 'Opção padrão', example: 'default:ring-2' },
1761
+ { variant: 'required', desc: 'Campo obrigatório', example: 'required:border-red-500' },
1762
+ { variant: 'valid', desc: 'Input válido', example: 'valid:border-green-500' },
1763
+ { variant: 'invalid', desc: 'Input inválido', example: 'invalid:border-red-500' },
1764
+ { variant: 'in-range', desc: 'Valor no range', example: 'in-range:border-green-500' },
1765
+ { variant: 'out-of-range', desc: 'Valor fora do range', example: 'out-of-range:border-red-500' },
1766
+ { variant: 'placeholder-shown', desc: 'Placeholder visível', example: 'placeholder-shown:border-gray-300' },
1767
+ { variant: 'autofill', desc: 'Preenchido pelo browser', example: 'autofill:bg-yellow-100' },
1768
+ { variant: 'read-only', desc: 'Campo somente leitura', example: 'read-only:bg-gray-100' },
1769
+ ],
1770
+ },
1771
+ 'pseudo-elements': {
1772
+ desc: 'Pseudo-elementos CSS',
1773
+ items: [
1774
+ { variant: 'before', desc: 'Pseudo-elemento ::before', example: 'before:content-[""] before:absolute' },
1775
+ { variant: 'after', desc: 'Pseudo-elemento ::after', example: 'after:content-["✓"] after:ml-2' },
1776
+ { variant: 'placeholder', desc: 'Texto do placeholder', example: 'placeholder:text-gray-400' },
1777
+ { variant: 'file', desc: 'Botão de input file', example: 'file:bg-blue-500 file:text-white' },
1778
+ { variant: 'marker', desc: 'Marcador de lista', example: 'marker:text-blue-500' },
1779
+ { variant: 'selection', desc: 'Texto selecionado', example: 'selection:bg-blue-200' },
1780
+ { variant: 'first-line', desc: 'Primeira linha', example: 'first-line:font-bold' },
1781
+ { variant: 'first-letter', desc: 'Primeira letra', example: 'first-letter:text-4xl' },
1782
+ { variant: 'backdrop', desc: 'Backdrop de dialog', example: 'backdrop:bg-black/50' },
1783
+ ],
1784
+ },
1785
+ responsive: {
1786
+ desc: 'Breakpoints responsivos (mobile-first)',
1787
+ items: [
1788
+ { variant: 'sm', desc: '≥640px', example: 'sm:flex sm:flex-row' },
1789
+ { variant: 'md', desc: '≥768px', example: 'md:grid md:grid-cols-2' },
1790
+ { variant: 'lg', desc: '≥1024px', example: 'lg:grid-cols-3' },
1791
+ { variant: 'xl', desc: '≥1280px', example: 'xl:grid-cols-4' },
1792
+ { variant: '2xl', desc: '≥1536px', example: '2xl:max-w-7xl' },
1793
+ { variant: 'min-[{n}px]', desc: 'Breakpoint customizado', example: 'min-[320px]:text-sm' },
1794
+ { variant: 'max-sm', desc: '<640px', example: 'max-sm:hidden' },
1795
+ { variant: 'max-md', desc: '<768px', example: 'max-md:flex-col' },
1796
+ { variant: 'max-lg', desc: '<1024px', example: 'max-lg:px-4' },
1797
+ { variant: 'max-xl', desc: '<1280px', example: 'max-xl:grid-cols-2' },
1798
+ { variant: 'max-2xl', desc: '<1536px', example: 'max-2xl:container' },
1799
+ { variant: 'max-[{n}px]', desc: 'Max breakpoint custom', example: 'max-[600px]:text-xs' },
1800
+ { variant: '@sm', desc: 'Container query ≥320px', example: '@sm:flex' },
1801
+ { variant: '@md', desc: 'Container query ≥384px', example: '@md:grid-cols-2' },
1802
+ { variant: '@lg', desc: 'Container query ≥512px', example: '@lg:p-6' },
1803
+ { variant: '@xl', desc: 'Container query ≥672px', example: '@xl:text-lg' },
1804
+ { variant: '@[{n}px]', desc: 'Container query custom', example: '@[400px]:flex-row' },
1805
+ ],
1806
+ },
1807
+ 'dark-mode': {
1808
+ desc: 'Modo escuro e preferências de mídia',
1809
+ items: [
1810
+ { variant: 'dark', desc: 'Modo escuro', example: 'dark:bg-gray-900 dark:text-white' },
1811
+ { variant: 'motion-safe', desc: 'Animações permitidas', example: 'motion-safe:animate-bounce' },
1812
+ { variant: 'motion-reduce', desc: 'Animações reduzidas', example: 'motion-reduce:animate-none' },
1813
+ { variant: 'contrast-more', desc: 'Alto contraste', example: 'contrast-more:border-2' },
1814
+ { variant: 'contrast-less', desc: 'Baixo contraste', example: 'contrast-less:opacity-80' },
1815
+ { variant: 'print', desc: 'Impressão', example: 'print:hidden print:text-black' },
1816
+ { variant: 'portrait', desc: 'Orientação retrato', example: 'portrait:flex-col' },
1817
+ { variant: 'landscape', desc: 'Orientação paisagem', example: 'landscape:flex-row' },
1818
+ ],
1819
+ },
1820
+ state: {
1821
+ desc: 'Estados especiais',
1822
+ items: [
1823
+ { variant: 'open', desc: 'Elemento open (details, dialog)', example: 'open:bg-white open:shadow-lg' },
1824
+ { variant: 'closed', desc: 'Elemento fechado', example: 'closed:opacity-0' },
1825
+ { variant: 'modal', desc: 'Dialog modal', example: 'modal:backdrop:bg-black/50' },
1826
+ { variant: 'fullscreen', desc: 'Modo fullscreen', example: 'fullscreen:p-0' },
1827
+ { variant: 'starting', desc: 'Estado inicial (v4)', example: 'starting:opacity-0' },
1828
+ { variant: 'inert', desc: 'Elemento inert', example: 'inert:opacity-50' },
1829
+ ],
1830
+ },
1831
+ compound: {
1832
+ desc: 'Variants compostos (group, peer, has)',
1833
+ items: [
1834
+ { variant: 'group-hover', desc: 'Hover no elemento pai .group', example: 'group-hover:text-blue-500' },
1835
+ { variant: 'group-focus', desc: 'Focus no elemento pai .group', example: 'group-focus:ring-2' },
1836
+ { variant: 'group-active', desc: 'Active no elemento pai .group', example: 'group-active:scale-95' },
1837
+ { variant: 'group-[.custom]', desc: 'Seletor custom no group', example: 'group-[.is-open]:block' },
1838
+ { variant: 'peer-hover', desc: 'Hover no irmão .peer', example: 'peer-hover:visible' },
1839
+ { variant: 'peer-focus', desc: 'Focus no irmão .peer', example: 'peer-focus:ring-2' },
1840
+ { variant: 'peer-checked', desc: 'Peer checkbox marcado', example: 'peer-checked:bg-blue-500' },
1841
+ { variant: 'peer-invalid', desc: 'Peer input inválido', example: 'peer-invalid:text-red-500' },
1842
+ { variant: 'peer-[.custom]', desc: 'Seletor custom no peer', example: 'peer-[.is-active]:font-bold' },
1843
+ { variant: 'has-[selector]', desc: 'Contém elemento (v4)', example: 'has-[input:focus]:ring-2' },
1844
+ { variant: 'has-checked', desc: 'Contém checkbox marcado', example: 'has-checked:bg-blue-100' },
1845
+ { variant: 'in-[selector]', desc: 'Está dentro de (v4)', example: 'in-[.dark]:text-white' },
1846
+ { variant: 'not-[selector]', desc: 'Negação (v4)', example: 'not-[.active]:opacity-50' },
1847
+ ],
1848
+ },
1849
+ aria: {
1850
+ desc: 'Atributos ARIA para acessibilidade',
1851
+ items: [
1852
+ { variant: 'aria-checked', desc: 'aria-checked="true"', example: 'aria-checked:bg-blue-500' },
1853
+ { variant: 'aria-disabled', desc: 'aria-disabled="true"', example: 'aria-disabled:opacity-50' },
1854
+ { variant: 'aria-expanded', desc: 'aria-expanded="true"', example: 'aria-expanded:rotate-180' },
1855
+ { variant: 'aria-hidden', desc: 'aria-hidden="true"', example: 'aria-hidden:invisible' },
1856
+ { variant: 'aria-pressed', desc: 'aria-pressed="true"', example: 'aria-pressed:bg-gray-700' },
1857
+ { variant: 'aria-selected', desc: 'aria-selected="true"', example: 'aria-selected:border-blue-500' },
1858
+ { variant: 'aria-required', desc: 'aria-required="true"', example: 'aria-required:border-red-500' },
1859
+ { variant: 'aria-invalid', desc: 'aria-invalid="true"', example: 'aria-invalid:border-red-500' },
1860
+ { variant: 'aria-busy', desc: 'aria-busy="true"', example: 'aria-busy:animate-pulse' },
1861
+ { variant: 'aria-[attr=value]', desc: 'ARIA customizado', example: 'aria-[current=page]:font-bold' },
1862
+ ],
1863
+ },
1864
+ data: {
1865
+ desc: 'Atributos data-*',
1866
+ items: [
1867
+ { variant: 'data-[state=open]', desc: 'data-state="open"', example: 'data-[state=open]:bg-white' },
1868
+ { variant: 'data-[state=closed]', desc: 'data-state="closed"', example: 'data-[state=closed]:hidden' },
1869
+ { variant: 'data-[active]', desc: 'data-active presente', example: 'data-[active]:font-bold' },
1870
+ { variant: 'data-[disabled]', desc: 'data-disabled presente', example: 'data-[disabled]:opacity-50' },
1871
+ { variant: 'data-[selected=true]', desc: 'data-selected="true"', example: 'data-[selected=true]:bg-blue-100' },
1872
+ { variant: 'data-[orientation=vertical]', desc: 'Orientação vertical', example: 'data-[orientation=vertical]:flex-col' },
1873
+ { variant: 'data-[side=left]', desc: 'Posição lado', example: 'data-[side=left]:mr-2' },
1874
+ ],
1875
+ },
1876
+ };
1877
+ if (!tipo) {
1878
+ let result = '# 🎯 Variants do Tailwind CSS\n\n';
1879
+ result += 'Variants são modificadores que aplicam estilos condicionalmente.\n\n';
1880
+ result += '**Sintaxe:** `variant:classe` → `hover:bg-blue-500`\n\n';
1881
+ result += '**Empilhamento:** `variant1:variant2:classe` → `dark:hover:bg-blue-600`\n\n';
1882
+ result += '| Tipo | Descrição | Variants |\n';
1883
+ result += '|------|-----------|----------|\n';
1884
+ for (const [key, value] of Object.entries(variants)) {
1885
+ result += `| \`${key}\` | ${value.desc} | ${value.items.length} |\n`;
1886
+ }
1887
+ result += '\n**Exemplo:** `tailwind_variants({ tipo: "responsive" })`\n';
1888
+ return { content: [{ type: 'text', text: result }] };
1889
+ }
1890
+ const varType = variants[tipo];
1891
+ if (!varType) {
1892
+ return {
1893
+ content: [{ type: 'text', text: `❌ Tipo não encontrado: ${tipo}\n\nTipos disponíveis: ${Object.keys(variants).join(', ')}` }],
1894
+ isError: true,
1895
+ };
1896
+ }
1897
+ let result = `# 🎯 Variants: ${tipo}\n\n`;
1898
+ result += `**${varType.desc}**\n\n`;
1899
+ result += '| Variant | Descrição | Exemplo |\n';
1900
+ result += '|---------|-----------|----------|\n';
1901
+ for (const v of varType.items) {
1902
+ result += `| \`${v.variant}:\` | ${v.desc} | \`${v.example}\` |\n`;
1903
+ }
1904
+ result += `\n**Total:** ${varType.items.length} variants\n`;
1905
+ return { content: [{ type: 'text', text: result }] };
1906
+ }
1907
+ case 'tailwind_cores': {
1908
+ const corArg = args?.cor;
1909
+ const colors = {
1910
+ slate: { '50': '#f8fafc', '100': '#f1f5f9', '200': '#e2e8f0', '300': '#cbd5e1', '400': '#94a3b8', '500': '#64748b', '600': '#475569', '700': '#334155', '800': '#1e293b', '900': '#0f172a', '950': '#020617' },
1911
+ gray: { '50': '#f9fafb', '100': '#f3f4f6', '200': '#e5e7eb', '300': '#d1d5db', '400': '#9ca3af', '500': '#6b7280', '600': '#4b5563', '700': '#374151', '800': '#1f2937', '900': '#111827', '950': '#030712' },
1912
+ zinc: { '50': '#fafafa', '100': '#f4f4f5', '200': '#e4e4e7', '300': '#d4d4d8', '400': '#a1a1aa', '500': '#71717a', '600': '#52525b', '700': '#3f3f46', '800': '#27272a', '900': '#18181b', '950': '#09090b' },
1913
+ neutral: { '50': '#fafafa', '100': '#f5f5f5', '200': '#e5e5e5', '300': '#d4d4d4', '400': '#a3a3a3', '500': '#737373', '600': '#525252', '700': '#404040', '800': '#262626', '900': '#171717', '950': '#0a0a0a' },
1914
+ stone: { '50': '#fafaf9', '100': '#f5f5f4', '200': '#e7e5e4', '300': '#d6d3d1', '400': '#a8a29e', '500': '#78716c', '600': '#57534e', '700': '#44403c', '800': '#292524', '900': '#1c1917', '950': '#0c0a09' },
1915
+ red: { '50': '#fef2f2', '100': '#fee2e2', '200': '#fecaca', '300': '#fca5a5', '400': '#f87171', '500': '#ef4444', '600': '#dc2626', '700': '#b91c1c', '800': '#991b1b', '900': '#7f1d1d', '950': '#450a0a' },
1916
+ orange: { '50': '#fff7ed', '100': '#ffedd5', '200': '#fed7aa', '300': '#fdba74', '400': '#fb923c', '500': '#f97316', '600': '#ea580c', '700': '#c2410c', '800': '#9a3412', '900': '#7c2d12', '950': '#431407' },
1917
+ amber: { '50': '#fffbeb', '100': '#fef3c7', '200': '#fde68a', '300': '#fcd34d', '400': '#fbbf24', '500': '#f59e0b', '600': '#d97706', '700': '#b45309', '800': '#92400e', '900': '#78350f', '950': '#451a03' },
1918
+ yellow: { '50': '#fefce8', '100': '#fef9c3', '200': '#fef08a', '300': '#fde047', '400': '#facc15', '500': '#eab308', '600': '#ca8a04', '700': '#a16207', '800': '#854d0e', '900': '#713f12', '950': '#422006' },
1919
+ lime: { '50': '#f7fee7', '100': '#ecfccb', '200': '#d9f99d', '300': '#bef264', '400': '#a3e635', '500': '#84cc16', '600': '#65a30d', '700': '#4d7c0f', '800': '#3f6212', '900': '#365314', '950': '#1a2e05' },
1920
+ green: { '50': '#f0fdf4', '100': '#dcfce7', '200': '#bbf7d0', '300': '#86efac', '400': '#4ade80', '500': '#22c55e', '600': '#16a34a', '700': '#15803d', '800': '#166534', '900': '#14532d', '950': '#052e16' },
1921
+ emerald: { '50': '#ecfdf5', '100': '#d1fae5', '200': '#a7f3d0', '300': '#6ee7b7', '400': '#34d399', '500': '#10b981', '600': '#059669', '700': '#047857', '800': '#065f46', '900': '#064e3b', '950': '#022c22' },
1922
+ teal: { '50': '#f0fdfa', '100': '#ccfbf1', '200': '#99f6e4', '300': '#5eead4', '400': '#2dd4bf', '500': '#14b8a6', '600': '#0d9488', '700': '#0f766e', '800': '#115e59', '900': '#134e4a', '950': '#042f2e' },
1923
+ cyan: { '50': '#ecfeff', '100': '#cffafe', '200': '#a5f3fc', '300': '#67e8f9', '400': '#22d3ee', '500': '#06b6d4', '600': '#0891b2', '700': '#0e7490', '800': '#155e75', '900': '#164e63', '950': '#083344' },
1924
+ sky: { '50': '#f0f9ff', '100': '#e0f2fe', '200': '#bae6fd', '300': '#7dd3fc', '400': '#38bdf8', '500': '#0ea5e9', '600': '#0284c7', '700': '#0369a1', '800': '#075985', '900': '#0c4a6e', '950': '#082f49' },
1925
+ blue: { '50': '#eff6ff', '100': '#dbeafe', '200': '#bfdbfe', '300': '#93c5fd', '400': '#60a5fa', '500': '#3b82f6', '600': '#2563eb', '700': '#1d4ed8', '800': '#1e40af', '900': '#1e3a8a', '950': '#172554' },
1926
+ indigo: { '50': '#eef2ff', '100': '#e0e7ff', '200': '#c7d2fe', '300': '#a5b4fc', '400': '#818cf8', '500': '#6366f1', '600': '#4f46e5', '700': '#4338ca', '800': '#3730a3', '900': '#312e81', '950': '#1e1b4b' },
1927
+ violet: { '50': '#f5f3ff', '100': '#ede9fe', '200': '#ddd6fe', '300': '#c4b5fd', '400': '#a78bfa', '500': '#8b5cf6', '600': '#7c3aed', '700': '#6d28d9', '800': '#5b21b6', '900': '#4c1d95', '950': '#2e1065' },
1928
+ purple: { '50': '#faf5ff', '100': '#f3e8ff', '200': '#e9d5ff', '300': '#d8b4fe', '400': '#c084fc', '500': '#a855f7', '600': '#9333ea', '700': '#7e22ce', '800': '#6b21a8', '900': '#581c87', '950': '#3b0764' },
1929
+ fuchsia: { '50': '#fdf4ff', '100': '#fae8ff', '200': '#f5d0fe', '300': '#f0abfc', '400': '#e879f9', '500': '#d946ef', '600': '#c026d3', '700': '#a21caf', '800': '#86198f', '900': '#701a75', '950': '#4a044e' },
1930
+ pink: { '50': '#fdf2f8', '100': '#fce7f3', '200': '#fbcfe8', '300': '#f9a8d4', '400': '#f472b6', '500': '#ec4899', '600': '#db2777', '700': '#be185d', '800': '#9d174d', '900': '#831843', '950': '#500724' },
1931
+ rose: { '50': '#fff1f2', '100': '#ffe4e6', '200': '#fecdd3', '300': '#fda4af', '400': '#fb7185', '500': '#f43f5e', '600': '#e11d48', '700': '#be123c', '800': '#9f1239', '900': '#881337', '950': '#4c0519' },
1932
+ };
1933
+ const specialColors = {
1934
+ inherit: 'Herda do pai',
1935
+ current: 'currentColor',
1936
+ transparent: 'transparent',
1937
+ black: '#000000',
1938
+ white: '#ffffff',
1939
+ };
1940
+ if (!corArg) {
1941
+ let result = '# 🎨 Paleta de Cores do Tailwind CSS\n\n';
1942
+ result += '## Cores Especiais\n\n';
1943
+ result += '| Classe | Valor |\n';
1944
+ result += '|--------|-------|\n';
1945
+ for (const [name, value] of Object.entries(specialColors)) {
1946
+ result += `| \`{type}-${name}\` | ${value} |\n`;
1947
+ }
1948
+ result += '\n## Paleta Completa\n\n';
1949
+ result += 'Use `tailwind_cores({ cor: "blue" })` para ver uma cor específica.\n\n';
1950
+ result += '| Cor | Preview (500) | Escalas |\n';
1951
+ result += '|-----|---------------|--------|\n';
1952
+ for (const [name, shades] of Object.entries(colors)) {
1953
+ result += `| \`${name}\` | ${shades['500']} | 50-950 |\n`;
1954
+ }
1955
+ result += '\n**Uso:** `text-{cor}-{escala}`, `bg-{cor}-{escala}`, `border-{cor}-{escala}`\n';
1956
+ result += '\n**Exemplo:** `bg-blue-500`, `text-gray-900`, `border-red-300`\n';
1957
+ return { content: [{ type: 'text', text: result }] };
1958
+ }
1959
+ const colorShades = colors[corArg];
1960
+ if (!colorShades) {
1961
+ return {
1962
+ content: [{ type: 'text', text: `❌ Cor não encontrada: ${corArg}\n\nCores disponíveis: ${Object.keys(colors).join(', ')}` }],
1963
+ isError: true,
1964
+ };
1965
+ }
1966
+ let result = `# 🎨 Cor: ${corArg}\n\n`;
1967
+ result += '| Escala | Hex | Classes |\n';
1968
+ result += '|--------|-----|--------|\n';
1969
+ for (const [shade, hex] of Object.entries(colorShades)) {
1970
+ result += `| ${shade} | ${hex} | \`text-${corArg}-${shade}\` \`bg-${corArg}-${shade}\` \`border-${corArg}-${shade}\` |\n`;
1971
+ }
1972
+ result += `\n**Exemplos de uso:**\n`;
1973
+ result += '```html\n';
1974
+ result += `<div class="bg-${corArg}-500 text-white">Background</div>\n`;
1975
+ result += `<p class="text-${corArg}-700">Texto</p>\n`;
1976
+ result += `<div class="border border-${corArg}-300">Border</div>\n`;
1977
+ result += `<div class="ring-2 ring-${corArg}-500">Ring</div>\n`;
1978
+ result += '```\n';
1979
+ return { content: [{ type: 'text', text: result }] };
1980
+ }
1981
+ case 'tailwind_spacing': {
1982
+ const spacing = [
1983
+ { key: '0', rem: '0', px: '0px' },
1984
+ { key: 'px', rem: '1px', px: '1px' },
1985
+ { key: '0.5', rem: '0.125rem', px: '2px' },
1986
+ { key: '1', rem: '0.25rem', px: '4px' },
1987
+ { key: '1.5', rem: '0.375rem', px: '6px' },
1988
+ { key: '2', rem: '0.5rem', px: '8px' },
1989
+ { key: '2.5', rem: '0.625rem', px: '10px' },
1990
+ { key: '3', rem: '0.75rem', px: '12px' },
1991
+ { key: '3.5', rem: '0.875rem', px: '14px' },
1992
+ { key: '4', rem: '1rem', px: '16px' },
1993
+ { key: '5', rem: '1.25rem', px: '20px' },
1994
+ { key: '6', rem: '1.5rem', px: '24px' },
1995
+ { key: '7', rem: '1.75rem', px: '28px' },
1996
+ { key: '8', rem: '2rem', px: '32px' },
1997
+ { key: '9', rem: '2.25rem', px: '36px' },
1998
+ { key: '10', rem: '2.5rem', px: '40px' },
1999
+ { key: '11', rem: '2.75rem', px: '44px' },
2000
+ { key: '12', rem: '3rem', px: '48px' },
2001
+ { key: '14', rem: '3.5rem', px: '56px' },
2002
+ { key: '16', rem: '4rem', px: '64px' },
2003
+ { key: '20', rem: '5rem', px: '80px' },
2004
+ { key: '24', rem: '6rem', px: '96px' },
2005
+ { key: '28', rem: '7rem', px: '112px' },
2006
+ { key: '32', rem: '8rem', px: '128px' },
2007
+ { key: '36', rem: '9rem', px: '144px' },
2008
+ { key: '40', rem: '10rem', px: '160px' },
2009
+ { key: '44', rem: '11rem', px: '176px' },
2010
+ { key: '48', rem: '12rem', px: '192px' },
2011
+ { key: '52', rem: '13rem', px: '208px' },
2012
+ { key: '56', rem: '14rem', px: '224px' },
2013
+ { key: '60', rem: '15rem', px: '240px' },
2014
+ { key: '64', rem: '16rem', px: '256px' },
2015
+ { key: '72', rem: '18rem', px: '288px' },
2016
+ { key: '80', rem: '20rem', px: '320px' },
2017
+ { key: '96', rem: '24rem', px: '384px' },
2018
+ ];
2019
+ let result = '# 📏 Escala de Espaçamento do Tailwind CSS\n\n';
2020
+ result += 'A escala de spacing é usada para margin, padding, gap, width, height, e outras propriedades.\n\n';
2021
+ result += '| Valor | Rem | Pixels | Exemplo Classes |\n';
2022
+ result += '|-------|-----|--------|----------------|\n';
2023
+ for (const s of spacing) {
2024
+ result += `| \`${s.key}\` | ${s.rem} | ${s.px} | \`p-${s.key}\` \`m-${s.key}\` \`gap-${s.key}\` \`w-${s.key}\` |\n`;
2025
+ }
2026
+ result += '\n## Valores Especiais\n\n';
2027
+ result += '| Valor | Descrição | Exemplo |\n';
2028
+ result += '|-------|-----------|--------|\n';
2029
+ result += '| `auto` | auto | `m-auto`, `ml-auto` |\n';
2030
+ result += '| `full` | 100% | `w-full`, `h-full` |\n';
2031
+ result += '| `screen` | 100vw/100vh | `w-screen`, `h-screen` |\n';
2032
+ result += '| `svh/lvh/dvh` | viewport units | `h-svh`, `h-lvh`, `h-dvh` |\n';
2033
+ result += '| `min` | min-content | `w-min`, `h-min` |\n';
2034
+ result += '| `max` | max-content | `w-max`, `h-max` |\n';
2035
+ result += '| `fit` | fit-content | `w-fit`, `h-fit` |\n';
2036
+ result += '\n## Frações (Width/Basis)\n\n';
2037
+ result += '| Valor | CSS | Exemplo |\n';
2038
+ result += '|-------|-----|--------|\n';
2039
+ result += '| `1/2` | 50% | `w-1/2`, `basis-1/2` |\n';
2040
+ result += '| `1/3` | 33.333% | `w-1/3`, `basis-1/3` |\n';
2041
+ result += '| `2/3` | 66.666% | `w-2/3`, `basis-2/3` |\n';
2042
+ result += '| `1/4` | 25% | `w-1/4`, `basis-1/4` |\n';
2043
+ result += '| `3/4` | 75% | `w-3/4`, `basis-3/4` |\n';
2044
+ result += '| `1/5` | 20% | `w-1/5`, `basis-1/5` |\n';
2045
+ result += '| `2/5` | 40% | `w-2/5`, `basis-2/5` |\n';
2046
+ result += '| `3/5` | 60% | `w-3/5`, `basis-3/5` |\n';
2047
+ result += '| `4/5` | 80% | `w-4/5`, `basis-4/5` |\n';
2048
+ result += '| `1/6` | 16.666% | `w-1/6`, `basis-1/6` |\n';
2049
+ result += '| `5/6` | 83.333% | `w-5/6`, `basis-5/6` |\n';
2050
+ result += '| `1/12` | 8.333% | `w-1/12`, `basis-1/12` |\n';
2051
+ return { content: [{ type: 'text', text: result }] };
2052
+ }
2053
+ case 'tailwind_breakpoints': {
2054
+ let result = '# 📱 Breakpoints Responsivos do Tailwind CSS\n\n';
2055
+ result += '## Breakpoints Padrão (Mobile-First)\n\n';
2056
+ result += '| Prefixo | Min-Width | CSS Media Query |\n';
2057
+ result += '|---------|-----------|----------------|\n';
2058
+ result += '| `sm:` | 640px | `@media (min-width: 640px)` |\n';
2059
+ result += '| `md:` | 768px | `@media (min-width: 768px)` |\n';
2060
+ result += '| `lg:` | 1024px | `@media (min-width: 1024px)` |\n';
2061
+ result += '| `xl:` | 1280px | `@media (min-width: 1280px)` |\n';
2062
+ result += '| `2xl:` | 1536px | `@media (min-width: 1536px)` |\n';
2063
+ result += '\n## Max-Width Variants\n\n';
2064
+ result += '| Prefixo | Max-Width | CSS Media Query |\n';
2065
+ result += '|---------|-----------|----------------|\n';
2066
+ result += '| `max-sm:` | <640px | `@media (max-width: 639px)` |\n';
2067
+ result += '| `max-md:` | <768px | `@media (max-width: 767px)` |\n';
2068
+ result += '| `max-lg:` | <1024px | `@media (max-width: 1023px)` |\n';
2069
+ result += '| `max-xl:` | <1280px | `@media (max-width: 1279px)` |\n';
2070
+ result += '| `max-2xl:` | <1536px | `@media (max-width: 1535px)` |\n';
2071
+ result += '\n## Breakpoints Arbitrários\n\n';
2072
+ result += '```html\n';
2073
+ result += '<!-- Min-width customizado -->\n';
2074
+ result += '<div class="min-[320px]:text-sm min-[480px]:text-base">\n\n';
2075
+ result += '<!-- Max-width customizado -->\n';
2076
+ result += '<div class="max-[600px]:hidden">\n';
2077
+ result += '```\n';
2078
+ result += '\n## Container Queries (v4)\n\n';
2079
+ result += '| Prefixo | Container Width | Uso |\n';
2080
+ result += '|---------|----------------|-----|\n';
2081
+ result += '| `@xs:` | ≥320px | `@xs:flex-row` |\n';
2082
+ result += '| `@sm:` | ≥384px | `@sm:grid-cols-2` |\n';
2083
+ result += '| `@md:` | ≥448px | `@md:p-6` |\n';
2084
+ result += '| `@lg:` | ≥512px | `@lg:text-lg` |\n';
2085
+ result += '| `@xl:` | ≥576px | `@xl:gap-8` |\n';
2086
+ result += '| `@2xl:` | ≥672px | `@2xl:grid-cols-4` |\n';
2087
+ result += '\n```html\n';
2088
+ result += '<!-- Uso de container queries -->\n';
2089
+ result += '<div class="@container">\n';
2090
+ result += ' <div class="@sm:flex @lg:grid @lg:grid-cols-2">\n';
2091
+ result += ' <!-- Responde ao tamanho do container pai -->\n';
2092
+ result += ' </div>\n';
2093
+ result += '</div>\n\n';
2094
+ result += '<!-- Container query arbitrário -->\n';
2095
+ result += '<div class="@[400px]:flex-row">\n';
2096
+ result += '```\n';
2097
+ result += '\n## Exemplo Responsivo Completo\n\n';
2098
+ result += '```html\n';
2099
+ result += '<div class="\n';
2100
+ result += ' flex flex-col /* Mobile: coluna */\n';
2101
+ result += ' sm:flex-row /* ≥640px: linha */\n';
2102
+ result += ' gap-2 sm:gap-4 /* Gap responsivo */\n';
2103
+ result += ' p-4 md:p-6 lg:p-8 /* Padding responsivo */\n';
2104
+ result += '">\n';
2105
+ result += ' <div class="w-full sm:w-1/2 lg:w-1/3">Item 1</div>\n';
2106
+ result += ' <div class="w-full sm:w-1/2 lg:w-1/3">Item 2</div>\n';
2107
+ result += ' <div class="hidden lg:block lg:w-1/3">Item 3</div>\n';
2108
+ result += '</div>\n';
2109
+ result += '```\n';
2110
+ return { content: [{ type: 'text', text: result }] };
2111
+ }
2112
+ case 'tailwind_receitas': {
2113
+ const componente = args?.componente;
2114
+ const receitas = {
2115
+ button: {
2116
+ desc: 'Botões com variantes',
2117
+ html: `<!-- Botão Primário -->
2118
+ <button class="px-4 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
2119
+ Botão Primário
2120
+ </button>
2121
+
2122
+ <!-- Botão Secundário -->
2123
+ <button class="px-4 py-2 bg-gray-200 text-gray-800 font-medium rounded-lg hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors">
2124
+ Botão Secundário
2125
+ </button>
2126
+
2127
+ <!-- Botão Outline -->
2128
+ <button class="px-4 py-2 border-2 border-blue-600 text-blue-600 font-medium rounded-lg hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
2129
+ Botão Outline
2130
+ </button>
2131
+
2132
+ <!-- Botão com Ícone -->
2133
+ <button class="inline-flex items-center gap-2 px-4 py-2 bg-green-600 text-white font-medium rounded-lg hover:bg-green-700">
2134
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2135
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
2136
+ </svg>
2137
+ Confirmar
2138
+ </button>
2139
+
2140
+ <!-- Botão Disabled -->
2141
+ <button disabled class="px-4 py-2 bg-gray-400 text-gray-200 font-medium rounded-lg cursor-not-allowed opacity-50">
2142
+ Desabilitado
2143
+ </button>
2144
+
2145
+ <!-- Botão Loading -->
2146
+ <button class="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg" disabled>
2147
+ <svg class="animate-spin h-5 w-5" viewBox="0 0 24 24">
2148
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"/>
2149
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/>
2150
+ </svg>
2151
+ Carregando...
2152
+ </button>`,
2153
+ },
2154
+ card: {
2155
+ desc: 'Cards com imagem, conteúdo e ações',
2156
+ html: `<!-- Card Básico -->
2157
+ <div class="max-w-sm bg-white rounded-xl shadow-md overflow-hidden">
2158
+ <img class="w-full h-48 object-cover" src="image.jpg" alt="Card image">
2159
+ <div class="p-6">
2160
+ <h3 class="text-xl font-bold text-gray-900 mb-2">Título do Card</h3>
2161
+ <p class="text-gray-600 mb-4">Descrição breve do conteúdo do card.</p>
2162
+ <a href="#" class="text-blue-600 hover:text-blue-800 font-medium">Saiba mais →</a>
2163
+ </div>
2164
+ </div>
2165
+
2166
+ <!-- Card Horizontal -->
2167
+ <div class="flex max-w-2xl bg-white rounded-xl shadow-md overflow-hidden">
2168
+ <img class="w-48 object-cover" src="image.jpg" alt="">
2169
+ <div class="p-6 flex flex-col justify-between">
2170
+ <div>
2171
+ <span class="text-sm text-blue-600 font-semibold">Categoria</span>
2172
+ <h3 class="text-xl font-bold text-gray-900 mt-1">Título do Card</h3>
2173
+ <p class="text-gray-600 mt-2">Descrição do conteúdo.</p>
2174
+ </div>
2175
+ <div class="flex items-center gap-4 mt-4">
2176
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-lg">Ação</button>
2177
+ </div>
2178
+ </div>
2179
+ </div>
2180
+
2181
+ <!-- Card com Footer -->
2182
+ <div class="max-w-sm bg-white rounded-xl shadow-md overflow-hidden">
2183
+ <div class="p-6">
2184
+ <h3 class="text-xl font-bold text-gray-900">Título</h3>
2185
+ <p class="text-gray-600 mt-2">Conteúdo do card.</p>
2186
+ </div>
2187
+ <div class="px-6 py-4 bg-gray-50 border-t flex justify-end gap-2">
2188
+ <button class="px-4 py-2 text-gray-600 hover:text-gray-800">Cancelar</button>
2189
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-lg">Salvar</button>
2190
+ </div>
2191
+ </div>`,
2192
+ },
2193
+ form: {
2194
+ desc: 'Formulário completo com validação visual',
2195
+ html: `<form class="max-w-md mx-auto space-y-6">
2196
+ <!-- Input com Label -->
2197
+ <div>
2198
+ <label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
2199
+ <input type="email" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors" placeholder="seu@email.com">
2200
+ </div>
2201
+
2202
+ <!-- Input com Erro -->
2203
+ <div>
2204
+ <label class="block text-sm font-medium text-gray-700 mb-1">Senha</label>
2205
+ <input type="password" class="w-full px-4 py-2 border border-red-500 rounded-lg focus:ring-2 focus:ring-red-500 focus:border-red-500 outline-none">
2206
+ <p class="mt-1 text-sm text-red-500">Senha deve ter no mínimo 8 caracteres</p>
2207
+ </div>
2208
+
2209
+ <!-- Select -->
2210
+ <div>
2211
+ <label class="block text-sm font-medium text-gray-700 mb-1">País</label>
2212
+ <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none bg-white">
2213
+ <option>Brasil</option>
2214
+ <option>Portugal</option>
2215
+ <option>EUA</option>
2216
+ </select>
2217
+ </div>
2218
+
2219
+ <!-- Checkbox -->
2220
+ <div class="flex items-center gap-2">
2221
+ <input type="checkbox" id="terms" class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
2222
+ <label for="terms" class="text-sm text-gray-700">Aceito os termos de uso</label>
2223
+ </div>
2224
+
2225
+ <!-- Submit -->
2226
+ <button type="submit" class="w-full px-4 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors">
2227
+ Enviar
2228
+ </button>
2229
+ </form>`,
2230
+ },
2231
+ input: {
2232
+ desc: 'Campos de input com variantes',
2233
+ html: `<!-- Input Padrão -->
2234
+ <input type="text" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none" placeholder="Digite aqui...">
2235
+
2236
+ <!-- Input com Ícone à Esquerda -->
2237
+ <div class="relative">
2238
+ <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
2239
+ <svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2240
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
2241
+ </svg>
2242
+ </div>
2243
+ <input type="search" class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="Buscar...">
2244
+ </div>
2245
+
2246
+ <!-- Input com Botão -->
2247
+ <div class="flex">
2248
+ <input type="email" class="flex-1 px-4 py-2 border border-r-0 border-gray-300 rounded-l-lg focus:ring-2 focus:ring-blue-500" placeholder="seu@email.com">
2249
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-r-lg hover:bg-blue-700">Inscrever</button>
2250
+ </div>
2251
+
2252
+ <!-- Textarea -->
2253
+ <textarea rows="4" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 resize-none" placeholder="Sua mensagem..."></textarea>`,
2254
+ },
2255
+ modal: {
2256
+ desc: 'Modal/Dialog com backdrop',
2257
+ html: `<!-- Modal Container -->
2258
+ <div class="fixed inset-0 z-50 flex items-center justify-center">
2259
+ <!-- Backdrop -->
2260
+ <div class="fixed inset-0 bg-black/50 backdrop-blur-sm"></div>
2261
+
2262
+ <!-- Modal -->
2263
+ <div class="relative bg-white rounded-xl shadow-2xl w-full max-w-md mx-4 overflow-hidden">
2264
+ <!-- Header -->
2265
+ <div class="flex items-center justify-between px-6 py-4 border-b">
2266
+ <h3 class="text-lg font-semibold text-gray-900">Título do Modal</h3>
2267
+ <button class="p-1 hover:bg-gray-100 rounded-lg">
2268
+ <svg class="w-5 h-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2269
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
2270
+ </svg>
2271
+ </button>
2272
+ </div>
2273
+
2274
+ <!-- Body -->
2275
+ <div class="px-6 py-4">
2276
+ <p class="text-gray-600">Conteúdo do modal aqui...</p>
2277
+ </div>
2278
+
2279
+ <!-- Footer -->
2280
+ <div class="flex justify-end gap-2 px-6 py-4 bg-gray-50 border-t">
2281
+ <button class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg">Cancelar</button>
2282
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">Confirmar</button>
2283
+ </div>
2284
+ </div>
2285
+ </div>`,
2286
+ },
2287
+ navbar: {
2288
+ desc: 'Navbar responsiva',
2289
+ html: `<nav class="bg-white shadow-md">
2290
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
2291
+ <div class="flex justify-between h-16">
2292
+ <!-- Logo -->
2293
+ <div class="flex items-center">
2294
+ <a href="#" class="text-xl font-bold text-blue-600">Logo</a>
2295
+ </div>
2296
+
2297
+ <!-- Desktop Menu -->
2298
+ <div class="hidden md:flex items-center gap-8">
2299
+ <a href="#" class="text-gray-600 hover:text-blue-600">Home</a>
2300
+ <a href="#" class="text-gray-600 hover:text-blue-600">Sobre</a>
2301
+ <a href="#" class="text-gray-600 hover:text-blue-600">Serviços</a>
2302
+ <a href="#" class="text-gray-600 hover:text-blue-600">Contato</a>
2303
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">Login</button>
2304
+ </div>
2305
+
2306
+ <!-- Mobile Menu Button -->
2307
+ <div class="md:hidden flex items-center">
2308
+ <button class="p-2 rounded-lg hover:bg-gray-100">
2309
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2310
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
2311
+ </svg>
2312
+ </button>
2313
+ </div>
2314
+ </div>
2315
+ </div>
2316
+
2317
+ <!-- Mobile Menu (toggle com JS) -->
2318
+ <div class="md:hidden border-t">
2319
+ <div class="px-4 py-2 space-y-1">
2320
+ <a href="#" class="block py-2 text-gray-600">Home</a>
2321
+ <a href="#" class="block py-2 text-gray-600">Sobre</a>
2322
+ <a href="#" class="block py-2 text-gray-600">Serviços</a>
2323
+ <a href="#" class="block py-2 text-gray-600">Contato</a>
2324
+ </div>
2325
+ </div>
2326
+ </nav>`,
2327
+ },
2328
+ footer: {
2329
+ desc: 'Footer com múltiplas colunas',
2330
+ html: `<footer class="bg-gray-900 text-gray-300">
2331
+ <div class="max-w-7xl mx-auto px-4 py-12 sm:px-6 lg:px-8">
2332
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
2333
+ <!-- Brand -->
2334
+ <div>
2335
+ <h3 class="text-white text-lg font-bold mb-4">Empresa</h3>
2336
+ <p class="text-sm">Descrição breve da empresa ou produto.</p>
2337
+ </div>
2338
+
2339
+ <!-- Links -->
2340
+ <div>
2341
+ <h4 class="text-white font-semibold mb-4">Produto</h4>
2342
+ <ul class="space-y-2 text-sm">
2343
+ <li><a href="#" class="hover:text-white">Features</a></li>
2344
+ <li><a href="#" class="hover:text-white">Preços</a></li>
2345
+ <li><a href="#" class="hover:text-white">FAQ</a></li>
2346
+ </ul>
2347
+ </div>
2348
+
2349
+ <div>
2350
+ <h4 class="text-white font-semibold mb-4">Empresa</h4>
2351
+ <ul class="space-y-2 text-sm">
2352
+ <li><a href="#" class="hover:text-white">Sobre</a></li>
2353
+ <li><a href="#" class="hover:text-white">Blog</a></li>
2354
+ <li><a href="#" class="hover:text-white">Carreiras</a></li>
2355
+ </ul>
2356
+ </div>
2357
+
2358
+ <div>
2359
+ <h4 class="text-white font-semibold mb-4">Legal</h4>
2360
+ <ul class="space-y-2 text-sm">
2361
+ <li><a href="#" class="hover:text-white">Privacidade</a></li>
2362
+ <li><a href="#" class="hover:text-white">Termos</a></li>
2363
+ </ul>
2364
+ </div>
2365
+ </div>
2366
+
2367
+ <div class="border-t border-gray-800 mt-8 pt-8 flex flex-col md:flex-row justify-between items-center">
2368
+ <p class="text-sm">© 2024 Empresa. Todos os direitos reservados.</p>
2369
+ <div class="flex gap-4 mt-4 md:mt-0">
2370
+ <a href="#" class="hover:text-white">Twitter</a>
2371
+ <a href="#" class="hover:text-white">GitHub</a>
2372
+ <a href="#" class="hover:text-white">LinkedIn</a>
2373
+ </div>
2374
+ </div>
2375
+ </div>
2376
+ </footer>`,
2377
+ },
2378
+ hero: {
2379
+ desc: 'Hero section para landing pages',
2380
+ html: `<!-- Hero com Background -->
2381
+ <section class="relative bg-gradient-to-br from-blue-600 to-purple-700 text-white">
2382
+ <div class="max-w-7xl mx-auto px-4 py-24 sm:px-6 lg:px-8">
2383
+ <div class="text-center">
2384
+ <h1 class="text-4xl md:text-6xl font-bold mb-6">
2385
+ Título Impactante
2386
+ </h1>
2387
+ <p class="text-xl md:text-2xl text-blue-100 mb-8 max-w-2xl mx-auto">
2388
+ Subtítulo explicando o valor do seu produto ou serviço.
2389
+ </p>
2390
+ <div class="flex flex-col sm:flex-row gap-4 justify-center">
2391
+ <button class="px-8 py-3 bg-white text-blue-600 font-semibold rounded-lg hover:bg-blue-50">
2392
+ Começar Agora
2393
+ </button>
2394
+ <button class="px-8 py-3 border-2 border-white text-white font-semibold rounded-lg hover:bg-white/10">
2395
+ Saiba Mais
2396
+ </button>
2397
+ </div>
2398
+ </div>
2399
+ </div>
2400
+ </section>
2401
+
2402
+ <!-- Hero com Imagem -->
2403
+ <section class="bg-white">
2404
+ <div class="max-w-7xl mx-auto px-4 py-16 sm:px-6 lg:px-8">
2405
+ <div class="grid md:grid-cols-2 gap-12 items-center">
2406
+ <div>
2407
+ <h1 class="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
2408
+ Título Principal
2409
+ </h1>
2410
+ <p class="text-xl text-gray-600 mb-8">
2411
+ Descrição do produto com benefícios claros para o usuário.
2412
+ </p>
2413
+ <button class="px-8 py-3 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700">
2414
+ Call to Action
2415
+ </button>
2416
+ </div>
2417
+ <div>
2418
+ <img src="hero-image.png" alt="Hero" class="rounded-xl shadow-2xl">
2419
+ </div>
2420
+ </div>
2421
+ </div>
2422
+ </section>`,
2423
+ },
2424
+ grid: {
2425
+ desc: 'Grid responsivo para layouts',
2426
+ html: `<!-- Grid de 3 colunas responsivo -->
2427
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
2428
+ <div class="p-6 bg-white rounded-lg shadow">Item 1</div>
2429
+ <div class="p-6 bg-white rounded-lg shadow">Item 2</div>
2430
+ <div class="p-6 bg-white rounded-lg shadow">Item 3</div>
2431
+ </div>
2432
+
2433
+ <!-- Grid de 4 colunas com span -->
2434
+ <div class="grid grid-cols-4 gap-4">
2435
+ <div class="col-span-4 md:col-span-2 lg:col-span-1 p-4 bg-blue-100 rounded">1</div>
2436
+ <div class="col-span-4 md:col-span-2 lg:col-span-1 p-4 bg-blue-200 rounded">2</div>
2437
+ <div class="col-span-4 md:col-span-2 lg:col-span-1 p-4 bg-blue-300 rounded">3</div>
2438
+ <div class="col-span-4 md:col-span-2 lg:col-span-1 p-4 bg-blue-400 rounded">4</div>
2439
+ </div>
2440
+
2441
+ <!-- Grid de 12 colunas (dashboard) -->
2442
+ <div class="grid grid-cols-12 gap-4">
2443
+ <div class="col-span-12 lg:col-span-8 p-6 bg-white rounded-lg shadow">Conteúdo Principal</div>
2444
+ <div class="col-span-12 lg:col-span-4 p-6 bg-white rounded-lg shadow">Sidebar</div>
2445
+ <div class="col-span-12 md:col-span-6 lg:col-span-4 p-6 bg-white rounded-lg shadow">Card 1</div>
2446
+ <div class="col-span-12 md:col-span-6 lg:col-span-4 p-6 bg-white rounded-lg shadow">Card 2</div>
2447
+ <div class="col-span-12 md:col-span-12 lg:col-span-4 p-6 bg-white rounded-lg shadow">Card 3</div>
2448
+ </div>
2449
+
2450
+ <!-- Auto-fit Grid -->
2451
+ <div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
2452
+ <div class="p-6 bg-white rounded-lg shadow">Auto 1</div>
2453
+ <div class="p-6 bg-white rounded-lg shadow">Auto 2</div>
2454
+ <div class="p-6 bg-white rounded-lg shadow">Auto 3</div>
2455
+ <div class="p-6 bg-white rounded-lg shadow">Auto 4</div>
2456
+ </div>`,
2457
+ },
2458
+ alert: {
2459
+ desc: 'Alertas e notificações',
2460
+ html: `<!-- Alert Info -->
2461
+ <div class="flex items-center gap-3 p-4 bg-blue-50 border border-blue-200 text-blue-800 rounded-lg">
2462
+ <svg class="w-5 h-5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
2463
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
2464
+ </svg>
2465
+ <p>Informação importante para o usuário.</p>
2466
+ </div>
2467
+
2468
+ <!-- Alert Success -->
2469
+ <div class="flex items-center gap-3 p-4 bg-green-50 border border-green-200 text-green-800 rounded-lg">
2470
+ <svg class="w-5 h-5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
2471
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
2472
+ </svg>
2473
+ <p>Operação realizada com sucesso!</p>
2474
+ </div>
2475
+
2476
+ <!-- Alert Warning -->
2477
+ <div class="flex items-center gap-3 p-4 bg-yellow-50 border border-yellow-200 text-yellow-800 rounded-lg">
2478
+ <svg class="w-5 h-5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
2479
+ <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
2480
+ </svg>
2481
+ <p>Atenção! Verifique os dados antes de continuar.</p>
2482
+ </div>
2483
+
2484
+ <!-- Alert Error -->
2485
+ <div class="flex items-center gap-3 p-4 bg-red-50 border border-red-200 text-red-800 rounded-lg">
2486
+ <svg class="w-5 h-5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
2487
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
2488
+ </svg>
2489
+ <p>Erro! Algo deu errado. Tente novamente.</p>
2490
+ </div>
2491
+
2492
+ <!-- Alert Dismissible -->
2493
+ <div class="flex items-center justify-between gap-3 p-4 bg-blue-50 border border-blue-200 text-blue-800 rounded-lg">
2494
+ <p>Notificação que pode ser fechada.</p>
2495
+ <button class="p-1 hover:bg-blue-100 rounded">
2496
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
2497
+ <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
2498
+ </svg>
2499
+ </button>
2500
+ </div>`,
2501
+ },
2502
+ badge: {
2503
+ desc: 'Badges e tags',
2504
+ html: `<!-- Badges Coloridos -->
2505
+ <span class="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">Novo</span>
2506
+ <span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded-full">Ativo</span>
2507
+ <span class="px-2 py-1 text-xs font-medium bg-yellow-100 text-yellow-800 rounded-full">Pendente</span>
2508
+ <span class="px-2 py-1 text-xs font-medium bg-red-100 text-red-800 rounded-full">Urgente</span>
2509
+ <span class="px-2 py-1 text-xs font-medium bg-gray-100 text-gray-800 rounded-full">Default</span>
2510
+
2511
+ <!-- Badge com Dot -->
2512
+ <span class="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded-full">
2513
+ <span class="w-2 h-2 bg-green-500 rounded-full"></span>
2514
+ Online
2515
+ </span>
2516
+
2517
+ <!-- Badge Pill -->
2518
+ <span class="px-3 py-1 text-sm font-semibold bg-purple-600 text-white rounded-full">PRO</span>
2519
+
2520
+ <!-- Badge com Ícone -->
2521
+ <span class="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded">
2522
+ <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
2523
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
2524
+ </svg>
2525
+ Verificado
2526
+ </span>`,
2527
+ },
2528
+ avatar: {
2529
+ desc: 'Avatares e fotos de perfil',
2530
+ html: `<!-- Avatar Circular -->
2531
+ <img class="w-12 h-12 rounded-full object-cover" src="avatar.jpg" alt="Avatar">
2532
+
2533
+ <!-- Avatar com Iniciais -->
2534
+ <div class="w-12 h-12 rounded-full bg-blue-500 flex items-center justify-center text-white font-semibold">
2535
+ JD
2536
+ </div>
2537
+
2538
+ <!-- Avatar com Status -->
2539
+ <div class="relative">
2540
+ <img class="w-12 h-12 rounded-full object-cover" src="avatar.jpg" alt="">
2541
+ <span class="absolute bottom-0 right-0 w-3 h-3 bg-green-500 border-2 border-white rounded-full"></span>
2542
+ </div>
2543
+
2544
+ <!-- Avatar Group -->
2545
+ <div class="flex -space-x-2">
2546
+ <img class="w-10 h-10 rounded-full border-2 border-white" src="avatar1.jpg" alt="">
2547
+ <img class="w-10 h-10 rounded-full border-2 border-white" src="avatar2.jpg" alt="">
2548
+ <img class="w-10 h-10 rounded-full border-2 border-white" src="avatar3.jpg" alt="">
2549
+ <div class="w-10 h-10 rounded-full border-2 border-white bg-gray-200 flex items-center justify-center text-sm text-gray-600">+5</div>
2550
+ </div>
2551
+
2552
+ <!-- Avatar Tamanhos -->
2553
+ <img class="w-8 h-8 rounded-full" src="avatar.jpg" alt="XS">
2554
+ <img class="w-10 h-10 rounded-full" src="avatar.jpg" alt="SM">
2555
+ <img class="w-12 h-12 rounded-full" src="avatar.jpg" alt="MD">
2556
+ <img class="w-16 h-16 rounded-full" src="avatar.jpg" alt="LG">
2557
+ <img class="w-20 h-20 rounded-full" src="avatar.jpg" alt="XL">`,
2558
+ },
2559
+ dropdown: {
2560
+ desc: 'Dropdown menu',
2561
+ html: `<!-- Dropdown Container -->
2562
+ <div class="relative inline-block">
2563
+ <!-- Trigger Button -->
2564
+ <button class="inline-flex items-center gap-2 px-4 py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">
2565
+ Opções
2566
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2567
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
2568
+ </svg>
2569
+ </button>
2570
+
2571
+ <!-- Dropdown Menu -->
2572
+ <div class="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border border-gray-200 py-1 z-10">
2573
+ <a href="#" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">Editar</a>
2574
+ <a href="#" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">Duplicar</a>
2575
+ <a href="#" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">Arquivar</a>
2576
+ <hr class="my-1 border-gray-200">
2577
+ <a href="#" class="block px-4 py-2 text-red-600 hover:bg-red-50">Excluir</a>
2578
+ </div>
2579
+ </div>
2580
+
2581
+ <!-- Dropdown com Ícones -->
2582
+ <div class="w-48 bg-white rounded-lg shadow-lg border border-gray-200 py-1">
2583
+ <a href="#" class="flex items-center gap-3 px-4 py-2 text-gray-700 hover:bg-gray-100">
2584
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2585
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/>
2586
+ </svg>
2587
+ Editar
2588
+ </a>
2589
+ <a href="#" class="flex items-center gap-3 px-4 py-2 text-gray-700 hover:bg-gray-100">
2590
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2591
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
2592
+ </svg>
2593
+ Duplicar
2594
+ </a>
2595
+ </div>`,
2596
+ },
2597
+ tabs: {
2598
+ desc: 'Abas de navegação',
2599
+ html: `<!-- Tabs Underline -->
2600
+ <div class="border-b border-gray-200">
2601
+ <nav class="flex gap-8">
2602
+ <a href="#" class="py-4 px-1 border-b-2 border-blue-500 text-blue-600 font-medium">Tab Ativa</a>
2603
+ <a href="#" class="py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">Tab 2</a>
2604
+ <a href="#" class="py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">Tab 3</a>
2605
+ </nav>
2606
+ </div>
2607
+
2608
+ <!-- Tabs Pills -->
2609
+ <div class="flex gap-2 bg-gray-100 p-1 rounded-lg">
2610
+ <button class="px-4 py-2 bg-white text-gray-900 rounded-md shadow-sm font-medium">Tab Ativa</button>
2611
+ <button class="px-4 py-2 text-gray-600 hover:text-gray-900 rounded-md font-medium">Tab 2</button>
2612
+ <button class="px-4 py-2 text-gray-600 hover:text-gray-900 rounded-md font-medium">Tab 3</button>
2613
+ </div>
2614
+
2615
+ <!-- Tabs com Ícones -->
2616
+ <div class="flex border-b border-gray-200">
2617
+ <a href="#" class="flex items-center gap-2 py-4 px-4 border-b-2 border-blue-500 text-blue-600">
2618
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2619
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
2620
+ </svg>
2621
+ Home
2622
+ </a>
2623
+ <a href="#" class="flex items-center gap-2 py-4 px-4 text-gray-500 hover:text-gray-700">
2624
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2625
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
2626
+ </svg>
2627
+ Perfil
2628
+ </a>
2629
+ </div>`,
2630
+ },
2631
+ breadcrumb: {
2632
+ desc: 'Breadcrumb de navegação',
2633
+ html: `<!-- Breadcrumb Simples -->
2634
+ <nav class="flex" aria-label="Breadcrumb">
2635
+ <ol class="flex items-center gap-2">
2636
+ <li>
2637
+ <a href="#" class="text-gray-500 hover:text-gray-700">Home</a>
2638
+ </li>
2639
+ <li class="text-gray-400">/</li>
2640
+ <li>
2641
+ <a href="#" class="text-gray-500 hover:text-gray-700">Produtos</a>
2642
+ </li>
2643
+ <li class="text-gray-400">/</li>
2644
+ <li>
2645
+ <span class="text-gray-900 font-medium">Detalhes</span>
2646
+ </li>
2647
+ </ol>
2648
+ </nav>
2649
+
2650
+ <!-- Breadcrumb com Chevron -->
2651
+ <nav class="flex" aria-label="Breadcrumb">
2652
+ <ol class="flex items-center">
2653
+ <li>
2654
+ <a href="#" class="text-gray-500 hover:text-gray-700">
2655
+ <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
2656
+ <path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"/>
2657
+ </svg>
2658
+ </a>
2659
+ </li>
2660
+ <li class="flex items-center">
2661
+ <svg class="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
2662
+ <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
2663
+ </svg>
2664
+ <a href="#" class="ml-2 text-gray-500 hover:text-gray-700">Categoria</a>
2665
+ </li>
2666
+ <li class="flex items-center">
2667
+ <svg class="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
2668
+ <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
2669
+ </svg>
2670
+ <span class="ml-2 text-gray-900 font-medium">Página Atual</span>
2671
+ </li>
2672
+ </ol>
2673
+ </nav>`,
2674
+ },
2675
+ pagination: {
2676
+ desc: 'Paginação',
2677
+ html: `<!-- Paginação Simples -->
2678
+ <nav class="flex items-center gap-1">
2679
+ <button class="px-3 py-2 text-gray-500 hover:bg-gray-100 rounded-lg disabled:opacity-50" disabled>
2680
+ Anterior
2681
+ </button>
2682
+ <button class="px-3 py-2 bg-blue-600 text-white rounded-lg">1</button>
2683
+ <button class="px-3 py-2 text-gray-700 hover:bg-gray-100 rounded-lg">2</button>
2684
+ <button class="px-3 py-2 text-gray-700 hover:bg-gray-100 rounded-lg">3</button>
2685
+ <span class="px-3 py-2 text-gray-500">...</span>
2686
+ <button class="px-3 py-2 text-gray-700 hover:bg-gray-100 rounded-lg">10</button>
2687
+ <button class="px-3 py-2 text-gray-700 hover:bg-gray-100 rounded-lg">
2688
+ Próximo
2689
+ </button>
2690
+ </nav>
2691
+
2692
+ <!-- Paginação com Ícones -->
2693
+ <nav class="flex items-center gap-1">
2694
+ <button class="p-2 text-gray-500 hover:bg-gray-100 rounded-lg">
2695
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2696
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
2697
+ </svg>
2698
+ </button>
2699
+ <button class="w-10 h-10 bg-blue-600 text-white rounded-lg">1</button>
2700
+ <button class="w-10 h-10 text-gray-700 hover:bg-gray-100 rounded-lg">2</button>
2701
+ <button class="w-10 h-10 text-gray-700 hover:bg-gray-100 rounded-lg">3</button>
2702
+ <button class="p-2 text-gray-500 hover:bg-gray-100 rounded-lg">
2703
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2704
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
2705
+ </svg>
2706
+ </button>
2707
+ </nav>`,
2708
+ },
2709
+ skeleton: {
2710
+ desc: 'Skeleton loaders',
2711
+ html: `<!-- Skeleton de Texto -->
2712
+ <div class="animate-pulse space-y-3">
2713
+ <div class="h-4 bg-gray-200 rounded w-3/4"></div>
2714
+ <div class="h-4 bg-gray-200 rounded"></div>
2715
+ <div class="h-4 bg-gray-200 rounded w-5/6"></div>
2716
+ </div>
2717
+
2718
+ <!-- Skeleton de Card -->
2719
+ <div class="animate-pulse">
2720
+ <div class="bg-gray-200 h-48 rounded-t-lg"></div>
2721
+ <div class="p-4 space-y-3">
2722
+ <div class="h-4 bg-gray-200 rounded w-3/4"></div>
2723
+ <div class="h-4 bg-gray-200 rounded"></div>
2724
+ <div class="h-4 bg-gray-200 rounded w-1/2"></div>
2725
+ </div>
2726
+ </div>
2727
+
2728
+ <!-- Skeleton de Avatar + Texto -->
2729
+ <div class="animate-pulse flex items-center gap-4">
2730
+ <div class="w-12 h-12 bg-gray-200 rounded-full"></div>
2731
+ <div class="flex-1 space-y-2">
2732
+ <div class="h-4 bg-gray-200 rounded w-1/4"></div>
2733
+ <div class="h-3 bg-gray-200 rounded w-1/2"></div>
2734
+ </div>
2735
+ </div>
2736
+
2737
+ <!-- Skeleton de Lista -->
2738
+ <div class="animate-pulse space-y-4">
2739
+ <div class="flex items-center gap-4">
2740
+ <div class="w-10 h-10 bg-gray-200 rounded"></div>
2741
+ <div class="flex-1 space-y-2">
2742
+ <div class="h-4 bg-gray-200 rounded w-3/4"></div>
2743
+ <div class="h-3 bg-gray-200 rounded w-1/2"></div>
2744
+ </div>
2745
+ </div>
2746
+ <div class="flex items-center gap-4">
2747
+ <div class="w-10 h-10 bg-gray-200 rounded"></div>
2748
+ <div class="flex-1 space-y-2">
2749
+ <div class="h-4 bg-gray-200 rounded w-2/3"></div>
2750
+ <div class="h-3 bg-gray-200 rounded w-1/3"></div>
2751
+ </div>
2752
+ </div>
2753
+ </div>`,
2754
+ },
2755
+ };
2756
+ if (!componente) {
2757
+ return {
2758
+ content: [{ type: 'text', text: `❌ Parâmetro 'componente' é obrigatório.\n\nComponentes disponíveis: ${Object.keys(receitas).join(', ')}` }],
2759
+ isError: true,
2760
+ };
2761
+ }
2762
+ const receita = receitas[componente];
2763
+ if (!receita) {
2764
+ return {
2765
+ content: [{ type: 'text', text: `❌ Componente não encontrado: ${componente}\n\nComponentes disponíveis: ${Object.keys(receitas).join(', ')}` }],
2766
+ isError: true,
2767
+ };
2768
+ }
2769
+ let result = `# 🍳 Receita: ${componente}\n\n`;
2770
+ result += `**${receita.desc}**\n\n`;
2771
+ result += '```html\n';
2772
+ result += receita.html;
2773
+ result += '\n```\n';
2774
+ return { content: [{ type: 'text', text: result }] };
2775
+ }
2776
+ case 'tailwind_migracao_v4': {
2777
+ const topico = args?.topico;
2778
+ const migracaoContent = {
2779
+ overview: `# 🚀 Migração Tailwind CSS v3 → v4
2780
+
2781
+ ## Principais Mudanças
2782
+
2783
+ ### 1. CSS-First Configuration
2784
+ O Tailwind v4 usa configuração via CSS ao invés de JavaScript:
2785
+
2786
+ \`\`\`css
2787
+ /* v4: Configuração em CSS */
2788
+ @import "tailwindcss";
2789
+
2790
+ @theme {
2791
+ --color-primary: oklch(0.6 0.2 250);
2792
+ --font-display: "Inter", sans-serif;
2793
+ }
2794
+ \`\`\`
2795
+
2796
+ ### 2. Nova Sintaxe de Import
2797
+ \`\`\`css
2798
+ /* v3 */
2799
+ @tailwind base;
2800
+ @tailwind components;
2801
+ @tailwind utilities;
2802
+
2803
+ /* v4 */
2804
+ @import "tailwindcss";
2805
+ \`\`\`
2806
+
2807
+ ### 3. Plugins via CSS
2808
+ \`\`\`css
2809
+ /* v4 */
2810
+ @import "tailwindcss";
2811
+ @plugin "@tailwindcss/typography";
2812
+ @plugin "@tailwindcss/forms";
2813
+ \`\`\`
2814
+
2815
+ ### 4. Novas Features
2816
+ - Container Queries nativas
2817
+ - \`@starting-style\` para animações
2818
+ - Variantes \`in-*\`, \`has-*\`, \`not-*\`
2819
+ - Cores em OKLCH
2820
+ - Performance 10x mais rápida
2821
+
2822
+ ### 5. Breaking Changes Importantes
2823
+ - \`text-opacity-*\` → usar modificador de cor \`/opacity\`
2824
+ - \`bg-opacity-*\` → usar modificador de cor \`/opacity\`
2825
+ - Algumas classes renomeadas`,
2826
+ 'css-first': `# 📝 CSS-First Configuration (v4)
2827
+
2828
+ ## Configuração no CSS
2829
+
2830
+ O v4 elimina o \`tailwind.config.js\` para a maioria dos casos:
2831
+
2832
+ \`\`\`css
2833
+ @import "tailwindcss";
2834
+
2835
+ /* Customização de tema */
2836
+ @theme {
2837
+ /* Cores customizadas */
2838
+ --color-brand: oklch(0.6 0.2 250);
2839
+ --color-accent: oklch(0.7 0.15 150);
2840
+
2841
+ /* Fontes */
2842
+ --font-display: "Cal Sans", sans-serif;
2843
+ --font-body: "Inter", sans-serif;
2844
+
2845
+ /* Spacing customizado */
2846
+ --spacing-18: 4.5rem;
2847
+ --spacing-88: 22rem;
2848
+
2849
+ /* Breakpoints customizados */
2850
+ --breakpoint-3xl: 1920px;
2851
+
2852
+ /* Border radius */
2853
+ --radius-4xl: 2rem;
2854
+
2855
+ /* Shadows */
2856
+ --shadow-glow: 0 0 20px oklch(0.6 0.2 250 / 0.5);
2857
+ }
2858
+ \`\`\`
2859
+
2860
+ ## Vantagens
2861
+ - Tipagem automática das variáveis CSS
2862
+ - Intellisense melhorado
2863
+ - Menor bundle size
2864
+ - Mais rápido para compilar`,
2865
+ 'theme-config': `# 🎨 Configuração de Tema (v4)
2866
+
2867
+ ## Variáveis de Tema
2868
+
2869
+ \`\`\`css
2870
+ @theme {
2871
+ /* === CORES === */
2872
+ /* Substitui colors no config JS */
2873
+ --color-*: valor;
2874
+
2875
+ /* Exemplo */
2876
+ --color-primary-50: oklch(0.97 0.01 250);
2877
+ --color-primary-500: oklch(0.6 0.2 250);
2878
+ --color-primary-900: oklch(0.3 0.1 250);
2879
+
2880
+ /* === TIPOGRAFIA === */
2881
+ --font-sans: "Inter", system-ui, sans-serif;
2882
+ --font-mono: "Fira Code", monospace;
2883
+
2884
+ --text-xs: 0.75rem;
2885
+ --text-xs--line-height: 1rem;
2886
+
2887
+ /* === SPACING === */
2888
+ --spacing-*: valor;
2889
+ --spacing-13: 3.25rem;
2890
+
2891
+ /* === BREAKPOINTS === */
2892
+ --breakpoint-sm: 640px;
2893
+ --breakpoint-md: 768px;
2894
+ --breakpoint-3xl: 1920px;
2895
+
2896
+ /* === RADIUS === */
2897
+ --radius-sm: 0.25rem;
2898
+ --radius-xl: 1rem;
2899
+
2900
+ /* === SHADOWS === */
2901
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05);
2902
+ --shadow-xl: 0 20px 25px rgb(0 0 0 / 0.1);
2903
+
2904
+ /* === ANIMAÇÕES === */
2905
+ --animate-spin: spin 1s linear infinite;
2906
+ --animate-custom: myAnimation 2s ease-in-out;
2907
+ }
2908
+
2909
+ @keyframes myAnimation {
2910
+ from { opacity: 0; }
2911
+ to { opacity: 1; }
2912
+ }
2913
+ \`\`\``,
2914
+ utilities: `# 🔧 Mudanças em Utilities (v4)
2915
+
2916
+ ## Classes Renomeadas
2917
+
2918
+ | v3 | v4 | Motivo |
2919
+ |----|----|--------|
2920
+ | \`shadow-sm\` | \`shadow-xs\` | Mais consistente |
2921
+ | \`shadow\` | \`shadow-sm\` | Escala ajustada |
2922
+ | \`drop-shadow-sm\` | \`drop-shadow-xs\` | Consistência |
2923
+ | \`blur-sm\` | \`blur-xs\` | Consistência |
2924
+ | \`rounded-sm\` | \`rounded-xs\` | Consistência |
2925
+
2926
+ ## Opacidade Inline
2927
+
2928
+ \`\`\`html
2929
+ <!-- v3 (deprecated) -->
2930
+ <div class="bg-blue-500 bg-opacity-50">
2931
+
2932
+ <!-- v4 (novo) -->
2933
+ <div class="bg-blue-500/50">
2934
+ \`\`\`
2935
+
2936
+ ## Novas Utilities
2937
+
2938
+ \`\`\`html
2939
+ <!-- Size (width + height) -->
2940
+ <div class="size-10"> <!-- w-10 h-10 -->
2941
+
2942
+ <!-- Inset shortcuts -->
2943
+ <div class="inset-x-4"> <!-- left-4 right-4 -->
2944
+ <div class="inset-y-4"> <!-- top-4 bottom-4 -->
2945
+
2946
+ <!-- Logical properties -->
2947
+ <div class="ps-4"> <!-- padding-inline-start -->
2948
+ <div class="pe-4"> <!-- padding-inline-end -->
2949
+ <div class="ms-4"> <!-- margin-inline-start -->
2950
+ <div class="me-4"> <!-- margin-inline-end -->
2951
+ \`\`\``,
2952
+ variants: `# 🎯 Novos Variants (v4)
2953
+
2954
+ ## Container Queries
2955
+
2956
+ \`\`\`html
2957
+ <div class="@container">
2958
+ <div class="@sm:flex @lg:grid @lg:grid-cols-2">
2959
+ <!-- Responde ao tamanho do container -->
2960
+ </div>
2961
+ </div>
2962
+
2963
+ <!-- Named containers -->
2964
+ <div class="@container/sidebar">
2965
+ <div class="@lg/sidebar:block">
2966
+ \`\`\`
2967
+
2968
+ ## Variants Compostos
2969
+
2970
+ \`\`\`html
2971
+ <!-- has-* (parent has child) -->
2972
+ <div class="has-[input:focus]:ring-2">
2973
+ <input type="text">
2974
+ </div>
2975
+
2976
+ <!-- in-* (is inside) -->
2977
+ <div class="in-[.dark]:text-white">
2978
+
2979
+ <!-- not-* (negation) -->
2980
+ <div class="not-[.active]:opacity-50">
2981
+ \`\`\`
2982
+
2983
+ ## Starting Style
2984
+
2985
+ \`\`\`html
2986
+ <!-- Animação de entrada -->
2987
+ <div class="
2988
+ opacity-100 transition-opacity
2989
+ starting:opacity-0
2990
+ ">
2991
+ \`\`\`
2992
+
2993
+ ## Novos State Variants
2994
+
2995
+ \`\`\`html
2996
+ <!-- Inert state -->
2997
+ <div class="inert:opacity-50" inert>
2998
+
2999
+ <!-- Open/closed (details, dialog) -->
3000
+ <details class="open:bg-white">
3001
+ <summary>Click me</summary>
3002
+ </details>
3003
+ \`\`\``,
3004
+ plugins: `# 🔌 Plugins no v4
3005
+
3006
+ ## Import via CSS
3007
+
3008
+ \`\`\`css
3009
+ @import "tailwindcss";
3010
+
3011
+ /* Plugins oficiais */
3012
+ @plugin "@tailwindcss/typography";
3013
+ @plugin "@tailwindcss/forms";
3014
+ @plugin "@tailwindcss/aspect-ratio";
3015
+ @plugin "@tailwindcss/container-queries";
3016
+
3017
+ /* Plugin customizado local */
3018
+ @plugin "./my-plugin.js";
3019
+ \`\`\`
3020
+
3021
+ ## Criando Plugin (v4)
3022
+
3023
+ \`\`\`js
3024
+ // my-plugin.js
3025
+ export default function({ addUtilities, theme }) {
3026
+ addUtilities({
3027
+ '.text-shadow': {
3028
+ 'text-shadow': '2px 2px 4px rgb(0 0 0 / 0.1)',
3029
+ },
3030
+ '.text-shadow-lg': {
3031
+ 'text-shadow': '4px 4px 8px rgb(0 0 0 / 0.2)',
3032
+ },
3033
+ })
3034
+ }
3035
+ \`\`\`
3036
+
3037
+ ## Diferenças do v3
3038
+
3039
+ | v3 | v4 |
3040
+ |----|----|
3041
+ | \`plugins: [require(...)]\` | \`@plugin "..."\` |
3042
+ | CommonJS | ES Modules |
3043
+ | \`tailwind.config.js\` | CSS direto |`,
3044
+ 'breaking-changes': `# ⚠️ Breaking Changes (v3 → v4)
3045
+
3046
+ ## Classes Removidas/Alteradas
3047
+
3048
+ ### Opacidade Separada (REMOVIDO)
3049
+ \`\`\`html
3050
+ <!-- ❌ NÃO funciona no v4 -->
3051
+ <div class="bg-blue-500 bg-opacity-50">
3052
+ <div class="text-red-500 text-opacity-75">
3053
+
3054
+ <!-- ✅ Use modificador inline -->
3055
+ <div class="bg-blue-500/50">
3056
+ <div class="text-red-500/75">
3057
+ \`\`\`
3058
+
3059
+ ### Transform Utilities
3060
+ \`\`\`html
3061
+ <!-- ❌ v3 (removido) -->
3062
+ <div class="transform scale-50">
3063
+
3064
+ <!-- ✅ v4 (automático) -->
3065
+ <div class="scale-50">
3066
+ \`\`\`
3067
+
3068
+ ### Filter Utilities
3069
+ \`\`\`html
3070
+ <!-- ❌ v3 (removido) -->
3071
+ <div class="filter blur-sm">
3072
+
3073
+ <!-- ✅ v4 (automático) -->
3074
+ <div class="blur-sm">
3075
+ \`\`\`
3076
+
3077
+ ### Ring Width Default
3078
+ \`\`\`html
3079
+ <!-- v3: ring = 3px -->
3080
+ <!-- v4: ring = 1px -->
3081
+
3082
+ <!-- Para manter 3px no v4 -->
3083
+ <div class="ring-3">
3084
+ \`\`\`
3085
+
3086
+ ## Configuração
3087
+
3088
+ \`\`\`js
3089
+ // ❌ v3 tailwind.config.js (não necessário no v4)
3090
+ module.exports = {
3091
+ content: ['./src/**/*.{html,js}'],
3092
+ theme: { extend: {} },
3093
+ plugins: [],
3094
+ }
3095
+ \`\`\`
3096
+
3097
+ \`\`\`css
3098
+ /* ✅ v4 - tudo no CSS */
3099
+ @import "tailwindcss";
3100
+ @source "./src/**/*.{html,js}";
3101
+ \`\`\``,
3102
+ 'postcss-vite': `# 🛠️ Setup PostCSS e Vite (v4)
3103
+
3104
+ ## Vite (Recomendado)
3105
+
3106
+ \`\`\`bash
3107
+ npm install tailwindcss @tailwindcss/vite
3108
+ \`\`\`
3109
+
3110
+ \`\`\`js
3111
+ // vite.config.js
3112
+ import tailwindcss from '@tailwindcss/vite'
3113
+
3114
+ export default {
3115
+ plugins: [tailwindcss()],
3116
+ }
3117
+ \`\`\`
3118
+
3119
+ \`\`\`css
3120
+ /* main.css */
3121
+ @import "tailwindcss";
3122
+ \`\`\`
3123
+
3124
+ ## PostCSS
3125
+
3126
+ \`\`\`bash
3127
+ npm install tailwindcss @tailwindcss/postcss
3128
+ \`\`\`
3129
+
3130
+ \`\`\`js
3131
+ // postcss.config.js
3132
+ export default {
3133
+ plugins: {
3134
+ '@tailwindcss/postcss': {},
3135
+ },
3136
+ }
3137
+ \`\`\`
3138
+
3139
+ ## CLI Standalone
3140
+
3141
+ \`\`\`bash
3142
+ npm install tailwindcss @tailwindcss/cli
3143
+ npx @tailwindcss/cli -i input.css -o output.css --watch
3144
+ \`\`\`
3145
+
3146
+ ## Content Sources
3147
+
3148
+ \`\`\`css
3149
+ /* Detecta automaticamente, mas pode especificar */
3150
+ @import "tailwindcss";
3151
+
3152
+ /* Adicionar sources explícitos */
3153
+ @source "./src/**/*.{html,js,jsx,ts,tsx}";
3154
+ @source "./components/**/*.vue";
3155
+
3156
+ /* Ignorar paths */
3157
+ @source not "./src/legacy/**";
3158
+ \`\`\``,
3159
+ };
3160
+ if (!topico) {
3161
+ let result = '# 📚 Guia de Migração Tailwind CSS v3 → v4\n\n';
3162
+ result += 'Escolha um tópico para ver detalhes:\n\n';
3163
+ result += '| Tópico | Descrição |\n';
3164
+ result += '|--------|----------|\n';
3165
+ result += '| `overview` | Visão geral das mudanças |\n';
3166
+ result += '| `css-first` | Nova configuração via CSS |\n';
3167
+ result += '| `theme-config` | Customização de tema |\n';
3168
+ result += '| `utilities` | Mudanças em classes |\n';
3169
+ result += '| `variants` | Novos variants |\n';
3170
+ result += '| `plugins` | Plugins no v4 |\n';
3171
+ result += '| `breaking-changes` | O que quebra |\n';
3172
+ result += '| `postcss-vite` | Setup do build |\n';
3173
+ result += '\n**Exemplo:** `tailwind_migracao_v4({ topico: "breaking-changes" })`\n';
3174
+ return { content: [{ type: 'text', text: result }] };
3175
+ }
3176
+ const content = migracaoContent[topico];
3177
+ if (!content) {
3178
+ return {
3179
+ content: [{ type: 'text', text: `❌ Tópico não encontrado: ${topico}\n\nTópicos disponíveis: ${Object.keys(migracaoContent).join(', ')}` }],
3180
+ isError: true,
3181
+ };
3182
+ }
3183
+ return { content: [{ type: 'text', text: content }] };
3184
+ }
3185
+ case 'tailwind_boas_praticas': {
3186
+ const topico = args?.topico;
3187
+ const boasPraticas = {
3188
+ organizacao: `# 📋 Organização de Classes
3189
+
3190
+ ## Ordem Recomendada
3191
+
3192
+ Organize classes nesta ordem para consistência:
3193
+
3194
+ 1. **Layout** (display, position, flexbox/grid)
3195
+ 2. **Sizing** (width, height)
3196
+ 3. **Spacing** (margin, padding)
3197
+ 4. **Typography** (font, text)
3198
+ 5. **Visual** (background, border, shadow)
3199
+ 6. **Effects** (opacity, filters)
3200
+ 7. **Transitions/Animations**
3201
+ 8. **Variants** (hover, focus, responsive)
3202
+
3203
+ \`\`\`html
3204
+ <button class="
3205
+ flex items-center justify-center /* Layout */
3206
+ w-full h-12 /* Sizing */
3207
+ px-4 py-2 /* Spacing */
3208
+ text-sm font-medium text-white /* Typography */
3209
+ bg-blue-600 rounded-lg shadow /* Visual */
3210
+ transition-colors /* Transitions */
3211
+ hover:bg-blue-700 focus:ring-2 /* Variants */
3212
+ ">
3213
+ Botão
3214
+ </button>
3215
+ \`\`\`
3216
+
3217
+ ## Multi-line para Legibilidade
3218
+
3219
+ \`\`\`html
3220
+ <!-- ❌ Difícil de ler -->
3221
+ <div class="flex items-center justify-between p-4 bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow">
3222
+
3223
+ <!-- ✅ Mais legível -->
3224
+ <div class="
3225
+ flex items-center justify-between
3226
+ p-4
3227
+ bg-white rounded-lg
3228
+ shadow-md hover:shadow-lg
3229
+ transition-shadow
3230
+ ">
3231
+ \`\`\``,
3232
+ componentes: `# 🧩 Extração de Componentes
3233
+
3234
+ ## Quando Extrair
3235
+
3236
+ Extraia quando:
3237
+ - Mesmo conjunto de classes usado 3+ vezes
3238
+ - Componente tem lógica complexa
3239
+ - Precisa de variantes (primary, secondary)
3240
+
3241
+ ## React/Vue Components
3242
+
3243
+ \`\`\`jsx
3244
+ // ✅ Componente React
3245
+ function Button({ variant = 'primary', children }) {
3246
+ const variants = {
3247
+ primary: 'bg-blue-600 text-white hover:bg-blue-700',
3248
+ secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
3249
+ outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50',
3250
+ }
3251
+
3252
+ return (
3253
+ <button className={\`
3254
+ px-4 py-2 font-medium rounded-lg
3255
+ transition-colors focus:outline-none focus:ring-2
3256
+ \${variants[variant]}
3257
+ \`}>
3258
+ {children}
3259
+ </button>
3260
+ )
3261
+ }
3262
+ \`\`\`
3263
+
3264
+ ## @apply (Usar com Moderação)
3265
+
3266
+ \`\`\`css
3267
+ /* ⚠️ Use apenas quando necessário */
3268
+ @layer components {
3269
+ .btn {
3270
+ @apply px-4 py-2 font-medium rounded-lg transition-colors;
3271
+ }
3272
+
3273
+ .btn-primary {
3274
+ @apply bg-blue-600 text-white hover:bg-blue-700;
3275
+ }
3276
+ }
3277
+ \`\`\`
3278
+
3279
+ ## Tailwind Merge (recomendado)
3280
+
3281
+ \`\`\`jsx
3282
+ import { twMerge } from 'tailwind-merge'
3283
+
3284
+ // Resolve conflitos de classes
3285
+ <div className={twMerge('px-4 py-2', className)}>
3286
+ \`\`\``,
3287
+ performance: `# ⚡ Performance
3288
+
3289
+ ## Content Configuration
3290
+
3291
+ \`\`\`css
3292
+ /* v4: Seja específico nos sources */
3293
+ @import "tailwindcss";
3294
+ @source "./src/**/*.{js,jsx,ts,tsx}";
3295
+ @source "./components/**/*.vue";
3296
+ @source not "./node_modules/**";
3297
+ \`\`\`
3298
+
3299
+ ## Evite Classes Dinâmicas
3300
+
3301
+ \`\`\`jsx
3302
+ // ❌ Tailwind não detecta
3303
+ <div className={\`bg-\${color}-500\`}>
3304
+
3305
+ // ✅ Use objeto de mapeamento
3306
+ const colors = {
3307
+ blue: 'bg-blue-500',
3308
+ red: 'bg-red-500',
3309
+ green: 'bg-green-500',
3310
+ }
3311
+ <div className={colors[color]}>
3312
+ \`\`\`
3313
+
3314
+ ## Safelist (quando necessário)
3315
+
3316
+ \`\`\`css
3317
+ /* v4: Forçar inclusão de classes */
3318
+ @import "tailwindcss";
3319
+ @utility bg-brand-* {
3320
+ /* Garante que bg-brand-{any} seja incluído */
3321
+ }
3322
+ \`\`\`
3323
+
3324
+ ## Minificação
3325
+
3326
+ \`\`\`bash
3327
+ # CLI com minificação
3328
+ npx @tailwindcss/cli -i input.css -o output.css --minify
3329
+
3330
+ # Vite faz automaticamente em build
3331
+ \`\`\`
3332
+
3333
+ ## Cache
3334
+
3335
+ - Use cache do bundler (Vite/Webpack)
3336
+ - Tailwind v4 é 10x mais rápido que v3`,
3337
+ acessibilidade: `# ♿ Acessibilidade
3338
+
3339
+ ## Focus Visible
3340
+
3341
+ \`\`\`html
3342
+ <!-- Foco apenas para navegação por teclado -->
3343
+ <button class="
3344
+ focus:outline-none
3345
+ focus-visible:ring-2 focus-visible:ring-blue-500
3346
+ ">
3347
+ Botão Acessível
3348
+ </button>
3349
+ \`\`\`
3350
+
3351
+ ## Screen Reader Only
3352
+
3353
+ \`\`\`html
3354
+ <!-- Texto só para leitores de tela -->
3355
+ <span class="sr-only">Fechar menu</span>
3356
+
3357
+ <!-- Ícone com label acessível -->
3358
+ <button aria-label="Fechar">
3359
+ <svg class="w-5 h-5" aria-hidden="true">...</svg>
3360
+ </button>
3361
+ \`\`\`
3362
+
3363
+ ## Motion Reduce
3364
+
3365
+ \`\`\`html
3366
+ <!-- Respeitar preferências do usuário -->
3367
+ <div class="
3368
+ animate-bounce
3369
+ motion-reduce:animate-none
3370
+ ">
3371
+ \`\`\`
3372
+
3373
+ ## Contraste
3374
+
3375
+ \`\`\`html
3376
+ <!-- Alto contraste quando necessário -->
3377
+ <div class="
3378
+ text-gray-600
3379
+ contrast-more:text-gray-900
3380
+ contrast-more:border-2
3381
+ ">
3382
+ \`\`\`
3383
+
3384
+ ## ARIA Variants
3385
+
3386
+ \`\`\`html
3387
+ <!-- Estilos baseados em ARIA -->
3388
+ <button
3389
+ aria-expanded="true"
3390
+ class="aria-expanded:rotate-180"
3391
+ >
3392
+ <svg>...</svg>
3393
+ </button>
3394
+ \`\`\``,
3395
+ responsivo: `# 📱 Design Responsivo
3396
+
3397
+ ## Mobile-First
3398
+
3399
+ \`\`\`html
3400
+ <!-- Base = mobile, depois aumenta -->
3401
+ <div class="
3402
+ flex flex-col /* Mobile: coluna */
3403
+ md:flex-row /* Tablet+: linha */
3404
+ ">
3405
+ \`\`\`
3406
+
3407
+ ## Container Queries (v4)
3408
+
3409
+ \`\`\`html
3410
+ <!-- Responde ao container, não à viewport -->
3411
+ <div class="@container">
3412
+ <div class="
3413
+ @sm:flex
3414
+ @lg:grid @lg:grid-cols-2
3415
+ ">
3416
+ \`\`\`
3417
+
3418
+ ## Breakpoints Úteis
3419
+
3420
+ \`\`\`html
3421
+ <div class="
3422
+ grid grid-cols-1 /* < 640px */
3423
+ sm:grid-cols-2 /* ≥ 640px */
3424
+ md:grid-cols-3 /* ≥ 768px */
3425
+ lg:grid-cols-4 /* ≥ 1024px */
3426
+ xl:grid-cols-5 /* ≥ 1280px */
3427
+ ">
3428
+ \`\`\`
3429
+
3430
+ ## Max-Width Variants
3431
+
3432
+ \`\`\`html
3433
+ <!-- Esconder apenas em mobile -->
3434
+ <div class="hidden sm:block">Desktop only</div>
3435
+
3436
+ <!-- Mostrar apenas em mobile -->
3437
+ <div class="sm:hidden">Mobile only</div>
3438
+ \`\`\`
3439
+
3440
+ ## Layout Responsivo Completo
3441
+
3442
+ \`\`\`html
3443
+ <div class="min-h-screen flex flex-col">
3444
+ <header class="h-16 px-4 md:px-6 lg:px-8">
3445
+ Nav
3446
+ </header>
3447
+
3448
+ <main class="flex-1 container mx-auto px-4 py-6">
3449
+ <div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
3450
+ <!-- Cards -->
3451
+ </div>
3452
+ </main>
3453
+
3454
+ <footer class="h-20">
3455
+ Footer
3456
+ </footer>
3457
+ </div>
3458
+ \`\`\``,
3459
+ 'dark-mode': `# 🌙 Dark Mode
3460
+
3461
+ ## Setup Básico
3462
+
3463
+ \`\`\`html
3464
+ <!-- Classe no html ou body -->
3465
+ <html class="dark">
3466
+ <body class="bg-white dark:bg-gray-900">
3467
+ \`\`\`
3468
+
3469
+ ## Padrões Comuns
3470
+
3471
+ \`\`\`html
3472
+ <!-- Texto -->
3473
+ <p class="text-gray-900 dark:text-white">
3474
+ <p class="text-gray-600 dark:text-gray-400">
3475
+
3476
+ <!-- Backgrounds -->
3477
+ <div class="bg-white dark:bg-gray-800">
3478
+ <div class="bg-gray-50 dark:bg-gray-900">
3479
+
3480
+ <!-- Borders -->
3481
+ <div class="border-gray-200 dark:border-gray-700">
3482
+
3483
+ <!-- Shadows -->
3484
+ <div class="shadow-lg dark:shadow-gray-900/20">
3485
+ \`\`\`
3486
+
3487
+ ## Toggle com JavaScript
3488
+
3489
+ \`\`\`js
3490
+ // Alternar dark mode
3491
+ document.documentElement.classList.toggle('dark')
3492
+
3493
+ // Persistir preferência
3494
+ localStorage.setItem('theme', 'dark')
3495
+
3496
+ // Detectar preferência do sistema
3497
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
3498
+ document.documentElement.classList.add('dark')
3499
+ }
3500
+ \`\`\`
3501
+
3502
+ ## Componente Dark Mode Aware
3503
+
3504
+ \`\`\`html
3505
+ <div class="
3506
+ bg-white dark:bg-gray-800
3507
+ text-gray-900 dark:text-white
3508
+ border border-gray-200 dark:border-gray-700
3509
+ shadow-lg dark:shadow-none
3510
+ rounded-lg p-6
3511
+ ">
3512
+ <h2 class="text-xl font-bold">Título</h2>
3513
+ <p class="text-gray-600 dark:text-gray-400">
3514
+ Conteúdo que funciona nos dois modos.
3515
+ </p>
3516
+ </div>
3517
+ \`\`\``,
3518
+ animacoes: `# 🎬 Animações e Transições
3519
+
3520
+ ## Transições Básicas
3521
+
3522
+ \`\`\`html
3523
+ <!-- Transição suave -->
3524
+ <button class="
3525
+ bg-blue-500
3526
+ transition-colors duration-200
3527
+ hover:bg-blue-600
3528
+ ">
3529
+
3530
+ <!-- Transição completa -->
3531
+ <div class="
3532
+ transform transition-all duration-300 ease-out
3533
+ hover:scale-105 hover:shadow-lg
3534
+ ">
3535
+ \`\`\`
3536
+
3537
+ ## Animações Built-in
3538
+
3539
+ \`\`\`html
3540
+ <!-- Spin (loading) -->
3541
+ <svg class="animate-spin h-5 w-5">
3542
+
3543
+ <!-- Pulse -->
3544
+ <div class="animate-pulse">
3545
+
3546
+ <!-- Bounce -->
3547
+ <div class="animate-bounce">
3548
+
3549
+ <!-- Ping (notification) -->
3550
+ <span class="animate-ping">
3551
+ \`\`\`
3552
+
3553
+ ## Animação Customizada
3554
+
3555
+ \`\`\`css
3556
+ @theme {
3557
+ --animate-fade-in: fadeIn 0.3s ease-out;
3558
+ --animate-slide-up: slideUp 0.4s ease-out;
3559
+ }
3560
+
3561
+ @keyframes fadeIn {
3562
+ from { opacity: 0; }
3563
+ to { opacity: 1; }
3564
+ }
3565
+
3566
+ @keyframes slideUp {
3567
+ from {
3568
+ opacity: 0;
3569
+ transform: translateY(10px);
3570
+ }
3571
+ to {
3572
+ opacity: 1;
3573
+ transform: translateY(0);
3574
+ }
3575
+ }
3576
+ \`\`\`
3577
+
3578
+ ## Starting Style (v4)
3579
+
3580
+ \`\`\`html
3581
+ <!-- Animação de entrada automática -->
3582
+ <div class="
3583
+ opacity-100 transition-opacity duration-300
3584
+ starting:opacity-0
3585
+ ">
3586
+ Aparece com fade
3587
+ </div>
3588
+ \`\`\`
3589
+
3590
+ ## Motion Safe/Reduce
3591
+
3592
+ \`\`\`html
3593
+ <div class="
3594
+ animate-bounce
3595
+ motion-reduce:animate-none
3596
+ motion-safe:transition-transform
3597
+ ">
3598
+ \`\`\``,
3599
+ forms: `# 📝 Formulários
3600
+
3601
+ ## Input Estilizado
3602
+
3603
+ \`\`\`html
3604
+ <input
3605
+ type="text"
3606
+ class="
3607
+ w-full px-4 py-2
3608
+ border border-gray-300 rounded-lg
3609
+ focus:ring-2 focus:ring-blue-500 focus:border-blue-500
3610
+ placeholder:text-gray-400
3611
+ disabled:bg-gray-100 disabled:cursor-not-allowed
3612
+ "
3613
+ placeholder="Digite aqui..."
3614
+ >
3615
+ \`\`\`
3616
+
3617
+ ## Estados de Validação
3618
+
3619
+ \`\`\`html
3620
+ <!-- Input válido -->
3621
+ <input class="
3622
+ border-green-500
3623
+ focus:ring-green-500
3624
+ valid:border-green-500
3625
+ ">
3626
+
3627
+ <!-- Input inválido -->
3628
+ <input class="
3629
+ border-red-500
3630
+ focus:ring-red-500
3631
+ invalid:border-red-500
3632
+ ">
3633
+ \`\`\`
3634
+
3635
+ ## Checkbox Customizado
3636
+
3637
+ \`\`\`html
3638
+ <label class="flex items-center gap-2 cursor-pointer">
3639
+ <input
3640
+ type="checkbox"
3641
+ class="
3642
+ w-5 h-5 rounded
3643
+ text-blue-600
3644
+ border-gray-300
3645
+ focus:ring-blue-500
3646
+ "
3647
+ >
3648
+ <span class="text-gray-700">Aceito os termos</span>
3649
+ </label>
3650
+ \`\`\`
3651
+
3652
+ ## Select Estilizado
3653
+
3654
+ \`\`\`html
3655
+ <select class="
3656
+ w-full px-4 py-2
3657
+ border border-gray-300 rounded-lg
3658
+ bg-white
3659
+ focus:ring-2 focus:ring-blue-500
3660
+ ">
3661
+ <option>Opção 1</option>
3662
+ <option>Opção 2</option>
3663
+ </select>
3664
+ \`\`\`
3665
+
3666
+ ## Plugin Forms (Recomendado)
3667
+
3668
+ \`\`\`css
3669
+ @import "tailwindcss";
3670
+ @plugin "@tailwindcss/forms";
3671
+ \`\`\`
3672
+
3673
+ Aplica estilos base automaticamente a todos os inputs.`,
3674
+ };
3675
+ if (!topico) {
3676
+ let result = '# 💡 Boas Práticas Tailwind CSS\n\n';
3677
+ result += 'Escolha um tópico:\n\n';
3678
+ result += '| Tópico | Descrição |\n';
3679
+ result += '|--------|----------|\n';
3680
+ result += '| `organizacao` | Ordem e organização de classes |\n';
3681
+ result += '| `componentes` | Extração e reutilização |\n';
3682
+ result += '| `performance` | Otimização de bundle |\n';
3683
+ result += '| `acessibilidade` | A11y com Tailwind |\n';
3684
+ result += '| `responsivo` | Design responsivo |\n';
3685
+ result += '| `dark-mode` | Implementação de dark mode |\n';
3686
+ result += '| `animacoes` | Transições e animações |\n';
3687
+ result += '| `forms` | Estilização de formulários |\n';
3688
+ result += '\n**Exemplo:** `tailwind_boas_praticas({ topico: "responsivo" })`\n';
3689
+ return { content: [{ type: 'text', text: result }] };
3690
+ }
3691
+ const content = boasPraticas[topico];
3692
+ if (!content) {
3693
+ return {
3694
+ content: [{ type: 'text', text: `❌ Tópico não encontrado: ${topico}\n\nTópicos disponíveis: ${Object.keys(boasPraticas).join(', ')}` }],
3695
+ isError: true,
3696
+ };
3697
+ }
3698
+ return { content: [{ type: 'text', text: content }] };
3699
+ }
1179
3700
  case 'tailwind_check_updates': {
1180
3701
  const updateInfo = await checkForUpdates();
1181
3702
  let result = '# 🔍 Verificação de Atualizações\n\n';
@@ -1341,7 +3862,7 @@ async function main() {
1341
3862
  console.error(`📁 Usando Tailwind CSS: ${TAILWIND_SRC_PATH}`);
1342
3863
  const transport = new StdioServerTransport();
1343
3864
  await mcpServer.connect(transport);
1344
- console.error('MCP Tailwind CSS server v2.0.0 running on stdio');
3865
+ console.error(`MCP Tailwind CSS server v${APP_VERSION} running on stdio`);
1345
3866
  if (AUTO_UPDATE_ENABLED) {
1346
3867
  const initialCheck = await checkForUpdates();
1347
3868
  if (initialCheck.hasUpdate) {