@icarusmx/creta 1.5.4 → 1.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/bin/creta.js +44 -3
  2. package/lib/aws-guide-viewer.js +179 -0
  3. package/lib/builders/MenuBuilder.js +23 -4
  4. package/lib/executors/ExercisesExecutor.js +8 -0
  5. package/lib/exercises/array-object-manipulation.md +1281 -0
  6. package/lib/exercises/aws-billing-detective.md +588 -0
  7. package/lib/exercises/git-stash-workflow.md +426 -0
  8. package/lib/exercises/iterm2-pane-navigation.md +504 -0
  9. package/lib/exercises/railway-deployment.md +1185 -0
  10. package/lib/papers/bitcoin/bitcoin.md +92 -0
  11. package/lib/papers/mapreduce/mapreduce.md +476 -0
  12. package/lib/papers/spark/spark.md +49 -0
  13. package/lib/vim-setup-tutorial.js +367 -0
  14. package/package.json +5 -1
  15. package/ascii-logo.txt +0 -8
  16. package/codex-refactor.txt +0 -13
  17. package/docs/diagrams/README.md +0 -131
  18. package/docs/diagrams/architecture-overview.mmd +0 -71
  19. package/docs/diagrams/architecture.svg +0 -1
  20. package/docs/diagrams/ecosystem-integration.mmd +0 -49
  21. package/docs/diagrams/evolution-phases.mmd +0 -49
  22. package/docs/diagrams/output.svg +0 -1
  23. package/docs/diagrams/phase2-command-help-flow.mmd +0 -51
  24. package/docs/diagrams/user-journey.mmd +0 -78
  25. package/ejemplo.sh +0 -3
  26. package/refactor.txt +0 -581
  27. package/templates/sveltekit-portfolio/package.json +0 -20
  28. package/templates/sveltekit-portfolio/src/app.css +0 -51
  29. package/templates/sveltekit-portfolio/src/app.html +0 -12
  30. package/templates/sveltekit-portfolio/src/routes/+layout.svelte +0 -108
  31. package/templates/sveltekit-portfolio/src/routes/+page.svelte +0 -79
  32. package/templates/sveltekit-portfolio/static/favicon.png +0 -0
  33. package/templates/sveltekit-portfolio/svelte.config.js +0 -10
  34. package/templates/sveltekit-portfolio/vite.config.js +0 -10
  35. package/test/enunciados.test.js +0 -72
  36. package/test/sintaxis-menu.test.js +0 -45
  37. package/wea-fome-qlia.sh +0 -92
