create-koppajs 1.2.1 → 1.2.3

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +116 -21
  3. package/bin/create-koppajs.js +10 -16
  4. package/package.json +10 -7
  5. package/template/README.md +19 -209
  6. package/template/_gitignore +0 -3
  7. package/template/index.html +1 -1
  8. package/template/package.json +9 -46
  9. package/template/public/favicon.png +0 -0
  10. package/template/public/koppajs-logo.png +0 -0
  11. package/template/src/app-view.kpa +1 -3
  12. package/template/tsconfig.json +2 -9
  13. package/template/vite.config.mjs +0 -35
  14. package/template-overlays/router/README.md +25 -203
  15. package/template-overlays/router/index.html +1 -1
  16. package/template-overlays/router/package.json +10 -47
  17. package/template-overlays/router/src/app-view.kpa +21 -78
  18. package/template-overlays/router/src/home-page.kpa +23 -60
  19. package/template-overlays/router/src/main.ts +0 -9
  20. package/template-overlays/router/src/not-found-page.kpa +16 -48
  21. package/template-overlays/router/src/router-page.kpa +34 -69
  22. package/template-overlays/router/src/style.css +5 -29
  23. package/template/AI_CONSTITUTION.md +0 -50
  24. package/template/ARCHITECTURE.md +0 -86
  25. package/template/CHANGELOG.md +0 -34
  26. package/template/CONTRIBUTING.md +0 -92
  27. package/template/DECISION_HIERARCHY.md +0 -32
  28. package/template/DEVELOPMENT_RULES.md +0 -57
  29. package/template/LICENSE +0 -201
  30. package/template/RELEASE.md +0 -230
  31. package/template/ROADMAP.md +0 -34
  32. package/template/TESTING_STRATEGY.md +0 -93
  33. package/template/_editorconfig +0 -12
  34. package/template/_github/instructions/ai-workflow.md +0 -33
  35. package/template/_github/workflows/ci.yml +0 -38
  36. package/template/_github/workflows/release.yml +0 -58
  37. package/template/_husky/commit-msg +0 -8
  38. package/template/_husky/pre-commit +0 -1
  39. package/template/_prettierignore +0 -7
  40. package/template/commitlint.config.mjs +0 -6
  41. package/template/docs/adr/0001-keep-the-starter-minimal.md +0 -32
  42. package/template/docs/adr/0002-adopt-a-living-meta-layer.md +0 -30
  43. package/template/docs/adr/0003-normalize-kpa-plugin-output.md +0 -24
  44. package/template/docs/adr/0004-adopt-an-automated-quality-baseline.md +0 -31
  45. package/template/docs/adr/0005-adopt-a-tag-driven-release-baseline.md +0 -45
  46. package/template/docs/adr/0006-adopt-commit-message-conventions.md +0 -39
  47. package/template/docs/adr/README.md +0 -37
  48. package/template/docs/adr/TEMPLATE.md +0 -18
  49. package/template/docs/architecture/module-boundaries.md +0 -48
  50. package/template/docs/meta/maintenance.md +0 -40
  51. package/template/docs/quality/quality-gates.md +0 -39
  52. package/template/docs/specs/README.md +0 -36
  53. package/template/docs/specs/TEMPLATE.md +0 -34
  54. package/template/docs/specs/app-bootstrap.md +0 -46
  55. package/template/docs/specs/counter-component.md +0 -48
  56. package/template/docs/specs/quality-workflow.md +0 -62
  57. package/template/eslint.config.mjs +0 -54
  58. package/template/playwright.config.ts +0 -31
  59. package/template/pnpm-lock.yaml +0 -3777
  60. package/template/prettier.config.mjs +0 -6
  61. package/template/public/favicon.svg +0 -15
  62. package/template/tests/e2e/app.spec.ts +0 -18
  63. package/template/tests/integration/main-bootstrap.test.ts +0 -33
  64. package/template/tests/unit/normalize-kpa-module-export.test.ts +0 -46
  65. package/template/vite.config.d.mts +0 -7
  66. package/template/vitest.config.mjs +0 -19
  67. package/template-overlays/router/ARCHITECTURE.md +0 -86
  68. package/template-overlays/router/CHANGELOG.md +0 -44
  69. package/template-overlays/router/DEVELOPMENT_RULES.md +0 -57
  70. package/template-overlays/router/ROADMAP.md +0 -34
  71. package/template-overlays/router/TESTING_STRATEGY.md +0 -67
  72. package/template-overlays/router/docs/adr/0001-keep-the-starter-minimal.md +0 -32
  73. package/template-overlays/router/docs/architecture/module-boundaries.md +0 -39
  74. package/template-overlays/router/docs/meta/maintenance.md +0 -38
  75. package/template-overlays/router/docs/specs/README.md +0 -19
  76. package/template-overlays/router/docs/specs/app-bootstrap.md +0 -42
  77. package/template-overlays/router/docs/specs/router-navigation.md +0 -41
  78. package/template-overlays/router/pnpm-lock.yaml +0 -3786
  79. package/template-overlays/router/tests/e2e/app.spec.ts +0 -38
  80. package/template-overlays/router/tests/integration/main-bootstrap.test.ts +0 -150
