@activatus/code-standards 0.0.0-stage → 3.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.
Files changed (180) hide show
  1. package/README.md +199 -2
  2. package/docs/Guides/_category_.json +4 -0
  3. package/docs/Guides/component-library-workflow.md +182 -0
  4. package/docs/Guides/migrating.md +161 -0
  5. package/docs/Guides/setup.md +158 -0
  6. package/docs/Standards/_category_.json +4 -0
  7. package/docs/Standards/agent-skills.md +125 -0
  8. package/docs/Standards/agent-specs.md +74 -0
  9. package/docs/Standards/direnv.mdx +249 -0
  10. package/docs/Standards/documentation.md +314 -0
  11. package/docs/Standards/editorconfig.md +74 -0
  12. package/docs/Standards/eslint.md +900 -0
  13. package/docs/Standards/human-readable-names.md +274 -0
  14. package/docs/Standards/lint-errors.md +171 -0
  15. package/docs/Standards/prettier.md +106 -0
  16. package/docs/Standards/readable-code.md +570 -0
  17. package/docs/Standards/stylelint.md +193 -0
  18. package/docs/Standards/styling.md +290 -0
  19. package/docs/Standards/tech-stack.md +158 -0
  20. package/docs/Structure/_category_.json +4 -0
  21. package/docs/Structure/api-routes.md +118 -0
  22. package/docs/Structure/component-organization.md +526 -0
  23. package/docs/Structure/folder-structure.md +366 -0
  24. package/docs/Structure/import-organization.md +158 -0
  25. package/docs/Structure/naming-conventions.md +334 -0
  26. package/docs/design-system-components.md +117 -0
  27. package/docs/intro.md +44 -0
  28. package/docs/ontology.md +127 -0
  29. package/docs/templates.mdx +396 -0
  30. package/docs/version-history.md +338 -0
  31. package/package.json +60 -3
  32. package/scripts/renameSymbol.mjs +188 -0
  33. package/static/templates/.editorconfig +25 -0
  34. package/static/templates/.envrc +25 -0
  35. package/static/templates/.nvmrc +1 -0
  36. package/static/templates/AGENTS.md +163 -0
  37. package/static/templates/decision-doc.md +19 -0
  38. package/static/templates/docs/ai/agent-harness.md +17 -0
  39. package/static/templates/docs/ai/agents.md +17 -0
  40. package/static/templates/docs/ai/architecture.md +17 -0
  41. package/static/templates/docs/ai/context.md +17 -0
  42. package/static/templates/docs/ai/model-routing.md +17 -0
  43. package/static/templates/docs/ai/models.md +17 -0
  44. package/static/templates/docs/ai/retrieval.md +17 -0
  45. package/static/templates/docs/ai/tools.md +17 -0
  46. package/static/templates/docs/architecture/authentication.md +17 -0
  47. package/static/templates/docs/architecture/backend.md +17 -0
  48. package/static/templates/docs/architecture/background-jobs.md +17 -0
  49. package/static/templates/docs/architecture/backups.md +17 -0
  50. package/static/templates/docs/architecture/caching.md +17 -0
  51. package/static/templates/docs/architecture/ci-cd.md +17 -0
  52. package/static/templates/docs/architecture/disaster-recovery.md +17 -0
  53. package/static/templates/docs/architecture/environments.md +17 -0
  54. package/static/templates/docs/architecture/frontend.md +17 -0
  55. package/static/templates/docs/architecture/hosting.md +17 -0
  56. package/static/templates/docs/architecture/observability.md +17 -0
  57. package/static/templates/docs/architecture/realtime.md +17 -0
  58. package/static/templates/docs/architecture/search.md +17 -0
  59. package/static/templates/docs/architecture/services.md +17 -0
  60. package/static/templates/docs/architecture/state-management.md +17 -0
  61. package/static/templates/docs/architecture/storage.md +17 -0
  62. package/static/templates/docs/architecture/system.md +17 -0
  63. package/static/templates/docs/business/buying-trigger.md +17 -0
  64. package/static/templates/docs/business/customer-value.md +17 -0
  65. package/static/templates/docs/business/customer.md +17 -0
  66. package/static/templates/docs/business/defensibility.md +17 -0
  67. package/static/templates/docs/business/growth.md +17 -0
  68. package/static/templates/docs/business/pricing.md +17 -0
  69. package/static/templates/docs/business/revenue-model.md +17 -0
  70. package/static/templates/docs/business/unit-economics.md +17 -0
  71. package/static/templates/docs/data/analytics.md +17 -0
  72. package/static/templates/docs/data/audit.md +17 -0
  73. package/static/templates/docs/data/database.md +17 -0
  74. package/static/templates/docs/data/indexing.md +17 -0
  75. package/static/templates/docs/data/migrations.md +17 -0
  76. package/static/templates/docs/data/model.md +17 -0
  77. package/static/templates/docs/data/retention.md +17 -0
  78. package/static/templates/docs/data/schema.md +17 -0
  79. package/static/templates/docs/deployment/approval.md +17 -0
  80. package/static/templates/docs/deployment/live-verification.md +17 -0
  81. package/static/templates/docs/deployment/process.md +17 -0
  82. package/static/templates/docs/deployment/rollback.md +17 -0
  83. package/static/templates/docs/design/design-system.md +17 -0
  84. package/static/templates/docs/design/errors.md +17 -0
  85. package/static/templates/docs/design/feedback.md +17 -0
  86. package/static/templates/docs/design/interactions.md +17 -0
  87. package/static/templates/docs/design/layout.md +17 -0
  88. package/static/templates/docs/design/navigation.md +17 -0
  89. package/static/templates/docs/design/principles.md +17 -0
  90. package/static/templates/docs/design/responsive.md +17 -0
  91. package/static/templates/docs/development/branching.md +17 -0
  92. package/static/templates/docs/development/code-quality.md +17 -0
  93. package/static/templates/docs/development/coding-standards.md +21 -0
  94. package/static/templates/docs/development/commits.md +17 -0
  95. package/static/templates/docs/development/merge-strategy.md +17 -0
  96. package/static/templates/docs/development/process.md +17 -0
  97. package/static/templates/docs/development/pull-requests.md +17 -0
  98. package/static/templates/docs/experience/accessibility.md +17 -0
  99. package/static/templates/docs/experience/aha-moment.md +17 -0
  100. package/static/templates/docs/experience/anti-experience.md +17 -0
  101. package/static/templates/docs/experience/friction.md +17 -0
  102. package/static/templates/docs/experience/outcomes.md +17 -0
  103. package/static/templates/docs/experience/principles.md +17 -0
  104. package/static/templates/docs/experience/retention.md +17 -0
  105. package/static/templates/docs/experience/sharing.md +17 -0
  106. package/static/templates/docs/overview/how-it-works.md +17 -0
  107. package/static/templates/docs/overview/what-is-it.md +17 -0
  108. package/static/templates/docs/overview/writing-docs.md +16 -0
  109. package/static/templates/docs/pitch/alternatives.md +17 -0
  110. package/static/templates/docs/pitch/assumptions.md +17 -0
  111. package/static/templates/docs/pitch/audience.md +17 -0
  112. package/static/templates/docs/pitch/concept.md +17 -0
  113. package/static/templates/docs/pitch/differentiators.md +17 -0
  114. package/static/templates/docs/pitch/outcomes.md +17 -0
  115. package/static/templates/docs/pitch/problem.md +17 -0
  116. package/static/templates/docs/pitch/product-market-fit.md +17 -0
  117. package/static/templates/docs/pitch/success-criteria.md +17 -0
  118. package/static/templates/docs/pitch/validation.md +17 -0
  119. package/static/templates/docs/pitch/value-proposition.md +17 -0
  120. package/static/templates/docs/pitch/vision.md +17 -0
  121. package/static/templates/docs/scope/core.md +17 -0
  122. package/static/templates/docs/scope/exclusions.md +17 -0
  123. package/static/templates/docs/scope/future.md +17 -0
  124. package/static/templates/docs/scope/launch.md +17 -0
  125. package/static/templates/docs/scope/post-launch.md +17 -0
  126. package/static/templates/docs/scope/priorities.md +17 -0
  127. package/static/templates/docs/scope/quality-bar.md +17 -0
  128. package/static/templates/docs/security/audit.md +17 -0
  129. package/static/templates/docs/security/data-access.md +17 -0
  130. package/static/templates/docs/security/logging.md +17 -0
  131. package/static/templates/docs/security/privacy.md +17 -0
  132. package/static/templates/docs/security/secrets.md +17 -0
  133. package/static/templates/docs/security/threat-model.md +17 -0
  134. package/static/templates/docs/testing/end-to-end.md +17 -0
  135. package/static/templates/docs/testing/integration.md +17 -0
  136. package/static/templates/docs/testing/regression.md +17 -0
  137. package/static/templates/docs/testing/security.md +17 -0
  138. package/static/templates/docs/testing/strategy.md +17 -0
  139. package/static/templates/docs/testing/test-data.md +17 -0
  140. package/static/templates/docs/testing/unit.md +17 -0
  141. package/static/templates/docs/uat/checks.md +17 -0
  142. package/static/templates/docs/uat/strategy.md +17 -0
  143. package/static/templates/docs/users/permissions.md +17 -0
  144. package/static/templates/docs/users/roles.md +17 -0
  145. package/static/templates/docs/users/user-types.md +17 -0
  146. package/static/templates/docs/workflows/assignment.md +17 -0
  147. package/static/templates/docs/workflows/bugfix.md +17 -0
  148. package/static/templates/docs/workflows/dependencies.md +17 -0
  149. package/static/templates/docs/workflows/deployment.md +17 -0
  150. package/static/templates/docs/workflows/development.md +17 -0
  151. package/static/templates/docs/workflows/planning.md +17 -0
  152. package/static/templates/docs/workflows/review.md +17 -0
  153. package/static/templates/docs/workflows/uat.md +17 -0
  154. package/static/templates/docsSite/docusaurus.config.mjs +144 -0
  155. package/static/templates/docsSite/gitignore.txt +3 -0
  156. package/static/templates/docsSite/package.json.txt +42 -0
  157. package/static/templates/docsSite/pnpm-workspace.yaml +2 -0
  158. package/static/templates/docsSite/sidebars.mjs +7 -0
  159. package/static/templates/docsSite/src/css/custom.css +7 -0
  160. package/static/templates/docsSite/src/pages/index.tsx +9 -0
  161. package/static/templates/docsSite/static/images/logo.svg +4 -0
  162. package/static/templates/docsSite/tsconfig.json +7 -0
  163. package/static/templates/eslint/base/eslint.config.mjs +104 -0
  164. package/static/templates/eslint/nextjs/eslint.config.mjs +181 -0
  165. package/static/templates/eslint/react/eslint.config.mjs +173 -0
  166. package/static/templates/eslint/typescript/eslint.config.mjs +154 -0
  167. package/static/templates/globals.css +16 -0
  168. package/static/templates/husky/pre-commit +1 -0
  169. package/static/templates/next.config.mjs +21 -0
  170. package/static/templates/prettier.config.mjs +26 -0
  171. package/static/templates/skills/codeReview.md +31 -0
  172. package/static/templates/skills/format.md +18 -0
  173. package/static/templates/skills/lint.md +21 -0
  174. package/static/templates/skills/lintFix.md +24 -0
  175. package/static/templates/skills/securityAudit.md +28 -0
  176. package/static/templates/skills/test.md +24 -0
  177. package/static/templates/skills/typescript.md +28 -0
  178. package/static/templates/skills/updateLayout.md +20 -0
  179. package/static/templates/stylelint/css/stylelint.config.mjs +40 -0
  180. package/static/templates/stylelint/scss/stylelint.config.mjs +13 -0