package/refactor.txt DELETED
@@ -1,581 +0,0 @@
1
- # CRETA CLI - REFACTORING STRATEGY v2.0
2
- # Data-Driven Architecture (Discord-Inspired)
3
- # bin/creta.js = 1616 líneas → Target: <100 líneas entry point
4
-
5
- ## 🚨 PROBLEMA ACTUAL
6
-
7
- bin/creta.js ha crecido a 1616 líneas con **text y logic acoplados**:
8
- - Hardcoded messages mezclados con execution logic
9
- - Lessons con 280+ líneas de text + code
10
- - Difícil traducir a otros idiomas
11
- - Imposible reutilizar lesson logic
12
- - No hay separación clara data vs behavior
13
-
14
- ## 💡 INSIGHT CLAVE (Discord API Pattern)
15
-
16
- ```js
17
- // Discord approach: Data + Builder
18
- const embed = new EmbedBuilder()
19
- .setTitle('Title here')
20
- .setDescription('Description here')
21
- .addFields({ name: 'Field', value: 'Value' })
22
-
23
- // Creta equivalent:
24
- const lesson = new LessonBuilder(TERMINAL_BASICO_DATA)
25
- .withIntro()
26
- .withSteps()
27
- .start()
28
- ```
29
-
30
- **Principio:** Separar QUÉ (data) de CÓMO (execution)
31
-
32
- ## 🎯 OBJETIVO
33
-
34
- **Data-Driven Architecture:**
35
- - **Data:** Constants (text, config, lesson content) - easy to modify
36
- - **Builders:** Execution engines (lesson-builder, menu-builder) - reusable
37
- - **Orchestrators:** Coordinan builders con data - simple routing
38
-
39
- ## 📁 NUEVA ESTRUCTURA
40
-
41
- ```
42
- cli/
43
- ├── bin/
44
- │ └── creta.js # <100 líneas - Pure orchestration
45
-
46
- ├── lib/
47
- │ ├── data/ # 📝 ALL CONTENT HERE
48
- │ │ ├── enunciados.js # ENUNCIADOS array
49
- │ │ ├── messages.js # UI messages, help text
50
- │ │ ├── lessons/ # Lesson content (data only)
51
- │ │ │ ├── lesson1-data.js # Sistema - text only
52
- │ │ │ ├── lesson2-data.js # Solicitudes - text only
53
- │ │ │ ├── lesson7-data.js # Definición - text only
54
- │ │ │ └── sintaxis/
55
- │ │ │ ├── terminal-basico.js
56
- │ │ │ ├── git-basico.js
57
- │ │ │ ├── git-colaboracion.js
58
- │ │ │ └── git-avanzado.js
59
- │ │ └── menus.js # Menu configurations
60
- │ │
61
- │ ├── builders/ # 🏗️ EXECUTION ENGINES
62
- │ │ ├── LessonBuilder.js # Executes lesson data
63
- │ │ ├── MenuBuilder.js # Renders menus from config
64
- │ │ ├── ProjectBuilder.js # Creates projects from templates
65
- │ │ └── InteractiveBuilder.js # Handles interactive flows
66
- │ │
67
- │ ├── executors/ # 🎮 ORCHESTRATORS
68
- │ │ ├── enunciados-executor.js # Lesson selector + executor
69
- │ │ ├── sintaxis-executor.js # Sintaxis lesson flow
70
- │ │ ├── proyectos-executor.js # Project creation flow
71
- │ │ └── portfolio-executor.js # Portfolio level flow
72
- │ │
73
- │ ├── templates/ # 📋 TEMPLATE OPERATIONS
74
- │ │ ├── TemplateProcessor.js # Copy & process templates
75
- │ │ ├── LevelModifier.js # Apply level modifications
76
- │ │ └── PlaceholderReplacer.js # Replace {{VARIABLES}}
77
- │ │
78
- │ ├── utils/ # 🔧 UTILITIES
79
- │ │ ├── input.js # readline helpers
80
- │ │ ├── output.js # console formatting
81
- │ │ ├── file-utils.js # fs operations
82
- │ │ └── validators.js # input validation
83
- │ │
84
- │ ├── session.js # Existing - no changes
85
- │ └── pr-tutorial.js # Existing - no changes
86
-
87
- ├── lessons/ # ❌ TO BE REMOVED
88
- │ └── lesson*.js # Migrate to data/ + LessonBuilder
89
-
90
- └── templates/ # ✅ KEEP AS IS
91
- ```
92
-
93
- ## 🏗️ CORE ARCHITECTURE PATTERNS
94
-
95
- ### Pattern 1: Data Objects (Discord-style)
96
-
97
- ```js
98
- // lib/data/lessons/sintaxis/terminal-basico.js
99
- export const TERMINAL_BASICO = {
100
- id: 'terminal-basico',
101
- title: 'Terminal Básico',
102
-
103
- intro: {
104
- definition: 'Sintaxis: estudia el modo en que se combinan las palabras...',
105
- explanation: 'En esta sección aprenderemos algo más que palabras, aprenderemos comandos.',
106
- detail: 'Al final del día un comando es una palabra, la diferencia es que está dotada de un significado que tu computadora entiende.'
107
- },
108
-
109
- steps: [
110
- {
111
- type: 'command',
112
- command: 'ls',
113
- description: 'Este es tu primer comando: ls',
114
- instruction: 'Presiona ctrl + c para terminar esta sesión y después ejecuta el comando ls en tu terminal',
115
- exitOnComplete: true
116
- },
117
- {
118
- type: 'command',
119
- command: 'pwd',
120
- description: '¿Dónde estás? Usa pwd para descubrirlo',
121
- expectedOutput: (output) => output.includes('/'),
122
- onSuccess: '¡Correcto! Ahora sabes tu ubicación actual.'
123
- },
124
- {
125
- type: 'interactive-challenge',
126
- prompt: '¿Qué comando usarías para crear un directorio?',
127
- answer: 'mkdir',
128
- hint: 'Piensa en "make directory"',
129
- onSuccess: '¡Exacto! mkdir crea directorios.'
130
- }
131
- ]
132
- }
133
- ```
134
-
135
- ### Pattern 2: Builders (Execution Logic)
136
-
137
- ```js
138
- // lib/builders/LessonBuilder.js
139
- export class LessonBuilder {
140
- constructor(lessonData) {
141
- this.data = lessonData
142
- }
143
-
144
- async start() {
145
- await this.showIntro()
146
- await this.executeSteps()
147
- }
148
-
149
- async showIntro() {
150
- console.log(this.data.intro.definition)
151
- await this.waitForEnter()
152
-
153
- if (this.data.intro.explanation) {
154
- console.log(`\n${this.data.intro.explanation}`)
155
- if (this.data.intro.detail) {
156
- console.log(`\n${this.data.intro.detail}`)
157
- }
158
- }
159
- }
160
-
161
- async executeSteps() {
162
- for (const step of this.data.steps) {
163
- await this.executeStep(step)
164
- }
165
- }
166
-
167
- async executeStep(step) {
168
- switch(step.type) {
169
- case 'command':
170
- await this.showCommand(step)
171
- break
172
- case 'interactive-challenge':
173
- await this.runChallenge(step)
174
- break
175
- case 'explanation':
176
- await this.showExplanation(step)
177
- break
178
- }
179
- }
180
-
181
- async showCommand(step) {
182
- console.log(`\n${step.description}`)
183
- console.log(`\n${step.instruction}`)
184
- if (step.exitOnComplete) {
185
- // Don't wait, let them exit
186
- return
187
- }
188
- }
189
-
190
- async runChallenge(step) {
191
- const rl = createPromptInterface()
192
- const answer = await askQuestion(rl, `\n${step.prompt}: `)
193
-
194
- if (answer.toLowerCase() === step.answer.toLowerCase()) {
195
- console.log(`\n✅ ${step.onSuccess}`)
196
- } else {
197
- console.log(`\n💡 Hint: ${step.hint}`)
198
- }
199
- rl.close()
200
- }
201
-
202
- async waitForEnter() {
203
- const rl = createPromptInterface()
204
- await new Promise(resolve => {
205
- rl.question('\nPresiona Enter para comenzar...', () => {
206
- rl.close()
207
- resolve()
208
- })
209
- })
210
- }
211
- }
212
- ```
213
-
214
- ### Pattern 3: Executors (Orchestration)
215
-
216
- ```js
217
- // lib/executors/sintaxis-executor.js
218
- import { TERMINAL_BASICO } from '../data/lessons/sintaxis/terminal-basico.js'
219
- import { GIT_BASICO } from '../data/lessons/sintaxis/git-basico.js'
220
- import { LessonBuilder } from '../builders/LessonBuilder.js'
221
- import { MenuBuilder } from '../builders/MenuBuilder.js'
222
-
223
- export async function executeSintaxis() {
224
- // Step 1: Show lesson menu
225
- const menuConfig = {
226
- title: 'Aprender Sintaxis',
227
- options: [
228
- { id: 1, title: 'Terminal básico', data: TERMINAL_BASICO },
229
- { id: 2, title: 'Git básico', data: GIT_BASICO },
230
- // ...
231
- ]
232
- }
233
-
234
- const menu = new MenuBuilder(menuConfig)
235
- const selected = await menu.show()
236
-
237
- // Step 2: Execute selected lesson
238
- if (selected) {
239
- const lesson = new LessonBuilder(selected.data)
240
- await lesson.start()
241
- }
242
- }
243
- ```
244
-
245
- ### Pattern 4: Minimal Entry Point
246
-
247
- ```js
248
- // bin/creta.js (<100 lines)
249
- import { executeEnunciados } from '../lib/executors/enunciados-executor.js'
250
- import { executeSintaxis } from '../lib/executors/sintaxis-executor.js'
251
- import { executeProyectos } from '../lib/executors/proyectos-executor.js'
252
- import { showHelp } from '../lib/commands/help.js'
253
- import { WELCOME_BANNER } from '../lib/data/messages.js'
254
-
255
- console.log(WELCOME_BANNER)
256
-
257
- const args = process.argv.slice(2)
258
- const command = args[0]
259
-
260
- if (!command) {
261
- const mainMenu = new MenuBuilder(MAIN_MENU_CONFIG)
262
- const choice = await mainMenu.show()
263
-
264
- switch(choice.id) {
265
- case 1: await executeSintaxis(); break
266
- case 2: await executeEnunciados(); break
267
- case 3: await executeProyectos(); break
268
- }
269
- process.exit(0)
270
- }
271
-
272
- // Route commands
273
- const commands = {
274
- 'enunciados': executeEnunciados,
275
- 'portafolio': executePortfolio,
276
- 'help': showHelp
277
- }
278
-
279
- const handler = commands[command]
280
- if (handler) {
281
- await handler(args)
282
- } else {
283
- console.log(`Comando no reconocido: ${command}`)
284
- process.exit(1)
285
- }
286
- ```
287
-
288
- ## 🔨 REFACTORING PHASES (Data-Driven)
289
-
290
- ### PHASE 1: Create Data Layer (Zero Risk)
291
- **Goal:** Extract ALL content to data files
292
-
293
- 1. **Create lib/data/enunciados.js**
294
- - Move ENUNCIADOS array
295
-
296
- 2. **Create lib/data/messages.js**
297
- - WELCOME_BANNER
298
- - HELP_TEXT
299
- - All user-facing strings
300
-
301
- 3. **Create lib/data/menus.js**
302
- - MAIN_MENU_CONFIG
303
- - ENUNCIADOS_MENU_CONFIG
304
- - PROYECTOS_MENU_CONFIG
305
-
306
- 4. **Create lib/data/lessons/lesson1-data.js → lesson7-data.js**
307
- - Extract all text from lesson files
308
- - Convert to data objects
309
- ```js
310
- export const LESSON_1_SISTEMA = {
311
- enunciado: { id: 1, texto: '...', nivel: '...' },
312
- intro: { ... },
313
- challenges: [ ... ],
314
- examples: [ ... ]
315
- }
316
- ```
317
-
318
- **Result:** All content centralized, easy to translate
319
-
320
- ### PHASE 2: Create Builders (Low Risk)
321
- **Goal:** Reusable execution engines
322
-
323
- 1. **Create lib/builders/LessonBuilder.js**
324
- - Takes lesson data object
325
- - Executes intro, steps, challenges
326
- - ~150 lines
327
-
328
- 2. **Create lib/builders/MenuBuilder.js**
329
- - Takes menu config
330
- - Renders interactive/fallback
331
- - Handles selection
332
- - ~120 lines
333
-
334
- 3. **Create lib/builders/ProjectBuilder.js**
335
- - Takes template config
336
- - Creates/updates projects
337
- - ~100 lines
338
-
339
- 4. **Create lib/builders/InteractiveBuilder.js**
340
- - Reusable interactive patterns
341
- - Arrow keys, prompts, etc.
342
- - ~80 lines
343
-
344
- **Result:** Reusable builders for all flows
345
-
346
- ### PHASE 3: Create Template System (Medium Risk)
347
- **Goal:** Clean template operations
348
-
349
- 1. **Create lib/templates/TemplateProcessor.js**
350
- - Copy templates
351
- - Binary file handling
352
- - ~80 lines
353
-
354
- 2. **Create lib/templates/LevelModifier.js**
355
- - applyLevelModifications logic
356
- - Layout/page modifications
357
- - ~150 lines
358
-
359
- 3. **Create lib/templates/PlaceholderReplacer.js**
360
- - Replace {{VARIABLES}}
361
- - Template string processing
362
- - ~40 lines
363
-
364
- **Result:** Template operations modular
365
-
366
- ### PHASE 4: Create Executors (Medium Risk)
367
- **Goal:** Orchestrate builders + data
368
-
369
- 1. **Create lib/executors/enunciados-executor.js**
370
- - Load lesson data
371
- - Use MenuBuilder for selection
372
- - Use LessonBuilder for execution
373
- - ~80 lines
374
-
375
- 2. **Create lib/executors/sintaxis-executor.js**
376
- - Load sintaxis lessons
377
- - Menu + execution flow
378
- - ~60 lines
379
-
380
- 3. **Create lib/executors/proyectos-executor.js**
381
- - PR tutorial + portfolio
382
- - Use ProjectBuilder
383
- - ~80 lines
384
-
385
- 4. **Create lib/executors/portfolio-executor.js**
386
- - Level selection + creation
387
- - ~60 lines
388
-
389
- **Result:** Clean orchestration layer
390
-
391
- ### PHASE 5: Refactor Entry Point (Low Risk)
392
- **Goal:** Minimal bin/creta.js
393
-
394
- 1. **Simplify bin/creta.js**
395
- - Import executors
396
- - Route commands
397
- - Handle errors
398
- - **Target: <100 lines**
399
-
400
- **Result:** Clean entry point
401
-
402
- ### PHASE 6: Migrate Existing Lessons (High Impact)
403
- **Goal:** Replace lessons/* with data + LessonBuilder
404
-
405
- 1. **For each lesson1-7:**
406
- - Extract to data/lessons/lesson{N}-data.js
407
- - Test with LessonBuilder
408
- - Remove old lesson file
409
-
410
- 2. **Update imports in executors**
411
-
412
- **Result:** All lessons use LessonBuilder
413
-
414
- ### PHASE 7: Create Utils (Low Risk)
415
- **Goal:** Shared utilities
416
-
417
- 1. **Create lib/utils/input.js**
418
- - readline helpers
419
- - ~40 lines
420
-
421
- 2. **Create lib/utils/output.js**
422
- - formatting, colors
423
- - ~40 lines
424
-
425
- 3. **Create lib/utils/file-utils.js**
426
- - fs operations
427
- - ~50 lines
428
-
429
- **Result:** Clean utility layer
430
-
431
- ## 📊 EXPECTED RESULTS
432
-
433
- **Before:**
434
- - bin/creta.js: 1616 lines (mixed concerns)
435
- - lessons/: 7 files × ~200 lines = 1400 lines (text + logic)
436
-
437
- **After:**
438
- - bin/creta.js: <100 lines (pure routing)
439
- - lib/data/: ~1200 lines (content only, easy to translate)
440
- - lib/builders/: ~450 lines (4 reusable engines)
441
- - lib/executors/: ~280 lines (4 orchestrators)
442
- - lib/templates/: ~270 lines (3 template modules)
443
- - lib/utils/: ~130 lines (3 utilities)
444
-
445
- **Total:** ~2430 lines in 25+ focused modules
446
- **Key win:** Content separated from logic, reusable builders
447
-
448
- ## 🎯 BENEFITS
449
-
450
- ### For Content:
451
- ✅ Easy to translate (just swap data files)
452
- ✅ Non-developers can edit lessons
453
- ✅ Version control friendly (small diffs)
454
- ✅ A/B test different lesson flows
455
-
456
- ### For Code:
457
- ✅ Reusable builders for all lessons
458
- ✅ Test builders once, works for all content
459
- ✅ Add new lesson = just add data file
460
- ✅ DRY - no repeated execution logic
461
-
462
- ### For Maintenance:
463
- ✅ Clear separation of concerns
464
- ✅ Easy to find and fix bugs
465
- ✅ Simple to add features
466
- ✅ Refactor-friendly architecture
467
-
468
- ## 🚀 EXECUTION STRATEGY
469
-
470
- ### Approach: "Discord Pattern Migration"
471
- 1. Create data structure for one lesson
472
- 2. Create builder that executes it
473
- 3. Verify it works identically
474
- 4. Migrate next lesson
475
- 5. Remove old code
476
- 6. Repeat
477
-
478
- ### Testing Each Phase:
479
- ```bash
480
- # Test lesson with new builder
481
- node -e "
482
- import { LESSON_1_SISTEMA } from './lib/data/lessons/lesson1-data.js'
483
- import { LessonBuilder } from './lib/builders/LessonBuilder.js'
484
- const lesson = new LessonBuilder(LESSON_1_SISTEMA)
485
- await lesson.start()
486
- "
487
-
488
- # Test full flow
489
- node bin/creta.js enunciados
490
- node bin/creta.js portafolio
491
- ```
492
-
493
- ### Git Strategy:
494
- - Commit after each phase
495
- - Keep old code until new is tested
496
- - Easy rollback
497
- - Tag stable versions
498
-
499
- ### Priority Order:
500
- 1. Phase 1 (data layer) - Foundation
501
- 2. Phase 2 (builders) - Core engines
502
- 3. Phase 7 (utils) - Supporting tools
503
- 4. Phase 4 (executors) - Orchestration
504
- 5. Phase 3 (templates) - Template system
505
- 6. Phase 5 (entry point) - Simplification
506
- 7. Phase 6 (migrate lessons) - Final migration
507
-
508
- ## 📝 ARCHITECTURAL PRINCIPLES
509
-
510
- ### Data-Driven Design:
511
- 1. **Data is King:** All content in data/
512
- 2. **Builders Execute:** Logic in builders/
513
- 3. **Executors Orchestrate:** Flow in executors/
514
- 4. **Entry Routes:** bin/creta.js just routes
515
-
516
- ### Simple Solutions:
517
- - No over-engineering
518
- - JavaScript objects (not complex schemas)
519
- - Readable, not clever
520
- - Maintainable over perfect
521
-
522
- ### Discord-Inspired Patterns:
523
- ```js
524
- // Instead of:
525
- class Lesson7 {
526
- async start() {
527
- console.log("hardcoded text...")
528
- // logic
529
- }
530
- }
531
-
532
- // Do this:
533
- const LESSON_7 = {
534
- intro: { text: "..." },
535
- steps: [...]
536
- }
537
- const lesson = new LessonBuilder(LESSON_7)
538
- await lesson.start()
539
- ```
540
-
541
- ## ✅ SUCCESS CRITERIA
542
-
543
- Refactoring complete when:
544
- 1. ✅ bin/creta.js < 100 lines
545
- 2. ✅ All content in lib/data/
546
- 3. ✅ All lessons use LessonBuilder
547
- 4. ✅ MenuBuilder handles all menus
548
- 5. ✅ No text hardcoded in logic
549
- 6. ✅ All existing commands work
550
- 7. ✅ Easy to add new lessons (just add data)
551
- 8. ✅ Easy to translate (just swap data files)
552
-
553
- ## 🎯 LONG-TERM WINS
554
-
555
- ### Easy Internationalization:
556
- ```js
557
- // lib/data/lessons/en/lesson1-data.js
558
- // lib/data/lessons/es/lesson1-data.js
559
- // Just swap import based on locale
560
- ```
561
-
562
- ### CMS-Ready:
563
- - Data files could come from database
564
- - Non-technical content updates
565
- - A/B testing different lesson flows
566
-
567
- ### Extensible:
568
- - New lesson types? Add to builder
569
- - New step types? Extend executeStep()
570
- - New templates? Add to ProjectBuilder
571
-
572
- ---
573
-
574
- **Philosophy:** "Text tells the story, builders bring it to life"
575
-
576
- **Start Date:** TBD
577
- **Target Completion:** 2-3 days (phased)
578
- **Estimated Effort:** 12-16 hours
579
- **Risk Level:** Low-Medium (data migration is safe, builders are reusable)
580
-
581
- Last updated: 2025-10-03
@@ -1,20 +0,0 @@
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
- "svelte": "^5.0.0",
15
- "tailwindcss": "^4.0.0",
16
- "@tailwindcss/vite": "^4.0.0",
17
- "vite": "^5.0.3"
18
- },
19
- "type": "module"
20
- }
@@ -1,51 +0,0 @@
1
- @import "tailwindcss";
2
-
3
- /* Animaciones personalizadas */
4
- @keyframes fade-in {
5
- from {
6
- opacity: 0;
7
- transform: translateY(20px);
8
- }
9
- to {
10
- opacity: 1;
11
- transform: translateY(0);
12
- }
13
- }
14
-
15
- .animate-fade-in {
16
- animation: fade-in 1s ease-out;
17
- }
18
-
19
- /* Mejoras de scroll suave */
20
- html {
21
- scroll-behavior: smooth;
22
- }
23
-
24
- /* Estilos personalizados para el código */
25
- code {
26
- font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
27
- }
28
-
29
- /* Hover effects para las tarjetas de proyectos */
30
- .project-card {
31
- transition: transform 0.2s ease-in-out;
32
- }
33
-
34
- .project-card:hover {
35
- transform: translateY(-5px);
36
- }
37
-
38
- /* Efectos de focus mejorados */
39
- input:focus,
40
- textarea:focus {
41
- outline: none;
42
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
43
- }
44
-
45
- /* Gradientes personalizados */
46
- .gradient-text {
47
- background: linear-gradient(45deg, #3b82f6, #8b5cf6);
48
- -webkit-background-clip: text;
49
- -webkit-text-fill-color: transparent;
50
- background-clip: text;
51
- }
@@ -1,12 +0,0 @@
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>