@@ -3,8 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "private": true,
5
5
  "description": "KoppaJS application scaffolded with create-koppajs.",
6
- "author": "Bastian Bensch",
7
- "license": "Apache-2.0",
8
6
  "keywords": [
9
7
  "koppajs",
10
8
  "koppa",
@@ -14,59 +12,24 @@
14
12
  "typescript",
15
13
  "web-components"
16
14
  ],
17
- "packageManager": "pnpm@10.12.1",
15
+ "packageManager": "pnpm@10.33.2",
18
16
  "engines": {
19
- "node": "^20.19.0 || ^22.13.0 || >=24.0.0",
20
- "pnpm": ">=10"
17
+ "node": ">=22.12.0",
18
+ "pnpm": ">=10.24.0"
21
19
  },
22
20
  "scripts": {
23
21
  "dev": "vite --host",
24
22
  "build": "tsc --noEmit && vite build",
25
- "lint": "eslint .",
26
- "lint:fix": "eslint . --fix",
27
- "format": "prettier . --write --ignore-unknown",
28
- "format:check": "prettier . --check --ignore-unknown",
29
- "test": "vitest run",
30
- "test:watch": "vitest",
31
- "test:run": "vitest run",
32
- "test:coverage": "vitest run --coverage",
33
- "test:e2e": "pnpm build && playwright test",
34
- "test:e2e:headed": "pnpm build && playwright test --headed",
35
- "test:e2e:ui": "pnpm build && playwright test --ui",
36
- "check": "pnpm lint && pnpm format:check && pnpm typecheck && pnpm test:run && pnpm build",
37
- "validate": "pnpm check && playwright test",
38
- "release:check": "pnpm validate",
39
23
  "typecheck": "tsc --noEmit",
40
- "serve": "vite preview",
41
- "serve:e2e": "vite preview --host 127.0.0.1 --strictPort --port 4173",
42
- "prepare": "husky"
24
+ "serve": "vite preview"
43
25
  },
44
26
  "dependencies": {
45
- "@koppajs/koppajs-core": "^3.0.3"
27
+ "@koppajs/koppajs-core": "3.0.7"
46
28
  },
47
29
  "devDependencies": {
48
- "@commitlint/cli": "^20.1.0",
49
- "@commitlint/config-conventional": "^20.0.0",
50
- "@eslint/js": "^10.0.1",
51
- "@koppajs/koppajs-vite-plugin": "^1.0.1",
52
- "@playwright/test": "^1.58.2",
53
- "@types/node": "^25.4.0",
54
- "@vitest/coverage-v8": "^4.0.18",
55
- "eslint": "^10.0.3",
56
- "globals": "^17.4.0",
57
- "husky": "^9.1.7",
58
- "lint-staged": "^16.3.3",
59
- "prettier": "^3.8.1",
60
- "typescript": "^5.9.3",
61
- "typescript-eslint": "^8.57.0",
62
- "vite": "7.2.6",
63
- "vitest": "^4.0.18"
64
- },
65
- "lint-staged": {
66
- "*.{js,mjs,cjs,ts,mts,cts}": [
67
- "eslint --fix",
68
- "prettier --write"
69
- ],
70
- "*.{css,html,json,md,yml,yaml}": "prettier --write"
30
+ "@koppajs/koppajs-vite-plugin": "1.0.4",
31
+ "@types/node": "25.6.0",
32
+ "typescript": "5.9.3",
33
+ "vite": "7.3.2"
71
34
  }
