@icarusmx/creta 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +25 -0
- package/bin/creta.js +215 -1
- package/package.json +2 -1
- package/templates/sveltekit-portfolio/package.json +21 -0
- package/templates/sveltekit-portfolio/postcss.config.js +6 -0
- package/templates/sveltekit-portfolio/src/app.css +3 -0
- package/templates/sveltekit-portfolio/src/app.html +12 -0
- package/templates/sveltekit-portfolio/src/routes/+layout.svelte +90 -0
- package/templates/sveltekit-portfolio/src/routes/+page.svelte +48 -0
- package/templates/sveltekit-portfolio/static/favicon.png +1 -0
- package/templates/sveltekit-portfolio/svelte.config.js +10 -0
- package/templates/sveltekit-portfolio/tailwind.config.js +8 -0
- package/templates/sveltekit-portfolio/vite.config.js +6 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
This is "@icarusmx/creta" - a minimal CLI tool for the Icarus software school. The project is currently in early development (v0.0.2) with basic structure in place.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
- **Entry point**: `bin/creta.js` - Simple Node.js CLI executable that outputs a welcome message
|
|
12
|
+
- **Package**: Published as `@icarusmx/creta` on npm with public access
|
|
13
|
+
- **Language**: JavaScript (no TypeScript)
|
|
14
|
+
|
|
15
|
+
## Development Commands
|
|
16
|
+
|
|
17
|
+
This is a minimal CLI project without build tools, testing frameworks, or linting configured yet. The main executable can be tested directly:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
node bin/creta.js
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Current State
|
|
24
|
+
|
|
25
|
+
The CLI currently only displays "Bienvenido a Crea" - this appears to be a foundational setup awaiting feature development.
|
package/bin/creta.js
CHANGED
|
@@ -1,3 +1,217 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { createInterface } from 'readline'
|
|
4
|
+
import { execSync } from 'child_process'
|
|
5
|
+
import fs from 'fs'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
|
|
8
|
+
const args = process.argv.slice(2)
|
|
9
|
+
const command = args[0]
|
|
10
|
+
|
|
11
|
+
console.log("¡Bienvenido a Creta! 🏛️")
|
|
12
|
+
console.log("Aprendamos construyendo productos reales.\n")
|
|
13
|
+
|
|
14
|
+
if (!command) {
|
|
15
|
+
console.log("Comandos disponibles:")
|
|
16
|
+
console.log(" creta website - Crea tu portfolio personal (reto completo)")
|
|
17
|
+
console.log(" creta website-1 - Portfolio con navbar hecho")
|
|
18
|
+
console.log(" creta website-2 - Portfolio con navbar + hero")
|
|
19
|
+
console.log(" creta website-3 - Portfolio completo (solución)")
|
|
20
|
+
process.exit(0)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (command.startsWith('website')) {
|
|
24
|
+
const level = command === 'website' ? 0 : parseInt(command.split('-')[1]) || 0
|
|
25
|
+
await createWebsiteProject(level)
|
|
26
|
+
} else {
|
|
27
|
+
console.log(`Comando no reconocido: ${command}`)
|
|
28
|
+
process.exit(1)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function createWebsiteProject(level) {
|
|
32
|
+
const rl = createInterface({
|
|
33
|
+
input: process.stdin,
|
|
34
|
+
output: process.stdout
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const askQuestion = (question) => {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
rl.question(question, resolve)
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const name = await askQuestion("¿Cuál es tu nombre? ")
|
|
45
|
+
const projectName = `${name.toLowerCase().replace(/\s+/g, '-')}-portfolio`
|
|
46
|
+
|
|
47
|
+
console.log(`\n🚀 Creando proyecto: ${projectName}`)
|
|
48
|
+
console.log(`📚 Nivel: ${level === 0 ? 'Reto completo' : `Con ${getLevelDescription(level)} completado`}`)
|
|
49
|
+
|
|
50
|
+
await createProjectFiles(projectName, name, level)
|
|
51
|
+
|
|
52
|
+
console.log(`\n✨ ¡Proyecto creado exitosamente!`)
|
|
53
|
+
console.log(`\n📁 Ingresa a tu proyecto: cd ${projectName}`)
|
|
54
|
+
console.log(`📦 Instala dependencias: npm install`)
|
|
55
|
+
console.log(`🚀 Inicia el servidor: npm run dev`)
|
|
56
|
+
console.log(`\n💡 Lee los comentarios en los archivos para saber qué hacer`)
|
|
57
|
+
|
|
58
|
+
rl.close()
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error('Error:', error.message)
|
|
61
|
+
rl.close()
|
|
62
|
+
process.exit(1)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function createProjectFiles(projectName, studentName, level) {
|
|
67
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname)
|
|
68
|
+
const templatePath = path.join(__dirname, '../templates/sveltekit-portfolio')
|
|
69
|
+
const targetPath = path.join(process.cwd(), projectName)
|
|
70
|
+
|
|
71
|
+
// Check if template exists
|
|
72
|
+
if (!fs.existsSync(templatePath)) {
|
|
73
|
+
throw new Error('Template no encontrado. Asegúrate de ejecutar desde el directorio correcto.')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Create target directory
|
|
77
|
+
if (fs.existsSync(targetPath)) {
|
|
78
|
+
throw new Error(`El directorio ${projectName} ya existe`)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
fs.mkdirSync(targetPath, { recursive: true })
|
|
82
|
+
|
|
83
|
+
// Copy template files
|
|
84
|
+
await copyTemplate(templatePath, targetPath, projectName, studentName, level)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function copyTemplate(src, dest, projectName, studentName, level) {
|
|
88
|
+
const items = fs.readdirSync(src)
|
|
89
|
+
|
|
90
|
+
for (const item of items) {
|
|
91
|
+
const srcPath = path.join(src, item)
|
|
92
|
+
const destPath = path.join(dest, item)
|
|
93
|
+
|
|
94
|
+
if (fs.statSync(srcPath).isDirectory()) {
|
|
95
|
+
fs.mkdirSync(destPath, { recursive: true })
|
|
96
|
+
await copyTemplate(srcPath, destPath, projectName, studentName, level)
|
|
97
|
+
} else {
|
|
98
|
+
let content = fs.readFileSync(srcPath, 'utf8')
|
|
99
|
+
|
|
100
|
+
// Apply level-specific modifications first
|
|
101
|
+
if (level > 0) {
|
|
102
|
+
content = applyLevelModifications(content, item, level)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Then replace placeholders
|
|
106
|
+
content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName)
|
|
107
|
+
content = content.replace(/\{\{STUDENT_NAME\}\}/g, studentName)
|
|
108
|
+
|
|
109
|
+
fs.writeFileSync(destPath, content)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function applyLevelModifications(content, filename, level) {
|
|
115
|
+
if (filename === '+layout.svelte') {
|
|
116
|
+
return applyLayoutModifications(content, level)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (filename === '+page.svelte') {
|
|
120
|
+
return applyPageModifications(content, level)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return content
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function applyLayoutModifications(content, level) {
|
|
127
|
+
if (level >= 1) {
|
|
128
|
+
// Replace navbar placeholder with complete solution
|
|
129
|
+
content = content.replace(
|
|
130
|
+
'<nav class="bg-white shadow-sm">\n <!-- ⚠️ COMPLETA AQUÍ LA NAVEGACIÓN -->\n</nav>',
|
|
131
|
+
`<nav class="bg-white shadow-sm">
|
|
132
|
+
<div class="max-w-7xl mx-auto px-4">
|
|
133
|
+
<div class="flex justify-between items-center py-3">
|
|
134
|
+
<div class="text-xl font-bold text-gray-900">{{STUDENT_NAME}}</div>
|
|
135
|
+
<div class="hidden md:flex space-x-6">
|
|
136
|
+
<a href="#inicio" class="text-gray-600 hover:text-blue-600">Inicio</a>
|
|
137
|
+
<a href="#sobre-mi" class="text-gray-600 hover:text-blue-600">Sobre mí</a>
|
|
138
|
+
<a href="#proyectos" class="text-gray-600 hover:text-blue-600">Proyectos</a>
|
|
139
|
+
<a href="#contacto" class="text-gray-600 hover:text-blue-600">Contacto</a>
|
|
140
|
+
</div>
|
|
141
|
+
<button class="md:hidden">
|
|
142
|
+
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
143
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
|
144
|
+
</svg>
|
|
145
|
+
</button>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</nav>`
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (level >= 3) {
|
|
153
|
+
// Replace footer placeholder with complete solution
|
|
154
|
+
content = content.replace(
|
|
155
|
+
'<footer class="bg-gray-50 border-t">\n <!-- ⚠️ COMPLETA AQUÍ EL FOOTER -->\n</footer>',
|
|
156
|
+
`<footer class="bg-gray-50 border-t">
|
|
157
|
+
<div class="max-w-7xl mx-auto py-8 px-4">
|
|
158
|
+
<div class="text-center text-gray-600 text-sm space-y-2">
|
|
159
|
+
<p>© ${new Date().getFullYear()} {{STUDENT_NAME}}. Todos los derechos reservados.</p>
|
|
160
|
+
<p>Hecho con ❤️ en <a href="https://creta.school" class="text-blue-600 hover:underline">Creta</a></p>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</footer>`
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return content
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function applyPageModifications(content, level) {
|
|
171
|
+
if (level >= 2) {
|
|
172
|
+
// Replace hero placeholder with complete solution
|
|
173
|
+
content = content.replace(
|
|
174
|
+
`<section class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100">
|
|
175
|
+
<!-- ⚠️ COMPLETA AQUÍ LA SECCIÓN HERO -->
|
|
176
|
+
<div class="max-w-4xl mx-auto px-4 text-center">
|
|
177
|
+
<h1 class="text-4xl md:text-6xl font-bold text-gray-900 mb-6">
|
|
178
|
+
¡Construye tu hero aquí!
|
|
179
|
+
</h1>
|
|
180
|
+
<p class="text-lg text-gray-600 mb-8">
|
|
181
|
+
Lee los comentarios arriba para saber qué hacer ☝️
|
|
182
|
+
</p>
|
|
183
|
+
</div>
|
|
184
|
+
</section>`,
|
|
185
|
+
`<section class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100">
|
|
186
|
+
<div class="max-w-4xl mx-auto px-4 text-center">
|
|
187
|
+
<h1 class="text-4xl md:text-6xl font-bold text-gray-900 mb-6">
|
|
188
|
+
Hola, soy {{STUDENT_NAME}}
|
|
189
|
+
</h1>
|
|
190
|
+
<p class="text-lg text-gray-600 mb-8 max-w-2xl mx-auto">
|
|
191
|
+
Soy un desarrollador apasionado por crear productos digitales que impacten positivamente.
|
|
192
|
+
Aprendo construyendo y siempre busco nuevos desafíos.
|
|
193
|
+
</p>
|
|
194
|
+
<div class="flex justify-center space-x-4">
|
|
195
|
+
<a href="#proyectos" class="bg-blue-600 hover:bg-blue-700 text-white px-8 py-3 rounded-lg transition-colors">
|
|
196
|
+
Ver proyectos
|
|
197
|
+
</a>
|
|
198
|
+
<a href="#contacto" class="border border-blue-600 text-blue-600 hover:bg-blue-50 px-8 py-3 rounded-lg transition-colors">
|
|
199
|
+
Contáctame
|
|
200
|
+
</a>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</section>`
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return content
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function getLevelDescription(level) {
|
|
211
|
+
const descriptions = {
|
|
212
|
+
1: 'navbar',
|
|
213
|
+
2: 'navbar + hero',
|
|
214
|
+
3: 'todo el portfolio'
|
|
215
|
+
}
|
|
216
|
+
return descriptions[level] || 'nivel desconocido'
|
|
217
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "vite build",
|
|
7
|
+
"dev": "vite dev",
|
|
8
|
+
"preview": "vite preview"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@sveltejs/adapter-auto": "^3.0.0",
|
|
12
|
+
"@sveltejs/kit": "^2.0.0",
|
|
13
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
14
|
+
"autoprefixer": "^10.4.16",
|
|
15
|
+
"postcss": "^8.4.32",
|
|
16
|
+
"svelte": "^5.0.0",
|
|
17
|
+
"tailwindcss": "^3.3.6",
|
|
18
|
+
"vite": "^5.0.3"
|
|
19
|
+
},
|
|
20
|
+
"type": "module"
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="es">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
%sveltekit.head%
|
|
8
|
+
</head>
|
|
9
|
+
<body data-sveltekit-preload-data="hover" class="antialiased">
|
|
10
|
+
<div style="display: contents">%sveltekit.body%</div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
RETO CRETA: PORTFOLIO PERSONAL
|
|
3
|
+
===============================
|
|
4
|
+
|
|
5
|
+
¡Hola {{STUDENT_NAME}}! 👋
|
|
6
|
+
|
|
7
|
+
Este es tu proyecto base para crear un portfolio personal.
|
|
8
|
+
Necesitas completar 3 secciones principales:
|
|
9
|
+
|
|
10
|
+
1. 🧭 NAVBAR (Barra de navegación)
|
|
11
|
+
2. 🌟 HERO (Sección principal)
|
|
12
|
+
3. 🦶 FOOTER (Pie de página)
|
|
13
|
+
|
|
14
|
+
Cada sección tiene comentarios que te guían sobre qué hacer.
|
|
15
|
+
|
|
16
|
+
COMANDOS ÚTILES:
|
|
17
|
+
- npm run dev (inicia el servidor de desarrollo)
|
|
18
|
+
- Ctrl+C (para parar el servidor)
|
|
19
|
+
|
|
20
|
+
¡Manos a la obra! 🚀
|
|
21
|
+
-->
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
import '../app.css'
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<!--
|
|
28
|
+
🧭 RETO 1: NAVBAR
|
|
29
|
+
==================
|
|
30
|
+
|
|
31
|
+
Crea una barra de navegación que incluya:
|
|
32
|
+
- Logo o nombre (lado izquierdo)
|
|
33
|
+
- Menú de navegación (lado derecho)
|
|
34
|
+
* Inicio
|
|
35
|
+
* Sobre mí
|
|
36
|
+
* Proyectos
|
|
37
|
+
* Contacto
|
|
38
|
+
|
|
39
|
+
TIPS DE TAILWIND:
|
|
40
|
+
- Usa 'flex justify-between items-center' para distribuir elementos
|
|
41
|
+
- Usa 'bg-white shadow-sm' para fondo y sombra sutil
|
|
42
|
+
- Usa 'px-4 py-3' para espaciado interno
|
|
43
|
+
- Usa 'hover:text-blue-600' para efectos hover
|
|
44
|
+
|
|
45
|
+
ESTRUCTURA SUGERIDA:
|
|
46
|
+
<nav class="bg-white shadow-sm">
|
|
47
|
+
<div class="max-w-7xl mx-auto px-4">
|
|
48
|
+
<div class="flex justify-between items-center py-3">
|
|
49
|
+
<!-- Logo/Nombre aquí -->
|
|
50
|
+
<!-- Menú aquí -->
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</nav>
|
|
54
|
+
-->
|
|
55
|
+
|
|
56
|
+
<nav class="bg-white shadow-sm">
|
|
57
|
+
<!-- ⚠️ COMPLETA AQUÍ LA NAVEGACIÓN -->
|
|
58
|
+
</nav>
|
|
59
|
+
|
|
60
|
+
<main>
|
|
61
|
+
<slot />
|
|
62
|
+
</main>
|
|
63
|
+
|
|
64
|
+
<!--
|
|
65
|
+
🦶 RETO 3: FOOTER
|
|
66
|
+
==================
|
|
67
|
+
|
|
68
|
+
Crea un pie de página simple que incluya:
|
|
69
|
+
- Tu nombre y año actual
|
|
70
|
+
- Links a redes sociales (opcional)
|
|
71
|
+
- Mensaje "Hecho con ❤️ en Creta"
|
|
72
|
+
|
|
73
|
+
TIPS DE TAILWIND:
|
|
74
|
+
- Usa 'bg-gray-50 border-t' para fondo y borde superior
|
|
75
|
+
- Usa 'py-8 px-4' para espaciado
|
|
76
|
+
- Usa 'text-center text-gray-600 text-sm' para texto centrado y gris
|
|
77
|
+
|
|
78
|
+
ESTRUCTURA SUGERIDA:
|
|
79
|
+
<footer class="bg-gray-50 border-t">
|
|
80
|
+
<div class="max-w-7xl mx-auto py-8 px-4">
|
|
81
|
+
<div class="text-center text-gray-600 text-sm">
|
|
82
|
+
<!-- Tu contenido aquí -->
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</footer>
|
|
86
|
+
-->
|
|
87
|
+
|
|
88
|
+
<footer class="bg-gray-50 border-t">
|
|
89
|
+
<!-- ⚠️ COMPLETA AQUÍ EL FOOTER -->
|
|
90
|
+
</footer>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
🌟 RETO 2: HERO SECTION
|
|
3
|
+
========================
|
|
4
|
+
|
|
5
|
+
Crea la sección principal de tu portfolio que incluya:
|
|
6
|
+
- Tu nombre como título principal
|
|
7
|
+
- Una descripción breve de quién eres
|
|
8
|
+
- Un botón de llamada a la acción
|
|
9
|
+
- Opcionalmente: tu foto o avatar
|
|
10
|
+
|
|
11
|
+
TIPS DE TAILWIND:
|
|
12
|
+
- Usa 'min-h-screen flex items-center justify-center' para centrar verticalmente
|
|
13
|
+
- Usa 'text-4xl md:text-6xl font-bold' para títulos grandes y responsivos
|
|
14
|
+
- Usa 'text-lg text-gray-600 mb-8' para descripciones
|
|
15
|
+
- Usa 'bg-blue-600 hover:bg-blue-700 text-white px-8 py-3 rounded-lg' para botones
|
|
16
|
+
|
|
17
|
+
ESTRUCTURA SUGERIDA:
|
|
18
|
+
<section class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100">
|
|
19
|
+
<div class="max-w-4xl mx-auto px-4 text-center">
|
|
20
|
+
<h1 class="text-4xl md:text-6xl font-bold text-gray-900 mb-6">
|
|
21
|
+
Hola, soy [Tu Nombre]
|
|
22
|
+
</h1>
|
|
23
|
+
<p class="text-lg text-gray-600 mb-8">
|
|
24
|
+
[Tu descripción aquí]
|
|
25
|
+
</p>
|
|
26
|
+
<a href="#contacto" class="bg-blue-600 hover:bg-blue-700 text-white px-8 py-3 rounded-lg">
|
|
27
|
+
Contáctame
|
|
28
|
+
</a>
|
|
29
|
+
</div>
|
|
30
|
+
</section>
|
|
31
|
+
-->
|
|
32
|
+
|
|
33
|
+
<svelte:head>
|
|
34
|
+
<title>{{STUDENT_NAME}} - Portfolio</title>
|
|
35
|
+
<meta name="description" content="Portfolio personal de {{STUDENT_NAME}}" />
|
|
36
|
+
</svelte:head>
|
|
37
|
+
|
|
38
|
+
<section class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100">
|
|
39
|
+
<!-- ⚠️ COMPLETA AQUÍ LA SECCIÓN HERO -->
|
|
40
|
+
<div class="max-w-4xl mx-auto px-4 text-center">
|
|
41
|
+
<h1 class="text-4xl md:text-6xl font-bold text-gray-900 mb-6">
|
|
42
|
+
¡Construye tu hero aquí!
|
|
43
|
+
</h1>
|
|
44
|
+
<p class="text-lg text-gray-600 mb-8">
|
|
45
|
+
Lee los comentarios arriba para saber qué hacer ☝️
|
|
46
|
+
</p>
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><rect width="32" height="32" fill="#3b82f6"/><text x="16" y="20" font-family="Arial" font-size="18" fill="white" text-anchor="middle">C</text></svg>
|