@rm-industries/create-forge 0.4.0-beta.1 → 0.4.0-beta.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 (27) hide show
  1. package/dist/template/.github/workflows/automation.yml +20 -0
  2. package/dist/template/.github/workflows/project.yml +27 -0
  3. package/dist/template/README.md +38 -0
  4. package/dist/template/astro.config.ts +5 -1
  5. package/dist/template/docs/github-pages.md +56 -0
  6. package/dist/template/docs/guides/content-and-cms.md +123 -0
  7. package/dist/template/docs/guides/getting-started.md +96 -0
  8. package/dist/template/docs/guides/quality-and-troubleshooting.md +118 -0
  9. package/dist/template/docs/guides/themes-and-accessibility.md +85 -0
  10. package/dist/template/package-lock.json +420 -479
  11. package/dist/template/package.json +3 -3
  12. package/dist/template/src/components/navigation/Footer.astro +2 -1
  13. package/dist/template/src/components/navigation/Navbar.astro +9 -5
  14. package/dist/template/src/components/navigation/Pagination.astro +4 -2
  15. package/dist/template/src/components/seo/SeoHead.astro +7 -6
  16. package/dist/template/src/components/ui/Card.astro +5 -2
  17. package/dist/template/src/config/deployment.test.ts +16 -0
  18. package/dist/template/src/config/deployment.ts +14 -0
  19. package/dist/template/src/integrations/sveltia/config.ts +3 -2
  20. package/dist/template/src/lib/paths.test.ts +26 -0
  21. package/dist/template/src/lib/paths.ts +17 -0
  22. package/dist/template/src/pages/404.astro +2 -1
  23. package/dist/template/src/pages/about.astro +5 -1
  24. package/dist/template/src/pages/index.astro +4 -3
  25. package/dist/template/src/pages/rss.xml.ts +2 -1
  26. package/dist/template/src/pages/site.webmanifest.ts +3 -2
  27. package/package.json +3 -3
@@ -57,3 +57,23 @@ jobs:
57
57
 
58
58
  - name: Validate workflows
59
59
  uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2
60
+
61
+ automation:
62
+ name: Automation
63
+ needs:
64
+ - security
65
+ - syntax
66
+ if: always()
67
+ runs-on: ubuntu-latest
68
+
69
+ steps:
70
+ - name: Confirm automation checks
71
+ env:
72
+ SECURITY_RESULT: ${{ needs.security.result }}
73
+ SYNTAX_RESULT: ${{ needs.syntax.result }}
74
+ run: |
75
+ if [[ "$SECURITY_RESULT" != 'success' || "$SYNTAX_RESULT" != 'success' ]]; then
76
+ echo '::error title=Automation validation failed::Workflow security and syntax checks must both pass.'
77
+ exit 1
78
+ fi
79
+ echo 'Workflow security and syntax checks passed.'
@@ -149,6 +149,12 @@ jobs:
149
149
  if-no-files-found: error
150
150
  retention-days: 7
151
151
 
152
+ - name: Upload GitHub Pages artifact
153
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
154
+ uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5
155
+ with:
156
+ path: dist
157
+
152
158
  browser-tests:
153
159
  name: Browser and accessibility tests
154
160
  runs-on: ubuntu-latest
@@ -233,3 +239,24 @@ jobs:
233
239
  steps:
234
240
  - name: Confirm project checks
235
241
  run: echo "All project checks passed."
242
+
243
+ deploy:
244
+ name: Deploy GitHub Pages
245
+ needs:
246
+ - build
247
+ - project
248
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
249
+ runs-on: ubuntu-latest
250
+
251
+ permissions:
252
+ pages: write
253
+ id-token: write
254
+
255
+ environment:
256
+ name: github-pages
257
+ url: ${{ steps.deployment.outputs.page_url }}
258
+
259
+ steps:
260
+ - name: Deploy GitHub Pages
261
+ id: deployment
262
+ uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5
@@ -11,6 +11,30 @@ The template's `.editorconfig` shares UTF-8, LF, final-newline, two-space, and
11
11
  120-column settings with supported editors and Oxfmt. `oxfmt.config.ts` contains
12
12
  only formatter-specific behavior such as quote and import ordering.