72
35
  }
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  [template]
2
2
  <div class="app-root">
3
- <img src="https://public-assets-1b57ca06-687a-4142-a525-0635f7649a5c.s3.eu-central-1.amazonaws.com/koppajs/koppajs-logo-text-900x226.png" width="420" alt="KoppaJS Logo" class="logo">
3
+ <img src="/koppajs-logo.png" width="420" alt="KoppaJS Logo" class="logo">
4
4
  <p class="subtitle">Minimal Starter</p>
5
5
  <counter-component></counter-component>
6
6
  </div>
@@ -31,5 +31,3 @@
31
31
  opacity: 0.8;
32
32
  }
33
33
  [/css]
34
-
35
-
@@ -10,17 +10,10 @@
10
10
  "forceConsistentCasingInFileNames": true,
11
11
  "noEmit": true
12
12
  },
13
- "include": [
14
- "src/**/*.ts",
15
- "tests/**/*.ts",
16
- "playwright.config.ts",
17
- "vite.config.d.mts"
18
- ],
13
+ "include": ["src/**/*.ts"],
19
14
  "exclude": [
20
15
  "coverage",
21
16
  "dist",
22
- "node_modules",
23
- "playwright-report",
24
- "test-results"
17
+ "node_modules"
25
18
  ]
26
19
  }
@@ -1,45 +1,10 @@
1
1
  import koppaPlugin from "@koppajs/koppajs-vite-plugin";
2
2
  import { defineConfig } from "vite";
3
3
 
4
- /**
5
- * Wrap raw `.kpa` object output in a valid ES module export.
6
- *
7
- * @returns {import("vite").Plugin}
8
- */
9
- export function normalizeKpaModuleExport() {
10
- return {
11
- name: "normalize-kpa-module-export",
12
- enforce: "post",
13
- /**
14
- * @param {string} code
15
- * @param {string} id
16
- */
17
- transform(code, id) {
18
- const cleanId = id.split("?")[0];
19
-
20
- if (!cleanId.endsWith(".kpa")) {
21
- return null;
22
- }
23
-
24
- const trimmed = code.trim();
25
-
26
- if (!trimmed.startsWith("{") || trimmed.startsWith("export default")) {
27
- return null;
28
- }
29
-
30
- return {
31
- code: `export default ${trimmed};`,
32
- map: null,
33
- };
34
- },
35
- };
36
- }
37
-
38
4
  export default defineConfig({
39
5
  plugins: [
40
6
  koppaPlugin({
41
7
  tsconfigFile: "./tsconfig.json",
42
8
  }),
43
- normalizeKpaModuleExport(),
44
9
  ],
45
10
  });
@@ -1,97 +1,11 @@
1
- <a id="readme-top"></a>
1
+ # __PROJECT_NAME__
2
2
 
