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