@vojtaholik/create-static-kit 1.0.0 → 1.0.1

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/dist/cli.js CHANGED
@@ -10,26 +10,67 @@ const TEMPLATES = {
10
10
  minimal: {
11
11
  name: "Minimal",
12
12
  description: "Just the basics - perfect starting point",
13
- features: ["Basic HTML/SCSS structure", "Component system", "Build pipeline"]
13
+ features: [
14
+ "Basic HTML/SCSS structure",
15
+ "Component system",
16
+ "Build pipeline",
17
+ ],
14
18
  },
15
19
  default: {
16
20
  name: "Default",
17
21
  description: "Starter with examples and components",
18
- features: ["Multiple page examples", "Component library", "SVG sprite system", "Basic styling"]
22
+ features: [
23
+ "Multiple page examples",
24
+ "Component library",
25
+ "SVG sprite system",
26
+ "Basic styling",
27
+ ],
19
28
  },
20
29
  styled: {
21
30
  name: "Styled",
22
31
  description: "Pre-styled with design system",
23
- features: ["Modern CSS reset", "Design tokens", "Typography scale", "Component showcase"]
24
- }
32
+ features: [
33
+ "Modern CSS reset",
34
+ "Design tokens",
35
+ "Typography scale",
36
+ "Component showcase",
37
+ ],
38
+ },
25
39
  };
40
+ function showHelp() {
41
+ console.log(`${cyan("create-static-kit")} ${green("v1.0.0")}`);
42
+ console.log();
43
+ console.log("Usage:");
44
+ console.log(" npx @vojtaholik/create-static-kit <project-name> [options]");
45
+ console.log();
46
+ console.log("Options:");
47
+ console.log(" --template=<name> Template to use (minimal, default)");
48
+ console.log(" --interactive Force interactive mode");
49
+ console.log(" --no-cursor-rules Skip including Cursor rules");
50
+ console.log(" --help, -h Show this help message");
51
+ console.log();
52
+ console.log("Examples:");
53
+ console.log(" npx @vojtaholik/create-static-kit my-site");
54
+ console.log(" npx @vojtaholik/create-static-kit my-site --template=minimal");
55
+ console.log(" npx @vojtaholik/create-static-kit my-site --no-cursor-rules");
56
+ console.log(" npx @vojtaholik/create-static-kit my-site --interactive");
57
+ console.log();
58
+ }
26
59
  async function main() {
60
+ const args = process.argv.slice(2);
61
+ // Check for help flag first (before showing header)
62
+ if (args.includes("--help") || args.includes("-h")) {
63
+ showHelp();
64
+ process.exit(0);
65
+ }
27
66
  console.log();
28
67
  console.log(`${cyan("create-static-kit")} ${green("v1.0.0")}`);
29
68
  console.log();
30
- const args = process.argv.slice(2);
31
69
  let projectName = args[0];
32
- let template = args.find(arg => arg.startsWith("--template="))?.split("=")[1];
70
+ let template = args
71
+ .find((arg) => arg.startsWith("--template="))
72
+ ?.split("=")[1];
73
+ const noCursorRules = args.includes("--no-cursor-rules");
33
74
  const interactive = args.includes("--interactive") || !projectName || !template;
34
75
  if (interactive) {
35
76
  const response = await prompts([
@@ -44,7 +85,7 @@ async function main() {
44
85
  if (!/^[a-zA-Z0-9-_]+$/.test(value))
45
86
  return "Project name can only contain letters, numbers, hyphens, and underscores";
46
87
  return true;
47
- }
88
+ },
48
89
  },
49
90
  {
50
91
  type: "select",
@@ -53,28 +94,34 @@ async function main() {
53
94
  choices: Object.entries(TEMPLATES).map(([key, config]) => ({
54
95
  title: `${config.name} - ${config.description}`,
55
96
  description: config.features.join(" • "),
56
- value: key
97
+ value: key,
57
98
  })),
58
- initial: 0
99
+ initial: 0,
59
100
  },
60
101
  {
61
102
  type: "confirm",
62
103
  name: "cssReset",
63
104
  message: "Include CSS reset?",
64
- initial: true
105
+ initial: true,
65
106
  },
66
107
  {
67
108
  type: "confirm",
68
109
  name: "designTokens",
69
110
  message: "Include design tokens?",
70
- initial: false
111
+ initial: false,
112
+ },
113
+ {
114
+ type: "confirm",
115
+ name: "includeCursorRules",
116
+ message: "Include Cursor rules for better dev experience?",
117
+ initial: true,
71
118
  },
72
119
  {
73
120
  type: "confirm",
74
121
  name: "initGit",
75
122
  message: "Initialize git repository?",
76
- initial: true
77
- }
123
+ initial: true,
124
+ },
78
125
  ]);
