campsitejs 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js ADDED
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env node
2
+ import { cp, mkdir, readFile, readdir, rm, writeFile } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import { dirname, join, relative, resolve } from "path";
5
+ import { fileURLToPath } from "url";
6
+ import { spawn } from "child_process";
7
+ import prompts from "prompts";
8
+ import kleur from "kleur";
9
+
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ const templateDir = join(__dirname, "template");
12
+ // Variant pages live under the template folder
13
+ const variantDir = join(templateDir, "variants");
14
+
15
+ function formatPackageName(name) {
16
+ return name
17
+ .trim()
18
+ .toLowerCase()
19
+ .replace(/[^a-z0-9-]/g, "-")
20
+ .replace(/^-+/, "")
21
+ .replace(/-+$/, "") || "campsite01";
22
+ }
23
+
24
+ function nextCampsiteName(rootDir) {
25
+ let i = 1;
26
+ // Find the first campsiteXX that doesn't exist in the target root
27
+ while (true) {
28
+ const candidate = `campsite${String(i).padStart(2, "0")}`;
29
+ if (!existsSync(join(rootDir, candidate))) return candidate;
30
+ i += 1;
31
+ }
32
+ }
33
+
34
+ async function ensureTargetDir(targetDir) {
35
+ if (!existsSync(targetDir)) {
36
+ await mkdir(targetDir, { recursive: true });
37
+ return;
38
+ }
39
+ const files = await readdir(targetDir);
40
+ if (files.length > 0) {
41
+ const { overwrite } = await prompts({
42
+ type: "confirm",
43
+ name: "overwrite",
44
+ message: `Directory ${targetDir} is not empty. Continue and potentially overwrite?`,
45
+ initial: false
46
+ });
47
+ if (!overwrite) {
48
+ console.log(kleur.yellow("Aborted to avoid overwriting files."));
49
+ process.exit(1);
50
+ }
51
+ }
52
+ }
53
+
54
+ async function copyBaseTemplate(targetDir) {
55
+ await cp(templateDir, targetDir, { recursive: true });
56
+ const gitignoreSource = join(targetDir, "_gitignore");
57
+ const gitignoreDest = join(targetDir, ".gitignore");
58
+ if (existsSync(gitignoreSource)) {
59
+ await rm(gitignoreDest).catch(() => {});
60
+ await cp(gitignoreSource, gitignoreDest);
61
+ await rm(gitignoreSource);
62
+ }
63
+ }
64
+
65
+ async function writeConfig(targetDir, answers) {
66
+ const configPath = join(targetDir, "campsite.config.js");
67
+ const primaryEngine = answers.templateEngines[0] || "nunjucks";
68
+ const config = `export default {
69
+ siteName: "${answers.projectName}",
70
+ srcDir: "src",
71
+ outDir: "dist",
72
+ templateEngine: "${primaryEngine}",
73
+ markdown: ${answers.markdown},
74
+ integrations: {
75
+ nunjucks: ${answers.templateEngines.includes("nunjucks")},
76
+ liquid: ${answers.templateEngines.includes("liquid")},
77
+ vue: ${answers.templateEngines.includes("vue")},
78
+ alpine: ${answers.templateEngines.includes("alpine")}
79
+ }
80
+ };
81
+ `;
82
+ await writeFile(configPath, config, "utf8");
83
+ }
84
+
85
+ async function updatePackageJson(targetDir, answers) {
86
+ const pkgPath = join(targetDir, "package.json");
87
+ const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
88
+ pkg.name = formatPackageName(answers.projectName);
89
+ pkg.dependencies = pkg.dependencies || {};
90
+ pkg.devDependencies = pkg.devDependencies || {};
91
+ const deps = pkg.dependencies;
92
+ const devDeps = pkg.devDependencies;
93
+ const localCoreDir = resolve(__dirname, "../basecampjs");
94
+ if (existsSync(localCoreDir)) {
95
+ const relCore = relative(targetDir, localCoreDir) || ".";
96
+ deps["basecampjs"] = `file:${relCore}`;
97
+ } else {
98
+ deps["basecampjs"] = "^0.0.1";
99
+ }
100
+ if (answers.markdown) deps["markdown-it"] = "^14.1.0";
101
+ if (answers.templateEngines.includes("nunjucks")) deps["nunjucks"] = "^3.2.4";
102
+ if (answers.templateEngines.includes("liquid")) deps["liquidjs"] = "^10.12.0";
103
+ if (answers.templateEngines.includes("vue")) deps["vue"] = "^3.4.0";
104
+ if (answers.templateEngines.includes("alpine")) deps["alpinejs"] = "^3.13.0";
105
+ devDeps["tailwindcss"] = "^3.4.13";
106
+ await writeFile(pkgPath, JSON.stringify(pkg, null, 2), "utf8");
107
+ }
108
+
109
+ async function swapPageTemplates(targetDir, answers) {
110
+ const pageDir = join(targetDir, "src", "pages");
111
+ if (answers.markdown) {
112
+ // keep markdown starter; ensure nunjucks variant removed
113
+ await rm(join(pageDir, "index.njk")).catch(() => {});
114
+ } else {
115
+ await rm(join(pageDir, "index.md")).catch(() => {});
116
+ await cp(join(variantDir, "index.njk"), join(pageDir, "index.njk"));
117
+ }
118
+ }
119
+
120
+ async function pruneComponents(targetDir, answers) {
121
+ const componentDir = join(targetDir, "src", "components");
122
+ if (!answers.templateEngines.includes("vue")) {
123
+ await rm(join(componentDir, "HelloCampsite.vue")).catch(() => {});
124
+ }
125
+ if (!answers.templateEngines.includes("alpine")) {
126
+ await rm(join(componentDir, "alpine-card.html")).catch(() => {});
127
+ }
128
+ }
129
+
130
+ async function installDependencies(targetDir, packageManager) {
131
+ return new Promise((resolve, reject) => {
132
+ const child = spawn(packageManager, ["install"], {
133
+ cwd: targetDir,
134
+ stdio: "inherit",
135
+ shell: process.platform === "win32"
136
+ });
137
+ child.on("close", (code) => {
138
+ if (code === 0) resolve();
139
+ else reject(new Error(`${packageManager} install failed with code ${code}`));
140
+ });
141
+ });
142
+ }
143
+
144
+ async function main() {
145
+ console.log(kleur.bold().cyan("\n🏕️ Welcome to Campsite"));
146
+ console.log(kleur.dim("Scaffold a cozy static site in seconds.\n"));
147
+
148
+ const argProjectName = process.argv[2];
149
+ const defaultProjectName = argProjectName || nextCampsiteName(process.cwd());
150
+ const answers = await prompts([
151
+ {
152
+ type: "text",
153
+ name: "projectName",
154
+ message: "Project name",
155
+ initial: defaultProjectName
156
+ },
157
+ {
158
+ type: "toggle",
159
+ name: "markdown",
160
+ message: "Include Markdown + frontmatter support?",
161
+ initial: true,
162
+ active: "yes",
163
+ inactive: "no"
164
+ },
165
+ {
166
+ type: "multiselect",
167
+ name: "templateEngines",
168
+ message: "Choose templating and UI options",
169
+ hint: "Use space to toggle, enter to confirm",
170
+ instructions: false,
171
+ min: 1,
172
+ choices: [
173
+ { title: "Nunjucks", value: "nunjucks", selected: true },
174
+ { title: "Liquid", value: "liquid", selected: true },
175
+ { title: "Vue components", value: "vue" },
176
+ { title: "AlpineJS sprinkles", value: "alpine" }
177
+ ]
178
+ },
179
+ {
180
+ type: "select",
181
+ name: "packageManager",
182
+ message: "Package manager",
183
+ initial: 0,
184
+ choices: [
185
+ { title: "npm", value: "npm" },
186
+ { title: "pnpm", value: "pnpm" },
187
+ { title: "yarn", value: "yarn" },
188
+ { title: "bun", value: "bun" }
189
+ ]
190
+ },
191
+ {
192
+ type: "toggle",
193
+ name: "install",
194
+ message: "Install dependencies now?",
195
+ initial: true,
196
+ active: "yes",
197
+ inactive: "no"
198
+ }
199
+ ], {
200
+ onCancel: () => {
201
+ console.log(kleur.yellow("Setup cancelled."));
202
+ process.exit(1);
203
+ }
204
+ });
205
+
206
+ const targetDir = resolve(process.cwd(), answers.projectName);
207
+ await ensureTargetDir(targetDir);
208
+ await copyBaseTemplate(targetDir);
209
+ await swapPageTemplates(targetDir, answers);
210
+ await pruneComponents(targetDir, answers);
211
+ await writeConfig(targetDir, answers);
212
+ await updatePackageJson(targetDir, answers);
213
+
214
+ if (answers.install) {
215
+ console.log(kleur.green("Setting up your campsite..."));
216
+ try {
217
+ await installDependencies(targetDir, answers.packageManager);
218
+ } catch (err) {
219
+ console.log(kleur.yellow(`Dependency installation failed: ${err.message}`));
220
+ }
221
+ }
222
+
223
+ console.log(kleur.bold().green("Setup Complete...") + " " + kleur.bold().cyan("Happy Camping! 🌲⛺🔥"));
224
+ console.log(`\n🧭 Navigate to ${kleur.bold(answers.projectName)} and run: ${kleur.cyan(`${answers.packageManager} run dev`)}`);
225
+ console.log("\n");
226
+ }
227
+
228
+ main().catch((err) => {
229
+ console.error(err);
230
+ process.exit(1);
231
+ });
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "campsitejs",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "description": "Create a new Campsite static site (campsitejs).",
6
+ "bin": {
7
+ "campsitejs": "./index.js"
8
+ },
9
+ "files": [
10
+ "index.js",
11
+ "template"
12
+ ],
13
+ "keywords": [
14
+ "campsite",
15
+ "static-site-generator",
16
+ "campsitejs",
17
+ "scaffolding"
18
+ ],
19
+ "license": "MIT",
20
+ "author": "Campsite",
21
+ "dependencies": {
22
+ "kleur": "^4.1.5",
23
+ "prompts": "^2.4.2"
24
+ },
25
+ "engines": {
26
+ "node": ">=18"
27
+ }
28
+ }
@@ -0,0 +1,6 @@
1
+ node_modules
2
+ npm-debug.log*
3
+ dist
4
+ public/style.css
5
+ .DS_Store
6
+ .env
@@ -0,0 +1,13 @@
1
+ export default {
2
+ siteName: "Campsite",
3
+ srcDir: "src",
4
+ outDir: "dist",
5
+ templateEngine: "nunjucks",
6
+ markdown: true,
7
+ integrations: {
8
+ nunjucks: true,
9
+ liquid: false,
10
+ vue: false,
11
+ alpine: false
12
+ }
13
+ };
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "campsite-site",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "build:css": "tailwindcss -c tailwind.config.cjs -i ./src/styles/tailwind.css -o ./public/style.css --minify",
8
+ "dev:css": "tailwindcss -c tailwind.config.cjs -i ./src/styles/tailwind.css -o ./public/style.css --watch",
9
+ "dev:site": "campsite dev",
10
+ "dev": "npm-run-all -p dev:css dev:site",
11
+ "prebuild": "npm run build:css",
12
+ "build": "campsite build",
13
+ "serve": "campsite serve",
14
+ "postinstall": "npm run build:css"
15
+ },
16
+ "dependencies": {
17
+ "basecampjs": "^0.0.1"
18
+ },
19
+ "devDependencies": {
20
+ "npm-run-all": "^4.1.5",
21
+ "tailwindcss": "^3.4.13"
22
+ }
23
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="550" height="139" fill="none" viewBox="0 0 550 139"><path fill="#000" d="M546.049 88.96q1.664 0 2.56 1.024 1.024 1.024 1.024 2.56 0 1.408-1.024 2.816-3.712 4.48-11.136 7.168-7.296 2.56-15.872 2.56-9.216 0-16.64-4.096-7.424-4.224-11.648-11.648-4.224-7.425-4.224-16.768 0-9.855 4.352-17.792 4.48-8.064 12.032-12.672 7.68-4.608 17.024-4.608 7.296 0 12.928 2.56 5.76 2.432 8.96 6.912 3.2 4.352 3.2 9.728 0 7.552-6.912 12.288-6.784 4.608-18.048 4.608-7.424 0-14.336-1.92-6.784-2.048-10.88-5.248-.64 3.584-.64 6.656 0 7.04 3.2 12.672 3.2 5.505 8.832 8.576t12.8 3.072q7.553 0 13.056-1.792 5.504-1.92 8.32-5.504 1.152-1.152 3.072-1.152m-23.552-43.776q-7.552 0-13.568 3.712-6.017 3.712-9.216 10.368 3.583 2.944 9.6 4.992 6.144 2.048 13.312 2.048 7.936 0 12.544-2.56 4.736-2.56 4.736-6.784 0-4.992-4.864-8.32-4.864-3.456-12.544-3.456M483.336 39.04q1.663 0 2.688 1.152 1.152 1.024 1.152 2.688 0 1.536-1.152 2.688-1.024 1.152-2.688 1.152h-13.824q0 34.688.128 39.168.128 4.864 2.304 6.912 2.304 2.048 5.888 2.944 1.663.383 2.688 1.664 1.024 1.152 1.024 2.816t-1.28 2.688q-1.152 1.024-2.816 1.024-3.968 0-7.552-1.92-3.584-2.047-5.76-5.76t-2.176-8.576q0-23.935-.128-40.96h-7.04q-1.536 0-2.688-1.152t-1.152-2.688q0-1.664 1.152-2.688 1.152-1.152 2.688-1.152h7.04V16.384q0-1.536 1.024-2.688 1.152-1.152 2.816-1.152 1.536 0 2.688 1.152t1.152 2.688V39.04zM435.029 18.048q-2.56 0-4.224-1.664-1.664-1.665-1.664-4.096 0-2.304 1.664-3.968 1.793-1.665 4.224-1.664 2.304 0 3.84 1.664 1.664 1.536 1.664 3.968t-1.664 4.096q-1.536 1.665-3.84 1.664m0 86.656q-1.536 0-2.688-1.152-1.152-1.024-1.152-2.56l.384-26.368.384-21.632q.128-2.431-1.024-4.992-1.152-2.688-2.56-3.456-1.536-1.024-2.432-1.792-.768-.768-.768-1.92 0-1.665 1.28-2.56a4.58 4.58 0 0 1 2.944-1.024q4.48 0 7.296 4.096 2.944 3.968 2.944 10.752 0 6.912-.256 18.816-.128 11.904-.256 18.176l-.256 11.904q0 1.663-1.152 2.688a3.92 3.92 0 0 1-2.688 1.024M386.088 104.576q-7.168 0-14.848-3.84-7.552-3.967-11.264-9.856a3.8 3.8 0 0 1-.512-1.92q0-1.664 1.024-2.688 1.152-1.152 2.816-1.152 2.176 0 3.2 1.792 2.432 4.48 8.064 7.424 5.76 2.816 11.52 2.816 7.936 0 12.544-2.432 4.736-2.56 4.736-7.04 0-4.224-3.968-7.296t-13.824-6.656q-9.857-3.585-16.128-7.808-6.144-4.352-6.144-11.776 0-4.864 3.072-8.704 3.2-3.968 8.448-6.144 5.376-2.304 11.776-2.304 8.448 0 14.976 3.84 6.656 3.712 9.216 9.856.256.512.256 1.664 0 1.792-1.024 2.816t-2.688 1.024q-1.024 0-2.048-.512a5.8 5.8 0 0 1-1.536-1.664q-1.92-4.224-6.656-6.912t-10.752-2.688q-6.656 0-11.008 2.816-4.352 2.688-4.352 6.912t4.736 7.296q4.865 2.944 13.056 5.504 11.904 3.84 17.024 8.448 5.248 4.608 5.248 12.288 0 7.936-6.656 12.416t-18.304 4.48M321.778 36.224q9.089 0 16.512 4.48 7.424 4.352 11.648 12.032t4.224 17.152q0 9.855-4.224 17.92-4.224 7.936-11.648 12.544-7.424 4.48-16.64 4.48-7.424 0-13.696-3.712-6.144-3.84-10.24-10.368-.512 40.576-.64 44.416 0 1.536-1.152 2.688-1.024 1.152-2.816 1.152-1.536 0-2.688-1.152a3.92 3.92 0 0 1-1.024-2.688l1.024-82.176q0-2.431-1.28-4.992-1.152-2.688-2.56-3.456-1.536-1.024-2.432-1.792a3.06 3.06 0 0 1-.768-2.048q0-1.665 1.28-2.56 1.28-.896 2.944-.896 3.968 0 6.784 3.328 2.944 3.2 3.584 8.96 4.096-6.144 10.24-9.728 6.272-3.584 13.568-3.584m-.128 60.928q7.04 0 12.672-3.584t8.832-9.728q3.328-6.272 3.328-13.952 0-7.425-3.328-13.312-3.2-5.887-8.832-9.216-5.632-3.456-12.672-3.456-6.784 0-12.16 3.456-5.376 3.328-8.448 9.216t-3.072 13.312q0 7.808 3.072 14.08 3.072 6.144 8.448 9.728 5.376 3.456 12.16 3.456M275.15 98.176q1.536.896 2.432 1.792.896.768.896 1.92 0 1.664-1.28 2.56t-3.072.896q-4.608 0-7.552-4.224t-2.816-11.392l.256-25.856q0-9.089-4.096-13.952-3.968-4.864-11.904-4.864-8.064 0-12.928 5.12t-5.632 13.056q0 6.784-.128 20.608-.128 13.696-.256 16.128a3.72 3.72 0 0 1-1.28 2.56q-1.152.896-2.688.896-1.663 0-2.688-1.024-1.024-1.024-1.024-2.432.128-3.967.256-17.664.128-13.696.128-19.968 0-7.808-4.224-12.544-4.096-4.864-10.88-4.864-7.807 0-13.056 4.864-5.248 4.865-6.272 12.288l-.768 37.888q0 1.663-1.152 2.688-1.152 1.024-2.816 1.024a3.92 3.92 0 0 1-2.688-1.024 3.92 3.92 0 0 1-1.024-2.688l.896-46.976q0-2.431-1.152-4.992-1.152-2.688-2.56-3.456-1.536-1.024-2.432-1.792a3.06 3.06 0 0 1-.768-2.048q0-1.665 1.28-2.56 1.28-.896 2.944-.896 3.712 0 6.4 2.944 2.688 2.816 3.584 7.936 3.584-5.12 8.832-7.808 5.376-2.688 11.136-2.688 6.784 0 12.16 3.712t7.936 10.112q3.328-6.655 8.96-10.24t12.288-3.584q11.136 0 17.152 6.912 6.144 6.784 6.144 19.072l-.256 25.984q0 2.432 1.152 5.12t2.56 3.456M143.486 37.957c1.42 1.196 1.617 3.333.407 4.754l-7.171 8.535 30.009 35.677a6.75 6.75 0 0 1 1.589 4.345v6.652a5.623 5.623 0 0 1-5.625 5.625h-60.75a5.623 5.623 0 0 1-5.625-5.625v-6.652c0-1.589.563-3.121 1.59-4.345l30.008-35.677-7.171-8.535a3.38 3.38 0 0 1 .407-4.754 3.383 3.383 0 0 1 4.754.408l6.412 7.636 6.413-7.622c1.195-1.42 3.332-1.617 4.753-.407zM103.07 91.268v5.527h8.888l2.151-2.306 15.75-16.875a3.34 3.34 0 0 1 2.461-1.07c.928 0 1.828.395 2.461 1.07l15.75 16.875 2.151 2.306h8.888v-5.527l-29.25-34.79zm18.113 5.527h22.26L132.306 84.87l-11.138 11.925zM80.512 85.76q1.025-1.152 2.688-1.152 1.536 0 2.688 1.152 1.152 1.025 1.152 2.688 0 1.536-1.28 2.816-6.144 6.272-16 9.856-9.728 3.456-19.712 3.456-14.208 0-25.6-6.528-11.392-6.655-17.92-18.432T0 52.864t6.528-27.008q6.528-12.16 17.92-18.944Q35.84 0 50.048 0q22.144 0 34.56 14.08 1.28 1.408 1.28 2.944t-1.152 2.688-2.816 1.152-2.688-1.152q-5.376-6.272-12.672-8.96-7.296-2.816-16.512-2.816-11.904 0-21.632 5.76-9.6 5.76-15.104 16-5.376 10.24-5.376 23.168 0 12.8 5.376 22.784 5.505 9.984 15.104 15.488 9.6 5.505 21.632 5.504 10.112 0 18.176-2.688t12.288-8.192"/></svg>
@@ -0,0 +1,100 @@
1
+ :root {
2
+ --fg-ink: #0b0c10;
3
+ --fg-ink-soft: #161821;
4
+ --fg-foam: #f4ede0;
5
+ --fg-glow: #f97316;
6
+ --fg-forest: #1f5130;
7
+ }
8
+ * {
9
+ box-sizing: border-box;
10
+ }
11
+ body {
12
+ margin: 0;
13
+ font-family: "Inter", system-ui, -apple-system, sans-serif;
14
+ }
15
+ a {
16
+ color: #fbbf24;
17
+ }
18
+ .site-header, .site-footer {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ padding: 1rem 1.25rem;
23
+ background: rgba(12, 13, 19, 0.8);
24
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
25
+ }
26
+ .site-footer {
27
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
28
+ border-bottom: none;
29
+ }
30
+ .brand {
31
+ font-weight: 700;
32
+ letter-spacing: 0.04em;
33
+ }
34
+ nav a {
35
+ margin-left: 1rem;
36
+ text-decoration: none;
37
+ }
38
+ main {
39
+ padding: 2rem 1.5rem 3rem;
40
+ max-width: 900px;
41
+ margin: 0 auto;
42
+ }
43
+ .hero {
44
+ padding: 2.5rem;
45
+ border-radius: 24px;
46
+ background: linear-gradient(135deg, rgba(249, 115, 22, 0.2), rgba(31, 81, 48, 0.2));
47
+ border: 1px solid rgba(255, 255, 255, 0.08);
48
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
49
+ }
50
+ .hero .eyebrow {
51
+ text-transform: uppercase;
52
+ letter-spacing: 0.24em;
53
+ font-size: 0.8rem;
54
+ opacity: 0.8;
55
+ }
56
+ .hero h1 {
57
+ margin: 0.2rem 0 0.6rem;
58
+ font-size: 2.4rem;
59
+ }
60
+ .hero p {
61
+ margin: 0.4rem 0;
62
+ }
63
+ pre, code {
64
+ font-family: "JetBrains Mono", Menlo, Consolas, monospace;
65
+ }
66
+ .alpine-card {
67
+ margin-top: 1.5rem;
68
+ padding: 1rem;
69
+ background: rgba(255, 255, 255, 0.04);
70
+ border: 1px solid rgba(255, 255, 255, 0.08);
71
+ border-radius: 12px;
72
+ }
73
+ .alpine-card button {
74
+ background: #f97316;
75
+ color: #0b0c10;
76
+ border: none;
77
+ border-radius: 8px;
78
+ padding: 0.6rem 1rem;
79
+ cursor: pointer;
80
+ }
81
+ .alpine-card .tip {
82
+ margin-top: 0.75rem;
83
+ }
84
+ @media (max-width: 640px) {
85
+ .site-header, .site-footer {
86
+ flex-direction: column;
87
+ gap: 0.5rem;
88
+ text-align: center;
89
+ }
90
+ nav a {
91
+ margin-left: 0;
92
+ margin-right: 1rem;
93
+ }
94
+ .hero {
95
+ padding: 1.5rem;
96
+ }
97
+ .hero h1 {
98
+ font-size: 1.9rem;
99
+ }
100
+ }
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div class="card">
3
+ <h2>Vue + Campsite</h2>
4
+ <p>{{ message }}</p>
5
+ <button @click="count++">You clicked {{ count }} times</button>
6
+ </div>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { ref } from 'vue';
11
+
12
+ const count = ref(0);
13
+ const message = 'This Vue component is ready to hydrate in your Campsite build.';
14
+ </script>
15
+
16
+ <style scoped>
17
+ .card {
18
+ border: 1px solid var(--fg-ink-soft);
19
+ border-radius: 12px;
20
+ padding: 1rem;
21
+ background: #0e1117;
22
+ color: #f6f4ef;
23
+ }
24
+ button {
25
+ margin-top: 0.75rem;
26
+ background: linear-gradient(120deg, #f97316, #ea580c);
27
+ color: #0b0c10;
28
+ border: none;
29
+ padding: 0.6rem 1rem;
30
+ border-radius: 8px;
31
+ cursor: pointer;
32
+ }
33
+ button:hover {
34
+ filter: brightness(1.05);
35
+ }
36
+ </style>
@@ -0,0 +1,4 @@
1
+ <div x-data="{ open: false }" class="alpine-card">
2
+ <button @click="open = !open">Toggle campfire tip</button>
3
+ <p x-show="open" class="tip">Pack light, carry warmth.</p>
4
+ </div>
@@ -0,0 +1,80 @@
1
+ <!doctype html>
2
+ <html lang="en" class="min-h-screen bg-radial bg-gradient-to-br from-campfire-900 from-10% to-black to-90%">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ {% set meta_title = frontmatter.title or title or site.name %}
8
+ {% set meta_description = frontmatter.description or page.description or "A cozy Campsite starter." %}
9
+ {% set meta_url = frontmatter.canonical or frontmatter.url %}
10
+ <title>{{ meta_title }}</title>
11
+ <meta name="description" content="{{ meta_description }}">
12
+ {% if frontmatter.robots %}
13
+ <meta name="robots" content="{{ frontmatter.robots }}">{% endif %}
14
+ {% if meta_url %}
15
+ <link rel="canonical" href="{{ meta_url }}">{% endif %}
16
+ <meta property="og:title" content="{{ meta_title }}">
17
+ <meta property="og:description" content="{{ meta_description }}">
18
+ {% if meta_url %}
19
+ <meta property="og:url" content="{{ meta_url }}">{% endif %}
20
+ <meta property="og:type" content="{{ frontmatter.og_type or " website" }}">
21
+ <meta property="og:site_name" content="{{ site.name }}">
22
+ <meta name="twitter:card" content="{{ frontmatter.twitter_card or " summary_large_image" }}">
23
+ <meta name="twitter:title" content="{{ meta_title }}">
24
+ <meta name="twitter:description" content="{{ meta_description }}">
25
+ {% if meta_url %}
26
+ <meta name="twitter:url" content="{{ meta_url }}">{% endif %}
27
+ <link rel="stylesheet" href="/style.css">
28
+ <link rel="preconnect" href="https://fonts.googleapis.com">
29
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
30
+ <link href="https://fonts.googleapis.com/css2?family=Caprasimo&display=swap" rel="stylesheet">
31
+ </head>
32
+
33
+ <body class="space-y-12 font-serif">
34
+ <header class="bg-stone-950 flex items-stretch justify-between py-2 px-6">
35
+ <a href="/" class="inline-flex items-center text-amber-50 font-bold text-lg tracking-wide py-3">
36
+ <svg class="h-6" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550 139"><path d="M546.049 88.96q1.664 0 2.56 1.024 1.024 1.024 1.024 2.56 0 1.408-1.024 2.816-3.712 4.48-11.136 7.168-7.296 2.56-15.872 2.56-9.216 0-16.64-4.096-7.424-4.224-11.648-11.648-4.224-7.425-4.224-16.768 0-9.855 4.352-17.792 4.48-8.064 12.032-12.672 7.68-4.608 17.024-4.608 7.296 0 12.928 2.56 5.76 2.432 8.96 6.912 3.2 4.352 3.2 9.728 0 7.552-6.912 12.288-6.784 4.608-18.048 4.608-7.424 0-14.336-1.92-6.784-2.048-10.88-5.248-.64 3.584-.64 6.656 0 7.04 3.2 12.672 3.2 5.505 8.832 8.576t12.8 3.072q7.553 0 13.056-1.792 5.504-1.92 8.32-5.504 1.152-1.152 3.072-1.152m-23.552-43.776q-7.552 0-13.568 3.712-6.017 3.712-9.216 10.368 3.583 2.944 9.6 4.992 6.144 2.048 13.312 2.048 7.936 0 12.544-2.56 4.736-2.56 4.736-6.784 0-4.992-4.864-8.32-4.864-3.456-12.544-3.456M483.336 39.04q1.663 0 2.688 1.152 1.152 1.024 1.152 2.688 0 1.536-1.152 2.688-1.024 1.152-2.688 1.152h-13.824q0 34.688.128 39.168.128 4.864 2.304 6.912 2.304 2.048 5.888 2.944 1.663.383 2.688 1.664 1.024 1.152 1.024 2.816t-1.28 2.688q-1.152 1.024-2.816 1.024-3.968 0-7.552-1.92-3.584-2.047-5.76-5.76t-2.176-8.576q0-23.935-.128-40.96h-7.04q-1.536 0-2.688-1.152t-1.152-2.688q0-1.664 1.152-2.688 1.152-1.152 2.688-1.152h7.04V16.384q0-1.536 1.024-2.688 1.152-1.152 2.816-1.152 1.536 0 2.688 1.152t1.152 2.688V39.04zM435.029 18.048q-2.56 0-4.224-1.664-1.664-1.665-1.664-4.096 0-2.304 1.664-3.968 1.793-1.665 4.224-1.664 2.304 0 3.84 1.664 1.664 1.536 1.664 3.968t-1.664 4.096q-1.536 1.665-3.84 1.664m0 86.656q-1.536 0-2.688-1.152-1.152-1.024-1.152-2.56l.384-26.368.384-21.632q.128-2.431-1.024-4.992-1.152-2.688-2.56-3.456-1.536-1.024-2.432-1.792-.768-.768-.768-1.92 0-1.665 1.28-2.56a4.58 4.58 0 0 1 2.944-1.024q4.48 0 7.296 4.096 2.944 3.968 2.944 10.752 0 6.912-.256 18.816-.128 11.904-.256 18.176l-.256 11.904q0 1.663-1.152 2.688a3.92 3.92 0 0 1-2.688 1.024M386.088 104.576q-7.168 0-14.848-3.84-7.552-3.967-11.264-9.856a3.8 3.8 0 0 1-.512-1.92q0-1.664 1.024-2.688 1.152-1.152 2.816-1.152 2.176 0 3.2 1.792 2.432 4.48 8.064 7.424 5.76 2.816 11.52 2.816 7.936 0 12.544-2.432 4.736-2.56 4.736-7.04 0-4.224-3.968-7.296t-13.824-6.656q-9.857-3.585-16.128-7.808-6.144-4.352-6.144-11.776 0-4.864 3.072-8.704 3.2-3.968 8.448-6.144 5.376-2.304 11.776-2.304 8.448 0 14.976 3.84 6.656 3.712 9.216 9.856.256.512.256 1.664 0 1.792-1.024 2.816t-2.688 1.024q-1.024 0-2.048-.512a5.8 5.8 0 0 1-1.536-1.664q-1.92-4.224-6.656-6.912t-10.752-2.688q-6.656 0-11.008 2.816-4.352 2.688-4.352 6.912t4.736 7.296q4.865 2.944 13.056 5.504 11.904 3.84 17.024 8.448 5.248 4.608 5.248 12.288 0 7.936-6.656 12.416t-18.304 4.48M321.778 36.224q9.089 0 16.512 4.48 7.424 4.352 11.648 12.032t4.224 17.152q0 9.855-4.224 17.92-4.224 7.936-11.648 12.544-7.424 4.48-16.64 4.48-7.424 0-13.696-3.712-6.144-3.84-10.24-10.368-.512 40.576-.64 44.416 0 1.536-1.152 2.688-1.024 1.152-2.816 1.152-1.536 0-2.688-1.152a3.92 3.92 0 0 1-1.024-2.688l1.024-82.176q0-2.431-1.28-4.992-1.152-2.688-2.56-3.456-1.536-1.024-2.432-1.792a3.06 3.06 0 0 1-.768-2.048q0-1.665 1.28-2.56 1.28-.896 2.944-.896 3.968 0 6.784 3.328 2.944 3.2 3.584 8.96 4.096-6.144 10.24-9.728 6.272-3.584 13.568-3.584m-.128 60.928q7.04 0 12.672-3.584t8.832-9.728q3.328-6.272 3.328-13.952 0-7.425-3.328-13.312-3.2-5.887-8.832-9.216-5.632-3.456-12.672-3.456-6.784 0-12.16 3.456-5.376 3.328-8.448 9.216t-3.072 13.312q0 7.808 3.072 14.08 3.072 6.144 8.448 9.728 5.376 3.456 12.16 3.456M275.15 98.176q1.536.896 2.432 1.792.896.768.896 1.92 0 1.664-1.28 2.56t-3.072.896q-4.608 0-7.552-4.224t-2.816-11.392l.256-25.856q0-9.089-4.096-13.952-3.968-4.864-11.904-4.864-8.064 0-12.928 5.12t-5.632 13.056q0 6.784-.128 20.608-.128 13.696-.256 16.128a3.72 3.72 0 0 1-1.28 2.56q-1.152.896-2.688.896-1.663 0-2.688-1.024-1.024-1.024-1.024-2.432.128-3.967.256-17.664.128-13.696.128-19.968 0-7.808-4.224-12.544-4.096-4.864-10.88-4.864-7.807 0-13.056 4.864-5.248 4.865-6.272 12.288l-.768 37.888q0 1.663-1.152 2.688-1.152 1.024-2.816 1.024a3.92 3.92 0 0 1-2.688-1.024 3.92 3.92 0 0 1-1.024-2.688l.896-46.976q0-2.431-1.152-4.992-1.152-2.688-2.56-3.456-1.536-1.024-2.432-1.792a3.06 3.06 0 0 1-.768-2.048q0-1.665 1.28-2.56 1.28-.896 2.944-.896 3.712 0 6.4 2.944 2.688 2.816 3.584 7.936 3.584-5.12 8.832-7.808 5.376-2.688 11.136-2.688 6.784 0 12.16 3.712t7.936 10.112q3.328-6.655 8.96-10.24t12.288-3.584q11.136 0 17.152 6.912 6.144 6.784 6.144 19.072l-.256 25.984q0 2.432 1.152 5.12t2.56 3.456M143.486 37.957c1.42 1.196 1.617 3.333.407 4.754l-7.171 8.535 30.009 35.677a6.75 6.75 0 0 1 1.589 4.345v6.652a5.623 5.623 0 0 1-5.625 5.625h-60.75a5.623 5.623 0 0 1-5.625-5.625v-6.652c0-1.589.563-3.121 1.59-4.345l30.008-35.677-7.171-8.535a3.38 3.38 0 0 1 .407-4.754 3.383 3.383 0 0 1 4.754.408l6.412 7.636 6.413-7.622c1.195-1.42 3.332-1.617 4.753-.407zM103.07 91.268v5.527h8.888l2.151-2.306 15.75-16.875a3.34 3.34 0 0 1 2.461-1.07c.928 0 1.828.395 2.461 1.07l15.75 16.875 2.151 2.306h8.888v-5.527l-29.25-34.79zm18.113 5.527h22.26L132.306 84.87l-11.138 11.925zM80.512 85.76q1.025-1.152 2.688-1.152 1.536 0 2.688 1.152 1.152 1.025 1.152 2.688 0 1.536-1.28 2.816-6.144 6.272-16 9.856-9.728 3.456-19.712 3.456-14.208 0-25.6-6.528-11.392-6.655-17.92-18.432T0 52.864t6.528-27.008q6.528-12.16 17.92-18.944Q35.84 0 50.048 0q22.144 0 34.56 14.08 1.28 1.408 1.28 2.944t-1.152 2.688-2.816 1.152-2.688-1.152q-5.376-6.272-12.672-8.96-7.296-2.816-16.512-2.816-11.904 0-21.632 5.76-9.6 5.76-15.104 16-5.376 10.24-5.376 23.168 0 12.8 5.376 22.784 5.505 9.984 15.104 15.488 9.6 5.505 21.632 5.504 10.112 0 18.176-2.688t12.288-8.192"/></svg>
37
+ </a>
38
+ <nav class="flex items-center gap-2">
39
+ <a href="/" class="px-2">Home</a>
40
+ <a href="https://github.com/FoxGroveMedia/campsite" target="_blank" rel="noreferrer" class="px-2">Docs</a>
41
+ <a href="https://github.com/FoxGroveMedia" target="_blank" rel="noreferrer">
42
+ <svg class="size-7" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
43
+ viewBox="0 0 640 640"><!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
44
+ <path
45
+ d="M237.9 461.4C237.9 463.4 235.6 465 232.7 465C229.4 465.3 227.1 463.7 227.1 461.4C227.1 459.4 229.4 457.8 232.3 457.8C235.3 457.5 237.9 459.1 237.9 461.4zM206.8 456.9C206.1 458.9 208.1 461.2 211.1 461.8C213.7 462.8 216.7 461.8 217.3 459.8C217.9 457.8 216 455.5 213 454.6C210.4 453.9 207.5 454.9 206.8 456.9zM251 455.2C248.1 455.9 246.1 457.8 246.4 460.1C246.7 462.1 249.3 463.4 252.3 462.7C255.2 462 257.2 460.1 256.9 458.1C256.6 456.2 253.9 454.9 251 455.2zM316.8 72C178.1 72 72 177.3 72 316C72 426.9 141.8 521.8 241.5 555.2C254.3 557.5 258.8 549.6 258.8 543.1C258.8 536.9 258.5 502.7 258.5 481.7C258.5 481.7 188.5 496.7 173.8 451.9C173.8 451.9 162.4 422.8 146 415.3C146 415.3 123.1 399.6 147.6 399.9C147.6 399.9 172.5 401.9 186.2 425.7C208.1 464.3 244.8 453.2 259.1 446.6C261.4 430.6 267.9 419.5 275.1 412.9C219.2 406.7 162.8 398.6 162.8 302.4C162.8 274.9 170.4 261.1 186.4 243.5C183.8 237 175.3 210.2 189 175.6C209.9 169.1 258 202.6 258 202.6C278 197 299.5 194.1 320.8 194.1C342.1 194.1 363.6 197 383.6 202.6C383.6 202.6 431.7 169 452.6 175.6C466.3 210.3 457.8 237 455.2 243.5C471.2 261.2 481 275 481 302.4C481 398.9 422.1 406.6 366.2 412.9C375.4 420.8 383.2 435.8 383.2 459.3C383.2 493 382.9 534.7 382.9 542.9C382.9 549.4 387.5 557.3 400.2 555C500.2 521.8 568 426.9 568 316C568 177.3 455.5 72 316.8 72zM169.2 416.9C167.9 417.9 168.2 420.2 169.9 422.1C171.5 423.7 173.8 424.4 175.1 423.1C176.4 422.1 176.1 419.8 174.4 417.9C172.8 416.3 170.5 415.6 169.2 416.9zM158.4 408.8C157.7 410.1 158.7 411.7 160.7 412.7C162.3 413.7 164.3 413.4 165 412C165.7 410.7 164.7 409.1 162.7 408.1C160.7 407.5 159.1 407.8 158.4 408.8zM190.8 444.4C189.2 445.7 189.8 448.7 192.1 450.6C194.4 452.9 197.3 453.2 198.6 451.6C199.9 450.3 199.3 447.3 197.3 445.4C195.1 443.1 192.1 442.8 190.8 444.4zM179.4 429.7C177.8 430.7 177.8 433.3 179.4 435.6C181 437.9 183.7 438.9 185 437.9C186.6 436.6 186.6 434 185 431.7C183.6 429.4 181 428.4 179.4 429.7z" />
46
+ </svg>
47
+ </a>
48
+ <a href="https://x.com/FoxGroveMedia" target="_blank" rel="noreferrer">
49
+ <svg class="size-7" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
50
+ viewBox="0 0 640 640"><!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
51
+ <path
52
+ d="M453.2 112L523.8 112L369.6 288.2L551 528L409 528L297.7 382.6L170.5 528L99.8 528L264.7 339.5L90.8 112L236.4 112L336.9 244.9L453.2 112zM428.4 485.8L467.5 485.8L215.1 152L173.1 152L428.4 485.8z" />
53
+ </svg>
54
+ </a>
55
+ </nav>
56
+ </header>
57
+ <main class="mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
58
+ <div
59
+ class="rounded-lg bg-white/5 shadow dark:bg-gray-800/50 dark:shadow-none dark:outline dark:outline-1 dark:-outline-offset-1 dark:outline-white/10 text-white">
60
+ <div class="px-4 py-5 sm:p-6">
61
+ {% block content %}
62
+ {% if content %}
63
+ {{ content | safe }}
64
+ {% else %}
65
+ <section class="hero">
66
+ <p class="eyebrow">Campfire ready</p>
67
+ <h1>Welcome to Campsite</h1>
68
+ <p>Edit <code>src/pages/index.md</code> to get started.</p>
69
+ </section>
70
+ {% endif %}
71
+ {% endblock %}
72
+ </div>
73
+ </div>
74
+ </main>
75
+ <footer class="text-xs text-amber-50/40 text-center">
76
+ <p>Built with <span class="font-semibold text-amber-50/60">Campsite</span>.</p>
77
+ </footer>
78
+ </body>
79
+
80
+ </html>
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Welcome to Campsite
3
+ layout: base.njk
4
+ description: Cozy, fast static sites with Campsite.
5
+ ---
6
+
7
+ ## Welcome, camper
8
+
9
+ Campsite sets up a warm starter for Markdown, Nunjucks, Liquid, Vue, and Alpine.
10
+
11
+ - Edit `src/pages/index.md` to make it yours.
12
+ - Tweak the layout in `src/layouts/base.njk`.
13
+ - Add data under `src/data/` and components in `src/components/`.
14
+
15
+ Happy camping! 🌲🏕️🔥
@@ -0,0 +1,17 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ code {
7
+ @apply bg-campfire-950 text-lime-500 font-mono py-1.5 px-3 rounded-md ml-2;
8
+ }
9
+ a {
10
+ @apply text-amber-500 hover:text-white;
11
+ }
12
+ }
13
+
14
+ h1, h2, h3, h4, h5, h6 {
15
+ font-family: "Caprasimo", serif;
16
+ font-style: normal;
17
+ }
@@ -0,0 +1,36 @@
1
+ module.exports = {
2
+ content: [
3
+ "./src/**/*.{html,md,njk,js,vue}",
4
+ "./public/**/*.{html,js}"
5
+ ],
6
+ theme: {
7
+ extend: {
8
+ colors: {
9
+ campfire: {
10
+ "50": "#fff0e5",
11
+ "100": "#ffe1cc",
12
+ "200": "#ffc499",
13
+ "300": "#ffa666",
14
+ "400": "#ff8833",
15
+ "500": "#ff6a00",
16
+ "600": "#cc5500",
17
+ "700": "#994000",
18
+ "800": "#662b00",
19
+ "900": "#331500",
20
+ "950": "#0a0501"
21
+ },
22
+ grove: {
23
+ ink: "#0b0c10",
24
+ foam: "#f4ede0",
25
+ glow: "#f97316",
26
+ forest: "#1f5130"
27
+ }
28
+ },
29
+ fontFamily: {
30
+ sans: ["Inter","system-ui","-apple-system","sans-serif"],
31
+ mono: ["JetBrains Mono","Menlo","Consolas","monospace"]
32
+ }
33
+ }
34
+ },
35
+ plugins: []
36
+ };
@@ -0,0 +1,8 @@
1
+ {% extends "base.njk" %}
2
+ {% block content %}
3
+ <section class="hero">
4
+ <p class="eyebrow">Campsite</p>
5
+ <h1>Welcome camper</h1>
6
+ <p>Swap this template with your own content in <code>src/pages/index.njk</code>.</p>
7
+ </section>
8
+ {% endblock %}