mnfst-starter 1.5.34
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/create-starter.js +189 -0
- package/package.json +37 -0
- package/templates/.gitignore +91 -0
- package/templates/LICENSE.md +11 -0
- package/templates/README.md +85 -0
- package/templates/_redirects +1 -0
- package/templates/components/footer.html +30 -0
- package/templates/components/header.html +85 -0
- package/templates/components/logo.html +12 -0
- package/templates/favicon.ico +0 -0
- package/templates/icons/192x192.png +0 -0
- package/templates/icons/512x512.png +0 -0
- package/templates/index.html +77 -0
- package/templates/locales.csv +12 -0
- package/templates/manifest.json +36 -0
- package/templates/manifest.theme.css +114 -0
- package/templates/privacy.md +33 -0
- package/templates/robots.txt +4 -0
- package/templates/sitemap.xml +27 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
// Get project name from command line arguments
|
|
8
|
+
const projectName = process.argv[2];
|
|
9
|
+
|
|
10
|
+
if (!projectName) {
|
|
11
|
+
console.log('Usage: npx mnfst-starter <project-name>');
|
|
12
|
+
console.log('Example: npx mnfst-starter MyProject');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Validate project name - allow most characters but prevent problematic ones
|
|
17
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(projectName) || projectName.includes('..') || projectName.startsWith('.') || projectName.endsWith('.')) {
|
|
18
|
+
console.error('Error: Project name must contain only letters, numbers, dots, underscores, and hyphens. Cannot start/end with dots or contain consecutive dots.');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const projectPath = path.resolve(process.cwd(), projectName);
|
|
23
|
+
|
|
24
|
+
// Check if directory already exists
|
|
25
|
+
if (fs.existsSync(projectPath)) {
|
|
26
|
+
console.error(`Error: Directory "${projectName}" already exists`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(`Creating Manifest project: ${projectName}`);
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
// Create project directory
|
|
34
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
35
|
+
|
|
36
|
+
// Copy all files from starter template
|
|
37
|
+
const starterDir = path.join(__dirname, 'templates');
|
|
38
|
+
const filesToCopy = [
|
|
39
|
+
'index.html',
|
|
40
|
+
'components',
|
|
41
|
+
'data',
|
|
42
|
+
'scripts',
|
|
43
|
+
'styles',
|
|
44
|
+
'icons',
|
|
45
|
+
'manifest.json',
|
|
46
|
+
'.gitignore',
|
|
47
|
+
'robots.txt',
|
|
48
|
+
'sitemap.xml',
|
|
49
|
+
'LICENSE.md',
|
|
50
|
+
'privacy.md',
|
|
51
|
+
'README.md',
|
|
52
|
+
'favicon.ico',
|
|
53
|
+
'_redirects',
|
|
54
|
+
'.htaccess'
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
filesToCopy.forEach(file => {
|
|
58
|
+
const srcPath = path.join(starterDir, file);
|
|
59
|
+
const destPath = path.join(projectPath, file);
|
|
60
|
+
|
|
61
|
+
if (fs.existsSync(srcPath)) {
|
|
62
|
+
if (fs.statSync(srcPath).isDirectory()) {
|
|
63
|
+
copyDir(srcPath, destPath);
|
|
64
|
+
} else {
|
|
65
|
+
fs.copyFileSync(srcPath, destPath);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Create .gitignore
|
|
71
|
+
const gitignore = `# Dependencies (if you add them later)
|
|
72
|
+
node_modules/
|
|
73
|
+
npm-debug.log*
|
|
74
|
+
yarn-debug.log*
|
|
75
|
+
yarn-error.log*
|
|
76
|
+
|
|
77
|
+
# Build outputs (if you add a build process)
|
|
78
|
+
dist/
|
|
79
|
+
build/
|
|
80
|
+
*.tgz
|
|
81
|
+
|
|
82
|
+
# Development files
|
|
83
|
+
.vscode/
|
|
84
|
+
.idea/
|
|
85
|
+
*.swp
|
|
86
|
+
*.swo
|
|
87
|
+
*~
|
|
88
|
+
bs-config.js
|
|
89
|
+
|
|
90
|
+
# OS generated files
|
|
91
|
+
.DS_Store
|
|
92
|
+
.DS_Store?
|
|
93
|
+
._*
|
|
94
|
+
.Spotlight-V100
|
|
95
|
+
.Trashes
|
|
96
|
+
ehthumbs.db
|
|
97
|
+
Thumbs.db
|
|
98
|
+
|
|
99
|
+
# Temporary files
|
|
100
|
+
*.tmp
|
|
101
|
+
*.temp
|
|
102
|
+
|
|
103
|
+
# Logs
|
|
104
|
+
logs
|
|
105
|
+
*.log
|
|
106
|
+
# Runtime data
|
|
107
|
+
pids
|
|
108
|
+
*.pid
|
|
109
|
+
*.seed
|
|
110
|
+
*.pid.lock
|
|
111
|
+
|
|
112
|
+
# Coverage directory used by tools like istanbul
|
|
113
|
+
coverage/
|
|
114
|
+
|
|
115
|
+
# nyc test coverage
|
|
116
|
+
.nyc_output
|
|
117
|
+
|
|
118
|
+
# Dependency directories
|
|
119
|
+
jspm_packages/
|
|
120
|
+
|
|
121
|
+
# Optional npm cache directory
|
|
122
|
+
.npm
|
|
123
|
+
|
|
124
|
+
# Optional REPL history
|
|
125
|
+
.node_repl_history
|
|
126
|
+
|
|
127
|
+
# Output of 'npm pack'
|
|
128
|
+
*.tgz
|
|
129
|
+
|
|
130
|
+
# Yarn Integrity file
|
|
131
|
+
.yarn-integrity
|
|
132
|
+
|
|
133
|
+
# dotenv environment variables file
|
|
134
|
+
.env
|
|
135
|
+
.env.local
|
|
136
|
+
.env.development.local
|
|
137
|
+
.env.test.local
|
|
138
|
+
.env.production.local
|
|
139
|
+
|
|
140
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
141
|
+
.cache
|
|
142
|
+
.parcel-cache
|
|
143
|
+
|
|
144
|
+
# next.js build output
|
|
145
|
+
.next
|
|
146
|
+
|
|
147
|
+
# nuxt.js build output
|
|
148
|
+
.nuxt
|
|
149
|
+
|
|
150
|
+
# vuepress build output
|
|
151
|
+
.vuepress/dist
|
|
152
|
+
|
|
153
|
+
# Serverless directories
|
|
154
|
+
.serverless
|
|
155
|
+
|
|
156
|
+
# FuseBox cache
|
|
157
|
+
.fusebox/
|
|
158
|
+
|
|
159
|
+
# DynamoDB Local files
|
|
160
|
+
.dynamodb/
|
|
161
|
+
`;
|
|
162
|
+
|
|
163
|
+
fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
|
|
164
|
+
|
|
165
|
+
console.log(`✅ Project created successfully!`);
|
|
166
|
+
console.log(`📁 Location: ${projectPath}`);
|
|
167
|
+
console.log(`See README.md for more details.`);
|
|
168
|
+
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error('Error creating project:', error.message);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Helper function to copy directories recursively
|
|
175
|
+
function copyDir(src, dest) {
|
|
176
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
177
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
178
|
+
|
|
179
|
+
for (const entry of entries) {
|
|
180
|
+
const srcPath = path.join(src, entry.name);
|
|
181
|
+
const destPath = path.join(dest, entry.name);
|
|
182
|
+
|
|
183
|
+
if (entry.isDirectory()) {
|
|
184
|
+
copyDir(srcPath, destPath);
|
|
185
|
+
} else {
|
|
186
|
+
fs.copyFileSync(srcPath, destPath);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mnfst-starter",
|
|
3
|
+
"version": "1.5.34",
|
|
4
|
+
"description": "Create a Manifest (mnfst) starter application",
|
|
5
|
+
"main": "index.html",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mnfst-starter": "create-starter.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "browser-sync start --config bs-config.js",
|
|
11
|
+
"build": "echo 'Starter template - no build needed'"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"manifest",
|
|
15
|
+
"mnfst",
|
|
16
|
+
"framework",
|
|
17
|
+
"starter",
|
|
18
|
+
"template",
|
|
19
|
+
"html",
|
|
20
|
+
"css",
|
|
21
|
+
"javascript"
|
|
22
|
+
],
|
|
23
|
+
"author": "Andrew Matlock",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/andrewmatlock/Manifest.git",
|
|
31
|
+
"directory": "packages/create-starter"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"create-starter.js",
|
|
35
|
+
"templates"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Dependencies (if you add them later)
|
|
2
|
+
node_modules/
|
|
3
|
+
npm-debug.log*
|
|
4
|
+
yarn-debug.log*
|
|
5
|
+
yarn-error.log*
|
|
6
|
+
|
|
7
|
+
# Build outputs (if you add a build process)
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.tgz
|
|
11
|
+
|
|
12
|
+
# Development files
|
|
13
|
+
.vscode/
|
|
14
|
+
.idea/
|
|
15
|
+
*.swp
|
|
16
|
+
*.swo
|
|
17
|
+
*~
|
|
18
|
+
bs-config.js
|
|
19
|
+
|
|
20
|
+
# OS generated files
|
|
21
|
+
.DS_Store
|
|
22
|
+
.DS_Store?
|
|
23
|
+
._*
|
|
24
|
+
.Spotlight-V100
|
|
25
|
+
.Trashes
|
|
26
|
+
ehthumbs.db
|
|
27
|
+
Thumbs.db
|
|
28
|
+
|
|
29
|
+
# Temporary files
|
|
30
|
+
*.tmp
|
|
31
|
+
*.temp
|
|
32
|
+
|
|
33
|
+
# Logs
|
|
34
|
+
logs
|
|
35
|
+
*.log
|
|
36
|
+
# Runtime data
|
|
37
|
+
pids
|
|
38
|
+
*.pid
|
|
39
|
+
*.seed
|
|
40
|
+
*.pid.lock
|
|
41
|
+
|
|
42
|
+
# Coverage directory used by tools like istanbul
|
|
43
|
+
coverage/
|
|
44
|
+
|
|
45
|
+
# nyc test coverage
|
|
46
|
+
.nyc_output
|
|
47
|
+
|
|
48
|
+
# Dependency directories
|
|
49
|
+
jspm_packages/
|
|
50
|
+
|
|
51
|
+
# Optional npm cache directory
|
|
52
|
+
.npm
|
|
53
|
+
|
|
54
|
+
# Optional REPL history
|
|
55
|
+
.node_repl_history
|
|
56
|
+
|
|
57
|
+
# Output of 'npm pack'
|
|
58
|
+
*.tgz
|
|
59
|
+
|
|
60
|
+
# Yarn Integrity file
|
|
61
|
+
.yarn-integrity
|
|
62
|
+
|
|
63
|
+
# dotenv environment variables file
|
|
64
|
+
.env
|
|
65
|
+
.env.local
|
|
66
|
+
.env.development.local
|
|
67
|
+
.env.test.local
|
|
68
|
+
.env.production.local
|
|
69
|
+
|
|
70
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
71
|
+
.cache
|
|
72
|
+
.parcel-cache
|
|
73
|
+
|
|
74
|
+
# next.js build output
|
|
75
|
+
.next
|
|
76
|
+
|
|
77
|
+
# nuxt.js build output
|
|
78
|
+
.nuxt
|
|
79
|
+
|
|
80
|
+
# vuepress build output
|
|
81
|
+
.vuepress/dist
|
|
82
|
+
|
|
83
|
+
# Serverless directories
|
|
84
|
+
.serverless
|
|
85
|
+
|
|
86
|
+
# FuseBox cache
|
|
87
|
+
.fusebox/
|
|
88
|
+
|
|
89
|
+
# DynamoDB Local files
|
|
90
|
+
.dynamodb/
|
|
91
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Copyright © 2025 Andrew Matlock
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
+
|
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
+
|
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Manifest Starter Project
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 🚀 Quick Start
|
|
6
|
+
|
|
7
|
+
Manifest projects include a built-in SPA router and require a local server to run.
|
|
8
|
+
|
|
9
|
+
**Local Server Options (choose one):**
|
|
10
|
+
|
|
11
|
+
1. **Python** (works on most systems): `python3 -m http.server 8000`
|
|
12
|
+
|
|
13
|
+
2. **Node.js** (if you have it installed): `npx http-server`
|
|
14
|
+
|
|
15
|
+
3. **Other options**:
|
|
16
|
+
- VS Code Live Server extension
|
|
17
|
+
- Browsersync (requires installation)
|
|
18
|
+
- Any other static file server
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📁 Project Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
project-name/
|
|
26
|
+
├── components/ # Reusable HTML components
|
|
27
|
+
│ ├── header.html # Page header
|
|
28
|
+
│ ├── footer.html # Page footer
|
|
29
|
+
│ └── logo.html # Inline SVG logo
|
|
30
|
+
├── icons/ # Web app (PWA) icons referenced in manifest.json
|
|
31
|
+
│ ├── 192x192.png # Small icon variant
|
|
32
|
+
│ └── 512x512.png # Large icon variant
|
|
33
|
+
├── _redirects # SPA routing support for modern static hosts
|
|
34
|
+
├── favicon.ico # Browser tab icon
|
|
35
|
+
├── index.html # Rendering entry point / main page
|
|
36
|
+
├── LICENSE.md # MIT License
|
|
37
|
+
├── locales.csv # Translated content in English, Arabic, and Chinese
|
|
38
|
+
├── manifest.json # Project & web app manifest
|
|
39
|
+
├── manifest.theme.css # Project theme variables
|
|
40
|
+
├── privacy.md # Privacy policy template, required by most sites & apps
|
|
41
|
+
├── README.md # This file
|
|
42
|
+
├── robots.txt # Website SEO asset
|
|
43
|
+
└── sitemap.xml # Website SEO asset
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ✅ Checklist
|
|
49
|
+
|
|
50
|
+
`index.html`
|
|
51
|
+
- [ ] Change `<html lang="en">` to default language code
|
|
52
|
+
- [ ] Update head `<title>` and `<meta>` tags, and add any custom links or scripts
|
|
53
|
+
|
|
54
|
+
`manifest.json`
|
|
55
|
+
- [ ] Update project config properties (e.g. name, author)
|
|
56
|
+
- [ ] Update or remove HTML components and data sources (e.g. for localization)
|
|
57
|
+
|
|
58
|
+
**Style & Content**
|
|
59
|
+
- [ ] Update `manifest.theme.css` variables
|
|
60
|
+
- [ ] Update `logo.html`, `header.html` and `footer.html` components
|
|
61
|
+
- [ ] Create custom HTML components for pages, sections, etc.
|
|
62
|
+
- [ ] Update index.html `<body>` with top-level routes and components
|
|
63
|
+
- [ ] Update or remove `LICENSE.md` and `privacy.md` text for your use case
|
|
64
|
+
|
|
65
|
+
**Websites**
|
|
66
|
+
- [ ] Replace `favicon.ico`
|
|
67
|
+
- [ ] Update `robots.txt` and `sitemap.xml` for SEO
|
|
68
|
+
- [ ] `_redirects` and `.htaccess` files are included for SPA routing support on most hosting services
|
|
69
|
+
|
|
70
|
+
**Web apps**
|
|
71
|
+
- [ ] Replace or remove `/icons` images referenced in manifest.json
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 📚 Learn More
|
|
76
|
+
|
|
77
|
+
This project supports routes, components, dynamic data, localization, icons, color themes, and much more.
|
|
78
|
+
|
|
79
|
+
For comprehensive documentation visit [manifestjs.org](https://manifestjs.org).
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 📄 License
|
|
84
|
+
|
|
85
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/* /index.html 200
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<footer class="border-t border-line">
|
|
2
|
+
|
|
3
|
+
<!-- Content area -->
|
|
4
|
+
<nav class="row-wrap justify-between items-center gap-4 py-10">
|
|
5
|
+
|
|
6
|
+
<!-- Left side -->
|
|
7
|
+
<div class="col items-start gap-2">
|
|
8
|
+
|
|
9
|
+
<!-- Logo with style overrides -->
|
|
10
|
+
<x-logo class="h-5 text-brand-content"></x-logo>
|
|
11
|
+
|
|
12
|
+
<!-- Copyright with author populated from manifest.json -->
|
|
13
|
+
<small><span x-text="$x.content.footer.copyright">Copyright © 2025</span> <span
|
|
14
|
+
x-text="$x.manifest.author"></span>.</small>
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- Right side -->
|
|
20
|
+
<div class="row-wrap gap-6">
|
|
21
|
+
<a href="/page-1" class="text-sm" x-text="$x.content.page1">Page 1</a>
|
|
22
|
+
<a href="/page-2" class="text-sm" x-text="$x.content.page2">Page 2</a>
|
|
23
|
+
<a href="/license" class="text-sm" x-text="$x.content.license">License</a>
|
|
24
|
+
<a href="/privacy" class="text-sm" x-text="$x.content.privacy">Privacy</a>
|
|
25
|
+
<a role="button" class="sm" href="https://manifestjs.org" target="_blank"
|
|
26
|
+
x-text="$x.content.footer.madeWith">Made with Manifest</a>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
</nav>
|
|
30
|
+
</footer>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<header class="border-b border-line">
|
|
2
|
+
|
|
3
|
+
<!-- Content area -->
|
|
4
|
+
<nav class="row justify-between items-center py-4">
|
|
5
|
+
|
|
6
|
+
<!-- logo.html component as home link -->
|
|
7
|
+
<a href="/">
|
|
8
|
+
<x-logo></x-logo>
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
<!-- Desktop -->
|
|
12
|
+
<div class="hidden md:row items-center gap-2">
|
|
13
|
+
<a href="/page-1" role="button" class="ghost" x-text="$x.content.page1"
|
|
14
|
+
:class="$route === '/page-1' ? 'text-brand-content' : ''"></a>
|
|
15
|
+
<a href="/page-2" role="button" class="ghost" x-text="$x.content.page2"
|
|
16
|
+
:class="$route === '/page-2' ? 'text-brand-content' : ''"></a>
|
|
17
|
+
<a href="https://manifest.build" target="_blank" role="button" class="ghost"><span>Manifest</span><span
|
|
18
|
+
x-icon="lucide:arrow-up-right"></span></a>
|
|
19
|
+
<div class="divider vertical"></div>
|
|
20
|
+
|
|
21
|
+
<!-- Localization menu -->
|
|
22
|
+
<button class="ghost" x-dropdown.bottom="localization-menu" aria-label="Localization Menu"
|
|
23
|
+
x-icon="lucide:languages"></button>
|
|
24
|
+
<menu popover id="localization-menu" class="bottom-end">
|
|
25
|
+
<li @click="$locale.set('en')" :class="{ 'brand pointer-events-none': $locale.current === 'en' }">
|
|
26
|
+
English</li>
|
|
27
|
+
<li @click="$locale.set('ar')" :class="{ 'brand pointer-events-none': $locale.current === 'ar' }">
|
|
28
|
+
العربية</li>
|
|
29
|
+
<li @click="$locale.set('zh')" :class="{ 'brand pointer-events-none': $locale.current === 'zh' }">中文
|
|
30
|
+
</li>
|
|
31
|
+
</menu>
|
|
32
|
+
|
|
33
|
+
<!-- Color theme menu -->
|
|
34
|
+
<button class="ghost" x-dropdown.bottom="color-theme" aria-label="Color Theme Menu"
|
|
35
|
+
x-icon="$theme.current === 'light' ? 'lucide:sun' : $theme.current === 'dark' ? 'lucide:moon' : 'lucide:sun-moon'"></button>
|
|
36
|
+
<menu popover id="color-theme" class="bottom-end min-w-0">
|
|
37
|
+
<li x-theme="'light'" :class="{ 'brand pointer-events-none': $theme.current === 'light' }"
|
|
38
|
+
x-icon="lucide:sun" :aria-label="$x.content.theme.light"></li>
|
|
39
|
+
<li x-theme="'dark'" :class="{ 'brand pointer-events-none': $theme.current === 'dark' }"
|
|
40
|
+
x-icon="lucide:moon" :aria-label="$x.content.theme.dark"></li>
|
|
41
|
+
<li x-theme="'system'" :class="{ 'brand pointer-events-none': $theme.current === 'system' }"
|
|
42
|
+
x-icon="lucide:sun-moon" :aria-label="$x.content.theme.system"></li>
|
|
43
|
+
</menu>
|
|
44
|
+
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<!-- Mobile sidebar -->
|
|
48
|
+
<button class="ghost flex md:hidden" popovertarget="sidebar" x-icon="lucide:menu"
|
|
49
|
+
aria-label="Navigation Menu"></button>
|
|
50
|
+
<aside popover id="sidebar"
|
|
51
|
+
class="col gap-4 w-90 p-4 border-s border-line shadow-2xl [&_a]:w-full [&_a]:justify-start">
|
|
52
|
+
<a href="/page-1" role="button" class="ghost" x-text="$x.content.page1"
|
|
53
|
+
:class="$route === '/page-1' ? 'bg-primary text-primary-foreground' : ''"></a>
|
|
54
|
+
<a href="/page-2" role="button" class="ghost" x-text="$x.content.page2"
|
|
55
|
+
:class="$route === '/page-2' ? 'bg-primary text-primary-foreground' : ''"></a>
|
|
56
|
+
<a href="https://manifest.build" role="button" class="ghost brand"><span>Manifest</span><span
|
|
57
|
+
x-icon="lucide:arrow-up-right"></span></a>
|
|
58
|
+
|
|
59
|
+
<div class="divider"></div>
|
|
60
|
+
|
|
61
|
+
<div role="group" class="w-full even">
|
|
62
|
+
<button x-theme="'light'" :class="{ 'brand pointer-events-none': $theme.current === 'light' }"
|
|
63
|
+
x-icon="lucide:sun" :aria-label="$x.content.theme.light"></button>
|
|
64
|
+
<button x-theme="'dark'" :class="{ 'brand pointer-events-none': $theme.current === 'dark' }"
|
|
65
|
+
x-icon="lucide:moon" :aria-label="$x.content.theme.dark"></button>
|
|
66
|
+
<button x-theme="'system'" :class="{ 'brand pointer-events-none': $theme.current === 'system' }"
|
|
67
|
+
x-icon="lucide:sun-moon" :aria-label="$x.content.theme.system"></button>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="divider"></div>
|
|
71
|
+
|
|
72
|
+
<div role="group" class="w-full even">
|
|
73
|
+
<button @click="$locale.set('en')"
|
|
74
|
+
:class="{ 'brand pointer-events-none': $locale.current === 'en' }">English</button>
|
|
75
|
+
<button @click="$locale.set('ar')"
|
|
76
|
+
:class="{ 'brand pointer-events-none': $locale.current === 'ar' }">العربية</button>
|
|
77
|
+
<button @click="$locale.set('zh')"
|
|
78
|
+
:class="{ 'brand pointer-events-none': $locale.current === 'zh' }">中文</button>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
</aside>
|
|
82
|
+
|
|
83
|
+
</nav>
|
|
84
|
+
|
|
85
|
+
</header>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg class="h-6 text-content-subtle" viewBox="0 0 182 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M8.91667 19.9166C13.2889 19.9166 16.8333 16.3722 16.8333 11.9999C16.8333 7.62766 13.2889 4.08325 8.91667 4.08325C4.54441 4.08325 1 7.62766 1 11.9999C1 16.3722 4.54441 19.9166 8.91667 19.9166Z"
|
|
4
|
+
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M8.91667 4.08325C6.88385 6.21771 5.75 9.05234 5.75 11.9999C5.75 14.9475 6.88385 17.7821 8.91667 19.9166C10.9495 17.7821 12.0833 14.9475 12.0833 11.9999C12.0833 9.05234 10.9495 6.21771 8.91667 4.08325Z"
|
|
7
|
+
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M1 12H16.8333" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
9
|
+
<path
|
|
10
|
+
d="M31.668 19.2441C28.0645 19.2441 25.916 17.3008 25.916 14.5664C25.916 14.1855 25.9551 13.7656 26.043 13.3457L27.8301 4.9082H31.4141L29.6465 13.2871C29.5781 13.6094 29.5391 13.9023 29.5488 14.1758C29.5586 15.4355 30.5059 16.1973 31.873 16.1973C33.2793 16.1973 34.2559 15.3379 34.5879 13.7656L36.4629 4.9082H40.0566L38.0156 14.5469C37.3906 17.4961 34.959 19.2441 31.668 19.2441ZM38.2605 19L40.5262 8.36523H43.7684L43.4168 9.98633H43.4949C44.2273 8.79492 45.5457 8.11133 46.991 8.11133C48.9051 8.11133 50.2234 9.3418 50.2234 11.1484C50.2234 11.5391 50.1746 11.9785 50.077 12.4473L48.7 19H45.3602L46.6395 12.9746C46.6883 12.6719 46.7176 12.4375 46.7176 12.2129C46.7176 11.3535 46.0633 10.7676 45.1062 10.7676C44.0711 10.7676 43.1922 11.5488 42.948 12.7305L41.6102 19H38.2605ZM54.7652 7.14453C53.8082 7.14453 53.0562 6.38281 53.0562 5.47461C53.0562 4.55664 53.8082 3.79492 54.7652 3.79492C55.7223 3.79492 56.4742 4.55664 56.4742 5.47461C56.4742 6.38281 55.7223 7.14453 54.7652 7.14453ZM50.1949 19L52.4605 8.36523H55.8297L53.5641 19H50.1949ZM56.4555 8.35547H59.8246L60.1469 16.0215H60.2152L63.7211 8.35547H67.3148L61.5336 19H57.6371L56.4555 8.35547ZM70.6457 19.2441C67.6281 19.2441 65.7629 17.4082 65.7629 14.4199C65.7629 10.8164 68.1164 8.11133 71.6223 8.11133C74.425 8.11133 76.3293 9.9082 76.3293 12.6816C76.3293 13.2285 76.2805 13.9023 76.1633 14.4199H68.8293C68.8098 14.5273 68.8 14.6348 68.8 14.7422C68.8 15.9434 69.552 16.8125 70.7922 16.8125C71.7687 16.8125 72.5012 16.3145 72.7453 15.5723H75.8898C75.3332 17.75 73.3508 19.2441 70.6457 19.2441ZM69.1516 12.4863H73.2238C73.2434 12.4277 73.2434 12.291 73.2434 12.1836C73.2434 11.2559 72.5891 10.5137 71.4758 10.5137C70.343 10.5137 69.4348 11.334 69.1516 12.4863ZM75.8027 19L78.0879 8.36523H81.3496L81.0469 9.87891H81.1152C81.6426 8.89258 82.5898 8.20898 83.7812 8.20898C84.3672 8.20898 84.8066 8.30664 85.1875 8.48242L84.543 11.4219C84.1133 11.2168 83.6152 11.0703 83.0098 11.0703C81.623 11.0703 80.7148 11.8418 80.373 13.4043L79.1719 19H75.8027ZM84.5926 11.6074C84.5926 9.50781 86.4285 8.12109 89.2508 8.12109C91.8973 8.12109 93.7625 9.55664 93.8309 11.627H90.8035C90.7547 10.8945 90.1199 10.3867 89.202 10.3867C88.323 10.3867 87.7859 10.7578 87.7859 11.3145C87.7859 11.7832 88.0984 12.0273 89.1824 12.3887L90.3152 12.7598C92.327 13.4336 93.0984 14.2441 93.0984 15.6699C93.0984 17.8184 91.1746 19.2539 88.2742 19.2539C85.3152 19.2539 83.4012 17.8184 83.323 15.6309H86.5164C86.575 16.4219 87.2879 16.9688 88.3719 16.9688C89.241 16.9688 89.7781 16.5977 89.7781 16.0312C89.7781 15.5918 89.4656 15.3672 88.4207 15.0156L87.4637 14.6934C85.491 14.0391 84.5926 13.0723 84.5926 11.6074ZM96.4879 19.1562C94.7105 19.1562 93.3434 17.9355 93.3434 16.2656C93.3434 14.0879 95.15 12.75 98.109 12.6621L100.619 12.584L100.746 11.959C100.785 11.793 100.785 11.7051 100.785 11.6074C100.785 10.9922 100.218 10.5918 99.3102 10.5918C98.4313 10.5918 97.8355 10.9727 97.6305 11.627H94.5543C94.9547 9.47852 96.8883 8.11133 99.5543 8.11133C102.25 8.11133 104.076 9.41016 104.076 11.3145C104.076 11.5977 104.037 11.959 103.988 12.1836L102.543 19H99.2809L99.5543 17.7402H99.4859C98.9195 18.5898 97.8258 19.1562 96.4879 19.1562ZM97.982 16.8223C98.9684 16.8223 99.8473 16.1777 100.033 15.2988L100.209 14.5078L98.275 14.5664C97.2496 14.6055 96.5953 15.0742 96.5953 15.7871C96.5953 16.4121 97.1617 16.8223 97.982 16.8223ZM103.51 19L106.508 4.9082H109.877L106.879 19H103.51ZM121.842 16.1191L121.236 19H111.578L114.576 4.9082H124.225L123.609 7.78906H117.545L116.949 10.6016H122.652L122.096 13.2383H116.393L115.777 16.1191H121.842ZM127.663 15.6699H127.595L125.27 19H121.55L125.905 13.6387L123.845 8.36523H127.448L128.512 11.6953H128.581L130.905 8.36523H134.636L130.27 13.7266L132.331 19H128.737L127.663 15.6699ZM135.33 22.4375H131.98L134.968 8.36523H138.24L137.918 9.89844H137.986C138.767 8.78516 139.959 8.20898 141.296 8.20898C143.533 8.20898 144.91 9.80078 144.91 12.3594C144.91 16.2754 142.664 19.1562 139.636 19.1562C138.093 19.1562 136.961 18.375 136.541 17.0469H136.482L135.33 22.4375ZM138.884 16.4805C140.32 16.4805 141.463 14.9082 141.463 12.8867C141.463 11.6172 140.789 10.7969 139.724 10.7969C138.269 10.7969 137.117 12.4961 137.117 14.4297C137.117 15.6504 137.82 16.4805 138.884 16.4805ZM151.297 8.11133C154.286 8.11133 156.287 10.0449 156.287 12.9062C156.287 16.5781 153.719 19.2539 150.135 19.2539C147.157 19.2539 145.145 17.3301 145.145 14.459C145.145 10.7871 147.723 8.11133 151.297 8.11133ZM150.272 16.6367C151.746 16.6367 152.86 15.0449 152.86 12.9746C152.86 11.627 152.186 10.7285 151.151 10.7285C149.657 10.7285 148.553 12.291 148.553 14.3906C148.553 15.7383 149.237 16.6367 150.272 16.6367ZM155.771 19L158.056 8.36523H161.318L161.015 9.87891H161.083C161.611 8.89258 162.558 8.20898 163.749 8.20898C164.335 8.20898 164.775 8.30664 165.155 8.48242L164.511 11.4219C164.081 11.2168 163.583 11.0703 162.978 11.0703C161.591 11.0703 160.683 11.8418 160.341 13.4043L159.14 19H155.771ZM168.633 19.1367C166.465 19.1367 165.146 18.3457 165.146 16.793C165.146 16.5293 165.166 16.1289 165.264 15.6797L166.221 11.1094H164.639L165.186 8.60938H166.768L167.305 6.05078H170.664L170.117 8.60938H172.246L171.709 11.1094H169.59L168.701 15.2988C168.652 15.4648 168.633 15.6992 168.633 15.8457C168.633 16.4512 169.033 16.7051 169.902 16.7051C170.283 16.7051 170.469 16.6855 170.605 16.6465L170.078 19.0098C169.775 19.0879 169.17 19.1367 168.633 19.1367ZM172.257 11.6074C172.257 9.50781 174.093 8.12109 176.915 8.12109C179.561 8.12109 181.427 9.55664 181.495 11.627H178.468C178.419 10.8945 177.784 10.3867 176.866 10.3867C175.987 10.3867 175.45 10.7578 175.45 11.3145C175.45 11.7832 175.762 12.0273 176.846 12.3887L177.979 12.7598C179.991 13.4336 180.762 14.2441 180.762 15.6699C180.762 17.8184 178.839 19.2539 175.938 19.2539C172.979 19.2539 171.065 17.8184 170.987 15.6309H174.18C174.239 16.4219 174.952 16.9688 176.036 16.9688C176.905 16.9688 177.442 16.5977 177.442 16.0312C177.442 15.5918 177.13 15.3672 176.085 15.0156L175.128 14.6934C173.155 14.0391 172.257 13.0723 172.257 11.6074Z"
|
|
11
|
+
fill="currentColor" />
|
|
12
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
|
|
6
|
+
<meta charset="UTF-8">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
8
|
+
|
|
9
|
+
<!-- Web -->
|
|
10
|
+
<title>Project Name</title>
|
|
11
|
+
<meta name="description" content="Lorem ipsum dolor sit amet.">
|
|
12
|
+
<meta name="author" content="Your Name">
|
|
13
|
+
<meta name="keywords" content="lorem, ipsum, dolor, sit, amet">
|
|
14
|
+
<meta name="robots" content="index, follow">
|
|
15
|
+
<meta name="googlebot" content="index, follow">
|
|
16
|
+
<meta name="google" content="notranslate">
|
|
17
|
+
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
18
|
+
|
|
19
|
+
<!-- Web App & Manifest -->
|
|
20
|
+
<meta name="theme-color" content="#FFFFFF" media="(prefers-color-scheme: light)">
|
|
21
|
+
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)">
|
|
22
|
+
<link rel="manifest" href="/manifest.json">
|
|
23
|
+
|
|
24
|
+
<!-- Styles -->
|
|
25
|
+
<link rel="stylesheet" href="/manifest.theme.css">
|
|
26
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mnfst@0.5.25/dist/manifest.min.css">
|
|
27
|
+
|
|
28
|
+
<!-- Scripts -->
|
|
29
|
+
<script src="https://cdn.jsdelivr.net/npm/mnfst@0.5.25/dist/manifest.min.js" data-tailwind
|
|
30
|
+
data-version="0.5.25"></script>
|
|
31
|
+
|
|
32
|
+
</head>
|
|
33
|
+
|
|
34
|
+
<!-- Page class applies classic web/app layout -->
|
|
35
|
+
|
|
36
|
+
<body class="page">
|
|
37
|
+
|
|
38
|
+
<!-- header.html component -->
|
|
39
|
+
<x-header x-route="/,page-1,page-2"></x-header>
|
|
40
|
+
|
|
41
|
+
<!-- Content area -->
|
|
42
|
+
<main class="[&>section]:py-10">
|
|
43
|
+
|
|
44
|
+
<x-test-localization x-route="test"></x-test-localization>
|
|
45
|
+
|
|
46
|
+
<!-- Home -->
|
|
47
|
+
<section x-route="/" class="prose w-full mb-40" x-markdown="README.md"></section>
|
|
48
|
+
|
|
49
|
+
<!-- Page 1 -->
|
|
50
|
+
<section x-route="page-1">
|
|
51
|
+
<h1 x-text="$x.content.page1">Page 1</h1>
|
|
52
|
+
</section>
|
|
53
|
+
|
|
54
|
+
<!-- Page 2 -->
|
|
55
|
+
<section x-route="page-2">
|
|
56
|
+
<h1 x-text="$x.content.page2">Page 2</h1>
|
|
57
|
+
</section>
|
|
58
|
+
|
|
59
|
+
<!-- License -->
|
|
60
|
+
<section x-route="license" class="prose w-full mb-40" x-markdown="LICENSE.md"></section>
|
|
61
|
+
|
|
62
|
+
<!-- Privacy -->
|
|
63
|
+
<section x-route="privacy" class="prose w-full mb-40" x-markdown="privacy.md"></section>
|
|
64
|
+
|
|
65
|
+
<!-- 404 -->
|
|
66
|
+
<section x-route="!*">
|
|
67
|
+
<h1 x-text="$x.content.notFound">404 Page Not Found</h1>
|
|
68
|
+
</section>
|
|
69
|
+
|
|
70
|
+
</main>
|
|
71
|
+
|
|
72
|
+
<!-- footer.html component -->
|
|
73
|
+
<x-footer></x-footer>
|
|
74
|
+
|
|
75
|
+
</body>
|
|
76
|
+
|
|
77
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
key,en,ar,zh
|
|
2
|
+
page1,Page 1,الصفحة 1,页面 1
|
|
3
|
+
page2,Page 2,الصفحة 2,页面 2
|
|
4
|
+
license,License,الترخيص,许可证
|
|
5
|
+
privacy,Privacy,الخصوصية,隐私
|
|
6
|
+
notFound,404 Page Not Found,404 الصفحة غير موجودة,404 页面未找到
|
|
7
|
+
footer.copyright,Copyright © 2025,حقوق النشر © 2025,版权 © 2025
|
|
8
|
+
footer.madeWith,Made with Manifest,صُنع بـ Manifest,使用 Manifest 制作
|
|
9
|
+
footer.privacy,Privacy,الخصوصية,隐私
|
|
10
|
+
theme.light,Light,فاتح,浅色
|
|
11
|
+
theme.dark,Dark,داكن,深色
|
|
12
|
+
theme.system,System,النظام,系统
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "My Project",
|
|
3
|
+
"short_name": "Project name",
|
|
4
|
+
"author": "Universal Exports",
|
|
5
|
+
"email": "universal@exports.com",
|
|
6
|
+
"description": "Lorem ipsum dolor sit amet.",
|
|
7
|
+
"start_url": "/",
|
|
8
|
+
"scope": "/",
|
|
9
|
+
"display": "standalone",
|
|
10
|
+
"orientation": "any",
|
|
11
|
+
"background_color": "#FFFFFF",
|
|
12
|
+
"icons": [
|
|
13
|
+
{
|
|
14
|
+
"src": "/icons/192x192.png",
|
|
15
|
+
"sizes": "192x192",
|
|
16
|
+
"type": "image/png"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"src": "/icons/512x512.png",
|
|
20
|
+
"sizes": "512x512",
|
|
21
|
+
"type": "image/png"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"components": [],
|
|
25
|
+
"preloadedComponents": [
|
|
26
|
+
"components/footer.html",
|
|
27
|
+
"components/header.html",
|
|
28
|
+
"components/logo.html"
|
|
29
|
+
],
|
|
30
|
+
"data": {
|
|
31
|
+
"manifest": "/manifest.json",
|
|
32
|
+
"content": {
|
|
33
|
+
"locales": "/locales.csv"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* Manifest Theme CSS
|
|
2
|
+
/* By Andrew Matlock under MIT license
|
|
3
|
+
/* https://manifestjs.org/styles/theme
|
|
4
|
+
/* Modify values to customize your project theme
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
:root,
|
|
8
|
+
::selection {
|
|
9
|
+
|
|
10
|
+
/* Default palette */
|
|
11
|
+
--color-50: oklch(100% 0 0);
|
|
12
|
+
--color-100: oklch(98.17% 0.0005 95.87);
|
|
13
|
+
--color-200: oklch(96.27% 0.0026 252.34);
|
|
14
|
+
--color-300: oklch(91.79% 0.0029 264.26);
|
|
15
|
+
--color-400: oklch(89.24% 0.0024 12.48);
|
|
16
|
+
--color-500: oklch(67.4% 0.0318 251.27);
|
|
17
|
+
--color-600: oklch(48.26% 0.0365 255.09);
|
|
18
|
+
--color-700: oklch(28.7% 0.030787 270.1);
|
|
19
|
+
--color-800: oklch(20.7% 0.026326 268.7);
|
|
20
|
+
--color-900: oklch(16.6% 0.026 267);
|
|
21
|
+
--color-950: oklch(3.89% 0.0181 262.25);
|
|
22
|
+
|
|
23
|
+
/* Light theme */
|
|
24
|
+
--color-page: var(--color-50);
|
|
25
|
+
--color-surface-1: var(--color-100);
|
|
26
|
+
--color-surface-2: var(--color-200);
|
|
27
|
+
--color-surface-3: var(--color-300);
|
|
28
|
+
--color-content-stark: var(--color-900);
|
|
29
|
+
--color-content-neutral: var(--color-600);
|
|
30
|
+
--color-content-subtle: var(--color-500);
|
|
31
|
+
--color-field-surface: var(--color-300);
|
|
32
|
+
--color-field-surface-hover: var(--color-400);
|
|
33
|
+
--color-field-inverse: var(--color-content-stark);
|
|
34
|
+
--color-popover-surface: var(--color-page);
|
|
35
|
+
--color-line: color-mix(in oklch, var(--color-content-stark) 11%, transparent);
|
|
36
|
+
--color-brand-surface: #f6c07b;
|
|
37
|
+
--color-brand-surface-hover: #f19b46;
|
|
38
|
+
--color-brand-inverse: #763518;
|
|
39
|
+
--color-brand-content: #de6618;
|
|
40
|
+
--color-accent-surface: #ffccd3;
|
|
41
|
+
--color-accent-surface-hover: #ffa1ad;
|
|
42
|
+
--color-accent-inverse: #a50036;
|
|
43
|
+
--color-accent-content: #ff637e;
|
|
44
|
+
--color-positive-surface: #16a34a;
|
|
45
|
+
--color-positive-surface-hover: #166534;
|
|
46
|
+
--color-positive-inverse: white;
|
|
47
|
+
--color-positive-content: var(--color-positive-surface);
|
|
48
|
+
--color-negative-surface: #ef4444;
|
|
49
|
+
--color-negative-surface-hover: #dc2626;
|
|
50
|
+
--color-negative-inverse: white;
|
|
51
|
+
--color-negative-content: var(--color-negative-surface);
|
|
52
|
+
|
|
53
|
+
/* Sizes */
|
|
54
|
+
--radius: 0.5rem;
|
|
55
|
+
--spacing: 0.25rem;
|
|
56
|
+
--spacing-content-width: 68.75rem;
|
|
57
|
+
--spacing-field-padding: calc(var(--spacing) * 2.5);
|
|
58
|
+
--spacing-field-height: calc(var(--spacing) * 9);
|
|
59
|
+
--spacing-popover-offset: calc(var(--spacing) * 2);
|
|
60
|
+
--spacing-resize-handle: 1rem;
|
|
61
|
+
--spacing-viewport-padding: 5vw;
|
|
62
|
+
|
|
63
|
+
/* Effects */
|
|
64
|
+
--transition: all .05s ease-in-out;
|
|
65
|
+
--tooltip-hover-delay: .5s;
|
|
66
|
+
|
|
67
|
+
/* Fonts */
|
|
68
|
+
--font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
69
|
+
|
|
70
|
+
/* Icons */
|
|
71
|
+
--icon-accordion: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 256 256'%3E%3Cpath fill='%23000' d='m184.49 136.49l-80 80a12 12 0 0 1-17-17L159 128L87.51 56.49a12 12 0 1 1 17-17l80 80a12 12 0 0 1-.02 17'/%3E%3C/svg%3E");
|
|
72
|
+
--icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='currentColor' d='m0 11l2-2l5 5L18 3l2 2L7 18z'/%3E%3C/svg%3E");
|
|
73
|
+
--icon-toast-dismiss: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M18 6L6 18M6 6l12 12'/%3E%3C/svg%3E");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Dark theme overrides */
|
|
77
|
+
.dark {
|
|
78
|
+
--color-page: var(--color-950);
|
|
79
|
+
--color-surface-1: var(--color-900);
|
|
80
|
+
--color-surface-2: var(--color-800);
|
|
81
|
+
--color-surface-3: var(--color-700);
|
|
82
|
+
--color-field-surface: var(--color-700);
|
|
83
|
+
--color-field-surface-hover: var(--color-600);
|
|
84
|
+
--color-popover-surface: var(--color-700);
|
|
85
|
+
--color-content-stark: var(--color-50);
|
|
86
|
+
--color-content-neutral: var(--color-400);
|
|
87
|
+
--color-content-subtle: var(--color-500);
|
|
88
|
+
--color-brand-content: #f6c07b;
|
|
89
|
+
--color-accent-content: #ffa1ad;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@layer base {
|
|
93
|
+
|
|
94
|
+
/* Default font and colors */
|
|
95
|
+
:where(html),
|
|
96
|
+
:host {
|
|
97
|
+
line-height: 1.5;
|
|
98
|
+
font-family: var(--font-sans);
|
|
99
|
+
color: var(--color-content-stark, inherit);
|
|
100
|
+
background-color: var(--color-page, inherit)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Text selection */
|
|
104
|
+
::selection {
|
|
105
|
+
background-color: color-mix(in oklch, var(--color-surface-1) 92%, var(--color-content-stark))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Focus state */
|
|
109
|
+
:where(:focus-visible),
|
|
110
|
+
:where(label:has(input[type=search], input[type=file]):focus-within) {
|
|
111
|
+
outline: none;
|
|
112
|
+
box-shadow: 0 0 0 2px color-mix(in oklch, var(--color-content-stark) 35%, transparent);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Privacy Policy
|
|
2
|
+
|
|
3
|
+
Updated 14 February, 2026
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This Privacy Policy describes <span x-text="$x.manifest.name"></span> ("<span x-text="$x.manifest.short_name"></span>") practices for handling your information in connection with this web application and any content, related documentation, information, and services made available to you on this web application (collectively, the "Services"). This Privacy Policy describes the personal information we process to support our Services.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What Kinds of Information Do We Collect?
|
|
12
|
+
|
|
13
|
+
We do not collect or store any type of personal data.
|
|
14
|
+
|
|
15
|
+
We may collect anonymized visitor data via third party services integrated in our Services. All integrations comply with the GDPR, ePrivacy (including PECR), COPPA and CCPA. Using these privacy-friendly integrations, your IP address is only briefly processed, and we (running the Services) have no way of identifying you. As per the CCPA, your personal information is de-identified.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## How Do We Use Information?
|
|
20
|
+
|
|
21
|
+
The sole purpose of collecting the aforementioned data is to understand our traffic and usage in the most privacy-friendly way possible, so that we may improve the Services. The lawful basis as per the GDPR is "Article 6(1)(f); where our legitimate interests are to improve our services and business continually." As per the explanation, no personal data is stored over time.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Data Retention
|
|
26
|
+
|
|
27
|
+
All data collected are stored on third party services and are subject to the services' respective data retention policies.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Questions
|
|
32
|
+
|
|
33
|
+
If you have any questions about this Privacy Policy or our practices, please contact us at <a :href="'mailto:' + $x.manifest.email" x-text="$x.manifest.email"></a>.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
3
|
+
<url>
|
|
4
|
+
<loc>https://universlexports.com</loc>
|
|
5
|
+
<lastmod>2026-01-01</lastmod>
|
|
6
|
+
<changefreq>monthly</changefreq>
|
|
7
|
+
<priority>1.0</priority>
|
|
8
|
+
</url>
|
|
9
|
+
<url>
|
|
10
|
+
<loc>https://universlexports.com/page-1</loc>
|
|
11
|
+
<lastmod>2026-01-01</lastmod>
|
|
12
|
+
<changefreq>monthly</changefreq>
|
|
13
|
+
<priority>0.9</priority>
|
|
14
|
+
</url>
|
|
15
|
+
<url>
|
|
16
|
+
<loc>https://universlexports.com/page-2</loc>
|
|
17
|
+
<lastmod>2026-01-01</lastmod>
|
|
18
|
+
<changefreq>monthly</changefreq>
|
|
19
|
+
<priority>0.5</priority>
|
|
20
|
+
</url>
|
|
21
|
+
<url>
|
|
22
|
+
<loc>https://universlexports.com/privacy</loc>
|
|
23
|
+
<lastmod>2026-01-01</lastmod>
|
|
24
|
+
<changefreq>quarterly</changefreq>
|
|
25
|
+
<priority>0.1</priority>
|
|
26
|
+
</url>
|
|
27
|
+
</urlset>
|