79
126
  if (!response.projectName) {
80
127
  console.log(red("✖") + " Operation cancelled");
@@ -85,7 +132,8 @@ async function main() {
85
132
  template: response.template,
86
133
  cssReset: response.cssReset,
87
134
  designTokens: response.designTokens,
88
- initGit: response.initGit
135
+ includeCursorRules: response.includeCursorRules,
136
+ initGit: response.initGit,
89
137
  };
90
138
  await createProject(options);
91
139
  }
@@ -96,13 +144,14 @@ async function main() {
96
144
  template: template || "default",
97
145
  cssReset: true,
98
146
  designTokens: false,
99
- initGit: true
147
+ includeCursorRules: !noCursorRules,
148
+ initGit: true,
100
149
  };
101
150
  await createProject(options);
102
151
  }
103
152
  }
104
153
  async function createProject(options) {
105
- const { projectName, template, cssReset, designTokens, initGit } = options;
154
+ const { projectName, template, cssReset, designTokens, includeCursorRules, initGit, } = options;
106
155
  console.log();
107
156
  console.log(`${cyan("✨")} Creating ${bold(projectName)}...`);
108
157
  console.log();
@@ -134,6 +183,10 @@ async function createProject(options) {
134
183
  if (designTokens) {
135
184
  await addDesignTokens(projectPath);
136
185
  }
186
+ // Remove Cursor rules if not wanted
187
+ if (!includeCursorRules) {
188
+ await removeCursorRules(projectPath);
189
+ }
137
190
  // Initialize git
138
191
  if (initGit) {
139
192
  await initializeGit(projectPath);
@@ -171,7 +224,7 @@ async function copyTemplate(templateName, projectPath) {
171
224
  const files = await fg("**/*", {
172
225
  cwd: templatePath,
173
226
  onlyFiles: true,
174
- dot: true
227
+ dot: true,
175
228
  });
176
229
  for (const file of files) {
177
230
  const srcPath = path.join(templatePath, file);
@@ -190,7 +243,7 @@ async function generatePackageJson(projectName, projectPath) {
190
243
  scripts: {
191
244
  dev: "vite",
192
245
  build: "tsc && vite build",
193
- preview: "vite preview"
246
+ preview: "vite preview",
194
247
  },
195
248
  devDependencies: {
196
249
  "@vojtaholik/static-kit-core": "^1.0.0",
@@ -199,30 +252,26 @@ async function generatePackageJson(projectName, projectPath) {
199
252
  postcss: "^8.5.6",
200
253
  "sass-embedded": "^1.90.0",
201
254
  typescript: "~5.9.2",
202
- vite: "^7.1.1"
203
- }
255
+ vite: "^7.1.1",
256
+ },
204
257
  };
205
258
  await fs.writeFile(path.join(projectPath, "package.json"), JSON.stringify(packageJson, null, 2));
206
259
  }
207
260
  async function generateViteConfig(projectPath) {
208
- const viteConfig = `import { defineConfig } from "vite";
209
- import { createStaticKitConfig } from "@vojtaholik/static-kit-core/vite";
261
+ const viteConfig = `import { createStaticKitConfig } from "@vojtaholik/static-kit-core/vite";
210
262
 
211
- export default defineConfig(async (env) => {
212
- const staticKitConfig = await createStaticKitConfig();
213
- return staticKitConfig;
214
- });`;
263
+ export default createStaticKitConfig();`;
215
264
  await fs.writeFile(path.join(projectPath, "vite.config.ts"), viteConfig);
216
265
  }
217
266
  async function generateStaticKitConfig(projectPath) {
218
267
  const config = {
219
268
  build: {
220
269
  base: "public/",
221
- output: "dist"
270
+ output: "dist",
222
271
  },
223
272
  templates: {
224
- language: "en"
225
- }
273
+ language: "en",
274
+ },
226
275
  };
227
276
  await fs.writeFile(path.join(projectPath, "static-kit.config.json"), JSON.stringify(config, null, 2));
228
277
  }
@@ -262,7 +311,7 @@ p, h1, h2, h3, h4, h5, h6 {
262
311
  const mainScssPath = path.join(projectPath, "src", "styles", "main.scss");
263
312
  try {
264
313
  const mainScss = await fs.readFile(mainScssPath, "utf-8");
265
- const updatedScss = `@import "reset";\n\n${mainScss}`;
314
+ const updatedScss = `@use "reset";\n\n${mainScss}`;
266
315
  await fs.writeFile(mainScssPath, updatedScss);
267
316
  }
268
317
  catch {
@@ -327,13 +376,22 @@ async function addDesignTokens(projectPath) {
327
376
  const mainScssPath = path.join(projectPath, "src", "styles", "main.scss");
328
377
  try {
329
378
  const mainScss = await fs.readFile(mainScssPath, "utf-8");
330
- const updatedScss = `@import "tokens";\n\n${mainScss}`;
379
+ const updatedScss = `@use "tokens";\n\n${mainScss}`;
331
380
  await fs.writeFile(mainScssPath, updatedScss);
332
381
  }
333
382
  catch {
334
383
  // main.scss doesn't exist or can't be read
335
384
  }
336
385
  }
386
+ async function removeCursorRules(projectPath) {
387
+ try {
388
+ const cursorDir = path.join(projectPath, ".cursor");
389
+ await fs.rm(cursorDir, { recursive: true, force: true });
390
+ }
391
+ catch {
392
+ // Directory doesn't exist or can't be removed, which is fine
393
+ }
394
+ }
337
395
  async function initializeGit(projectPath) {
338
396
  const gitignore = `# Dependencies
339
397
  node_modules/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vojtaholik/create-static-kit",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "CLI tool to create new Static Kit projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -34,7 +34,7 @@
34
34
  "scaffold",
35
35
  "template"
36
36
  ],
37
- "author": "Vojta Holik <vojta@hey.com>",
37
+ "author": "Vojta Holik <vojta@holik.dev>",
38
38
  "license": "MIT",
39
39
  "repository": {
40
40
  "type": "git",
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Static Kit configuration and build settings
3
+ globs: ["static-kit.config.json", "static-kit.local.json"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Configuration
8
+
9
+ Global build configuration in `static-kit.config.json`. Local overrides go in `static-kit.local.json` (ignored by git).
10
+
11
+ ## Configuration Files
12
+
13
+ - `static-kit.config.json` - Global build configuration
14
+ - `static-kit.local.json` - Local overrides (git ignored)
15
+
16
+ ## Guidelines
17
+
18
+ - Keep global settings in main config
19
+ - Use local config for environment-specific overrides
20
+ - Local config is automatically ignored by git
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Figma MCP integration and design-to-dev workflow
3
+ globs: ["**/*.html"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Figma Integration
8
+
9
+ For Figma MCP integration, component and page file names should match Figma node/component names for proper mapping.
10
+
11
+ ## Design-to-Dev Workflow
12
+
13
+ - Component/page file names should match Figma node names
14
+ - Follow Static Kit conventions when generating from Figma designs
15
+ - Maintain consistent naming between design and code
16
+ - Use proper file placement per Static Kit rules
17
+
18
+ ## Guidelines
19
+
20
+ - Generate HTML/SCSS from Figma following Static Kit conventions
21
+ - Ensure proper file placement in src/ directories
22
+ - Maintain design-code consistency through naming
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Reusable HTML components conventions
3
+ globs: ["src/components/**/*.html"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # HTML Components
8
+
9
+ Reusable HTML components should follow specific naming and structure conventions.
10
+
11
+ ## File Naming
12
+
13
+ - Use lowercase kebab-case for file names
14
+ - Examples: `button.html`, `ui/card.html`
15
+
16
+ ## Structure Rules
17
+
18
+ - No `<html>` or `<body>` tags in components
19
+ - Keep components focused and reusable
20
+ - Place under `src/components/` directory
21
+
22
+ ## Import Usage
23
+
24
+ Components should be imported using `@components/` prefix in pages.
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: HTML pages structure and import conventions
3
+ globs: ["src/pages/**/*.html"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # HTML Pages
8
+
9
+ HTML pages go in `src/pages/` directory. Use `@components/` prefix for imports, not relative paths.
10
+
11
+ ## Import Examples
12
+
13
+ ```html
14
+ <!-- @import: @components/header.html -->
15
+ <!-- @import: @components/footer.html -->
16
+ ```
17
+
18
+ ## Guidelines
19
+
20
+ - Place all pages under `src/pages/` with correct folder structure
21
+ - Use `@components/` prefix for component imports
22
+ - Avoid relative imports unless absolutely necessary
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: Static Kit project overview and general guidelines
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Static Kit Framework
8
+
9
+ Static site framework with TypeScript, SCSS, and HTML imports. Integrated with Figma MCP for design-to-dev workflow.
10
+
11
+ ## Core Principles
12
+
13
+ - Use `@components/` prefix for imports, not relative paths
14
+ - Follow lowercase kebab-case naming for files
15
+ - Keep modules isolated and modular
16
+ - Maintain clean separation between pages, components, and styles
17
+
18
+ ## Git Conventions
19
+
20
+ ### Commit Message Conventions
21
+
22
+ - `feat: new component/page`
23
+ - `style: scss changes`
24
+ - `fix: bugfix`
25
+ - `design-sync: figma-linked update`
26
+
27
+ ### Ignored Files
28
+
29
+ - `dist/` - Build output
30
+ - `static-kit.local.json` - Local configuration overrides
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Public assets organization and handling
3
+ globs: ["public/**/*"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Public Assets
8
+
9
+ Static assets copied directly to dist/ with no processing. Organize into logical folders.
10
+
11
+ ## Organization
12
+
13
+ - `public/images/` - Image assets
14
+ - `public/fonts/` - Font files
15
+ - `public/` - Other static assets
16
+
17
+ ## Guidelines
18
+
19
+ - Assets are copied as-is to dist/
20
+ - No build-time processing
21
+ - Organize into meaningful subdirectories
22
+ - Reference in development as `/<filename>` (no 'public' prefix needed)
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: SCSS styling conventions and import structure
3
+ globs: ["src/styles/**/*.scss"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # SCSS Styles
8
+
9
+ SCSS entrypoint is `src/styles/main.scss`. Component styles should be imported into main.scss.
10
+
11
+ ## Import Structure
12
+
13
+ ```scss
14
+ @import "./components/button.scss";
15
+ ```
16
+
17
+ ## Guidelines
18
+
19
+ - Main entrypoint: `src/styles/main.scss`
20
+ - Import component styles into main.scss
21
+ - Follow modular SCSS architecture
22
+ - Keep component styles organized and focused
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: SVG icon naming and sprite conventions
3
+ globs: ["src/icons/**/*.svg"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # SVG Icons
8
+
9
+ SVG icons should use lowercase-kebab-case naming. Folder structure defines sprite ID namespace.
10
+
11
+ ## Naming Convention
12
+
13
+ ```
14
+ src/icons/ui/arrow.svg → <use href="/sprite.svg#ui-arrow"></use>
15
+ ```
16
+
17
+ ## Guidelines
18
+
19
+ - Use lowercase kebab-case for icon names
20
+ - Folder structure creates namespace (ui/, social/, etc.)
21
+ - Icons are compiled into sprite.svg
22
+ - Reference using sprite ID format: `namespace-iconname`
@@ -0,0 +1,23 @@
1
+ ---
2
+ description: TypeScript and JavaScript module conventions
3
+ globs: ["src/js/**/*.ts", "src/js/**/*.js"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # TypeScript/JavaScript Modules
8
+
9
+ Component-specific scripts go in `src/js/components/`. Keep modules isolated with no bundler-only imports.
10
+
11
+ ## File Organization
12
+
13
+ ```
14
+ src/js/components/modal.ts
15
+ ```
16
+
17
+ ## Guidelines
18
+
19
+ - Place component scripts in `src/js/components/`
20
+ - Keep modules isolated and modular
21
+ - Avoid bundler-only patterns
22
+ - Use effective TypeScript for library-style code
23
+ - Maintain clean module boundaries
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Static Kit configuration and build settings
3
+ globs: ["static-kit.config.json", "static-kit.local.json"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Configuration
8
+
9
+ Global build configuration in `static-kit.config.json`. Local overrides go in `static-kit.local.json` (ignored by git).
10
+
11
+ ## Configuration Files
12
+
13
+ - `static-kit.config.json` - Global build configuration
14
+ - `static-kit.local.json` - Local overrides (git ignored)
15
+
16
+ ## Guidelines
17
+
18
+ - Keep global settings in main config
19
+ - Use local config for environment-specific overrides
20
+ - Local config is automatically ignored by git
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Figma MCP integration and design-to-dev workflow
3
+ globs: ["**/*.html"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Figma Integration
8
+
9
+ For Figma MCP integration, component and page file names should match Figma node/component names for proper mapping.
10
+
11
+ ## Design-to-Dev Workflow
12
+
13
+ - Component/page file names should match Figma node names
14
+ - Follow Static Kit conventions when generating from Figma designs
15
+ - Maintain consistent naming between design and code
16
+ - Use proper file placement per Static Kit rules
17
+
18
+ ## Guidelines
19
+
20
+ - Generate HTML/SCSS from Figma following Static Kit conventions
21
+ - Ensure proper file placement in src/ directories
22
+ - Maintain design-code consistency through naming
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Reusable HTML components conventions
3
+ globs: ["src/components/**/*.html"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # HTML Components
8
+
9
+ Reusable HTML components should follow specific naming and structure conventions.
10
+
11
+ ## File Naming
12
+
13
+ - Use lowercase kebab-case for file names
14
+ - Examples: `button.html`, `ui/card.html`
15
+
16
+ ## Structure Rules
17
+
18
+ - No `<html>` or `<body>` tags in components
19
+ - Keep components focused and reusable
20
+ - Place under `src/components/` directory
21
+
22
+ ## Import Usage
23
+
24
+ Components should be imported using `@components/` prefix in pages.
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: HTML pages structure and import conventions
3
+ globs: ["src/pages/**/*.html"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # HTML Pages
8
+
9
+ HTML pages go in `src/pages/` directory. Use `@components/` prefix for imports, not relative paths.
10
+
11
+ ## Import Examples
12
+
13
+ ```html
14
+ <!-- @import: @components/header.html -->
15
+ <!-- @import: @components/footer.html -->
16
+ ```
17
+
18
+ ## Guidelines
19
+
20
+ - Place all pages under `src/pages/` with correct folder structure
21
+ - Use `@components/` prefix for component imports
22
+ - Avoid relative imports unless absolutely necessary
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: Static Kit project overview and general guidelines
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Static Kit Framework
8
+
9
+ Static site framework with TypeScript, SCSS, and HTML imports. Integrated with Figma MCP for design-to-dev workflow.
10
+
11
+ ## Core Principles
12
+
13
+ - Use `@components/` prefix for imports, not relative paths
14
+ - Follow lowercase kebab-case naming for files
15
+ - Keep modules isolated and modular
16
+ - Maintain clean separation between pages, components, and styles
17
+
18
+ ## Git Conventions
19
+
20
+ ### Commit Message Conventions
21
+
22
+ - `feat: new component/page`
23
+ - `style: scss changes`
24
+ - `fix: bugfix`
25
+ - `design-sync: figma-linked update`
26
+
27
+ ### Ignored Files
28
+
29
+ - `dist/` - Build output
30
+ - `static-kit.local.json` - Local configuration overrides
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Public assets organization and handling
3
+ globs: ["public/**/*"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Public Assets
8
+
9
+ Static assets copied directly to dist/ with no processing. Organize into logical folders.
10
+
11
+ ## Organization
12
+
13
+ - `public/images/` - Image assets
14
+ - `public/fonts/` - Font files
15
+ - `public/` - Other static assets
16
+
17
+ ## Guidelines
18
+
19
+ - Assets are copied as-is to dist/
20
+ - No build-time processing
21
+ - Organize into meaningful subdirectories
22
+ - Reference in development as `/<filename>` (no 'public' prefix needed)
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: SCSS styling conventions and import structure
3
+ globs: ["src/styles/**/*.scss"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # SCSS Styles
8
+
9
+ SCSS entrypoint is `src/styles/main.scss`. Component styles should be imported into main.scss.
10
+
11
+ ## Import Structure
12
+
13
+ ```scss
14
+ @import "./components/button.scss";
15
+ ```
16
+
17
+ ## Guidelines
18
+
19
+ - Main entrypoint: `src/styles/main.scss`
20
+ - Import component styles into main.scss
21
+ - Follow modular SCSS architecture
22
+ - Keep component styles organized and focused
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: SVG icon naming and sprite conventions
3
+ globs: ["src/icons/**/*.svg"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # SVG Icons
8
+
9
+ SVG icons should use lowercase-kebab-case naming. Folder structure defines sprite ID namespace.
10
+
11
+ ## Naming Convention
12
+
13
+ ```
14
+ src/icons/ui/arrow.svg → <use href="/sprite.svg#ui-arrow"></use>
15
+ ```
16
+
17
+ ## Guidelines
18
+
19
+ - Use lowercase kebab-case for icon names
20
+ - Folder structure creates namespace (ui/, social/, etc.)
21
+ - Icons are compiled into sprite.svg
22
+ - Reference using sprite ID format: `namespace-iconname`
@@ -0,0 +1,23 @@
1
+ ---
2
+ description: TypeScript and JavaScript module conventions
3
+ globs: ["src/js/**/*.ts", "src/js/**/*.js"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # TypeScript/JavaScript Modules
8
+
9
+ Component-specific scripts go in `src/js/components/`. Keep modules isolated with no bundler-only imports.
10
+
11
+ ## File Organization
12
+
13
+ ```
14
+ src/js/components/modal.ts
15
+ ```
16
+
17
+ ## Guidelines
18
+
19
+ - Place component scripts in `src/js/components/`
20
+ - Keep modules isolated and modular
21
+ - Avoid bundler-only patterns
22
+ - Use effective TypeScript for library-style code
23
+ - Maintain clean module boundaries