3
- <div align="center">
4
- <img src="https://public-assets-1b57ca06-687a-4142-a525-0635f7649a5c.s3.eu-central-1.amazonaws.com/koppajs/koppajs-logo-text-900x226.png" width="500" alt="KoppaJS Logo">
5
- </div>
6
-
7
- <br>
8
-
9
- <div align="center">
10
- <a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square" alt="License"></a>
11
- </div>
12
-
13
- <br>
14
-
15
- <div align="center">
16
- <h1 align="center">__PROJECT_NAME__</h1>
17
- <h3 align="center">KoppaJS router starter project</h3>
18
- <p align="center">
19
- <i>Scaffolded from the official KoppaJS router starter baseline.</i>
20
- </p>
21
- </div>
22
-
23
- <br>
24
-
25
- <div align="center">
26
- <p align="center">
27
- <a href="https://github.com/koppajs/koppajs-documentation">Documentation</a>
28
- &middot;
29
- <a href="https://github.com/koppajs/koppajs-core">KoppaJS Core</a>
30
- &middot;
31
- <a href="https://github.com/koppajs/koppajs-router">KoppaJS Router</a>
32
- &middot;
33
- <a href="https://github.com/koppajs/koppajs-vite-plugin">Vite Plugin</a>
34
- </p>
35
- </div>
36
-
37
- <br>
38
-
39
- <details>
40
- <summary>Table of Contents</summary>
41
- <ol>
42
- <li><a href="#what-is-this">What is this?</a></li>
43
- <li><a href="#requirements">Requirements</a></li>
44
- <li><a href="#getting-started">Getting Started</a></li>
45
- <li><a href="#quality-workflow">Quality Workflow</a></li>
46
- <li><a href="#routing-overview">Routing Overview</a></li>
47
- <li><a href="#project-structure">Project Structure</a></li>
48
- <li><a href="#meta-layer">Meta Layer</a></li>
49
- <li><a href="#community--contribution">Community & Contribution</a></li>
50
- <li><a href="#license">License</a></li>
51
- </ol>
52
- </details>
53
-
54
- ---
55
-
56
- ## What is this?
57
-
58
- This project was scaffolded from the official KoppaJS router starter baseline.
59
-
60
- It keeps the application intentionally small while demonstrating one extra
61
- subsystem beyond the minimal starter:
62
-
63
- - one HTML shell
64
- - one TypeScript bootstrap file
65
- - one root app shell component
66
- - one router instance with a visible two-page flow
67
- - one counter component on the home route
68
- - one explicit catch-all route for unmatched paths
69
-
70
- It also carries the same quality and governance baseline as the minimal starter:
71
-
72
- - ESLint for source and tooling files
73
- - Prettier plus `.editorconfig` for supported text formats
74
- - Vitest for local unit and integration coverage
75
- - Playwright for a real-browser smoke test
76
- - Husky plus lint-staged for fast staged-file checks
77
- - Conventional Commits enforcement via `commitlint`
78
- - a tag-driven GitHub release baseline with `CHANGELOG.md` and `RELEASE.md`
79
-
80
- Use it when you want to start from a small KoppaJS app that already shows how
81
- route definitions, `data-route` links, and route-based outlet rendering fit
82
- together.
83
-
84
- ---
3
+ KoppaJS router starter project scaffolded with `create-koppajs`.
85
4
 
86
5
  ## Requirements
87
6
 
88
- - Node.js 20.19+, 22.13+, or 24+
89
- - pnpm >= 10
90
-
91
- Node 23 is intentionally not treated as supported here because the current
92
- upstream frontend toolchain excludes it.
93
-
94
- ---
7
+ - Node.js >= 22.12.0
8
+ - pnpm >= 10.24.0
95
9
 
96
10
  ## Getting Started
97
11
 
@@ -100,144 +14,52 @@ pnpm install
100
14
  pnpm dev
101
15
  ```
102
16
 
103
- Install the Playwright browser once if you want to run the browser smoke test locally:
17
+ ## Scripts
104
18
 
105
19
  ```bash
106
- pnpm exec playwright install chromium
107
- ```
108
-
109
- Useful commands:
110
-
111
- ```bash
112
- pnpm lint
113
- pnpm format:check
114
- pnpm typecheck
115
- pnpm test:run
116
- pnpm test:coverage
117
20
  pnpm build
21
+ pnpm typecheck
118
22
  pnpm serve
119
- pnpm release:check
120
23
  ```
121
24
 
122
- ---
123
-
124
- ## Quality Workflow
125
-
126
- Fast local baseline:
127
-
128
- ```bash
129
- pnpm check
130
- ```
131
-
132
- Full validation, including Playwright:
133
-
134
- ```bash
135
- pnpm validate
136
- ```
137
-
138
- Standalone browser smoke test:
139
-
140
- ```bash
141
- pnpm test:e2e
142
- ```
143
-
144
- ---
145
-
146
- ## Routing Overview
25
+ ## Routing
147
26
 
148
27
  The starter wires `@koppajs/koppajs-router` in `src/main.ts`.
149
28
 
150
- The route table currently contains:
29
+ The route table contains:
151
30
 
152
31
  - `/` -> `home-page`
153
32
  - `/router` -> `router-page`
154
33
  - `*` -> `not-found-page`
155
34
 
156
- The router renders into `#app-outlet`, updates active navigation state for
157
- links that use `data-route`, and keeps the browser URL aligned with the current
158
- page.
159
-
160
- ---
161
-
162
35
  ## Project Structure
