aztomiq 1.0.7 → 1.0.9
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/package.json +2 -1
- package/scripts/builds/assets.js +21 -10
- package/src/assets/css/landing.css +241 -0
- package/src/includes/landing-features.ejs +28 -0
- package/src/includes/landing-hero.ejs +14 -0
- package/src/includes/landing-pricing.ejs +34 -0
- package/src/pages/404.ejs +8 -0
- package/src/pages/about.ejs +30 -0
- package/src/pages/categories.ejs +70 -0
- package/src/pages/changelog.ejs +54 -0
- package/src/pages/index.ejs +120 -0
- package/src/pages/landing-demo.ejs +39 -0
- package/src/pages/privacy.ejs +55 -0
- package/src/pages/terms.ejs +38 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aztomiq",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "AZtomiq - A comprehensive A-Z multi-tool framework with atomic architecture",
|
|
5
5
|
"main": "scripts/build.js",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"src/assets",
|
|
13
13
|
"src/includes",
|
|
14
14
|
"src/templates",
|
|
15
|
+
"src/pages",
|
|
15
16
|
"src/locales",
|
|
16
17
|
"server.js",
|
|
17
18
|
"package.json",
|
package/scripts/builds/assets.js
CHANGED
|
@@ -67,16 +67,27 @@ async function buildAssets() {
|
|
|
67
67
|
console.time('🎨 Assets Build');
|
|
68
68
|
|
|
69
69
|
// 0. Copy all raw assets (images, fonts, vendor, etc)
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
const assetSubDirs = ['images', 'fonts', 'vendor', 'favicons'];
|
|
71
|
+
for (const sub of assetSubDirs) {
|
|
72
|
+
const srcDirs = [
|
|
73
|
+
path.join(paths.CORE_ROOT, 'src/assets', sub),
|
|
74
|
+
path.join(paths.SRC, 'assets', sub)
|
|
75
|
+
].filter(fs.existsSync);
|
|
76
|
+
|
|
77
|
+
if (srcDirs.length === 0) continue;
|
|
78
|
+
|
|
79
|
+
const destDir = path.join(paths.ASSETS_DIST, sub);
|
|
80
|
+
await fs.ensureDir(destDir);
|
|
81
|
+
|
|
82
|
+
for (const dir of srcDirs) {
|
|
83
|
+
const items = fs.readdirSync(dir);
|
|
84
|
+
for (const item of items) {
|
|
85
|
+
const srcPath = path.join(dir, item);
|
|
86
|
+
const destPath = path.join(destDir, item);
|
|
87
|
+
if (hasChanged(srcPath, `assets-${sub}/`, false)) {
|
|
88
|
+
await fs.copy(srcPath, destPath);
|
|
89
|
+
hasChanged(srcPath, `assets-${sub}/`, true);
|
|
90
|
+
}
|
|
80
91
|
}
|
|
81
92
|
}
|
|
82
93
|
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
|
|
2
|
+
/* Landing Page Styles */
|
|
3
|
+
:root {
|
|
4
|
+
--landing-primary: #22d3ee;
|
|
5
|
+
--landing-secondary: #818cf8;
|
|
6
|
+
--landing-bg: #0f172a;
|
|
7
|
+
--landing-card-bg: rgba(30, 41, 59, 0.7);
|
|
8
|
+
--landing-card-border: rgba(255, 255, 255, 0.1);
|
|
9
|
+
--landing-text: #f8fafc;
|
|
10
|
+
--landing-text-muted: #94a3b8;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.landing-page {
|
|
14
|
+
background: var(--landing-bg);
|
|
15
|
+
color: var(--landing-text);
|
|
16
|
+
overflow-x: hidden;
|
|
17
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Hero Section */
|
|
21
|
+
.hero-section {
|
|
22
|
+
position: relative;
|
|
23
|
+
min-height: 90vh;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
text-align: center;
|
|
28
|
+
padding: 120px 24px 80px;
|
|
29
|
+
background: radial-gradient(circle at top center, rgba(34, 211, 238, 0.15), transparent 60%);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.hero-content {
|
|
33
|
+
max-width: 800px;
|
|
34
|
+
z-index: 2;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.hero-badge {
|
|
38
|
+
display: inline-block;
|
|
39
|
+
padding: 6px 16px;
|
|
40
|
+
background: rgba(34, 211, 238, 0.1);
|
|
41
|
+
border: 1px solid rgba(34, 211, 238, 0.3);
|
|
42
|
+
color: var(--landing-primary);
|
|
43
|
+
border-radius: 99px;
|
|
44
|
+
font-size: 14px;
|
|
45
|
+
font-weight: 600;
|
|
46
|
+
margin-bottom: 24px;
|
|
47
|
+
backdrop-filter: blur(4px);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.hero-title {
|
|
51
|
+
font-size: clamp(2.5rem, 8vw, 4.5rem);
|
|
52
|
+
font-weight: 800;
|
|
53
|
+
line-height: 1.1;
|
|
54
|
+
margin-bottom: 24px;
|
|
55
|
+
background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
|
|
56
|
+
-webkit-background-clip: text;
|
|
57
|
+
background-clip: text;
|
|
58
|
+
-webkit-text-fill-color: transparent;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.hero-description {
|
|
62
|
+
font-size: 1.25rem;
|
|
63
|
+
color: var(--landing-text-muted);
|
|
64
|
+
margin-bottom: 40px;
|
|
65
|
+
line-height: 1.6;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.cta-group {
|
|
69
|
+
display: flex;
|
|
70
|
+
gap: 16px;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
flex-wrap: wrap;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.btn-primary-landing {
|
|
76
|
+
padding: 14px 32px;
|
|
77
|
+
background: var(--landing-primary);
|
|
78
|
+
color: #000;
|
|
79
|
+
font-weight: 700;
|
|
80
|
+
border-radius: 12px;
|
|
81
|
+
transition: all 0.3s ease;
|
|
82
|
+
text-decoration: none;
|
|
83
|
+
box-shadow: 0 0 20px rgba(34, 211, 238, 0.4);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.btn-primary-landing:hover {
|
|
87
|
+
transform: translateY(-2px);
|
|
88
|
+
box-shadow: 0 0 30px rgba(34, 211, 238, 0.6);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.btn-secondary-landing {
|
|
92
|
+
padding: 14px 32px;
|
|
93
|
+
background: rgba(255, 255, 255, 0.05);
|
|
94
|
+
color: #fff;
|
|
95
|
+
font-weight: 600;
|
|
96
|
+
border-radius: 12px;
|
|
97
|
+
border: 1px solid var(--landing-card-border);
|
|
98
|
+
transition: all 0.3s ease;
|
|
99
|
+
text-decoration: none;
|
|
100
|
+
backdrop-filter: blur(10px);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.btn-secondary-landing:hover {
|
|
104
|
+
background: rgba(255, 255, 255, 0.1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Features Grid */
|
|
108
|
+
.section-padding {
|
|
109
|
+
padding: 100px 24px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.section-header {
|
|
113
|
+
text-align: center;
|
|
114
|
+
max-width: 600px;
|
|
115
|
+
margin: 0 auto 60px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.section-title {
|
|
119
|
+
font-size: 2.5rem;
|
|
120
|
+
font-weight: 700;
|
|
121
|
+
margin-bottom: 16px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.features-grid {
|
|
125
|
+
display: grid;
|
|
126
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
127
|
+
gap: 32px;
|
|
128
|
+
max-width: 1200px;
|
|
129
|
+
margin: 0 auto;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.feature-card {
|
|
133
|
+
padding: 40px;
|
|
134
|
+
background: var(--landing-card-bg);
|
|
135
|
+
border: 1px solid var(--landing-card-border);
|
|
136
|
+
border-radius: 24px;
|
|
137
|
+
backdrop-filter: blur(16px);
|
|
138
|
+
transition: all 0.3s ease;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.feature-card:hover {
|
|
142
|
+
border-color: rgba(34, 211, 238, 0.3);
|
|
143
|
+
transform: translateY(-5px);
|
|
144
|
+
background: rgba(30, 41, 59, 0.9);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.feature-icon {
|
|
148
|
+
width: 56px;
|
|
149
|
+
height: 56px;
|
|
150
|
+
background: rgba(34, 211, 238, 0.1);
|
|
151
|
+
color: var(--landing-primary);
|
|
152
|
+
border-radius: 16px;
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
justify-content: center;
|
|
156
|
+
margin-bottom: 24px;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.feature-title {
|
|
160
|
+
font-size: 1.5rem;
|
|
161
|
+
font-weight: 600;
|
|
162
|
+
margin-bottom: 12px;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.feature-desc {
|
|
166
|
+
color: var(--landing-text-muted);
|
|
167
|
+
line-height: 1.6;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Pricing Section */
|
|
171
|
+
.pricing-grid {
|
|
172
|
+
display: grid;
|
|
173
|
+
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
|
174
|
+
gap: 32px;
|
|
175
|
+
max-width: 1000px;
|
|
176
|
+
margin: 0 auto;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.pricing-card {
|
|
180
|
+
padding: 48px;
|
|
181
|
+
background: var(--landing-card-bg);
|
|
182
|
+
border: 1px solid var(--landing-card-border);
|
|
183
|
+
border-radius: 32px;
|
|
184
|
+
position: relative;
|
|
185
|
+
display: flex;
|
|
186
|
+
flex-direction: column;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.pricing-card.featured {
|
|
190
|
+
border-color: var(--landing-primary);
|
|
191
|
+
background: rgba(34, 211, 238, 0.03);
|
|
192
|
+
transform: scale(1.05);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.popular-badge {
|
|
196
|
+
position: absolute;
|
|
197
|
+
top: 24px;
|
|
198
|
+
right: 24px;
|
|
199
|
+
background: var(--landing-primary);
|
|
200
|
+
color: #000;
|
|
201
|
+
font-size: 12px;
|
|
202
|
+
font-weight: 700;
|
|
203
|
+
padding: 4px 12px;
|
|
204
|
+
border-radius: 99px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.price-value {
|
|
208
|
+
font-size: 3.5rem;
|
|
209
|
+
font-weight: 800;
|
|
210
|
+
margin: 24px 0 8px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.price-period {
|
|
214
|
+
color: var(--landing-text-muted);
|
|
215
|
+
font-size: 1rem;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.price-features {
|
|
219
|
+
list-style: none;
|
|
220
|
+
padding: 0;
|
|
221
|
+
margin: 32px 0;
|
|
222
|
+
flex-grow: 1;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.price-features li {
|
|
226
|
+
margin-bottom: 16px;
|
|
227
|
+
display: flex;
|
|
228
|
+
align-items: center;
|
|
229
|
+
gap: 12px;
|
|
230
|
+
color: var(--landing-text-muted);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.price-features li svg {
|
|
234
|
+
color: var(--landing-primary);
|
|
235
|
+
flex-shrink: 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@media (max-width: 768px) {
|
|
239
|
+
.hero-title { font-size: 2.5rem; }
|
|
240
|
+
.pricing-card.featured { transform: scale(1); }
|
|
241
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<section id="features" class="section-padding">
|
|
2
|
+
<div class="section-header">
|
|
3
|
+
<h2 class="section-title">Built for Performance</h2>
|
|
4
|
+
<p class="hero-description" style="font-size: 1.1rem">Everything you need to ship high-quality web applications in
|
|
5
|
+
record time.</p>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<div class="features-grid">
|
|
9
|
+
<div class="feature-card">
|
|
10
|
+
<div class="feature-icon"><i data-lucide="zap"></i></div>
|
|
11
|
+
<h3 class="feature-title">Lightning Fast</h3>
|
|
12
|
+
<p class="feature-desc">Pre-rendered static pages ensure zero loading lag and perfect Lighthouse scores by
|
|
13
|
+
default.</p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="feature-card">
|
|
17
|
+
<div class="feature-icon"><i data-lucide="layers"></i></div>
|
|
18
|
+
<h3 class="feature-title">Atomic Design</h3>
|
|
19
|
+
<p class="feature-desc">Modular features and components that are easy to maintain, override, and scale.</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="feature-card">
|
|
23
|
+
<div class="feature-icon"><i data-lucide="shield"></i></div>
|
|
24
|
+
<h3 class="feature-title">SEO Ready</h3>
|
|
25
|
+
<p class="feature-desc">Automatic sitemap, robots.txt, and metadata generation tailored for search engines.</p>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</section>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<section class="hero-section">
|
|
2
|
+
<div class="hero-content">
|
|
3
|
+
<span class="hero-badge">New: AZtomiq Framework v1.0.8</span>
|
|
4
|
+
<h1 class="hero-title">
|
|
5
|
+
<%= title || 'Build Faster with Atomic Architecture' %>
|
|
6
|
+
</h1>
|
|
7
|
+
<p class="hero-description">The ultimate SSG framework for building multi-tool platforms, documentation sites, and
|
|
8
|
+
high-performance landing pages.</p>
|
|
9
|
+
<div class="cta-group">
|
|
10
|
+
<a href="#features" class="btn-primary-landing">Get Started Free</a>
|
|
11
|
+
<a href="#" class="btn-secondary-landing">View Documentation</a>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</section>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<section id="pricing" class="section-padding" style="background: rgba(0,0,0,0.2)">
|
|
2
|
+
<div class="section-header">
|
|
3
|
+
<h2 class="section-title">Honest Pricing</h2>
|
|
4
|
+
<p class="hero-description" style="font-size: 1.1rem">Choose the plan that fits your ambition.</p>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="pricing-grid">
|
|
8
|
+
<div class="pricing-card">
|
|
9
|
+
<h3>Starter</h3>
|
|
10
|
+
<div class="price-value">$0</div>
|
|
11
|
+
<span class="price-period">Forever free for hobbyists</span>
|
|
12
|
+
<ul class="price-features">
|
|
13
|
+
<li><i data-lucide="check"></i> Core Framework</li>
|
|
14
|
+
<li><i data-lucide="check"></i> 5 Tools / Features</li>
|
|
15
|
+
<li><i data-lucide="check"></i> Community Support</li>
|
|
16
|
+
</ul>
|
|
17
|
+
<a href="#" class="btn-secondary-landing">Get Started</a>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="pricing-card featured">
|
|
21
|
+
<span class="popular-badge">Recommended</span>
|
|
22
|
+
<h3>Pro</h3>
|
|
23
|
+
<div class="price-value">$19</div>
|
|
24
|
+
<span class="price-period">per month, billed yearly</span>
|
|
25
|
+
<ul class="price-features">
|
|
26
|
+
<li><i data-lucide="check"></i> Everything in Starter</li>
|
|
27
|
+
<li><i data-lucide="check"></i> Unlimited Tools</li>
|
|
28
|
+
<li><i data-lucide="check"></i> Custom Domain</li>
|
|
29
|
+
<li><i data-lucide="check"></i> Priority Email Support</li>
|
|
30
|
+
</ul>
|
|
31
|
+
<a href="#" class="btn-primary-landing">Go Pro Now</a>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</section>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<!-- title: 404 - Page Not Found -->
|
|
2
|
+
<section class="tool-container" style="text-align: center; padding: 4rem 1rem;">
|
|
3
|
+
<div style="font-size: 5rem; margin-bottom: 1rem;">🤔</div>
|
|
4
|
+
<h1 style="margin-bottom: 1rem;">404 - You're lost, bro!</h1>
|
|
5
|
+
<p style="color: var(--text-muted); margin-bottom: 2rem;">The page you are looking for does not exist or has been
|
|
6
|
+
moved.</p>
|
|
7
|
+
<a href="<%= rootPath %><%= locale %>/" class="btn">Back to Home</a>
|
|
8
|
+
</section>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<section class="container page-content" style="padding: 2rem 0; max-width: 800px; margin: 0 auto;">
|
|
2
|
+
<h1 style="text-align: center; margin-bottom: 2rem;">
|
|
3
|
+
<%= t('about.title') %>
|
|
4
|
+
</h1>
|
|
5
|
+
|
|
6
|
+
<div class="card">
|
|
7
|
+
<h2>
|
|
8
|
+
<%= t('about.intro_h2') %>
|
|
9
|
+
</h2>
|
|
10
|
+
<p><%- t('about.intro_p1') %></p>
|
|
11
|
+
<p><%- t('about.intro_p2') %></p>
|
|
12
|
+
|
|
13
|
+
<h3 style="margin-top: 1.5rem;">
|
|
14
|
+
<%= t('about.why_h3') %>
|
|
15
|
+
</h3>
|
|
16
|
+
<ul>
|
|
17
|
+
<li><%- t('about.why_li1') %></li>
|
|
18
|
+
<li><%- t('about.why_li2') %></li>
|
|
19
|
+
<li><%- t('about.why_li3') %></li>
|
|
20
|
+
</ul>
|
|
21
|
+
|
|
22
|
+
<h3 style="margin-top: 1.5rem;">
|
|
23
|
+
<%= t('about.contact_h3') %>
|
|
24
|
+
</h3>
|
|
25
|
+
<p>
|
|
26
|
+
<%= t('about.contact_p') %>
|
|
27
|
+
<a href="mailto:contact@aztomiq.site">contact@aztomiq.site</a>
|
|
28
|
+
</p>
|
|
29
|
+
</div>
|
|
30
|
+
</section>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<!-- title: <%= t('nav.menu_categories') %> - AZtomiq -->
|
|
2
|
+
|
|
3
|
+
<div class="container page-categories" style="margin-bottom: 6rem;">
|
|
4
|
+
<div class="page-header" style="text-align: center; margin-bottom: 3rem;">
|
|
5
|
+
<h1><i data-lucide="folder-kanban"
|
|
6
|
+
style="width: 32px; height: 32px; vertical-align: middle; margin-right: 10px;"></i>
|
|
7
|
+
<%= t('nav.menu_categories') %>
|
|
8
|
+
</h1>
|
|
9
|
+
<p>
|
|
10
|
+
<%= t('home.hero_desc') %>
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="categories-grid">
|
|
15
|
+
<% const catOrder=['job', 'finance' , 'text' , 'generator' , 'daily' , 'dev' ]; const catMap={ 'job' : { title:
|
|
16
|
+
t('home.cats.job.title') || 'Job & Income' , icon: 'briefcase' }, 'finance' : { title:
|
|
17
|
+
t('home.cats.finance.title') || 'Finance' , icon: 'line-chart' }, 'text' : { title: t('home.cats.text.title')
|
|
18
|
+
|| 'Text Tools' , icon: 'type' }, 'generator' : { title: t('home.cats.generator.title') || 'Generators' ,
|
|
19
|
+
icon: 'wand-2' }, 'daily' : { title: t('home.cats.daily.title') || 'Daily Utilities' , icon: 'calendar' }, 'dev' :
|
|
20
|
+
{ title: t('home.cats.dev.title') || 'Dev Tools' , icon: 'code' } }; catOrder.forEach(catId=> {
|
|
21
|
+
const catTools=tools.filter(t=> t.category === catId
|
|
22
|
+
&& (t.status === 'active' || t.status === 'legacy' || t.status === 'not-ready'));
|
|
23
|
+
if (catTools.length === 0) return;
|
|
24
|
+
%>
|
|
25
|
+
<div class="category-card card" id="cat-<%= catId %>">
|
|
26
|
+
<h2 class="category-title">
|
|
27
|
+
<span class="cat-icon">
|
|
28
|
+
<i data-lucide="<%= catMap[catId].icon %>"></i>
|
|
29
|
+
</span>
|
|
30
|
+
<%= catMap[catId].title %>
|
|
31
|
+
<span class="cat-count">
|
|
32
|
+
<%= catTools.length %> tools
|
|
33
|
+
</span>
|
|
34
|
+
</h2>
|
|
35
|
+
<div class="cat-tools-list">
|
|
36
|
+
<% catTools.forEach(tool=> {
|
|
37
|
+
let modeClass = '';
|
|
38
|
+
if (tool.mode === 'standard') modeClass = 'mode-standard-only';
|
|
39
|
+
else if (tool.mode === 'advanced') modeClass = 'mode-advanced-only';
|
|
40
|
+
%>
|
|
41
|
+
<a href="<%= rootPath %><%= locale %><%= tool.link %>"
|
|
42
|
+
class="cat-tool-item <%= tool.status === 'legacy' ? 'legacy-item' : '' %> <%= modeClass %>">
|
|
43
|
+
<span class="tool-icon">
|
|
44
|
+
<i data-lucide="<%= tool.icon %>"></i>
|
|
45
|
+
<% if (tool.status==='legacy' ) { %>
|
|
46
|
+
<span class="legacy-dot" title="Legacy Tool"
|
|
47
|
+
style="display:inline-block; width: 6px; height: 6px; background: var(--text-muted); border-radius: 50%; position: absolute; top: 0; right: 0;"></span>
|
|
48
|
+
<% } %>
|
|
49
|
+
</span>
|
|
50
|
+
<span class="tool-name">
|
|
51
|
+
<%= t(tool.translationKey + '.title' ) %>
|
|
52
|
+
</span>
|
|
53
|
+
|
|
54
|
+
<% if (tool.status==='not-ready' ) { %>
|
|
55
|
+
<span class="tool-badge beta" style="margin-left: auto; position: static;">BETA</span>
|
|
56
|
+
<% } else if (tool.highlight) { %>
|
|
57
|
+
<span class="tool-badge hot"
|
|
58
|
+
style="font-size: 0.6rem; padding: 2px 6px; background: #fff7ed; color: #c2410c; border: 1px solid #fb923c; border-radius: 4px; display: flex; align-items: center; gap: 3px; font-weight: 700; position: static; margin-left: auto;">
|
|
59
|
+
<i data-lucide="sparkles" style="width: 10px; height: 10px;"></i> HOT
|
|
60
|
+
</span>
|
|
61
|
+
<% } %>
|
|
62
|
+
</a>
|
|
63
|
+
<% }); %>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<% }); %>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<link rel="stylesheet" href="<%= asset('assets/css/categories.css') %>">
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<section class="container page-content" style="padding: 2rem 0; max-width: 800px; margin: 0 auto;">
|
|
2
|
+
<h1 style="text-align: center; margin-bottom: 2rem;">
|
|
3
|
+
<%= t('changelog.title') || 'Nhật Ký Thay Đổi' %>
|
|
4
|
+
</h1>
|
|
5
|
+
|
|
6
|
+
<div class="card markdown-body" style="padding: 2rem;">
|
|
7
|
+
<%- changelogHtml %>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div style="text-align: center; margin-top: 3rem;">
|
|
11
|
+
<a href="<%= rootPath %><%= locale %>/" class="btn-primary" style="text-decoration: none;">
|
|
12
|
+
← <%= t('nav.home') || 'Quay về trang chủ' %>
|
|
13
|
+
</a>
|
|
14
|
+
</div>
|
|
15
|
+
</section>
|
|
16
|
+
|
|
17
|
+
<!-- Include Markdown Styles -->
|
|
18
|
+
<style>
|
|
19
|
+
.markdown-body {
|
|
20
|
+
line-height: 1.6;
|
|
21
|
+
color: var(--text-color);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.markdown-body h2 {
|
|
25
|
+
margin-top: 2rem;
|
|
26
|
+
margin-bottom: 1rem;
|
|
27
|
+
padding-bottom: 0.5rem;
|
|
28
|
+
border-bottom: 1px solid var(--border-color);
|
|
29
|
+
color: var(--primary-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.markdown-body h3 {
|
|
33
|
+
margin-top: 1.5rem;
|
|
34
|
+
margin-bottom: 0.75rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.markdown-body ul {
|
|
38
|
+
padding-left: 1.5rem;
|
|
39
|
+
margin-bottom: 1.5rem;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.markdown-body li {
|
|
43
|
+
margin-bottom: 0.5rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.markdown-body a {
|
|
47
|
+
color: var(--primary-color);
|
|
48
|
+
text-decoration: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.markdown-body a:hover {
|
|
52
|
+
text-decoration: underline;
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<!-- title: <%= t('meta.title') %> -->
|
|
2
|
+
<% if (global.build.entry_point==='blog' ) { %>
|
|
3
|
+
<script>
|
|
4
|
+
// Redirect to blog if this is the entry point
|
|
5
|
+
if (window.location.pathname.endsWith('/<%= locale %>/') || window.location.pathname.endsWith('/<%= locale %>')) {
|
|
6
|
+
window.location.href = '<%= rootPath %><%= locale %>/blog/';
|
|
7
|
+
}
|
|
8
|
+
</script>
|
|
9
|
+
<% } %>
|
|
10
|
+
<section class="hero">
|
|
11
|
+
<h1>
|
|
12
|
+
<%= t('home.hero_title') || 'Welcome to AZtomiq Core' %>
|
|
13
|
+
</h1>
|
|
14
|
+
<p>
|
|
15
|
+
<%= t('home.hero_desc') || 'The modern framework for your utility site.' %>
|
|
16
|
+
</p>
|
|
17
|
+
</section>
|
|
18
|
+
|
|
19
|
+
<!-- Big Hero Search Section -->
|
|
20
|
+
<div class="hero-search-wrap">
|
|
21
|
+
<div class="search-box-hero">
|
|
22
|
+
<span class="search-icon"><i data-lucide="search"></i></span>
|
|
23
|
+
<input type="text" id="home-search" placeholder="<%= t('nav.search_placeholder') || 'Search tools...' %>"
|
|
24
|
+
aria-label="Search tools">
|
|
25
|
+
<div class="search-hints">
|
|
26
|
+
<kbd>Ctrl</kbd>
|
|
27
|
+
<span>+</span>
|
|
28
|
+
<kbd>K</kbd>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<% if (tools.length===0) { %>
|
|
34
|
+
<div class="container"
|
|
35
|
+
style="text-align: center; padding: 4rem 2rem; background: var(--bg-hover); border-radius: 24px; border: 1px dashed var(--border-color);">
|
|
36
|
+
<i data-lucide="package-open" style="width: 64px; height: 64px; margin-bottom: 1.5rem; opacity: 0.5;"></i>
|
|
37
|
+
<h2>Your framework is ready!</h2>
|
|
38
|
+
<p style="color: var(--text-muted); max-width: 500px; margin: 1rem auto;">
|
|
39
|
+
Start building your tools by adding folders into <code>src/features/</code>.
|
|
40
|
+
Each tool needs a <code>tool.yaml</code>, <code>index.ejs</code>, and optional assets.
|
|
41
|
+
</p>
|
|
42
|
+
<div style="margin-top: 2rem;">
|
|
43
|
+
<a href="https://github.com/ph4n4n/aztomiq" class="btn btn-primary">Read Documentation</a>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
<% } else { %>
|
|
47
|
+
<!-- Favorites Section (Dynamic) -->
|
|
48
|
+
<div class="container favorites-section" id="favorites-section" style="display: none; margin-bottom: 3rem;">
|
|
49
|
+
<div class="category-header">
|
|
50
|
+
<h2 class="category-title" style="display: flex; align-items: center; gap: 10px;">
|
|
51
|
+
<i data-lucide="star" style="color: #f59e0b; fill: #f59e0b;"></i>
|
|
52
|
+
<%= t('home.favorites') || 'My Tools' %>
|
|
53
|
+
</h2>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="tools-grid" id="favorites-grid">
|
|
56
|
+
<!-- Dynamically populated -->
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<% const categories=Object.keys(global.categories || {}).map(key=> ({
|
|
61
|
+
id: key,
|
|
62
|
+
...global.categories[key]
|
|
63
|
+
}));
|
|
64
|
+
%>
|
|
65
|
+
|
|
66
|
+
<% categories.forEach(cat=> {
|
|
67
|
+
const catTools = tools.filter(t => t.category === cat.id);
|
|
68
|
+
if (catTools.length === 0) return;
|
|
69
|
+
%>
|
|
70
|
+
<div class="category-section" id="<%= cat.id %>-tools">
|
|
71
|
+
<h2 class="category-title" style="display: flex; align-items: center; gap: 10px;">
|
|
72
|
+
<i data-lucide="<%= cat.icon || 'folder' %>"></i>
|
|
73
|
+
<%= t(cat.translation_key) || cat.key %>
|
|
74
|
+
</h2>
|
|
75
|
+
<div class="tools-grid">
|
|
76
|
+
<% catTools.forEach(tool=> { %>
|
|
77
|
+
<% let modeClass='' ; if (tool.mode==='standard' ) modeClass='mode-standard-only' ; else if
|
|
78
|
+
(tool.mode==='advanced' ) modeClass='mode-advanced-only' ; %>
|
|
79
|
+
<div class="tool-card-wrapper <%= modeClass %>">
|
|
80
|
+
<div
|
|
81
|
+
class="tool-card <%= (tool.status==='legacy' || tool.status==='not-ready') ? 'legacy-item' : '' %>">
|
|
82
|
+
<button class="star-btn" data-tool-id="<%= tool.id %>" aria-label="Add to favorites"
|
|
83
|
+
title="Add to favorites">
|
|
84
|
+
<i data-lucide="star" style="width: 16px; height: 16px;"></i>
|
|
85
|
+
</button>
|
|
86
|
+
|
|
87
|
+
<div class="tool-badge-row">
|
|
88
|
+
<% if (tool.status==='legacy' ) { %>
|
|
89
|
+
<span class="tool-badge legacy">LEGACY</span>
|
|
90
|
+
<% } else if (tool.status==='not-ready' ) { %>
|
|
91
|
+
<span class="tool-badge beta">BETA</span>
|
|
92
|
+
<% } %>
|
|
93
|
+
<% if (tool.highlight) { %>
|
|
94
|
+
<span class="tool-badge hot" style="display: flex; align-items: center; gap: 4px;">
|
|
95
|
+
<i data-lucide="sparkles" style="width: 10px; height: 10px;"></i> HOT
|
|
96
|
+
</span>
|
|
97
|
+
<% } %>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<a href="<%= rootPath %><%= locale %><%= tool.link %>" class="tool-link">
|
|
101
|
+
<div class="tool-icon-wrap">
|
|
102
|
+
<i data-lucide="<%= tool.icon || 'tool' %>" style="width: 32px; height: 32px;"></i>
|
|
103
|
+
</div>
|
|
104
|
+
<h3>
|
|
105
|
+
<%= t(tool.translationKey + '.title' ) %>
|
|
106
|
+
</h3>
|
|
107
|
+
<p>
|
|
108
|
+
<%= t(tool.translationKey + '.desc' ) %>
|
|
109
|
+
</p>
|
|
110
|
+
</a>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
<% }); %>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
<% }); %>
|
|
117
|
+
<% } %>
|
|
118
|
+
|
|
119
|
+
<script src="<%= asset('assets/js/home.js') %>"></script>
|
|
120
|
+
<link rel="stylesheet" href="<%= asset('assets/css/home.css') %>">
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="<%= locale %>">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Landing Demo | <%= global.site.title %>
|
|
8
|
+
</title>
|
|
9
|
+
<link rel="stylesheet" href="<%= rootPath %>assets/css/global.css">
|
|
10
|
+
<link rel="stylesheet" href="<%= rootPath %>assets/css/landing.css">
|
|
11
|
+
<script src="https://unpkg.com/lucide@latest"></script>
|
|
12
|
+
</head>
|
|
13
|
+
|
|
14
|
+
<body class="landing-page">
|
|
15
|
+
<%- include('header.ejs') %>
|
|
16
|
+
|
|
17
|
+
<main>
|
|
18
|
+
<%- include('landing-hero.ejs') %>
|
|
19
|
+
<%- include('landing-features.ejs') %>
|
|
20
|
+
<%- include('landing-pricing.ejs') %>
|
|
21
|
+
</main>
|
|
22
|
+
|
|
23
|
+
<%- include('footer.ejs') %>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
lucide.createIcons();
|
|
27
|
+
// Simple scroll header effect
|
|
28
|
+
window.addEventListener('scroll', () => {
|
|
29
|
+
const header = document.querySelector('.site-header');
|
|
30
|
+
if (window.scrollY > 50) {
|
|
31
|
+
header.classList.add('scrolled');
|
|
32
|
+
} else {
|
|
33
|
+
header.classList.remove('scrolled');
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
</script>
|
|
37
|
+
</body>
|
|
38
|
+
|
|
39
|
+
</html>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<section class="container page-content" style="padding: 2rem 0; max-width: 800px; margin: 0 auto;">
|
|
2
|
+
<h1 style="text-align: center; margin-bottom: 2rem;">
|
|
3
|
+
<%= t('privacy.title') %>
|
|
4
|
+
</h1>
|
|
5
|
+
|
|
6
|
+
<div class="card">
|
|
7
|
+
<p><em>
|
|
8
|
+
<%= t('privacy.last_updated') %>
|
|
9
|
+
</em></p>
|
|
10
|
+
|
|
11
|
+
<h3 style="margin-top: 1.5rem;">
|
|
12
|
+
<%= t('privacy.section1_h3') %>
|
|
13
|
+
</h3>
|
|
14
|
+
<p><%- t('privacy.section1_p') %></p>
|
|
15
|
+
<ul>
|
|
16
|
+
<li>
|
|
17
|
+
<%= t('privacy.section1_li1') %>
|
|
18
|
+
</li>
|
|
19
|
+
<li><%- t('privacy.section1_li2') %></li>
|
|
20
|
+
<li>
|
|
21
|
+
<%= t('privacy.section1_li3') %>
|
|
22
|
+
</li>
|
|
23
|
+
</ul>
|
|
24
|
+
|
|
25
|
+
<h3 style="margin-top: 1.5rem;">
|
|
26
|
+
<%= t('privacy.section2_h3') %>
|
|
27
|
+
</h3>
|
|
28
|
+
<p><%- t('privacy.section2_p') %></p>
|
|
29
|
+
<ul>
|
|
30
|
+
<li>
|
|
31
|
+
<%= t('privacy.section2_li1') %>
|
|
32
|
+
</li>
|
|
33
|
+
<li>
|
|
34
|
+
<%= t('privacy.section2_li2') %>
|
|
35
|
+
</li>
|
|
36
|
+
</ul>
|
|
37
|
+
<p>
|
|
38
|
+
<%= t('privacy.section2_p2') %>
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<h3 style="margin-top: 1.5rem;">
|
|
42
|
+
<%= t('privacy.section3_h3') %>
|
|
43
|
+
</h3>
|
|
44
|
+
<p>
|
|
45
|
+
<%= t('privacy.section3_p') %>
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<h3 style="margin-top: 1.5rem;">
|
|
49
|
+
<%= t('privacy.section4_h3') %>
|
|
50
|
+
</h3>
|
|
51
|
+
<p>
|
|
52
|
+
<%= t('privacy.section4_p') %>
|
|
53
|
+
</p>
|
|
54
|
+
</div>
|
|
55
|
+
</section>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<section class="container page-content" style="padding: 2rem 0; max-width: 800px; margin: 0 auto;">
|
|
2
|
+
<h1 style="text-align: center; margin-bottom: 2rem;">
|
|
3
|
+
<%= t('terms.title') %>
|
|
4
|
+
</h1>
|
|
5
|
+
|
|
6
|
+
<div class="card">
|
|
7
|
+
<h3 style="margin-top: 1.5rem;">
|
|
8
|
+
<%= t('terms.section1_h3') %>
|
|
9
|
+
</h3>
|
|
10
|
+
<p><%- t('terms.section1_p') %></p>
|
|
11
|
+
|
|
12
|
+
<h3 style="margin-top: 1.5rem;">
|
|
13
|
+
<%= t('terms.section2_h3') %>
|
|
14
|
+
</h3>
|
|
15
|
+
<p>
|
|
16
|
+
<%= t('terms.section2_p') %>
|
|
17
|
+
</p>
|
|
18
|
+
<ul>
|
|
19
|
+
<li><%- t('terms.section2_li1') %></li>
|
|
20
|
+
<li><%- t('terms.section2_li2') %></li>
|
|
21
|
+
<li><%- t('terms.section2_li3') %></li>
|
|
22
|
+
</ul>
|
|
23
|
+
|
|
24
|
+
<h3 style="margin-top: 1.5rem;">
|
|
25
|
+
<%= t('terms.section3_h3') %>
|
|
26
|
+
</h3>
|
|
27
|
+
<p>
|
|
28
|
+
<%= t('terms.section3_p') %>
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
<h3 style="margin-top: 1.5rem;">
|
|
32
|
+
<%= t('terms.section4_h3') %>
|
|
33
|
+
</h3>
|
|
34
|
+
<p>
|
|
35
|
+
<%= t('terms.section4_p') %>
|
|
36
|
+
</p>
|
|
37
|
+
</div>
|
|
38
|
+
</section>
|