forgefy 1.0.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/bin/cli.js ADDED
@@ -0,0 +1,425 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from 'child_process'
4
+ import fs from 'fs-extra'
5
+ import path from 'path'
6
+ import ora from 'ora'
7
+ import chalk from 'chalk'
8
+ import prompts from 'prompts'
9
+ import { fileURLToPath } from 'url'
10
+
11
+ const __filename = fileURLToPath(import.meta.url)
12
+ const __dirname = path.dirname(__filename)
13
+
14
+ const TEMPLATES_DIR = path.resolve(__dirname, '../templates')
15
+
16
+ const PROJECT_VARIANTS = [
17
+ { id: 'base_landpage', title: 'Landpage' },
18
+ { id: 'base_sistema_simples', title: 'Sistema simples' },
19
+ { id: 'base_sistema_robusto', title: 'Sistema robusto' }
20
+ ]
21
+
22
+ const VARIANT_CHOICES = PROJECT_VARIANTS.map((v) => ({
23
+ title: v.title,
24
+ value: v.id
25
+ }))
26
+
27
+ function getVariantLabel(variantId) {
28
+ const found = PROJECT_VARIANTS.find((v) => v.id === variantId)
29
+ return found ? found.title : variantId
30
+ }
31
+
32
+ const LIBS_BY_STACK = {
33
+ next: {
34
+ base_landpage: {
35
+ deps: ['next-intl', 'sass', 'typescript'],
36
+ devDeps: ['@types/node', '@types/react', '@types/react-dom']
37
+ },
38
+ base_sistema_simples: {
39
+ deps: ['next-intl', 'sass', 'typescript'],
40
+ devDeps: ['@types/node', '@types/react', '@types/react-dom']
41
+ },
42
+ base_sistema_robusto: {
43
+ deps: [
44
+ 'leaflet',
45
+ 'moment',
46
+ 'next-intl',
47
+ 'react-toastify',
48
+ 'sass',
49
+ 'typescript'
50
+ ],
51
+ devDeps: [
52
+ '@types/leaflet',
53
+ '@types/node',
54
+ '@types/react',
55
+ '@types/react-dom'
56
+ ]
57
+ }
58
+ },
59
+ vue: {
60
+ base_landpage: {
61
+ deps: ['sass'],
62
+ devDeps: []
63
+ },
64
+ base_sistema_simples: {
65
+ deps: ['sass', 'vue-router'],
66
+ devDeps: []
67
+ },
68
+ base_sistema_robusto: {
69
+ deps: ['sass', 'vue-router', 'pinia'],
70
+ devDeps: []
71
+ }
72
+ }
73
+ }
74
+
75
+ function applyBaseLayout(cwd, baseTemplate, spinner, label) {
76
+ if (!fs.existsSync(baseTemplate)) {
77
+ return
78
+ }
79
+ spinner.text = `Aplicando ${label} (public só da base, restante em src/)...`
80
+ const projectPublic = path.join(cwd, 'public')
81
+ if (fs.existsSync(projectPublic)) {
82
+ fs.removeSync(projectPublic)
83
+ }
84
+ const basePublic = path.join(baseTemplate, 'public')
85
+ if (fs.existsSync(basePublic)) {
86
+ fs.copySync(basePublic, projectPublic, { overwrite: true })
87
+ }
88
+ const srcDir = path.join(cwd, 'src')
89
+ fs.ensureDirSync(srcDir)
90
+ for (const ent of fs.readdirSync(baseTemplate, { withFileTypes: true })) {
91
+ if (ent.name === 'public') {
92
+ continue
93
+ }
94
+ fs.copySync(
95
+ path.join(baseTemplate, ent.name),
96
+ path.join(srcDir, ent.name),
97
+ { overwrite: true }
98
+ )
99
+ }
100
+ }
101
+
102
+ function rewriteNextBaseImportsInSrc(projectRoot, spinner) {
103
+ const srcRoot = path.join(projectRoot, 'src')
104
+ if (!fs.existsSync(srcRoot)) {
105
+ return
106
+ }
107
+ spinner.text = 'Ajustando imports (next/base → @/)...'
108
+ const exts = new Set([
109
+ '.ts',
110
+ '.tsx',
111
+ '.js',
112
+ '.jsx',
113
+ '.mjs',
114
+ '.cjs',
115
+ '.scss',
116
+ '.sass',
117
+ '.css'
118
+ ])
119
+ const prefixRe = /(["'`])next\/base\//g
120
+ function walk(dir) {
121
+ for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
122
+ if (ent.name === 'node_modules' || ent.name === '.next') {
123
+ continue
124
+ }
125
+ const full = path.join(dir, ent.name)
126
+ if (ent.isDirectory()) {
127
+ walk(full)
128
+ continue
129
+ }
130
+ if (!exts.has(path.extname(ent.name))) {
131
+ continue
132
+ }
133
+ let content = fs.readFileSync(full, 'utf8')
134
+ const nextContent = content.replace(prefixRe, '$1@/')
135
+ if (nextContent !== content) {
136
+ fs.writeFileSync(full, nextContent, 'utf8')
137
+ }
138
+ }
139
+ }
140
+ walk(srcRoot)
141
+ }
142
+
143
+ function applyNextTemplates(cwd, variant, stackTemplatesRoot, spinner) {
144
+ const baseTemplate = path.join(stackTemplatesRoot, 'base')
145
+ const variantTemplate = path.join(stackTemplatesRoot, variant)
146
+ applyBaseLayout(cwd, baseTemplate, spinner, 'base Next.js')
147
+ const appPath = path.join(cwd, 'src', 'app')
148
+ const templateAppPath = path.join(variantTemplate, 'app')
149
+ const hasVariantTemplate = fs.existsSync(variantTemplate)
150
+ const hasVariantApp = fs.existsSync(templateAppPath)
151
+ if (hasVariantApp) {
152
+ if (fs.existsSync(appPath)) {
153
+ fs.removeSync(appPath)
154
+ }
155
+ spinner.text = 'Aplicando estrutura do projeto...'
156
+ fs.copySync(templateAppPath, appPath, { overwrite: true })
157
+ }
158
+ if (hasVariantTemplate) {
159
+ const srcDir = path.join(cwd, 'src')
160
+ for (const ent of fs.readdirSync(variantTemplate, { withFileTypes: true })) {
161
+ if (ent.name === 'app' || ent.name === 'public') {
162
+ continue
163
+ }
164
+ fs.copySync(
165
+ path.join(variantTemplate, ent.name),
166
+ path.join(srcDir, ent.name),
167
+ { overwrite: true }
168
+ )
169
+ }
170
+ }
171
+ rewriteNextBaseImportsInSrc(cwd, spinner)
172
+ }
173
+
174
+ function applyVueTemplates(cwd, variant, stackTemplatesRoot, spinner) {
175
+ const baseTemplate = path.join(stackTemplatesRoot, 'base')
176
+ const variantTemplate = path.join(stackTemplatesRoot, variant)
177
+ applyBaseLayout(cwd, baseTemplate, spinner, 'base Vue')
178
+ if (!fs.existsSync(variantTemplate)) {
179
+ return
180
+ }
181
+ const templateSrc = path.join(variantTemplate, 'src')
182
+ const targetSrc = path.join(cwd, 'src')
183
+ if (fs.existsSync(templateSrc)) {
184
+ spinner.text = 'Aplicando estrutura do projeto (src)...'
185
+ fs.copySync(templateSrc, targetSrc, { overwrite: true })
186
+ }
187
+ fs.copySync(variantTemplate, cwd, {
188
+ overwrite: true,
189
+ filter: (filePath) => {
190
+ const rel = path.relative(variantTemplate, filePath)
191
+ if (!rel) return true
192
+ const first = rel.split(path.sep)[0]
193
+ return first !== 'src' && first !== 'public'
194
+ }
195
+ })
196
+ }
197
+
198
+ function patchNextTurbopackRoot(projectRoot) {
199
+ const candidates = ['next.config.ts', 'next.config.mjs', 'next.config.js']
200
+ for (const name of candidates) {
201
+ const filePath = path.join(projectRoot, name)
202
+ if (!fs.existsSync(filePath)) {
203
+ continue
204
+ }
205
+ let content = fs.readFileSync(filePath, 'utf8')
206
+ if (/turbopack\s*:\s*\{[\s\S]*?root\s*:/s.test(content)) {
207
+ return
208
+ }
209
+ if (name === 'next.config.ts') {
210
+ if (!/\bimport\s+path\s+from\s+['"]path['"]/.test(content)) {
211
+ content = content.replace(
212
+ /^(import\s+type\s+\{\s*NextConfig\s*\}\s+from\s+['"]next['"];)\s*/m,
213
+ '$1\nimport path from "path";\n\n'
214
+ )
215
+ }
216
+ content = content.replace(
217
+ /(const\s+nextConfig:\s*NextConfig\s*=\s*\{)/,
218
+ '$1\n turbopack: {\n root: path.join(__dirname),\n },'
219
+ )
220
+ fs.writeFileSync(filePath, content, 'utf8')
221
+ return
222
+ }
223
+ if (name === 'next.config.mjs') {
224
+ const prelude = []
225
+ if (!/\bimport\s+path\s+from\s+['"]path['"]/.test(content)) {
226
+ prelude.push('import path from "path";')
227
+ }
228
+ if (!/fileURLToPath/.test(content)) {
229
+ prelude.push('import { fileURLToPath } from "url";')
230
+ }
231
+ if (!/\bconst __dirname\b/.test(content)) {
232
+ prelude.push(
233
+ 'const __dirname = path.dirname(fileURLToPath(import.meta.url));'
234
+ )
235
+ }
236
+ if (prelude.length) {
237
+ content = `${prelude.join('\n')}\n\n${content}`
238
+ }
239
+ content = content.replace(
240
+ /(const\s+nextConfig[^=]*=\s*\{)/,
241
+ '$1\n turbopack: {\n root: path.join(__dirname),\n },'
242
+ )
243
+ fs.writeFileSync(filePath, content, 'utf8')
244
+ return
245
+ }
246
+ if (name === 'next.config.js') {
247
+ if (!/require\(['"]path['"]\)/.test(content)) {
248
+ content = `const path = require('path');\n${content}`
249
+ }
250
+ content = content.replace(
251
+ /(module\.exports\s*=\s*\{)/,
252
+ '$1\n turbopack: {\n root: path.join(__dirname),\n },'
253
+ )
254
+ fs.writeFileSync(filePath, content, 'utf8')
255
+ return
256
+ }
257
+ }
258
+ }
259
+
260
+ const STACKS = {
261
+ next: {
262
+ id: 'next',
263
+ promptLabel: 'Next.js',
264
+ bannerStack: 'Next.js',
265
+ createMessage: 'Criando projeto Next.js...',
266
+ createProject: (projectName) => {
267
+ execSync(
268
+ `npx create-next-app@latest ${projectName} --typescript --eslint --app --src-dir --import-alias "@/*"`,
269
+ { stdio: 'inherit' }
270
+ )
271
+ },
272
+ applyTemplates: applyNextTemplates
273
+ },
274
+ vue: {
275
+ id: 'vue',
276
+ promptLabel: 'Vue (Vite + TypeScript)',
277
+ bannerStack: 'Vue 3 (Vite)',
278
+ createMessage: 'Criando projeto Vue (Vite)...',
279
+ createProject: (projectName) => {
280
+ execSync(
281
+ `npm create vite@latest ${projectName} -- --template vue-ts`,
282
+ { stdio: 'inherit' }
283
+ )
284
+ },
285
+ applyTemplates: applyVueTemplates
286
+ }
287
+ }
288
+
289
+ const STACK_CHOICES = Object.values(STACKS).map((s) => ({
290
+ title: s.promptLabel,
291
+ value: s.id
292
+ }))
293
+
294
+ function showBanner(projectName, stackId, variant) {
295
+ const stack = STACKS[stackId]
296
+ const stackName = stack ? stack.bannerStack : stackId
297
+
298
+ console.log(`
299
+ ${chalk.cyan.bold(`
300
+ ███████╗ ██████╗ ██████╗ ██████╗ ███████╗
301
+ ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
302
+ █████╗ ██║ ██║██████╔╝██║ ███╗█████╗
303
+ ██╔══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝
304
+ ██║ ╚██████╔╝██║ ██║╚██████╔╝███████
305
+ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝
306
+ ███████╗██╗ ██╗
307
+ ██╔════╝╚██╗ ██╔╝
308
+ █████╗ ╚████╔╝
309
+ ██╔══╝ ╚██╔╝
310
+ ██║ ██║
311
+ ╚═╝ ╚═╝
312
+ `)}
313
+ ${chalk.magenta.bold('⚡ FORGE FY CLI')}
314
+ ${chalk.gray('────────────────────────────────────────')}
315
+ ${chalk.yellow('📦 Projeto:')} ${projectName}
316
+ ${chalk.yellow('⚡ Stack:')} ${stackName}
317
+ ${chalk.yellow('🎯 Tipo de sistema:')} ${getVariantLabel(variant)}
318
+ ${chalk.gray('────────────────────────────────────────')}
319
+ ${chalk.green('✔ Projeto criado com sucesso!')}
320
+ ${chalk.gray('👨‍💻 Desenvolvido por Caio Fortes')}
321
+ `)
322
+ }
323
+
324
+ async function main() {
325
+ const response = await prompts([
326
+ {
327
+ type: 'text',
328
+ name: 'projectName',
329
+ message: 'Nome do projeto:',
330
+ initial: 'my-app'
331
+ },
332
+ {
333
+ type: 'select',
334
+ name: 'stack',
335
+ message: 'Linguagem / framework:',
336
+ choices: STACK_CHOICES
337
+ },
338
+ {
339
+ type: 'select',
340
+ name: 'variant',
341
+ message: 'Tipo de sistema:',
342
+ choices: VARIANT_CHOICES
343
+ }
344
+ ])
345
+
346
+ const { projectName, stack: stackId, variant } = response
347
+
348
+ if (!projectName || !stackId || !variant) {
349
+ console.log(chalk.red('❌ Operação cancelada'))
350
+ process.exit(1)
351
+ }
352
+
353
+ const stack = STACKS[stackId]
354
+ if (!stack) {
355
+ console.log(chalk.red(`❌ Stack não suportada: ${stackId}`))
356
+ process.exit(1)
357
+ }
358
+
359
+ const stackLibs = LIBS_BY_STACK[stackId]
360
+ if (!stackLibs || !stackLibs[variant]) {
361
+ console.log(
362
+ chalk.red(
363
+ `❌ Variante "${variant}" sem dependências definidas para stack "${stackId}". Ajuste LIBS_BY_STACK no CLI.`
364
+ )
365
+ )
366
+ process.exit(1)
367
+ }
368
+
369
+ const targetDir = path.join(process.cwd(), projectName)
370
+
371
+ if (fs.existsSync(targetDir)) {
372
+ console.log(chalk.red('❌ Pasta já existe'))
373
+ process.exit(1)
374
+ }
375
+
376
+ const spinner = ora(stack.createMessage).start()
377
+
378
+ try {
379
+ stack.createProject(projectName)
380
+
381
+ process.chdir(projectName)
382
+
383
+ if (stackId === 'next') {
384
+ patchNextTurbopackRoot(process.cwd())
385
+ }
386
+
387
+ spinner.text = 'Instalando dependências do scaffold...'
388
+ execSync('npm install', { stdio: 'inherit' })
389
+
390
+ const { deps, devDeps } = stackLibs[variant]
391
+
392
+ spinner.text = 'Instalando dependências extras...'
393
+
394
+ if (deps.length) {
395
+ execSync(`npm install ${deps.join(' ')}`, {
396
+ stdio: 'inherit'
397
+ })
398
+ }
399
+
400
+ if (devDeps.length) {
401
+ execSync(`npm install -D ${devDeps.join(' ')}`, {
402
+ stdio: 'inherit'
403
+ })
404
+ }
405
+
406
+ const stackTemplatesRoot = path.join(TEMPLATES_DIR, stackId)
407
+ stack.applyTemplates(process.cwd(), variant, stackTemplatesRoot, spinner)
408
+
409
+ spinner.succeed('Projeto criado com sucesso!')
410
+
411
+ showBanner(projectName, stackId, variant)
412
+
413
+ console.log('\n👉 Próximos passos:')
414
+ console.log(chalk.yellow(`cd ${projectName}`))
415
+ console.log(chalk.yellow('npm run dev'))
416
+
417
+ } catch (error) {
418
+ spinner.fail('Erro ao criar projeto')
419
+ console.error(error)
420
+ process.exit(1)
421
+ }
422
+ }
423
+
424
+ main()
425
+
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "forgefy",
3
+ "version": "1.0.0",
4
+ "description": "CLI para iniciar projetos rapidamente",
5
+ "main": "cli.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "bin": {
10
+ "create-forgefy-app": "./bin/cli.js"
11
+ },
12
+ "keywords": [],
13
+ "author": "",
14
+ "license": "ISC",
15
+ "type": "module",
16
+ "dependencies": {
17
+ "chalk": "^4.1.2",
18
+ "fs-extra": "^11.3.4",
19
+ "ora": "^5.4.1",
20
+ "prompts": "^2.4.2"
21
+ }
22
+ }
@@ -0,0 +1,8 @@
1
+ export default function BodyContainer() {
2
+ return (
3
+ <h4>
4
+ Landing em TypeScript: use esta pasta para hero, seções de produto e CTAs. <br />
5
+ Estilos compartilhados ficam em <code>src/scss</code> (copiados da base do template).
6
+ </h4>
7
+ );
8
+ }
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+
3
+ import type { CSSProperties, ReactNode } from 'react';
4
+ import './styles.scss';
5
+
6
+ export interface ButtonProps {
7
+ onClick?: () => void;
8
+ id?: string;
9
+ sx?: CSSProperties;
10
+ children?: ReactNode;
11
+ }
12
+
13
+ export default function Button({ onClick, children, id, sx }: ButtonProps) {
14
+ return (
15
+ <button
16
+ id={id}
17
+ type="button"
18
+ onClick={onClick}
19
+ style={sx}
20
+ className="base-button"
21
+ >
22
+ {children}
23
+ </button>
24
+ );
25
+ }
@@ -0,0 +1,34 @@
1
+ @use '@/scss/_colors.scss' as *;
2
+ @use '@/scss/_mixins.scss' as *;
3
+
4
+ .base-button {
5
+ padding: 1rem;
6
+ border-radius: 2rem;
7
+ font-family: inter-semibold, 'Inter', sans-serif;
8
+ border: 4px solid $black-green;
9
+ display: flex;
10
+ align-items: center;
11
+ gap: 1rem;
12
+ justify-content: center;
13
+ transition: transform 0.3s ease;
14
+ @include set-color-black-green;
15
+ @include set-background-light-green;
16
+
17
+ @include respond-to(md) {
18
+ padding: 1rem;
19
+ }
20
+
21
+ @include respond-to(sm) {
22
+ padding: 0.7rem;
23
+ }
24
+ }
25
+
26
+ .base-button:hover {
27
+ animation: pulse 0.6s ease;
28
+ }
29
+
30
+ @keyframes pulse {
31
+ 0% { transform: scale(1); }
32
+ 50% { transform: scale(1.15); }
33
+ 100% { transform: scale(1); }
34
+ }
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+
3
+ import Image from 'next/image';
4
+ import './styles.scss';
5
+
6
+ export default function Header() {
7
+ const links = [
8
+ { label: 'Quem somos' },
9
+ { label: 'Especialistas' },
10
+ { label: 'Empresas' },
11
+ { label: 'Startups' },
12
+ { label: 'Blog' },
13
+ ];
14
+
15
+ return (
16
+ <div id="headerContainer">
17
+ <div className="logo">
18
+ <Image
19
+ src="/icons/next._icon.svg"
20
+ alt="logo"
21
+ width={96}
22
+ height={80}
23
+ priority
24
+ />
25
+ </div>
26
+ <div>
27
+ <ul className="lista-horizontal">
28
+ {links.map((link, index) => (
29
+ <li key={index}>
30
+ <a href="#">{link.label}</a>
31
+ </li>
32
+ ))}
33
+ </ul>
34
+ </div>
35
+ </div>
36
+ );
37
+ }
@@ -0,0 +1,28 @@
1
+ @use '@/scss/_mixins' as *;
2
+
3
+ #headerContainer {
4
+ gap: 4rem;
5
+ padding: 4rem 0rem;
6
+ @include center-flex;
7
+
8
+ @include respond-to(lg) {
9
+ gap: 1.5rem;
10
+ a { @include responsive-font(1vw, 1.5vw); }
11
+ }
12
+ }
13
+
14
+ .logo {
15
+ width: 6rem;
16
+ height: 5rem;
17
+ z-index: 1;
18
+
19
+ @include respond-to(md) {
20
+ width: 4rem;
21
+ height: 3rem;
22
+ }
23
+ }
24
+
25
+ .lista-horizontal {
26
+ @include row-flex;
27
+ gap: 3rem;
28
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1,59 @@
1
+ @use '@/scss/_mixins';
2
+
3
+ $light-green: #8DE42B;
4
+ $black-green: #2C4511;
5
+ $black: rgb(0, 0, 0);
6
+
7
+ // Cores secundárias
8
+ $white: #FFFFFF;
9
+ $light-grey: #F8F8F8;
10
+ $grey: #B6B6B6;
11
+ $lighter-black: #1E1F268C;
12
+ $row: #7a77778c;
13
+
14
+ // Mixins
15
+
16
+ // Cores primárias
17
+ @mixin set-color-light-green { color: $light-green; }
18
+ @mixin set-background-light-green { background-color: $light-green; }
19
+
20
+ @mixin set-color-black-green { color: $black-green; }
21
+ @mixin set-background-black-green { background-color: $black-green; }
22
+
23
+ @mixin set-color-black { color: $black; }
24
+ @mixin set-background-black { background-color: $black; }
25
+
26
+ // Cores secundárias
27
+ @mixin set-color-white { color: $white; }
28
+ @mixin set-background-white { background-color: $white; }
29
+
30
+ @mixin set-color-light-grey { color: $light-grey; }
31
+ @mixin set-background-light-grey { background-color: $light-grey; }
32
+
33
+ @mixin set-color-grey { color: $grey; }
34
+ @mixin set-background-grey { background-color: $grey; }
35
+
36
+ @mixin set-color-lighter-black { color: $lighter-black; }
37
+ @mixin set-background-lighter-black { background-color: $lighter-black; }
38
+
39
+ // Classes utilitárias
40
+ .color-light-green { @include set-color-light-green; }
41
+ .background-light-green { @include set-background-light-green; }
42
+
43
+ .color-black-green { @include set-color-black-green; }
44
+ .background-black-green { @include set-background-black-green; }
45
+
46
+ .color-black { @include set-color-black; }
47
+ .background-black { @include set-background-black; }
48
+
49
+ .color-white { @include set-color-white; }
50
+ .background-white { @include set-background-white; }
51
+
52
+ .color-light-grey { @include set-color-light-grey; }
53
+ .background-light-grey { @include set-background-light-grey; }
54
+
55
+ .color-grey { @include set-color-grey; }
56
+ .background-grey { @include set-background-grey; }
57
+
58
+ .color-lighter-black { @include set-color-lighter-black; }
59
+ .background-lighter-black { @include set-background-lighter-black; }