163
36
 
164
37
  ```text
165
38
  __PROJECT_NAME__/
166
- ├── .editorconfig
167
- ├── .github/
39
+ ├── .gitattributes
168
40
  ├── .gitignore
169
- ├── .husky/
170
41
  ├── .npmrc
171
- ├── .prettierignore
172
- ├── CHANGELOG.md
173
- ├── commitlint.config.mjs
174
- ├── AI_CONSTITUTION.md
175
- ├── ARCHITECTURE.md
176
- ├── CONTRIBUTING.md
177
- ├── DECISION_HIERARCHY.md
178
- ├── DEVELOPMENT_RULES.md
179
- ├── RELEASE.md
180
- ├── ROADMAP.md
181
- ├── TESTING_STRATEGY.md
182
- ├── eslint.config.mjs
42
+ ├── README.md
183
43
  ├── index.html
184
44
  ├── package.json
185
- ├── playwright.config.ts
186
- ├── pnpm-lock.yaml
187
- ├── prettier.config.mjs
188
45
  ├── tsconfig.json
189
46
  ├── vite.config.mjs
190
- ├── vitest.config.mjs
191
- ├── docs/
192
- │ ├── adr/
193
- │ ├── architecture/
194
- │ ├── meta/
195
- │ ├── quality/
196
- │ └── specs/
197
47
  ├── public/
198
- └── favicon.svg
199
- ├── src/
200
- │ ├── main.ts
201
- ├── style.css
202
- ├── app-view.kpa
203
- ├── counter-component.kpa
204
- ├── home-page.kpa
205
- ├── router-page.kpa
206
- │ └── not-found-page.kpa
207
- └── tests/
208
- ├── e2e/
209
- ├── integration/
210
- └── unit/
48
+ ├── favicon.png
49
+ │ └── koppajs-logo.png
50
+ └── src/
51
+ ├── app-view.kpa
52
+ ├── counter-component.kpa
53
+ ├── home-page.kpa
54
+ ├── main.ts
55
+ ├── not-found-page.kpa
56
+ ├── router-page.kpa
57
+ └── style.css
211
58
  ```
212
59
 
213
- ---
214
-
215
- ## Meta Layer
216
-
217
- The repository includes an explicit meta layer so architecture, testing, and
218
- contributor rules evolve together with the codebase.
219
-
220
- Start here:
221
-
222
- - `DECISION_HIERARCHY.md`
223
- - `AI_CONSTITUTION.md`
224
- - `ARCHITECTURE.md`
225
- - `DEVELOPMENT_RULES.md`
226
- - `TESTING_STRATEGY.md`
227
- - `CHANGELOG.md`
228
- - `RELEASE.md`
229
- - `docs/quality/quality-gates.md`
230
- - `docs/adr/`
231
- - `docs/specs/`
232
-
233
- ---
234
-
235
- ## Community & Contribution
236
-
237
- Contribution workflow details live in `CONTRIBUTING.md`.
238
- Update this section with your own repository links once the project has a
239
- canonical home.
240
-
241
- ---
60
+ ## Useful Links
242
61
 