13
13
 
14
+ ## Start here
15
+
16
+ The generated documentation is organized by task:
17
+
18
+ - [Getting started and site configuration](docs/guides/getting-started.md)
19
+ covers installation, local development, branding, identity assets, pages, and
20
+ the first verification pass.
21
+ - [Content and CMS editing](docs/guides/content-and-cms.md) covers Markdown
22
+ articles, drafts, Sveltia local mode, deployed editing, shared model changes,
23
+ media, and recovery.
24
+ - [Themes and accessibility](docs/guides/themes-and-accessibility.md) covers
25
+ themes, fonts, layout semantics, automated checks, and manual review.
26
+ - [Quality checks, dependency updates, and troubleshooting](docs/guides/quality-and-troubleshooting.md)
27
+ explains the validation layers, common failures, Dependabot review, and safe
28
+ support requests.
29
+ - [GitHub Pages deployment](docs/github-pages.md) covers project sites, custom
30
+ domains, environment protection, and deployment diagnosis.
31
+ - [Accessibility review](docs/accessibility-checklist.md) and the
32
+ [Lighthouse performance budget](docs/performance-budget.md) record the
33
+ generated baseline and the manual checks projects must maintain.
34
+
35
+ The remainder of this README is the complete command and implementation
36
+ reference.
37
+
14
38
  | Command | Purpose |
15
39
  | ------------------------ | ---------------------------------------------------------------- |
16
40
  | `npm run dev` | Start Astro's local development server. |
@@ -62,6 +86,10 @@ The generated `.github/workflows/project.yml` runs on pull requests targeting
62
86
  unit tests, the validated production build, browser and accessibility tests,
63
87
  and Lighthouse budgets so failures identify the affected gate directly. The
64
88
  required `Project` result succeeds only after every release-blocking job passes.
89
+ On pushes to `main`, that result unlocks a separate GitHub Pages deployment;
90
+ pull requests never upload or deploy a Pages artifact. Deployment setup,
91
+ project-site URLs, custom domains, and environment protections are documented in
92
+ [`docs/github-pages.md`](docs/github-pages.md).
65
93
 
66
94
  The workflow installs dependencies with `npm ci`, caches npm downloads using
67
95
  the lockfile, cancels superseded runs on the same Git reference, and grants only
@@ -80,6 +108,10 @@ Security tab without failing the workflow solely because it found an issue.
80
108
  The job receives `security-events: write` only for that upload; all other access
81
109
  remains read-only. Repositories can make selected code-scanning severities
82
110
  merge-blocking later through their ruleset without changing the workflow.
111
+ The `Automation` aggregate runs when `.github/**` changes and succeeds only after
112
+ both workflow syntax and security validation pass. Because it is path-filtered,
113
+ do not configure it as a globally required status check; review it whenever an
114
+ automation change causes it to appear.
83
115
 
84
116
  Dependabot checks npm and GitHub Actions weekly. Minor and patch npm updates are
85
117
  grouped by production or development scope, while major updates remain separate
@@ -141,6 +173,12 @@ configuration, shared layout, and reusable SEO head consume this single
141
173
  validated source. New pages should use `src/layouts/BaseLayout.astro` to inherit
142
174
  the document shell and canonical metadata.
143
175
 
176
+ The canonical URL may include a pathname for a GitHub Pages project site, such
177
+ as `https://owner.github.io/repository`. The Astro configuration derives its
178
+ deployment base from that pathname, and shared URL helpers apply it to local
179
+ navigation, metadata, supporting files, and assets. Root-hosted and custom-domain
180
+ sites use an origin-only URL and therefore have no deployment prefix.
181
+
144
182
  The standalone source template uses `https://example.com` as a valid,
145
183
  non-production site origin. Projects created by Forge receive the values
146
184
  selected through the generator input contract.
@@ -2,12 +2,16 @@ import sitemap from '@astrojs/sitemap';
2
2
  import tailwindcss from '@tailwindcss/vite';
3
3
  import { defineConfig } from 'astro/config';
4
4
 
5
+ import { getDeploymentConfig } from './src/config/deployment';
5
6
  import { site } from './src/config/site';
6
7
 
