+ &__body { ... } //
+}
+// Removed &__toggle-buttons because no component uses it
+```
+
+### How to Detect
+
+1. For each selector in a changed or reviewed SCSS/CSS file, search the codebase for a corresponding `className` usage (e.g., grep for the resolved class name in TSX/JSX files).
+2. Flag any selector with zero references — it is likely orphaned from a previous refactor.
+3. Pay special attention to nested BEM selectors (`&__element`, `&--modifier`) whose parent block exists but the specific element or modifier is no longer rendered.
+
+**Scope note:** Full codebase verification is expensive during manual review. Focus on CSS rules within files changed in the current PR.
\ No newline at end of file
diff --git a/.agents/review-checklists/react/performance.md b/.agents/review-checklists/react/performance.md
new file mode 100644
index 0000000000..be604c27ee
--- /dev/null
+++ b/.agents/review-checklists/react/performance.md
@@ -0,0 +1,144 @@
+# Rule Catalog — Performance
+
+> **Prerequisite:** Review and apply the common guidelines in [`common.md`](../common.md) before using this checklist.
+
+## Inline object/array literals in JSX props
+
+**Urgency:** urgent
+
+### Category
+
+Maintainability
+
+### Confidence Threshold
+
+Flag when referential identity matters in the changed code (for example, prop passed to a memoized child, dependency-sensitive hook, or effectful child) or when re-renders are already a known issue. If the child is not memoized and the object is tiny, prefer a suggestion or no comment.
+
+### Exceptions / False Positives
+
+- Do not flag inline literals passed to non-memoized children when there is no evidence that referential identity affects behavior or performance.
+- Do not require `useMemo` for values that are truly static and can simply be hoisted to module scope instead.
+- Avoid adding `useMemo` by default when it meaningfully harms readability and there is no demonstrated performance concern.
+
+### Description
+
+Do not pass inline object or array literals directly as JSX props. Each render creates a new reference, causing child components to re-render even when the values haven't changed. Extract the value into a `useMemo` (or a module-level constant if truly static) to preserve referential identity.
+
+Wrong:
+
+```tsx
+
+```
+
+Right:
+
+```tsx
+const config = useMemo(() => ({
+ provider: ...,
+ detail: ...
+}), [provider, detail]);
+
+
+```
+
+---
+
+## Expensive computations in render should use `useMemo`
+
+**Urgency:** suggestion
+
+### Category
+
+Maintainability
+
+### Confidence Threshold
+
+Flag when the computation is non-trivial (for example, sorting/filtering large collections or repeated transformations) and can run frequently with unchanged inputs. For small arrays or infrequent renders, make this a suggestion only.
+
+### Exceptions / False Positives
+
+- Do not force `useMemo` for cheap computations over small data where memoization adds more complexity than benefit.
+- Do not flag one-time or rarely re-rendered components without evidence that render cost is material.
+- If dependencies are hard to express correctly and memoization risks stale data bugs, prefer a profiling-backed follow-up suggestion.
+
+### Description
+
+Operations that sort, filter, reduce, or transform large collections should be wrapped in `useMemo` so the work only runs when inputs change — regardless of whether the result is passed as a prop. This rule targets **computational cost**, not referential identity.
+
+### Anti-patterns to Flag
+
+```tsx
+// ❌ Re-sorts on every render even when `items` and `sortKey` haven't changed
+const SortedList: FC<{ items: Item[]; sortKey: string }> = ({ items, sortKey }) => {
+ const sorted = [...items].sort((a, b) => a[sortKey].localeCompare(b[sortKey]));
+ return
{sorted.map(item => - {item.name}
)}
;
+};
+```
+
+### Suggested Fix
+
+```tsx
+// ✅ Only recalculates when items or sortKey change
+const SortedList: FC<{ items: Item[]; sortKey: string }> = ({ items, sortKey }) => {
+ const sorted = useMemo(
+ () => [...items].sort((a, b) => a[sortKey].localeCompare(b[sortKey])),
+ [items, sortKey]
+ );
+ return
{sorted.map(item => - {item.name}
)}
;
+};
+```
+
+---
+
+## No component definitions inside other components
+
+**Urgency:** urgent
+
+### Category
+
+Correctness
+
+### Confidence Threshold
+
+Flag as a high-severity finding when a nested function is used as a React component type (capitalized and rendered with JSX) inside a component body, causing remounts and state loss. Do not confuse this with render helpers that return JSX but are not treated as component types.
+
+### Exceptions / False Positives
+
+- Do not flag plain helper functions inside components that return JSX and are called like normal functions (not rendered as `
`).
+- Do not flag render-prop callbacks or inline functions passed to APIs that expect functions rather than component types.
+- If the nested component is intentionally recreated and stateless for a localized pattern, prefer a note unless remount behavior is harmful.
+
+### Description
+
+Defining a component (function or arrow) inside another component's render body creates a new component type on every render. React unmounts and remounts the inner component each time, destroying all state and DOM, which causes flickering and performance problems.
+
+### Anti-patterns to Flag
+
+```tsx
+// ❌ Inner component re-created every render — loses state on each parent re-render
+const ParentComponent: FC = () => {
+ const InnerRow = ({ item }) =>
| {item.name} |
;
+
+ return
;
+};
+```
+
+### Suggested Fix
+
+Move the inner component to module scope:
+
+```tsx
+// ✅ Stable component identity — React can reconcile correctly
+const InnerRow: FC<{ item: Item }> = ({ item }) =>
| {item.name} |
;
+
+const ParentComponent: FC = () => {
+ return
;
+};
+```
\ No newline at end of file
diff --git a/.claude/skills/code-review-jest/skill.md b/.claude/skills/code-review-jest/skill.md
new file mode 100644
index 0000000000..568eb90ca0
--- /dev/null
+++ b/.claude/skills/code-review-jest/skill.md
@@ -0,0 +1,123 @@
+---
+name: code-review-jest
+description: "Trigger when the user requests a review of Jest test files (e.g., `.test.tsx`, `.spec.tsx`). Supports --full flag for complete file/directory review; defaults to staged changes when a path is provided."
+---
+
+# Jest Test Code Review
+
+## Intent
+Use this skill whenever the user asks to review Jest test code (especially `.test.tsx`, `.spec.tsx`, `.test.ts`, or `.spec.ts` files). Support three review modes:
+
+1. **Pending-change review** – bare invocation with no arguments; inspects staged/working-tree
+ files slated for commit across all repos.
+2. **Path review (default)** – a file or directory path is provided (no flag); reviews only the
+ git staged/working-tree changes for that path.
+3. **Full review** – a file or directory path is provided with `--full`; reviews the entire file
+ contents (or all matching files in a directory) regardless of git status.
+
+Stick to the checklist below for every applicable file and mode. Apply only the Jest checklist rules to test files — do not apply React component rules to component code that happens to be visible via imports in the test file.
+
+## Checklist
+See [.agents/review-checklists/common.md](../../../.agents/review-checklists/common.md) for reviewer priority and standard review format, and [.agents/review-checklists/jest/code-quality.md](../../../.agents/review-checklists/jest/code-quality.md), [.agents/review-checklists/jest/performance.md](../../../.agents/review-checklists/jest/performance.md), [.agents/review-checklists/jest/business-logic.md](../../../.agents/review-checklists/jest/business-logic.md) for the living checklist split by category—treat it as the canonical set of rules to follow.
+
+Use the rule's `Urgency` to place findings in the "urgent issues" vs "suggestions" sections.
+
+## Review Process
+
+**Argument parsing:**
+
+Parse the invocation arguments to extract:
+- An optional flag: `--full`
+- An optional path: a file path or directory path
+
+**File discovery:**
+
+- **No path, no flag (bare invocation):** Pending-change review. Discover nested repos by
+ running `find server/modules -maxdepth 2 -name ".git" -type d` from the workspace root,
+ then for each discovered repo (and the top-level root) run `git diff --cached --name-only`
+ and `git diff --name-only`. Aggregate all results, filtering to test file extensions
+ (`.test.tsx`, `.spec.tsx`, `.test.ts`, `.spec.ts`).
+
+- **Path provided (no `--full` flag — default):** Determine the git root via
+ `git -C
rev-parse --show-toplevel`.
+ - *File path:* Run `git diff --cached -- ` and `git diff -- `. If there are
+ no changes, report "No staged or working-tree changes found for ``." and stop.
+ If there are changes, proceed to review.
+ - *Directory path:* Run `git diff --cached --name-only -- ` and
+ `git diff --name-only -- `. Filter to test file extensions. If no changed files
+ are found, report "No staged or working-tree changes found under ``." and stop.
+
+- **Path + `--full`:** Review the entire contents regardless of git status.
+ - *File path:* Use the file directly — no git discovery needed.
+ - *Directory path:* Find all files matching test file extensions under the directory
+ (using glob/find). Review every matching file.
+
+- **`--full` with no path:** Ask the user to provide a file or directory path.
+
+**Review scope when reviewing staged changes (default mode):**
+
+When reviewing staged changes, read the full file for context but **focus the review on changed
+lines and their immediate surroundings**. Use the diff output to identify which sections
+changed, then apply the checklist rules primarily to those sections. Still flag issues in
+unchanged code only if they directly interact with or are affected by the changes.
+
+**Multi-file grouping:** When reviewing multiple files, group all findings together by urgency section (urgent issues first, then suggestions), not per-file. Include the file path in each finding's `FilePath` field.
+
+1. Open the relevant test file(s). Gather all lines.
+2. For each applicable checklist rule, evaluate the code against the rule text, confidence threshold, and exceptions/false positives before deciding to flag it.
+3. For each confirmed violation, capture evidence (exact snippet and/or file/line), record the rule's primary category, and note confidence briefly.
+4. Compose the review section per the template below. Group findings by **Urgency** section first (urgent issues, then suggestions). Within each section, order findings by the checklist primary category priority: **Correctness**, then **Maintainability**, then **Style**.
+
+## Required output
+When invoked, the response must exactly follow one of the two templates:
+
+### Template A (any findings)
+```
+# Code review
+Found urgent issues that need to be fixed:
+
+## 1
+FilePath: line
+Evidence:
+Category:
+Confidence: -
+Exceptions checked:
+
+
+### Suggested fix
+
+
+---
+... (repeat for each urgent issue) ...
+
+Found suggestions for improvement:
+
+## 1
+FilePath: line
+Evidence:
+Category:
+Confidence: -
+Exceptions checked:
+
+
+### Suggested fix
+
+
+---
+
+... (repeat for each suggestion) ...
+```
+
+If there are no urgent issues, omit that section. If there are no suggestions, omit that section.
+
+Always list every urgent issue — never cap or truncate them. If there are more than 10 suggestions, summarize as "10+ suggestions" and output the first 10.
+
+Don't compress the blank lines between sections; keep them as-is for readability.
+
+If you use Template A (i.e., there are issues to fix) and at least one issue requires code changes, append a brief follow-up question after the structured output asking whether the user wants you to apply the suggested fix(es). For example: "Would you like me to apply the suggested fixes?"
+
+### Template B (no issues)
+```
+# Code review
+No issues found.
+```
diff --git a/.claude/skills/code-review-react/skill.md b/.claude/skills/code-review-react/skill.md
new file mode 100644
index 0000000000..3cb2a78a6f
--- /dev/null
+++ b/.claude/skills/code-review-react/skill.md
@@ -0,0 +1,123 @@
+---
+name: code-review-react
+description: "Trigger when the user requests a review of frontend files (e.g., `.tsx`, `.ts`, `.js`). Excludes test files. Supports --full flag for complete file/directory review; defaults to staged changes when a path is provided."
+---
+
+# Frontend Code Review
+
+## Intent
+Use this skill whenever the user asks to review frontend code (especially `.tsx`, `.ts`, `.scss`, `.css` or `.js` files). **Exclude test files** with extensions `.test.tsx`, `.test.ts`, `.spec.tsx`, or `.spec.ts` — those should be reviewed using the `code-review-jest` skill instead. Support three review modes:
+
+1. **Pending-change review** – bare invocation with no arguments; inspects staged/working-tree
+ files slated for commit across all repos.
+2. **Path review (default)** – a file or directory path is provided (no flag); reviews only the
+ git staged/working-tree changes for that path.
+3. **Full review** – a file or directory path is provided with `--full`; reviews the entire file
+ contents (or all matching files in a directory) regardless of git status.
+
+Stick to the checklist below for every applicable file and mode. Apply only the React/frontend checklist rules — do not apply Jest test rules to test code that may be co-located or visible in the same file.
+
+## Checklist
+See [.agents/review-checklists/common.md](../../../.agents/review-checklists/common.md) for reviewer priority and standard review format, and [.agents/review-checklists/react/code-quality.md](../../../.agents/review-checklists/react/code-quality.md), [.agents/review-checklists/react/performance.md](../../../.agents/review-checklists/react/performance.md), [.agents/review-checklists/react/business-logic.md](../../../.agents/review-checklists/react/business-logic.md) for the living checklist split by category—treat it as the canonical set of rules to follow.
+
+Use the rule's `Urgency` to place findings in the "urgent issues" vs "suggestions" sections.
+
+## Review Process
+
+**Argument parsing:**
+
+Parse the invocation arguments to extract:
+- An optional flag: `--full`
+- An optional path: a file path or directory path
+
+**File discovery:**
+
+- **No path, no flag (bare invocation):** Pending-change review. Discover nested repos by
+ running `find server/modules -maxdepth 2 -name ".git" -type d` from the workspace root,
+ then for each discovered repo (and the top-level root) run `git diff --cached --name-only`
+ and `git diff --name-only`. Aggregate all results, filtering to applicable frontend
+ extensions (`.tsx`, `.ts`, `.js`, `.scss`, `.css`) and excluding test files.
+
+- **Path provided (no `--full` flag — default):** Determine the git root via
+ `git -C rev-parse --show-toplevel`.
+ - *File path:* Run `git diff --cached -- ` and `git diff -- `. If there are
+ no changes, report "No staged or working-tree changes found for ``." and stop.
+ If there are changes, proceed to review.
+ - *Directory path:* Run `git diff --cached --name-only -- ` and
+ `git diff --name-only -- `. Filter to applicable extensions. If no changed files
+ are found, report "No staged or working-tree changes found under ``." and stop.
+
+- **Path + `--full`:** Review the entire contents regardless of git status.
+ - *File path:* Use the file directly — no git discovery needed.
+ - *Directory path:* Find all files matching applicable extensions under the directory
+ (using glob/find). Review every matching file.
+
+- **`--full` with no path:** Ask the user to provide a file or directory path.
+
+**Review scope when reviewing staged changes (default mode):**
+
+When reviewing staged changes, read the full file for context but **focus the review on changed
+lines and their immediate surroundings**. Use the diff output to identify which sections
+changed, then apply the checklist rules primarily to those sections. Still flag issues in
+unchanged code only if they directly interact with or are affected by the changes.
+
+**Multi-file grouping:** When reviewing multiple files, group all findings together by urgency section (urgent issues first, then suggestions), not per-file. Include the file path in each finding's `FilePath` field.
+
+1. Open the relevant component/module. Gather all lines.
+2. For each applicable checklist rule, evaluate the code against the rule text, confidence threshold, and exceptions/false positives before deciding to flag it.
+3. For each confirmed violation, capture evidence (exact snippet and/or file/line), record the rule's primary category, and note confidence briefly.
+4. Compose the review section per the template below. Group findings by **Urgency** section first (urgent issues, then suggestions). Within each section, order findings by the checklist primary category priority: **Correctness**, then **Maintainability**, then **Style**.
+
+## Required output
+When invoked, the response must exactly follow one of the two templates:
+
+### Template A (any findings)
+```
+# Code review
+Found urgent issues that need to be fixed:
+
+## 1
+FilePath: line
+Evidence:
+Category:
+Confidence: -
+Exceptions checked:
+
+
+### Suggested fix
+
+
+---
+... (repeat for each urgent issue) ...
+
+Found suggestions for improvement:
+
+## 1
+FilePath: line
+Evidence:
+Category:
+Confidence: -
+Exceptions checked:
+
+
+### Suggested fix
+
+
+---
+
+... (repeat for each suggestion) ...
+```
+
+If there are no urgent issues, omit that section. If there are no suggestions, omit that section.
+
+Always list every urgent issue — never cap or truncate them. If there are more than 10 suggestions, summarize as "10+ suggestions" and output the first 10.
+
+Don't compress the blank lines between sections; keep them as-is for readability.
+
+If you use Template A (i.e., there are issues to fix) and at least one issue requires code changes, append a brief follow-up question after the structured output asking whether the user wants you to apply the suggested fix(es). For example: "Would you like me to apply the suggested fixes?"
+
+### Template B (no issues)
+```
+# Code review
+No issues found.
+```