@@ -0,0 +1,193 @@
1
+ ---
2
+ sidebar_position: 5
3
+ sidebar_label: "Stylelint"
4
+ ---
5
+
6
+ # Stylelint Configuration
7
+
8
+ Components are styled with [Tailwind CSS](/Standards/styling), and Stylelint lints the CSS that is still written by hand — `globals.css` and any CSS Modules. Start from the config below that matches the project:
9
+
10
+ | Config | Use when |
11
+ | --------------------------------------- | ----------------------------------------- |
12
+ | [Plain CSS](#plain-css-and-css-modules) | Plain CSS and CSS Modules (`.module.css`) |
13
+ | [SCSS](#scss) | SCSS / Sass |
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pnpm add -D stylelint stylelint-config-standard stylelint-config-recess-order
19
+ ```
20
+
21
+ For SCSS projects, install `stylelint-config-standard-scss` in place of `stylelint-config-standard`:
22
+
23
+ ```bash
24
+ pnpm add -D stylelint stylelint-config-standard-scss stylelint-config-recess-order
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Create `stylelint.config.mjs` in your project root:
30
+
31
+ ### Plain CSS and CSS Modules
32
+
33
+ ```js title="stylelint.config.mjs"
34
+ /** @type {import("stylelint").Config} */
35
+ export default {
36
+ ignoreFiles: ["**/vendor/**"],
37
+ extends: [
38
+ "stylelint-config-standard",
39
+ "stylelint-config-recess-order",
40
+ ],
41
+ rules: {
42
+ "selector-max-id": 0,
43
+ "property-no-vendor-prefix": true,
44
+ "color-function-notation": "modern",
45
+ "import-notation": "string",
46
+ "at-rule-no-unknown": [
47
+ true,
48
+ {
49
+ ignoreAtRules: [
50
+ "theme",
51
+ "utility",
52
+ "variant",
53
+ "custom-variant",
54
+ "source",
55
+ "plugin",
56
+ ],
57
+ },
58
+ ],
59
+ },
60
+ overrides: [
61
+ {
62
+ files: ["**/*.module.css"],
63
+ rules: {
64
+ "color-named": "never",
65
+ "color-no-hex": true,
66
+ "selector-class-pattern": [
67
+ "^[a-z][a-zA-Z0-9]*$",
68
+ { message: "Expected class selector to be camelCase" },
69
+ ],
70
+ },
71
+ },
72
+ ],
73
+ };
74
+ ```
75
+
76
+ ### SCSS
77
+
78
+ ```js title="stylelint.config.mjs"
79
+ /** @type {import("stylelint").Config} */
80
+ export default {
81
+ ignoreFiles: ["**/vendor/**"],
82
+ extends: [
83
+ "stylelint-config-standard-scss",
84
+ "stylelint-config-recess-order",
85
+ ],
86
+ rules: {
87
+ "selector-max-id": 0,
88
+ "property-no-vendor-prefix": true,
89
+ "color-function-notation": "modern",
90
+ },
91
+ };
92
+ ```
93
+
94
+ ### Project-specific overrides
95
+
96
+ Add to the `rules` block:
97
+
98
+ ```js
99
+ export default {
100
+ // ...
101
+ rules: {
102
+ // ...
103
+ // project-specific overrides
104
+ "selector-max-type": 3,
105
+ },
106
+ };
107
+ ```
108
+
109
+ Add a lint script to `package.json`:
110
+
111
+ ```json
112
+ {
113
+ "scripts": {
114
+ "lint:css": "stylelint \"**/*.{css,scss}\"",
115
+ "lint:css:fix": "stylelint \"**/*.{css,scss}\" --fix"
116
+ }
117
+ }
118
+ ```
119
+
120
+ ## Extended configs
121
+
122
+ | Config | Used by | Purpose |
123
+ | -------------------------------- | ------------------------- | ---------------------------------------- |
124
+ | `stylelint-config-standard` | Plain CSS and CSS Modules | Stylelint's recommended modern CSS rules |
125
+ | `stylelint-config-standard-scss` | SCSS | Standard rules + SCSS-specific rules |
126
+ | `stylelint-config-recess-order` | all | Enforces Bootstrap/RECESS property order |
127
+
128
+ ## Property order
129
+
130
+ Properties are sorted using the [RECESS order](https://github.com/stordahl/stylelint-config-recess-order) (the same order used by Bootstrap). The broad grouping:
131
+
132
+ 1. Positioning (`position`, `top`, `z-index`, …)
133
+ 2. Box model (`display`, `width`, `margin`, `padding`, …)
134
+ 3. Typography (`font`, `line-height`, `color`, …)
135
+ 4. Visual (`background`, `border`, `opacity`, …)
136
+ 5. Misc (`transition`, `animation`, …)
137
+
138
+ ## Key rule decisions
139
+
140
+ ### `selector-max-id: 0`
141
+
142
+ ID selectors create specificity that is nearly impossible to override without escalating to `!important`. Use classes instead.
143
+
144
+ ### `property-no-vendor-prefix: true`
145
+
146
+ Vendor prefixes should be added by **Autoprefixer** in the build pipeline, not written by hand. Hand-written prefixes become stale as browser support improves. Configure Autoprefixer with a Browserslist query instead.
147
+
148
+ ### `color-function-notation: "modern"`
149
+
150
+ Enforces `rgb(255 0 0 / 50%)` instead of `rgba(255, 0, 0, 0.5)`. The modern syntax is part of CSS Color Level 4 and is supported in all modern browsers.
151
+
152
+ ### `ignoreFiles`: third-party code is exempt
153
+
154
+ CSS in a `vendor/` folder is not ours, so it is not linted. See [Third-party code is exempt](/Standards/eslint#third-party-code-is-exempt).
155
+
156
+ ### Tailwind: `import-notation: "string"` and `at-rule-no-unknown`
157
+
158
+ `stylelint-config-standard` rejects `@import "tailwindcss"` and does not know Tailwind's at-rules. These two settings allow the import and the `@theme`, `@utility`, `@variant`, `@custom-variant`, `@source` and `@plugin` at-rules.
159
+
160
+ ### Custom properties: kebab-case
161
+
162
+ `stylelint-config-standard` requires CSS variables to be kebab-case (`--color-brand-primary`). See [CSS Styling](/Standards/styling#css-variables).
163
+
164
+ ### CSS Modules: `color-named: never` and `color-no-hex`
165
+
166
+ Colours come from the [global colour variables](/Standards/styling#-colours-always-come-from-global-variables). A CSS Module may not contain `white` or `#3b82f6` — it references `var(--color-white)` or `var(--color-brand-primary)`. Colour values are only written in `globals.css`.
167
+
168
+ ### CSS Modules: `selector-class-pattern: camelCase`
169
+
170
+ CSS Modules are consumed in JavaScript as `styles.myClass`. Kebab-case names require bracket notation (`styles["my-class"]`), which is easy to mistype. camelCase names allow dot notation and are consistent with JavaScript naming conventions.
171
+
172
+ ### SCSS: `scss/load-no-partial-leading-underscore`
173
+
174
+ Leading underscores on `@import` paths are a Sass 1.x convention for marking partials. With `@use` and `@forward` (the modern Sass module system), the underscore is handled automatically — including it manually in `@use` paths is an error. `stylelint-config-standard-scss` enforces this.
175
+
176
+ ## Editor integration
177
+
178
+ ### VS Code
179
+
180
+ Install the [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) extension, then add to workspace settings:
181
+
182
+ ```json
183
+ {
184
+ "stylelint.validate": ["css", "scss"],
185
+ "editor.codeActionsOnSave": {
186
+ "source.fixAll.stylelint": "explicit"
187
+ }
188
+ }
189
+ ```
190
+
191
+ ### JetBrains IDEs
192
+
193
+ Go to **Settings → Languages & Frameworks → Style Sheets → Stylelint** and enable it.
@@ -0,0 +1,290 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # CSS Styling
6
+
7
+ Standards for styling React components and applications.
8
+
9
+ ---
10
+
11
+ ## 🎨 Tailwind CSS
12
+
13
+ Use Tailwind CSS utility classes for all component styling. Tailwind is compatible with React Server Components and is the foundation [shadcn/ui](/Guides/component-library-workflow) is built on.
14
+
15
+ ```tsx
16
+ // Button.tsx
17
+ export const Button = () => {
18
+ return (
19
+ <button className="rounded-md bg-brand-primary px-8 py-4 text-white transition-colors hover:bg-brand-primary-hover">
20
+ Click me
21
+ </button>
22
+ );
23
+ };
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 📐 Layout: Flexbox First
29
+
30
+ **Build every layout with flexbox.** Reach for `flex` first, and split the layout into child components so each one styles only itself.
31
+
32
+ **Only use CSS grid when it is specifically asked for.**
33
+
34
+ ### ✅ Flex parent, child components
35
+
36
+ The parent arranges its children with flex. Each child is its own component with its own styles:
37
+
38
+ ```tsx title="pageHeader/PageHeader.tsx"
39
+ import { PageHeaderActions } from "./pageHeaderActions";
40
+ import { PageHeaderTitle } from "./pageHeaderTitle";
41
+
42
+ export const PageHeader = () => {
43
+ return (
44
+ <header className="flex items-center justify-between gap-4">
45
+ <PageHeaderTitle />
46
+ <PageHeaderActions />
47
+ </header>
48
+ );
49
+ };
50
+ ```
51
+
52
+ ```tsx title="pageHeader/pageHeaderActions/PageHeaderActions.tsx"
53
+ export const PageHeaderActions = () => {
54
+ return (
55
+ <div className="flex items-center gap-2">
56
+ <button className="rounded-md bg-brand-primary px-4 py-2 text-white">
57
+ Save
58
+ </button>
59
+ <button className="rounded-md px-4 py-2 text-text">
60
+ Cancel
61
+ </button>
62
+ </div>
63
+ );
64
+ };
65
+ ```
66
+
67
+ ### ❌ One component styling everything
68
+
69
+ ```tsx
70
+ // ❌ Bad — grid without being asked, and every piece styled in one place
71
+ export const PageHeader = () => {
72
+ return (
73
+ <header className="grid grid-cols-[1fr_auto] items-center gap-4">
74
+ <div className="flex flex-col gap-1">
75
+ <h1 className="text-2xl font-semibold text-text">Invoices</h1>
76
+ <p className="text-sm text-text">
77
+ All invoices for this account
78
+ </p>
79
+ </div>
80
+ <div className="flex items-center gap-2">
81
+ <button className="rounded-md bg-brand-primary px-4 py-2 text-white">
82
+ Save
83
+ </button>
84
+ <button className="rounded-md px-4 py-2 text-text">
85
+ Cancel
86
+ </button>
87
+ </div>
88
+ </header>
89
+ );
90
+ };
91
+ ```
92
+
93
+ ### Rules
94
+
95
+ - **Flex first.** `flex`, `flex-col`, `gap-*`, `items-*` and `justify-*` cover almost every layout.
96
+ - **The parent positions, the child styles itself.** A parent sets direction, spacing and alignment. Each child component owns its own padding, colour and typography.
97
+ - **Split into child components** rather than growing one long `className` or a deep tree of `div`s. Each child gets [its own folder](/Structure/component-organization#nested-components).
98
+ - **Space with `gap`**, not margins on the children.
99
+ - **Grid only when asked.** Do not choose CSS grid on your own — use it only when the task specifically asks for a grid.
100
+
101
+ ---
102
+
103
+ ## ❌ Avoid These
104
+
105
+ - ❌ **CSS grid**, unless it was specifically asked for
106
+
107
+ - ❌ **Hard-coded colours** — hex, `rgb()` or named colours anywhere outside the theme
108
+ - ❌ **Arbitrary colour values** (`bg-[#3b82f6]`) — if the colour is not in the palette, it is not used
109
+ - ❌ **Inline styles** (except for dynamic values)
110
+ - ❌ **Styled-components or emotion** (not compatible with RSC)
111
+ - ❌ **Global CSS files for component styles**
112
+
113
+ ---
114
+
115
+ ## ✅ Colours Always Come From Global Variables
116
+
117
+ **Strictly follow the global colour palette.** Every colour is defined **once**, as a global colour variable in the theme. Components never contain a colour value — they reference a variable.
118
+
119
+ The palette is two things, and nothing else:
120
+
121
+ - **Tailwind's built-in colours** (`bg-white`, `text-slate-900`, `border-blue-500`) — allowed
122
+ - **Project colours** added to the `@theme` block (`bg-brand-primary`)
123
+
124
+ A colour that is in neither is not used. If a design calls for a new colour, add it to the global palette first — never write a one-off value in a component.
125
+
126
+ ### ✅ Define the colours
127
+
128
+ Each project defines its colours once, in its global stylesheet:
129
+
130
+ ```css
131
+ /* app/globals.css */
132
+ @import "tailwindcss";
133
+
134
+ @theme {
135
+ --color-brand-primary: #3b82f6;
136
+ --color-brand-primary-hover: #2563eb;
137
+ --color-brand-secondary: #64748b;
138
+ --color-surface: #fff;
139
+ --color-text: #0f172a;
140
+ }
141
+
142
+ [data-theme="dark"] {
143
+ --color-brand-primary: #60a5fa;
144
+ --color-brand-primary-hover: #93c5fd;
145
+ --color-surface: #0f172a;
146
+ --color-text: #f8fafc;
147
+ }
148
+ ```
149
+
150
+ Tailwind turns every `--color-*` variable in `@theme` into utility classes: `--color-brand-primary` becomes `bg-brand-primary`, `text-brand-primary`, `border-brand-primary` and so on.
151
+
152
+ The project's design decisions — what each colour is for, the fonts, the spacing — are recorded in its `docs/design/design-system.md` [Decision Doc](/Standards/documentation).
153
+
154
+ ### ✅ Use the colours
155
+
156
+ ```tsx
157
+ // ✅ Good — colours come from the theme
158
+ <p className="bg-surface text-text">Hello</p>
159
+ <button className="bg-brand-primary text-white">Save</button>
160
+
161
+ // ❌ Bad — colours hard-coded in the component
162
+ <p className="bg-[#fff] text-[#0f172a]">Hello</p>
163
+ <button style={{ background: "#3b82f6", color: "white" }}>Save</button>
164
+ ```
165
+
166
+ When you do write CSS by hand, reference the variable — never the value:
167
+
168
+ ```css
169
+ /* ✅ Good */
170
+ .chart {
171
+ color: var(--color-white);
172
+ background: var(--color-brand-primary);
173
+ }
174
+
175
+ /* ❌ Bad */
176
+ .chart {
177
+ color: white;
178
+ background: #3b82f6;
179
+ }
180
+ ```
181
+
182
+ Tailwind's built-in colours are variables too — `white` is `var(--color-white)`.
183
+
184
+ ---
185
+
186
+ ## 💡 Best Practices
187
+
188
+ ### Tailwind utilities
189
+
190
+ - **Use for**: All component styling
191
+ - **Layout**: Flexbox first; grid only when specifically asked
192
+ - **Colours**: Global palette only — Tailwind colours and project colours from `@theme` — never arbitrary values
193
+ - **Long class lists**: Extract a component, not a CSS class
194
+ - **Conditional classes**: Use `clsx`
195
+ - **Class order**: Sorted automatically by [Prettier](/Standards/prettier#tailwind-class-sorting) — do not sort by hand
196
+
197
+ ### Global CSS
198
+
199
+ - **Use for**: The Tailwind import, the `@theme` block, theme overrides, global resets
200
+ - **Location**: `app/globals.css`
201
+ - **Avoid**: Component-specific styles
202
+ - **Import only**: In the root layout
203
+
204
+ ### CSS Modules
205
+
206
+ - **Use for**: The rare style Tailwind cannot express (complex keyframe animations, third-party overrides)
207
+ - **File naming**: `componentName.module.css`
208
+ - **Colours**: `var(--color-*)` only — Stylelint rejects hex and named colours in CSS Modules
209
+ - **Import**: Co-located with component
210
+
211
+ ### Inline Styles
212
+
213
+ - **Use for**: Dynamic values only (e.g., `style={{ height: sliderValue }}`)
214
+ - **Avoid**: Static styles that should be Tailwind utilities
215
+
216
+ ---
217
+
218
+ ## 📁 File Organization
219
+
220
+ ### Component Styles
221
+
222
+ Styles live in the component's `className` — there is no separate style file:
223
+
224
+ ```text
225
+ components/
226
+ └── button/
227
+ ├── Button.tsx
228
+ ├── Button.test.tsx
229
+ └── index.ts
230
+ ```
231
+
232
+ ### Global Styles
233
+
234
+ ```text
235
+ app/
236
+ ├── globals.css # Tailwind import, @theme colour variables, resets
237
+ ├── layout.tsx
238
+ └── page.tsx
239
+ ```
240
+
241
+ ---
242
+
243
+ ## 🎯 Naming Conventions
244
+
245
+ ### CSS Variables
246
+
247
+ **Use kebab-case for variable names.** This is the CSS convention, it is what Tailwind's theme namespaces (`--color-*`, `--spacing-*`, `--font-*`) require, and Stylelint enforces it.
248
+
249
+ ```css
250
+ /* ✅ Good */
251
+ --color-brand-primary: #3b82f6;
252
+ --spacing-unit: 0.25rem;
253
+ --radius-card: 0.5rem;
254
+
255
+ /* ❌ Bad */
256
+ --colorBrandPrimary: #3b82f6;
257
+ --spacing_unit: 0.25rem;
258
+ --RadiusCard: 0.5rem;
259
+ ```
260
+
261
+ Name colours by **role**, not by value: `--color-brand-primary`, not `--color-blue`.
262
+
263
+ ### CSS Modules
264
+
265
+ **Use camelCase for class names**, because they are read in JavaScript as `styles.primaryButton`:
266
+
267
+ ```css
268
+ /* ✅ Good */
269
+ .button {
270
+ }
271
+ .primaryButton {
272
+ }
273
+ .submitButton {
274
+ }
275
+
276
+ /* ❌ Bad */
277
+ .primary-button {
278
+ }
279
+ .submit_button {
280
+ }
281
+ ```
282
+
283
+ ---
284
+
285
+ ## 📚 Related Documentation
286
+
287
+ - [Stylelint](/Standards/stylelint) - Linting for hand-written CSS
288
+ - [Component Organization](/Structure/component-organization) - How to organize component files
289
+ - [Folder Structure](/Structure/folder-structure) - Overall project structure
290
+ - [Naming Conventions](/Structure/naming-conventions) - File and folder naming rules
@@ -0,0 +1,158 @@
1
+ ---
2
+ sidebar_position: 11
3
+ ---
4
+
5
+ # Tech Stack
6
+
7
+ Standard technology choices for Activatus projects.
8
+
9
+ ---
10
+
11
+ ## 📋 Standard Stack
12
+
13
+ - **Framework**: Next.js 16 (App Router)
14
+ - **Language**: TypeScript 7
15
+ - **Package Manager**: pnpm (monorepo: workspaces)
16
+ - **Styling**: Tailwind CSS
17
+ - **Node Version**: `^22.11 || ^24 || >=26`
18
+ - **Build Tool**: Turbopack (Next.js built-in)
19
+
20
+ ### TypeScript 7
21
+
22
+ TypeScript 7 is the compiler rewritten in Go. It is a drop-in replacement for
23
+ the JavaScript implementation for compiling and type-checking, but two things
24
+ change for tooling:
25
+
26
+ - **There is no `tsserver`.** The compiler is its own language server, started
27
+ with `tsc --lsp --stdio`. Editors and tools that drove TypeScript through
28
+ `typescript-language-server` have nothing to drive; they talk to `tsc`
29
+ directly instead.
30
+ - **It answers diagnostics on request.** TypeScript 7 supports LSP pull
31
+ diagnostics, so a client that only waits for a `publishDiagnostics` push can
32
+ sit there believing a file is clean.
33
+
34
+ ### Parameterise a library's generics
35
+
36
+ A generic whose default is a permissive index signature returns `any` at every use, and
37
+ the code reads as though it were typed. Storyblok's story type is the one to watch:
38
+
39
+ ```ts
40
+ // storyblok-js-client
41
+ interface ISbStoryData<
42
+ Content = ISbComponentType<string> & { [index: string]: any },
43
+ > {
44
+ content: Content;
45
+ // …
46
+ }
47
+ ```
48
+
49
+ Left bare, `ISbStoryData` makes `story.content` that `any`-indexed fallback. Every field
50
+ access resolves, nothing is checked, and a renamed block field fails in the browser
51
+ rather than in CI. Declare the block and pass it:
52
+
53
+ ```ts
54
+ export interface HeroBlokType extends ISbComponentType<"hero"> {
55
+ headline: string;
56
+ subhead?: string;
57
+ callToAction?: CallToActionBlokType[];
58
+ }
59
+
60
+ // story.content.headline is string; story.content.headlien is a compile error.
61
+ const story: ISbStoryData<HeroBlokType> = await getStory();
62
+ ```
63
+
64
+ The parameter flows, so the surrounding types carry it too — `ISbResult`'s
65
+ `data.stories` becomes `ISbStoryData<HeroBlokType>[]`. Where a story can hold one of several
66
+ blocks, make `Content` a discriminated union on `component` and switch on it.
67
+
68
+ Extend the published type rather than restating its fields: `ISbComponentType<"hero">`
69
+ already contributes `_uid`, `component` and `_editable`, and a hand-written copy drifts
70
+ the moment the library changes.
71
+
72
+ Read every library generic this way. An unparameterised one with a permissive default is
73
+ usually a silent `any`, not a sensible fallback. The [`/typescript` skill](/Standards/agent-skills)
74
+ applies this as a rule.
75
+
76
+ ---
77
+
78
+ ## 🧪 Testing Stack
79
+
80
+ - **Unit Testing**: Vitest
81
+ - **Component Testing**: @testing-library/react
82
+ - **E2E Testing**: Playwright
83
+ - **Coverage**: @vitest/coverage-v8
84
+
85
+ ---
86
+
87
+ ## 🗄️ Database & Backend
88
+
89
+ - **Database**: Supabase (PostgreSQL)
90
+ - **ORM**: Supabase client (direct)
91
+ - **Validation**: Zod schemas
92
+
93
+ ---
94
+
95
+ ## ⚛️ State Management
96
+
97
+ - **Server State**: @tanstack/react-query
98
+ - **Global State**: Zustand
99
+ - **Form State**: @tanstack/react-form
100
+
101
+ ---
102
+
103
+ ## 📦 Package Versions
104
+
105
+ See `package.json` for specific version requirements. Key dependencies:
106
+
107
+ ```json
108
+ {
109
+ "dependencies": {
110
+ "next": "^16.3.5",
111
+ "react": "^19.3.0",
112
+ "@tanstack/react-query": "^5.85.5",
113
+ "zustand": "^5.0.7"
114
+ },
115
+ "devDependencies": {
116
+ "typescript": "^7.0.2",
117
+ "vitest": "^2.1.8",
118
+ "@testing-library/react": "^16.1.0",
119
+ "playwright": "^1.63.0"
120
+ }
121
+ }
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 🎨 UI Libraries
127
+
128
+ - **Design System**: Custom (Radix UI primitives)
129
+ - **Icons**: Lucide React
130
+ - **Forms**: React Hook Form
131
+ - **Tables**: TanStack Table
132
+
133
+ ---
134
+
135
+ ## 🔧 Development Tools
136
+
137
+ - **Linting**: ESLint 9+
138
+ - **Formatting**: Prettier
139
+ - **Git Hooks**: Husky
140
+ - **Monorepo**: Turborepo
141
+ - **Documentation**: Docusaurus
142
+
143
+ ---
144
+
145
+ ## Version Requirements
146
+
147
+ ### Node.js
148
+
149
+ - **Consumer minimum**: 20.0.0, matching the packages' `engines` requirement
150
+ - **Repository version**: 24, pinned in `.nvmrc`
151
+ - **Package manager minimum for consumers**: pnpm 9, matching the root `engines` requirement
152
+ - **Repository package manager**: pnpm 11.23.0, pinned in `package.json#packageManager`
153
+
154
+ ### TypeScript
155
+
156
+ - **Version**: 5.0+
157
+ - **Strict Mode**: Enabled
158
+ - **Target**: ES2022+
@@ -0,0 +1,4 @@
1
+ {
2
+ "label": "Structure",
3
+ "position": 7
4
+ }