8
+ const deployment = getDeploymentConfig(site.url);
9
+
7
10
  export default defineConfig({
11
+ base: deployment.base,
8
12
  integrations: [sitemap()],
9
13
  output: 'static',
10
- site: site.url,
14
+ site: deployment.site,
11
15
  trailingSlash: 'always',
12
16
  vite: {
13
17
  plugins: [tailwindcss()],
@@ -0,0 +1,56 @@
1
+ # GitHub Pages deployment
2
+
3
+ The project workflow publishes the validated production build to GitHub Pages
4
+ after every push to `main`. Pull requests build and test the site, but they do
5
+ not upload a Pages artifact or run a deployment.
6
+
7
+ ## Enable deployment
8
+
9
+ 1. Open the repository's **Settings → Pages** page.
10
+ 2. Under **Build and deployment**, select **GitHub Actions** as the source.
11
+ 3. Open **Settings → Environments → github-pages** after its first appearance.
12
+ 4. Restrict deployment branches to `main`. Add required reviewers when the site
13
+ needs a manual production approval.
14
+
15
+ The build job has read-only repository access. The separate deployment job is
16
+ the only job granted `pages: write` and `id-token: write`, and it cannot begin
17
+ until the complete `Project` quality gate succeeds.
18
+
19
+ ## Choose the public URL
20
+
21
+ Set `url` in `src/config/site.ts` to the complete public address. Forge derives
22
+ Astro's deployment base from this value, so canonical metadata, navigation,
23
+ assets, the RSS feed, the web manifest, and CMS branding use the same path.
24
+
25
+ For a project site, include the repository name:
26
+
27
+ ```ts
28
+ url: 'https://owner.github.io/repository',
29
+ ```
30
+
31
+ For an organization or user site, use the root address:
32
+
33
+ ```ts
34
+ url: 'https://owner.github.io',
35
+ ```
36
+
37
+ Run `npm run build && npm run validate:build` after changing the URL. Once the
38
+ workflow succeeds on `main`, its deployment summary links to the published site.
39
+
40
+ ## Use a custom domain
41
+
42
+ Set the site URL to the custom origin without a repository pathname:
43
+
44
+ ```ts
45
+ url: 'https://www.example.com',
46
+ ```
47
+
48
+ Add `public/CNAME` containing only the domain name, configure the same domain in
49
+ **Settings → Pages**, and create the DNS records GitHub documents for the chosen
50
+ domain. The template does not include a `CNAME` file because generated projects
51
+ do not share a domain. Enable **Enforce HTTPS** after GitHub verifies the DNS
52
+ configuration.
53
+
54
+ Do not configure both a repository pathname and a custom domain. A custom domain
55
+ is served from its root, while a project site uses the repository name as its
56
+ base path.
@@ -0,0 +1,123 @@
1
+ # Content and CMS editing
2
+
3
+ Forge stores article content as Markdown in `src/content/articles/`. Astro and
4
+ Sveltia use the same model from
5
+ `src/config/content-models/articles.ts`, so field rules are not duplicated.
6
+
7
+ ## Publish an article in Markdown
8
+
9
+ Create `src/content/articles/my-first-article.md`:
10
+
11
+ ```md
12
+ ---
13
+ title: My first article
14
+ description: What I learned while building this site.
15
+ publishedAt: 2026-09-02
16
+ tags:
17
+ - notes
18
+ draft: false
19
+ ---
20
+
21
+ # My first article
22
+
23
+ Write the article body here.
24
+ ```
25
+
26
+ The file name becomes the article slug. Use a unique lowercase, hyphenated file
27
+ name. Required fields, dates, defaults, and body content are validated during
28
+ development, type checking, and builds.
29
+
30
+ Set `draft: true` while writing. Draft articles appear during local development
31
+ but are omitted from production article pages and RSS output. Before publishing:
32
+
33
+ ```sh
34
+ npm run typecheck
35
+ npm test
36
+ npm run build
37
+ npm run validate:build
38
+ ```
39
+
40
+ Then inspect the article route and `/rss.xml` in the production preview:
41
+
42
+ ```sh
43
+ npm run preview
44
+ ```
45
+
46
+ ## Edit content with Sveltia locally
47
+
48
+ Local editing writes directly to the checked-out project; it does not require a
49
+ GitHub token.
50
+
51
+ 1. Start the site with `npm run dev`.
52
+ 2. Open the printed local address with `/admin/`, normally
53
+ `http://localhost:4321/admin/`.
54
+ 3. Choose **Work with Local Repository**.
55
+ 4. Grant access to the generated project root, not only the content folder.
56
+ 5. Create or edit an article and save it.
57
+ 6. Review the resulting files with Git, run the checks above, and commit them
58
+ through the normal project workflow.
59
+
60
+ A Chromium-based browser is the supported baseline for the local directory
61
+ picker. The browser controls directory permission; if access is denied or
62
+ revoked, reload `/admin/` and select the project again. Sveltia does not run a
63
+ separate local proxy server in this setup.
64
+
65
+ ## Configure the deployed CMS
66
+
67
+ Edit `src/integrations/sveltia/config.ts` and replace:
68
+
69
+ ```ts
70
+ repo: 'your-github-user/your-repository',
71
+ ```
72
+
73
+ with the same `owner/repository` configured in `src/config/site.ts`. The
74
+ generated backend targets `main` and offers Sveltia's GitHub token flow. Tokens
75
+ are entered by each editor in the CMS and must never be committed to the
76
+ repository, configuration, documentation, or environment files.
77
+
78
+ Before enabling editors, decide who may push to `main`, which branch protections
79
+ apply, and whether the project needs a supported OAuth service instead of
80
+ personal tokens. Treat `/admin/` as an editing application: it is excluded from
81
+ search indexing and public Lighthouse budgets, but it is still publicly
82
+ reachable on a deployed static site.
83
+
84
+ ## Change article fields
85
+
86
+ Edit only `src/config/content-models/articles.ts`. The registry passes the model
87
+ to both the Astro and Sveltia adapters.
88
+
89
+ When adding or changing a field:
90
+
91
+ 1. choose whether it is required and whether it needs a default;
92
+ 2. update existing Markdown files to satisfy the new model;
93
+ 3. update pages or components that render the value;
94
+ 4. update or add model, Astro, Sveltia, and preview tests; and
95
+ 5. run `npm run quality:core` before checking the editor manually.
96
+
97
+ Do not create a separate CMS YAML schema. A second schema can drift from the
98
+ validation applied during builds.
99
+
100
+ ## Media
101
+
102
+ The default CMS stores uploaded media under `public/assets/` and publishes it
103
+ from `/assets`. Add only purposeful assets, keep file sizes appropriate for the
104
+ [performance budget](../performance-budget.md), and provide useful alternative
105
+ text where media conveys meaning. Decorative imagery should use empty
106
+ alternative text at its rendering site.
107
+
108
+ ## Recover from an editing problem
109
+
110
+ - If an article is missing in production, confirm `draft` is `false`, its front
111
+ matter passes `npm run typecheck`, and the file extension is `.md` or
112
+ `.mdx`.
113
+ - If the CMS shows the wrong fields, confirm the model is registered in
114
+ `src/config/content-models/registry.ts` and reload the editor.
115
+ - If local CMS changes appear in an unexpected directory, revoke the browser's
116
+ directory permission and select the project root again.
117
+ - If deployed authentication fails, verify the repository identifier, branch,
118
+ token permissions, and organization access before changing content fields.
119
+ - If a save produced an unwanted change, use Git to inspect and restore the
120
+ affected content file before committing it.
121
+
122
+ For broader command failures, use
123
+ [quality checks and troubleshooting](quality-and-troubleshooting.md).
@@ -0,0 +1,96 @@
1
+ # Getting started and site configuration
2
+
3
+ This guide takes a newly generated Forge project from installation to a branded
4
+ local site. Run every command from the project root.
5
+
6
+ ## Install and start the site
7
+
8
+ Use a supported Node.js and npm version from the `engines` field in
9
+ `package.json`, then install the committed dependency graph:
10
+
11
+ ```sh
12
+ npm ci
13
+ npm run dev
14
+ ```
15
+
16
+ Astro prints the local address, normally `http://localhost:4321`. Stop the
17
+ server with `Control+C`.
18
+
19
+ Use `npm ci`, rather than `npm install`, when reproducing the committed project.
20
+ Use `npm install <package>` only when deliberately changing dependencies and
21
+ commit both `package.json` and `package-lock.json` afterward.
22
+
23
+ ## Change the site identity
24
+
25
+ Edit `src/config/site.ts`. The exported `site` object is the single source for
26
+ page metadata, navigation, feeds, the manifest, and CMS branding.
27
+
28
+ ```ts
29
+ export const site = defineSiteConfig({
30
+ name: 'Example Studio',
31
+ description: 'Notes about thoughtful product design.',
32
+ author: 'Example Team',
33
+ url: 'https://example.com',
34
+ repository: 'example/example-site',
35
+ language: 'en',
36
+ socialImage: '/social-card.svg',
37
+ navigation: [
38
+ { label: 'Home', href: '/' },
39
+ { label: 'Articles', href: '/articles/' },
40
+ { label: 'About', href: '/about/' },
41
+ ],
42
+ socialLinks: [{ label: 'GitHub', href: 'https://github.com/example' }],
43
+ });
44
+ ```
45
+
46
+ Use the complete production URL for `url`. A GitHub Pages project site includes
47
+ its repository path, for example `https://example.github.io/example-site`.
48
+ Root-hosted and custom-domain sites use only their origin. The
49
+ [GitHub Pages guide](../github-pages.md) explains each form.
50
+
51
+ Keep `repository` in `owner/repository` form. An empty value is valid while a
52
+ repository does not exist, but configure it before using the deployed CMS.
53
+
54
+ ## Replace identity assets
55
+
56
+ - Replace `public/favicon.svg` with the browser icon.
57
+ - Replace `public/social-card.svg` with the default sharing image.
58
+ - Change `site.socialImage` when the sharing image has a different path.
59
+ - Edit `src/pages/about.astro` and the homepage copy in
60
+ `src/pages/index.astro` to describe the project.
61
+
62
+ Files under `public/` are copied to the production build without processing.
63
+ Reference them with site-relative paths and use the path helpers already used
64
+ by the template when a component must support a GitHub Pages project prefix.
65
+
66
+ ## Add a page
67
+
68
+ Create an Astro file under `src/pages/` and compose the shared layout:
69
+
70
+ ```astro
71
+ ---
72
+ import BaseLayout from '../layouts/BaseLayout.astro';
73
+ ---
74
+
75
+ <BaseLayout title="Contact" description="How to contact Example Studio.">
76
+ <h1>Contact</h1>
77
+ <p>Send us a message.</p>
78
+ </BaseLayout>
79
+ ```
80
+
81
+ Add the route to `site.navigation` if it belongs in primary navigation. Do not
82
+ add another `main` element: `BaseLayout` already supplies the document shell,
83
+ skip link, landmarks, metadata, header, and footer.
84
+
85
+ ## Verify the first customization
86
+
87
+ ```sh
88
+ npm run quality:core
89
+ npm run dev
90
+ ```
91
+
92
+ Inspect the homepage, the changed page, `/articles/`, and `/admin/` in the
93
+ browser. Run the complete `npm run quality` gate before opening a pull request.
94
+
95
+ Continue with [content and CMS editing](content-and-cms.md), then review
96
+ [themes and accessibility](themes-and-accessibility.md).
@@ -0,0 +1,118 @@
1
+ # Quality checks, dependency updates, and troubleshooting
2
+
3
+ Forge provides fast focused commands and one complete release-blocking command.
4
+ Run commands from the generated project root.
5
+
6
+ ## Choose the right check
7
+
8
+ ```sh
9
+ npm run quality:static
10
+ npm run quality:core
11
+ npm run quality
12
+ ```
13
+
14
+ - `quality:static` checks formatting, code, CSS, Markdown, spelling, unused code,
15
+ types, Astro diagnostics, and dependency policy.
16
+ - `quality:core` adds coverage-enforced unit tests, a production build, and
17
+ required-output validation.
18
+ - `quality` adds Playwright browser/accessibility tests and Lighthouse budgets.
19
+
20
+ Use the focused command while developing and run `npm run quality` before
21
+ requesting review. The complete pipeline stops at the first failure.
22
+
23
+ ## Fix common failures
24
+
25
+ ### Installation fails
26
+
27
+ Confirm the Node.js and npm versions satisfy `package.json`, then retry the
28
+ committed graph:
29
+
30
+ ```sh
31
+ npm ci
32
+ ```
33
+
34
+ Do not delete or regenerate `package-lock.json` merely to bypass an error. If a
35
+ dependency intentionally changes, use npm to update the manifest and lockfile
36
+ together and review the resulting install scripts and package contents.
37
+
38
+ ### Formatting or linting fails
39
+
40
+ Apply the available safe fixes, then rerun the reported check:
41
+
42
+ ```sh
43
+ npm run format:fix
44
+ npm run lint:code:fix
45
+ npm run lint:css:fix
46
+ npm run lint:markdown:fix
47
+ ```
48
+
49
+ Spelling, type, accessibility, and behavioral failures require a deliberate
50
+ source or dictionary change; do not suppress them without documenting why.
51
+
52
+ ### Type checking or Astro diagnostics fail
53
+
54
+ Run `npm run typecheck` and `npm run astro:check` separately for focused output.
55
+ Check content front matter, import paths, component props, and the shared content
56
+ model before changing compiler settings.
57
+
58
+ ### A browser test fails
59
+
60
+ Install the browser version required by the committed Playwright package when
61
+ working on a new machine:
62
+
63
+ ```sh
64
+ npx playwright install chromium
65
+ ```
66
+
67
+ Rerun `npm run test:e2e`. Screenshots and traces are written to
68
+ `test-results/`; the HTML report is written to `playwright-report/`. Both are
69
+ generated and ignored. CI retains them for failed runs.
70
+
71
+ ### Lighthouse fails
72
+
73
+ Run `npm run lighthouse:ci` and inspect `.lighthouseci/`. Confirm the test used
74
+ the production build, then compare the failing route and resource type with
75
+ `docs/performance-budget.md`. Optimize the change or document a deliberately
76
+ reviewed budget revision; do not raise a threshold only to pass CI.
77
+
78
+ ### The build succeeds but output is incomplete
79
+
80
+ Run `npm run validate:build`. It verifies the required pages and supporting
81
+ files and scans generated text for unresolved starter values. Add an output to
82
+ the validator when introducing a route that is part of the public contract.
83
+
84
+ ### GitHub Pages does not deploy
85
+
86
+ Open the `Project` workflow first. Deployment is intentionally blocked unless
87
+ all quality jobs pass on `main`. If they pass, inspect the `github-pages`
88
+ environment, Pages source, branch restrictions, URL configuration, and deploy
89
+ job. Follow the [GitHub Pages guide](../github-pages.md) rather than bypassing
90
+ the quality dependency.
91
+
92
+ ## Review dependency updates
93
+
94
+ Dependabot proposes npm and GitHub Actions updates. Before merging one:
95
+
96
+ 1. read the upstream release notes and security advisory;
97
+ 2. confirm the supported Node.js range and licenses remain acceptable;
98
+ 3. review changes to `package.json` and `package-lock.json` together;
99
+ 4. keep Sveltia updates within the exact content-model compatibility range;
100
+ 5. run `npm run audit`, `npm run quality`, and any affected manual check; and
101
+ 6. merge only after project and security workflows pass.
102
+
103
+ Do not widen `@rm-industries/content-model` peer compatibility inside a
104
+ generated project. Forge publishes tested content-model compatibility first,
105
+ then template dependency automation can adopt it. Existing generated projects
106
+ remain owner-maintained source and do not receive template files automatically.
107
+
108
+ High-severity audit exceptions are documented narrowly in `audit-ci.jsonc` and
109
+ `docs/performance-budget.md`. Review their expiry and exposure; do not copy an
110
+ exception to silence an unrelated advisory.
111
+
112
+ ## Ask for help safely
113
+
114
+ When reporting a reproducible problem, include the Node.js and npm versions,
115
+ operating system, exact command, error output, and the smallest safe reproduction.
116
+ Remove tokens, repository secrets, private URLs, and unpublished content. Follow
117
+ the upstream Forge `SECURITY.md` process for vulnerabilities rather than opening
118
+ a public issue.
@@ -0,0 +1,85 @@
1
+ # Themes and accessibility
2
+
3
+ Forge starts with four Catppuccin themes, bundled fonts, semantic layout
4
+ components, keyboard navigation, reduced-motion behavior, and automated
5
+ accessibility checks. Customization must preserve those user-facing guarantees.
6
+
7
+ ## Choose a theme
8
+
9
+ The site follows the operating-system color preference: Latte is the default
10
+ light theme and Mocha is the dark theme. Theme definitions live in
11
+ `src/themes/`, and `src/components/theme/ThemeHead.astro` initializes them.
12
+
13
+ The available `data-theme` values are `latte`, `frappe`, `macchiato`, and
14
+ `mocha`. If a project adds a theme control, apply one of those values to the
15
+ document element, persist only a validated value, and retain an operating-system
16
+ fallback. Test the control with JavaScript disabled so content and navigation
17
+ remain usable.
18
+
19
+ ## Change colors or add a theme
20
+
21
+ Keep theme values in `src/themes/` instead of scattering colors through Astro
22
+ components. Update `src/themes/site-theme.test.ts` whenever the registered theme
23
+ set or light/dark defaults change.
24
+
25
+ Prefer DaisyUI component classes in templates. Use Tailwind utilities only for
26
+ layout or behavior that DaisyUI does not provide, and keep ordinary CSS in
27
+ `src/styles/global.css` or `src/styles/print.css`. Do not add component-local CSS
28
+ for patterns that belong to a shared primitive.
29
+
30
+ After changing a theme, inspect text, links, controls, focus indicators, code,
31
+ cards, and article typography in both color schemes. Then run:
32
+
33
+ ```sh
34
+ npm run lint:css
35
+ npm run test:e2e
36
+ npm run lighthouse:ci
37
+ ```
38
+
39
+ ## Replace fonts
40
+
41
+ Fira Sans and Fira Code are installed through Fontsource and imported by
42
+ `src/styles/global.css`; no remote font service is used. To replace them:
43
+
44
+ ```sh
45
+ npm uninstall @fontsource/fira-sans @fontsource/fira-code
46
+ npm install @fontsource/inter @fontsource/source-code-pro
47
+ ```
48
+
49
+ Replace the imports and the `--font-sans` and `--font-mono` values in
50
+ `src/styles/global.css`. Import only weights the site uses. For system fonts,
51
+ remove the Fontsource packages and imports and retain suitable generic fallback
52
+ families.
53
+
54
+ Run `npm run build` after changing fonts. Missing weights fail at build time;
55
+ unexpected transfer growth fails the Lighthouse budget.
56
+
57
+ ## Preserve layout semantics
58
+
59
+ - Wrap pages in `src/layouts/BaseLayout.astro`.
60
+ - Keep one level-one heading that identifies each page.
61
+ - Do not add a second `main` landmark inside the layout.
62
+ - Use real links and buttons rather than clickable generic elements.
63
+ - Preserve the skip link, visible focus states, current-page indication, and
64
+ named navigation.
65
+ - Use `navigation/Pagination.astro` only with real previous and next routes.
66
+ - Use the shared container and card primitives before creating a new variant.
67
+
68
+ ## Review accessibility
69
+
70
+ Automation catches many regressions but cannot judge wording, reading order,
71
+ alternative-text quality, or every visual state. After changing content,
72
+ navigation, themes, components, or interaction:
73
+
74
+ 1. run `npm run test:a11y`;
75
+ 2. complete `docs/accessibility-checklist.md` with the actual date, browsers,
76
+ screen sizes, input methods, and result;
77
+ 3. test keyboard-only use at desktop and mobile widths;
78
+ 4. inspect light, dark, reduced-motion, and print behavior; and
79
+ 5. record unresolved failures as issues rather than checking an unverified item.
80
+
81
+ The CMS interface is supplied by Sveltia and is outside the template's public
82
+ site audit. Evaluate that interface with the people who will edit the site.
83
+
84
+ See the [accessibility review checklist](../accessibility-checklist.md) and
85
+ [performance budget](../performance-budget.md) for the enforced baseline.