free-framework 4.6.8 → 4.7.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.
@@ -200,185 +200,195 @@ if (server.namedMiddlewares['auth']) server.namedMiddlewares['AuthGuard'] = serv
200
200
  " }\n" +
201
201
  "\n" +
202
202
  " const headerHtml = helpers.renderComponent('Header', props);\n" +
203
- " const fullHTML = `<!DOCTYPE html><html lang=\"en\"><head>\n" +
204
- " <meta charset=\"UTF-8\"><title>Free Ultra | " + viewName + "</title>\n" +
205
- " <meta name=\"csrf-token\" content=\"${res.context.csrfToken || ''}\">\n" +
206
- " <link href=\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;700;900&display=swap\" rel=\"stylesheet\">\n" +
207
- " <link rel=\"stylesheet\" href=\"/css/app.css\">\n" +
208
- " <style>\n" +
209
- " :root { --primary:#00ff88; --secondary:#00bdff; --dark:#050505; }\n" +
210
- " * { box-sizing:border-box; }\n" +
211
- " body { margin:0; font-family:'Outfit',sans-serif; background:var(--dark); color:white; overflow-x:hidden; scroll-behavior:smooth; }\n" +
212
- " main { width:100%; max-width:1000px; margin:0 auto; padding:6rem 2rem 2rem; min-height:100vh; }\n" +
213
- " ${scopedCSS}\n" +
214
- " </style>\n" +
215
- " <script src=\"/free-runtime.js\" defer></script></head>\n" +
216
- " <body>${headerHtml}<main id=\"free-app-root\">${pageHtml}</main></body></html>`;\n" +
217
- " const minified = await minify(fullHTML, { collapseWhitespace: true, removeComments: true, continueOnParseError: true });\n" +
218
- " res.header('Content-Type', 'text/html').send(fullHTML);\n" +
203
+ " const fullHTML = `<!DOCTYPE html>
204
+ < html lang = "en" >
205
+ <head>
206
+ <meta charset="UTF-8">
207
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
208
+ <title>Free Ultra | ${viewName}</title>
209
+ <meta name="csrf-token" content="${res.context.csrfToken || ''}">
210
+ <link rel="preconnect" href="https://fonts.googleapis.com">
211
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
212
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
213
+ <link rel="stylesheet" href="/css/app.css">
214
+ <style>
215
+ :root {--primary:#00ff88; --secondary:#00bdff; --dark:#050505; }
216
+ body {margin:0; font-family:'Outfit', system-ui, sans-serif; background:var(--dark); color:white; overflow-x:hidden; scroll-behavior:smooth; }
217
+ ${scopedCSS}
218
+ </style>
219
+ <script src="/free-runtime.js" defer></script>
220
+ </head>
221
+ <body>
222
+ ${headerHtml}
223
+ <main id="free-app-root">
224
+ ${pageHtml}
225
+ </main>
226
+ </body>
227
+ </html>`;
228
+ res.header('Content-Type', 'text/html').send(fullHTML);
219
229
  " } else {\n" +
220
- " // API route - return JSON\n" +
221
- " res.json({ success: true, result });\n" +
230
+ " // API route - return JSON\n" +
231
+ " res.json({success: true, result });\n" +
222
232
  " }\n" +
223
233
  "});\n";
224
234
  }
225
235
  });
226
236
 
227
- output += `\nif (require.main === module) {
228
- ORM.migrate(modelsRegistry).then(() => {
229
- server.start(process.env.PORT || 4000);
230
- }).catch(err => console.error(err));
237
+ output += `\nif (require.main === module) {
238
+ ORM.migrate(modelsRegistry).then(() => {
239
+ server.start(process.env.PORT || 4000);
240
+ }).catch(err => console.error(err));
231
241
  }
232
242
 
233
- module.exports = { ...modelsRegistry, server, modelsRegistry, ORM };
234
- `;
243
+ module.exports = {...modelsRegistry, server, modelsRegistry, ORM};
244
+ `;
235
245
 
236
- return output;
246
+ return output;
237
247
  }
238
248
 
239
- function generateUltraComponent(node) {
249
+ function generateUltraComponent(node) {
240
250
  const onMount = node.body.find(n => n.type === 'onMount')?.code || '';
241
251
  const onDestroy = node.body.find(n => n.type === 'onDestroy')?.code || '';
242
252
  const isInteractive = node.states.length > 0 || onMount !== '' || onDestroy !== '' || hasInteractivity(node.body);
243
253
  const stateNames = node.states.map(s => s.name);
244
254
 
245
- let code = `\nfunction render${node.name}(props = { }, helpers = { }) {\n`;
255
+ let code = `\nfunction render${node.name}(props = { }, helpers = { }) {\n`;
246
256
  code += ` const e = (str) => String(str).replace(/[&<>'"]/g, m => ({'&': '&amp;', '<': '&lt;', '>': '&gt;', "'": '&#39;', '"': '&quot;' }[m]));\n`;
247
- code += ` const state = {\n`;
257
+ code += ` const state = {\n`;
248
258
  node.states.forEach(s => {
249
- let val = s.default;
250
- const isExpression = typeof val === 'string' && (val.includes('props.') || val.includes('||') || val.includes('&&') || val === 'true' || val === 'false' || val === 'null' || val.trim().startsWith('{') || val.trim().startsWith('['));
259
+ let val = s.default;
260
+ const isExpression = typeof val === 'string' && (val.includes('props.') || val.includes('||') || val.includes('&&') || val === 'true' || val === 'false' || val === 'null' || val.trim().startsWith('{') || val.trim().startsWith('['));
251
261
  const finalVal = (isExpression || typeof val === 'number') ? val : `"${val}"`;
252
- code += ` "${s.name}": ${finalVal},\n`;
262
+ code += ` "${s.name}": ${finalVal},\n`;
253
263
  });
254
264
  code += ` };\n`;
255
265
  if (stateNames.length > 0) {
256
- code += ` const { ${stateNames.join(', ')} } = state;\n`;
266
+ code += ` const { ${stateNames.join(', ')} } = state;\n`;
257
267
  }
258
268
 
259
- code += ` const _events = [];\n`;
260
- code += ` const islandAttr = ${isInteractive} ? ' data-component="${node.name}"' : '';\n`;
261
- code += ` let html = "<div class='free-component'" + islandAttr + " data-state='" + JSON.stringify(state).replace(/'/g, "&#39;") + "'";\n`;
269
+ code += ` const _events = [];\n`;
270
+ code += ` const islandAttr = ${isInteractive} ? ' data-component="${node.name}"' : '';\n`;
271
+ code += ` let html = "<div class='free-component'" + islandAttr + " data-state='" + JSON.stringify(state).replace(/'/g, "&#39;") + "'";\n`;
262
272
 
263
- if (onMount) {
264
- code += ` _events.push({ id: 'onMount', fn: function(state) { ${onMount} } });\n`;
265
- code += ` html += " data-free-on-mount='onMount'";\n`;
273
+ if (onMount) {
274
+ code += ` _events.push({ id: 'onMount', fn: function(state) { ${onMount} } });\n`;
275
+ code += ` html += " data-free-on-mount='onMount'";\n`;
266
276
  }
267
- if (onDestroy) {
268
- code += ` _events.push({ id: 'onDestroy', fn: function(state) { ${onDestroy} } });\n`;
269
- code += ` html += " data-free-on-destroy='onDestroy'";\n`;
277
+ if (onDestroy) {
278
+ code += ` _events.push({ id: 'onDestroy', fn: function(state) { ${onDestroy} } });\n`;
279
+ code += ` html += " data-free-on-destroy='onDestroy'";\n`;
270
280
  }
271
281
 
272
282
  code += ` html += ">";\n`;
273
- code += generateComponentBody(node.body, stateNames);
283
+ code += generateComponentBody(node.body, stateNames);
274
284
 
275
- if (isInteractive) {
276
- code += ` html += "<script>window.__free_actions = window.__free_actions || {}; window.__free_actions['${node.name}'] = {};";\n`;
285
+ if (isInteractive) {
286
+ code += ` html += "<script>window.__free_actions = window.__free_actions || {}; window.__free_actions['${node.name}'] = {};";\n`;
277
287
  code += ` _events.forEach(ev => {\n`;
278
- code += ` html += "window.__free_actions['${node.name}'][ev.id] = " + ev.fn.toString() + ";";\n`;
288
+ code += ` html += "window.__free_actions['${node.name}'][ev.id] = " + ev.fn.toString() + ";";\n`;
279
289
  code += ` });\n`;
280
- code += ` html += "</script>";\n`;
290
+ code += ` html += "</script>";\n`;
281
291
  }
282
292
 
283
- code += ` html += "</div>";\n return html;\n}\n`;
284
- return code;
293
+ code += ` html += "</div>";\n return html;\n}\n`;
294
+ return code;
285
295
  }
286
296
 
287
- function generateComponentBody(body, stateNames) {
288
- let code = "";
297
+ function generateComponentBody(body, stateNames) {
298
+ let code = "";
289
299
  body.forEach(node => {
290
300
  if (node.type === 'tag') {
291
- code += generateTagCode(node, stateNames);
301
+ code += generateTagCode(node, stateNames);
292
302
  } else if (node.type === 'event') {
293
303
  return;
294
304
  } else if (node.type === 'script') {
295
305
  const scriptCode = node.code.replace(/`/g, '\\`').replace(/\$/g, '\\$');
296
- code += ` html += \`<script>${scriptCode}</script>\`;\n`;
306
+ code += ` html += \`<script>${scriptCode}</script>\`;\n`;
297
307
  } else if (node.type === 'loop') {
298
- code += " if (Array.isArray(" + node.list + ")) {\n";
308
+ code += " if (Array.isArray(" + node.list + ")) {\n";
299
309
  code += " " + node.list + ".forEach(" + node.item + " => {\n";
300
- code += generateComponentBody(node.body, stateNames).replace(/^ /gm, ' ');
310
+ code += generateComponentBody(node.body, stateNames).replace(/^ /gm, ' ');
301
311
  code += " });\n";
302
312
  code += " }\n";
303
313
  } else if (node.type === 'condition') {
304
- code += " if (" + node.condition + ") {\n";
305
- code += generateComponentBody(node.body, stateNames).replace(/^ /gm, ' ');
314
+ code += " if (" + node.condition + ") {\n";
315
+ code += generateComponentBody(node.body, stateNames).replace(/^ /gm, ' ');
306
316
  code += " }\n";
307
317
  }
308
318
  });
309
- return code;
319
+ return code;
310
320
  }
311
321
 
312
- function hasInteractivity(nodes) {
322
+ function hasInteractivity(nodes) {
313
323
  return nodes.some(n => {
314
324
  if (n.type === 'tag') {
315
325
  if (n.attributes && Object.keys(n.attributes).some(a => a.startsWith('on'))) return true;
316
- if (n.children && hasInteractivity(n.children)) return true;
326
+ if (n.children && hasInteractivity(n.children)) return true;
317
327
  }
318
- return false;
328
+ return false;
319
329
  });
320
330
  }
321
331
 
322
- function generateTagCode(tag, stateNames) {
332
+ function generateTagCode(tag, stateNames) {
323
333
  const isComponent = tag.name[0] === tag.name[0].toUpperCase();
324
- if (isComponent) {
325
- let propsStr = "{";
334
+ if (isComponent) {
335
+ let propsStr = "{";
326
336
  if (tag.attributes) {
327
- Object.keys(tag.attributes).forEach((a, i) => {
328
- let val = tag.attributes[a].replace(/\{([^}]+)\}/g, (_, p) => "${" + p + "}");
329
- propsStr += (i === 0 ? "" : ", ") + '"' + a + '": `' + val + '`';
330
- });
337
+ Object.keys(tag.attributes).forEach((a, i) => {
338
+ let val = tag.attributes[a].replace(/\{([^}]+)\}/g, (_, p) => "${" + p + "}");
339
+ propsStr += (i === 0 ? "" : ", ") + '"' + a + '": `' + val + '`';
340
+ });
331
341
  }
332
342
  propsStr += "}";
333
- return ` html += helpers.renderComponent('${tag.name}', ${propsStr}, helpers);\n`;
343
+ return ` html += helpers.renderComponent('${tag.name}', ${propsStr}, helpers);\n`;
334
344
  }
335
345
 
336
- let code = ` html += "<${tag.name}";\n`;
337
-
338
- if (tag.attributes) {
339
- Object.keys(tag.attributes).forEach(a => {
340
- if (a.startsWith('on')) {
341
- const eventName = a.substring(2).toLowerCase();
342
- const uniqueId = `${eventName}_${tag.name}_${Math.random().toString(36).substring(7)}`;
343
- if (tag.attributes[a].includes('++')) {
344
- const key = tag.attributes[a].split('++')[0].trim();
345
- code += ` _events.push({ id: '${uniqueId}', fn: function(state) { state['${key}']++; } });\n`;
346
- } else {
347
- code += ` _events.push({ id: '${uniqueId}', fn: function(state, event) { ${tag.attributes[a]} } });\n`;
348
- }
349
- code += ` html += " data-on-${eventName}='${uniqueId}'";\n`;
350
- } else {
351
- let val = tag.attributes[a].replace(/\{([^}]+)\}/g, (_, p) => "${e(" + p + ")}");
352
- code += " html += \" \" + " + JSON.stringify(a) + " + \"='\" + `" + val + "` + \"'\";\n";
353
- }
354
- });
346
+ let code = ` html += "<${tag.name}";\n`;
347
+
348
+ if (tag.attributes) {
349
+ Object.keys(tag.attributes).forEach(a => {
350
+ if (a.startsWith('on')) {
351
+ const eventName = a.substring(2).toLowerCase();
352
+ const uniqueId = `${eventName}_${tag.name}_${Math.random().toString(36).substring(7)}`;
353
+ if (tag.attributes[a].includes('++')) {
354
+ const key = tag.attributes[a].split('++')[0].trim();
355
+ code += ` _events.push({ id: '${uniqueId}', fn: function(state) { state['${key}']++; } });\n`;
356
+ } else {
357
+ code += ` _events.push({ id: '${uniqueId}', fn: function(state, event) { ${tag.attributes[a]} } });\n`;
358
+ }
359
+ code += ` html += " data-on-${eventName}='${uniqueId}'";\n`;
360
+ } else {
361
+ let val = tag.attributes[a].replace(/\{([^}]+)\}/g, (_, p) => "${e(" + p + ")}");
362
+ code += " html += \" \" + " + JSON.stringify(a) + " + \"='\" + `" + val + "` + \"'\";\n";
363
+ }
364
+ });
355
365
  }
356
366
 
357
- if (tag.children) {
358
- tag.children.forEach(child => {
359
- if (child.type === 'event') {
360
- const eventName = child.event.toLowerCase();
361
- const uniqueId = `${eventName}_child_${Math.random().toString(36).substring(7)}`;
362
- code += ` _events.push({ id: '${uniqueId}', fn: function(state, event) { ${child.code} } });\n`;
363
- code += ` html += " data-on-${eventName}='${uniqueId}'";\n`;
364
- }
365
- });
367
+ if (tag.children) {
368
+ tag.children.forEach(child => {
369
+ if (child.type === 'event') {
370
+ const eventName = child.event.toLowerCase();
371
+ const uniqueId = `${eventName}_child_${Math.random().toString(36).substring(7)}`;
372
+ code += ` _events.push({ id: '${uniqueId}', fn: function(state, event) { ${child.code} } });\n`;
373
+ code += ` html += " data-on-${eventName}='${uniqueId}'";\n`;
374
+ }
375
+ });
366
376
  }
367
377
 
368
378
  code += ` html += ">";\n`;
369
379
 
370
- if (tag.content) {
371
- let cont = tag.content.replace(/`/g, '\\`').replace(/\$/g, '\\$').replace(/\{([^}]+)\}/g, (_, p) => {
380
+ if (tag.content) {
381
+ let cont = tag.content.replace(/`/g, '\\`').replace(/\$/g, '\\$').replace(/\{([^}]+)\}/g, (_, p) => {
372
382
  const parts = p.split('.');
373
- if (stateNames.includes(parts[0])) return `\${e(state["${parts[0]}"]${parts.slice(1).map(part => `?.["${part}"]`).join('')})}`;
374
- return `\${e(${p})}`;
383
+ if (stateNames.includes(parts[0])) return `\${e(state["${parts[0]}"]${ parts.slice(1).map(part => `?.["${part}"]`).join('') })}`;
384
+ return `\${e(${ p })}`;
375
385
  });
376
- code += ` html += \`${cont}\`;\n`;
386
+ code += ` html += \`${cont}\`;\n`;
377
387
  }
378
388
 
379
- if (tag.children) code += generateComponentBody(tag.children, stateNames);
380
- code += ` html += "</${tag.name}>";\n`;
381
- return code;
389
+ if (tag.children) code += generateComponentBody(tag.children, stateNames);
390
+ code += ` html += "</${tag.name}>";\n`;
391
+ return code;
382
392
  }
383
393
 
384
- module.exports = { generate };
394
+ module.exports = {generate};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-framework",
3
- "version": "4.6.8",
3
+ "version": "4.7.0",
4
4
  "description": "Professional Node.js engine for the .free language. Blazing-fast SSR, Islands Architecture, and built-in ORM.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -2,6 +2,81 @@
2
2
  @tailwind components;
3
3
  @tailwind utilities;
4
4
 
5
+ :root {
6
+ --primary: #00ff88;
7
+ --primary-glow: rgba(0, 255, 136, 0.4);
8
+ --secondary: #00bdff;
9
+ --dark: #050505;
10
+ --surface: rgba(255, 255, 255, 0.03);
11
+ --glass-border: rgba(255, 255, 255, 0.1);
12
+ }
13
+
14
+ body {
15
+ @apply bg-black text-gray-100 selection:bg-primary selection:text-black;
16
+ background-image:
17
+ radial-gradient(circle at 20% 20%, rgba(0, 255, 136, 0.05) 0%, transparent 40%),
18
+ radial-gradient(circle at 80% 80%, rgba(0, 189, 255, 0.05) 0%, transparent 40%);
19
+ }
20
+
21
+ .glass {
22
+ @apply backdrop-blur-xl bg-white/5 border border-white/10;
23
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.8);
24
+ }
25
+
26
+ .nav-link {
27
+ @apply relative py-2 transition-all duration-300 hover:text-primary;
28
+ }
29
+
30
+ .nav-link::after {
31
+ content: '';
32
+ @apply absolute bottom-0 left-0 w-0 h-0.5 bg-primary transition-all duration-300;
33
+ }
34
+
35
+ .nav-link:hover::after {
36
+ @apply w-full;
37
+ }
38
+
39
+ .btn-premium {
40
+ @apply px-8 py-4 rounded-full font-bold transition-all duration-500 relative overflow-hidden flex items-center gap-2;
41
+ background: linear-gradient(135deg, var(--primary), var(--secondary));
42
+ color: #000;
43
+ box-shadow: 0 0 20px var(--primary-glow);
44
+ }
45
+
46
+ .btn-premium:hover {
47
+ @apply scale-105;
48
+ box-shadow: 0 0 40px var(--primary-glow);
49
+ }
50
+
51
+ .hero-text {
52
+ @apply text-7xl md:text-9xl font-black tracking-tighter leading-none;
53
+ background: linear-gradient(180deg, #fff 0%, #888 100%);
54
+ -webkit-background-clip: text;
55
+ -webkit-text-fill-color: transparent;
56
+ }
57
+
58
+ @keyframes float {
59
+ 0% {
60
+ transform: translateY(0px);
61
+ }
62
+
63
+ 50% {
64
+ transform: translateY(-20px);
65
+ }
66
+
67
+ 100% {
68
+ transform: translateY(0px);
69
+ }
70
+ }
71
+
72
+ .animate-float {
73
+ animation: float 6s ease-in-out infinite;
74
+ }
75
+
76
+ .feature-card {
77
+ @apply p-8 rounded-3xl glass transition-all duration-500 hover:-translate-y-2 hover:border-primary/30;
78
+ }
79
+
5
80
  /* --------------------------------------------------------------------------
6
81
  * Free Framework Enterprise Styles
7
82
  * --------------------------------------------------------------------------
@@ -1,18 +1,29 @@
1
1
  component Header {
2
- header {
3
- class "fixed top-0 left-0 w-full p-6 flex justify-between items-center backdrop-blur-md bg-black/50 z-50 border-b border-white/10"
2
+ header class="fixed top-0 left-0 w-full z-50 transition-all duration-300 border-b border-white/5 backdrop-blur-md bg-black/30" {
3
+ nav class="max-w-7xl mx-auto px-6 h-20 flex items-center justify-between" {
4
+ div class="flex items-center gap-8" {
5
+ a href="/" class="flex items-center gap-2 group" {
6
+ div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-primary to-secondary flex items-center justify-center shadow-lg shadow-primary/20 group-hover:rotate-12 transition-transform duration-500" {
7
+ span class="text-black font-black text-xl" { text "F" }
8
+ }
9
+ span class="text-2xl font-black tracking-tighter text-white" { text "FREE ULTRA" }
10
+ }
4
11
 
5
- div {
6
- class "text-2xl font-black italic tracking-tighter"
7
- span { class "text-primary"; text "FREE" }
8
- text " APP"
12
+ div class="hidden md:flex items-center gap-6 ml-8" {
13
+ a href="/" class="nav-link font-medium" { text "Home" }
14
+ a href="/dashboard" class="nav-link font-medium" { text "Dashboard" }
15
+ a href="/docs" class="nav-link font-medium" { text "Documentation" }
9
16
  }
17
+ }
10
18
 
11
- nav {
12
- class "flex gap-8 font-medium text-sm letter-spacing-1"
13
- a { href "/"; text "HOME" }
14
- a { href "/dashboard"; text "DASHBOARD" }
15
- a { href "/login"; text "LOGIN"; class "text-primary" }
19
+ div class="flex items-center gap-4" {
20
+ span class="hidden sm:inline-flex items-center px-3 py-1 rounded-full bg-primary/10 border border-primary/20 text-primary text-xs font-bold tracking-widest uppercase animate-pulse" {
21
+ text "v4.7.0 ACTIVE"
22
+ }
23
+ a href="/login" class="px-5 py-2 rounded-full border border-white/10 hover:bg-white/5 transition-colors font-semibold" {
24
+ text "Sign In"
16
25
  }
26
+ }
17
27
  }
28
+ }
18
29
  }
@@ -10,17 +10,66 @@ component Home {
10
10
  .hero { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; background: linear-gradient(to right, #1f2937, #111827); color: white; }
11
11
  }
12
12
 
13
- div class="hero text-center" {
14
- h1 class="text-6xl font-extrabold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-emerald-400" {
15
- text "Free Framework"
16
- }
17
- p class="text-xl mb-8 text-gray-300" {
18
- text "The Enterprise Node.js Ecosystem. MVC, JWT, and Extreme Performance."
13
+ main class="pt-32 pb-20 px-6" {
14
+ // Hero Section
15
+ section class="relative max-w-7xl mx-auto flex flex-col items-center text-center py-20 md:py-32" {
16
+ div class="absolute -top-20 w-72 h-72 bg-primary/20 rounded-full blur-[120px] -z-10 animate-pulse" { }
17
+ div class="absolute top-40 -right-20 w-96 h-96 bg-secondary/10 rounded-full blur-[150px] -z-10" { }
18
+
19
+ h1 class="hero-text mb-8" {
20
+ text "Build Faster."
21
+ br { }
22
+ span class="text-primary" { text "Deploy Sharper." }
23
+ }
24
+
25
+ p class="text-xl md:text-2xl text-gray-400 max-w-2xl mb-12 font-medium leading-relaxed" {
26
+ text "The Enterprise Node.js Ecosystem you've been waiting for. Powered by Islands Architecture, built-in ORM, and Extreme SSR Performance."
27
+ }
28
+
29
+ div class="flex flex-wrap justify-center gap-6" {
30
+ a href="/docs" class="btn-premium" {
31
+ span { text "Get Started" }
32
+ svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" {
33
+ path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="Arrow-right" { }
34
+ }
35
+ }
36
+ a href="https://github.com/dev-omartolba" class="px-8 py-4 rounded-full glass font-bold hover:bg-white/10 transition-all flex items-center gap-2" {
37
+ text "View Source"
38
+ }
39
+ }
40
+
41
+ div class="mt-20 w-full glass rounded-[40px] p-4 animate-float" {
42
+ div class="rounded-[32px] overflow-hidden border border-white/5 bg-black/40" {
43
+ div class="px-4 py-3 border-b border-white/5 flex gap-2" {
44
+ div class="w-3 h-3 rounded-full bg-red-500/50" { }
45
+ div class="w-3 h-3 rounded-full bg-yellow-500/50" { }
46
+ div class="w-3 h-3 rounded-full bg-green-500/50" { }
47
+ }
48
+ pre class="p-8 text-left text-primary font-mono text-lg" {
49
+ code { text "npx free-framework new my-app" }
50
+ }
51
+ }
52
+ }
19
53
  }
20
54
 
21
- div class="flex gap-4" {
22
- a href="https://github.com/omartolba" class="px-6 py-3 bg-blue-600 hover:bg-blue-700 rounded-lg font-bold transition-colors" { text "Documentation" }
23
- a href="/dashboard" class="px-6 py-3 bg-gray-700 hover:bg-gray-600 rounded-lg font-bold transition-colors" { text "View Dashboard" }
55
+ // Features Section
56
+ section class="max-w-7xl mx-auto py-32" {
57
+ h2 class="text-4xl md:text-6xl font-black mb-20 text-center" { text "Why Free Ultra?" }
58
+
59
+ div class="grid md:grid-cols-3 gap-8" {
60
+ div class="feature-card" {
61
+ h3 class="text-2xl font-bold mb-4 text-primary" { text "HyperExpress Core" }
62
+ p class="text-gray-400" { text "Built on top of uWebSockets.js, providing the fastest HTTP/WebSocket performance in the Node.js ecosystem." }
63
+ }
64
+ div class="feature-card" {
65
+ h3 class="text-2xl font-bold mb-4 text-secondary" { text "Islands Architecture" }
66
+ p class="text-gray-400" { text "Ships zero Javascript by default. Only hydrate the components that need interactivity for ultimate SEO and speed." }
67
+ }
68
+ div class="feature-card" {
69
+ h3 class="text-2xl font-bold mb-4 text-white" { text "Pro-Grade ORM" }
70
+ p class="text-gray-400" { text "A built-in migration system and elegant Model layer that makes database management a breeze." }
71
+ }
72
+ }
24
73
  }
25
74
  }
26
75
  }