243
- ## License
62
+ - [KoppaJS documentation](https://github.com/koppajs/koppajs-documentation)
63
+ - [KoppaJS core](https://github.com/koppajs/koppajs-core)
64
+ - [KoppaJS router](https://github.com/koppajs/koppajs-router)
65
+ - [KoppaJS Vite plugin](https://github.com/koppajs/koppajs-vite-plugin)
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>KoppaJS Router Starter</title>
7
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
+ <link rel="icon" type="image/png" href="/favicon.png" />
8
8
  <link rel="stylesheet" href="/src/style.css" />
9
9
  </head>
10
10
  <body>
@@ -3,8 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "private": true,
5
5
  "description": "KoppaJS router application scaffolded with create-koppajs.",
6
- "author": "Bastian Bensch",
7
- "license": "Apache-2.0",
8
6
  "keywords": [
9
7
  "koppajs",
10
8
  "koppa",
@@ -15,60 +13,25 @@
15
13
  "web-components",
16
14
  "router"
17
15
  ],
18
- "packageManager": "pnpm@10.12.1",
16
+ "packageManager": "pnpm@10.33.2",
19
17
  "engines": {
20
- "node": "^20.19.0 || ^22.13.0 || >=24.0.0",
21
- "pnpm": ">=10"
18
+ "node": ">=22.12.0",
19
+ "pnpm": ">=10.24.0"
22
20
  },
23
21
  "scripts": {
24
22
  "dev": "vite --host",
25
23
  "build": "tsc --noEmit && vite build",
26
- "lint": "eslint .",
27
- "lint:fix": "eslint . --fix",
28
- "format": "prettier . --write --ignore-unknown",
29
- "format:check": "prettier . --check --ignore-unknown",
30
- "test": "vitest run",
31
- "test:watch": "vitest",
32
- "test:run": "vitest run",
33
- "test:coverage": "vitest run --coverage",
34
- "test:e2e": "pnpm build && playwright test",
35
- "test:e2e:headed": "pnpm build && playwright test --headed",
36
- "test:e2e:ui": "pnpm build && playwright test --ui",
37
- "check": "pnpm lint && pnpm format:check && pnpm typecheck && pnpm test:run && pnpm build",
38
- "validate": "pnpm check && playwright test",
39
- "release:check": "pnpm validate",
40
24
  "typecheck": "tsc --noEmit",
41
- "serve": "vite preview",
42
- "serve:e2e": "vite preview --host 127.0.0.1 --strictPort --port 4173",
43
- "prepare": "husky"
25
+ "serve": "vite preview"
44
26
  },
45
27
  "dependencies": {
46
- "@koppajs/koppajs-core": "^3.0.3",
47
- "@koppajs/koppajs-router": "^0.1.0"
28
+ "@koppajs/koppajs-core": "3.0.7",
29
+ "@koppajs/koppajs-router": "0.1.2"
48
30
  },
49
31
  "devDependencies": {
50
- "@commitlint/cli": "^20.1.0",
51
- "@commitlint/config-conventional": "^20.0.0",
52
- "@eslint/js": "^10.0.1",
53
- "@koppajs/koppajs-vite-plugin": "^1.0.1",
54
- "@playwright/test": "^1.58.2",
55
- "@types/node": "^25.4.0",
56
- "@vitest/coverage-v8": "^4.0.18",
57
- "eslint": "^10.0.3",
58
- "globals": "^17.4.0",
59
- "husky": "^9.1.7",
60
- "lint-staged": "^16.3.3",
61
- "prettier": "^3.8.1",
62
- "typescript": "^5.9.3",
63
- "typescript-eslint": "^8.57.0",
64
- "vite": "7.2.6",
65
- "vitest": "^4.0.18"
66
- },
67
- "lint-staged": {
68
- "*.{js,mjs,cjs,ts,mts,cts}": [
69
- "eslint --fix",
70
- "prettier --write"
71
- ],
72
- "*.{css,html,json,md,yml,yaml}": "prettier --write"
32
+ "@koppajs/koppajs-vite-plugin": "1.0.4",
33
+ "@types/node": "25.6.0",
34
+ "typescript": "5.9.3",
35
+ "vite": "7.3.2"
73
36
  }
74
37
  }
@@ -1,20 +1,11 @@
1
1
  [template]
2
2
  <div class="app-shell">
3
- <header class="hero-panel">
4
- <div class="hero-copy">
5
- <img src="https://public-assets-1b57ca06-687a-4142-a525-0635f7649a5c.s3.eu-central-1.amazonaws.com/koppajs/koppajs-logo-text-900x226.png" width="320" alt="KoppaJS Logo" class="logo">
6
- <p class="eyebrow">Router Starter</p>
7
- <h1 class="title">Optional routing for new KoppaJS projects</h1>
8
- <p class="lead">
9
- This starter keeps the original lightweight baseline, adds
10
- <code>@koppajs/koppajs-router</code>, and shows how route-based rendering
11
- fits into a small app shell.
12
- </p>
13
- </div>
3
+ <header class="app-header">
4
+ <img src="/koppajs-logo.png" width="280" alt="KoppaJS Logo" class="logo">
14
5
 
15
6
  <nav class="main-nav" aria-label="Primary">
16
7
  <a data-route="/" href="/" class="nav-link">Home</a>
17
- <a data-route="/router" href="/router" class="nav-link">Router Page</a>
8
+ <a data-route="/router" href="/router" class="nav-link">Router</a>
18
9
  </nav>
19
10
  </header>
20
11
 
@@ -24,105 +15,57 @@
24
15
 
25
16
  [css]
26
17
  .app-shell {
27
- width: min(1080px, calc(100vw - 2rem));
18
+ width: min(920px, calc(100vw - 2rem));
28
19
  margin: 0 auto;
29
20
  padding: 2rem 0 3rem;
30
21
  }
31
22
 
32
- .hero-panel {
33
- display: grid;
34
- gap: 1.5rem;
35
- padding: 1.5rem;
36
- border: 1px solid var(--border);
37
- border-radius: 1.75rem;
38
- background: linear-gradient(180deg, rgba(8, 17, 31, 0.88), rgba(8, 17, 31, 0.72));
39
- box-shadow: var(--shadow);
40
- backdrop-filter: blur(18px);
41
- }
42
-
43
- .hero-copy {
23
+ .app-header {
44
24
  display: flex;
45
- flex-direction: column;
46
- gap: 0.9rem;
25
+ align-items: center;
26
+ justify-content: space-between;
27
+ gap: 1rem;
28
+ padding: 1rem 0 1.5rem;
29
+ border-bottom: 1px solid var(--border);
47
30
  }
48
31
 
49
32
  .logo {
50
- width: min(320px, 72vw);
51
- }
52
-
53
- .eyebrow {
54
- font-size: 0.82rem;
55
- letter-spacing: 0.3em;
56
- text-transform: uppercase;
57
- color: var(--accent);
58
- }
59
-
60
- .title {
61
- font-size: clamp(2.1rem, 5vw, 3.6rem);
62
- line-height: 1.05;
63
- max-width: 14ch;
64
- }
65
-
66
- .lead {
67
- max-width: 58ch;
68
- color: var(--muted);
69
- line-height: 1.65;
70
- }
71
-
72
- .lead code {
73
- color: var(--accent-strong);
33
+ width: min(280px, 56vw);
74
34
  }
75
35
 
76
36
  .main-nav {
77
37
  display: flex;
78
38
  flex-wrap: wrap;
79
- gap: 0.8rem;
39
+ gap: 0.6rem;
80
40
  }
81
41
 
82
42
  .nav-link {
83
43
  display: inline-flex;
84
44
  align-items: center;
85
45
  justify-content: center;
86
- min-height: 2.8rem;
87
- padding: 0 1.15rem;
46
+ min-height: 2.5rem;
47
+ padding: 0 1rem;
48
+ border: 1px solid var(--border);
88
49
  border-radius: 999px;
89
- border: 1px solid rgba(100, 220, 232, 0.24);
90
- background: rgba(100, 220, 232, 0.06);
91
50
  color: var(--text);
92
51
  text-decoration: none;
93
- transition: background 0.25s ease, border-color 0.25s ease, transform 0.15s ease;
94
- }
95
-
96
- .nav-link:hover {
97
- background: rgba(100, 220, 232, 0.12);
98
- border-color: rgba(100, 220, 232, 0.4);
99
- }
100
-
101
- .nav-link:active {
102
- transform: translateY(1px);
103
52
  }
104
53
 
54
+ .nav-link:hover,
105
55
  .nav-link.is-active,
106
56
  .nav-link[aria-current="page"] {
107
- background: var(--accent);
108
57
  border-color: var(--accent);
109
- color: #07111e;
110
- font-weight: 700;
58
+ color: var(--accent);
111
59
  }
112
60
 
113
61
  .app-outlet {
114
- padding-top: 1.5rem;
62
+ padding-top: 2rem;
115
63
  }
116
64
 
117
65
  @media (max-width: 640px) {
118
- .app-shell {
119
- width: min(100vw - 1rem, 1080px);
120
- padding-top: 0.75rem;
121
- }
122
-
123
- .hero-panel {
124
- padding: 1.15rem;
125
- border-radius: 1.25rem;
66
+ .app-header {
67
+ align-items: flex-start;
68
+ flex-direction: column;
126
69
  }
127
70
  }
128
71
  [/css]