diff --git a/docs/lint/html/index.md b/docs/lint/html/index.md
new file mode 100644
index 0000000000..15d693843c
--- /dev/null
+++ b/docs/lint/html/index.md
@@ -0,0 +1,4 @@
+[DSpace ESLint plugins](../../../lint/README.md) > HTML rules
+_______
+
+- [`dspace-angular-html/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via the selector of their `ThemedComponent` wrapper class
diff --git a/docs/lint/html/rules/themed-component-usages.md b/docs/lint/html/rules/themed-component-usages.md
new file mode 100644
index 0000000000..a04fe1c770
--- /dev/null
+++ b/docs/lint/html/rules/themed-component-usages.md
@@ -0,0 +1,110 @@
+[DSpace ESLint plugins](../../../../lint/README.md) > [HTML rules](../index.md) > `dspace-angular-html/themed-component-usages`
+_______
+
+Themeable components should be used via the selector of their `ThemedComponent` wrapper class
+
+This ensures that custom themes can correctly override _all_ instances of this component.
+The only exception to this rule are unit tests, where we may want to use the base component in order to keep the test setup simple.
+
+
+_______
+
+[Source code](../../../../lint/src/rules/html/themed-component-usages.ts)
+
+### Examples
+
+
+#### Valid code
+
+##### use no-prefix selectors in HTML templates
+
+```html
+
+
+
+```
+
+##### use no-prefix selectors in TypeScript templates
+
+```html
+@Component({
+ template: ''
+})
+class Test {
+}
+```
+
+##### use no-prefix selectors in TypeScript test templates
+
+Filename: `lint/test/fixture/src/test.spec.ts`
+
+```html
+@Component({
+ template: ''
+})
+class Test {
+}
+```
+
+##### base selectors are also allowed in TypeScript test templates
+
+Filename: `lint/test/fixture/src/test.spec.ts`
+
+```html
+@Component({
+ template: ''
+})
+class Test {
+}
+```
+
+
+
+
+#### Invalid code & automatic fixes
+
+##### themed override selectors are not allowed in HTML templates
+
+```html
+
+
+
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper's selector
+Themeable components should be used via their ThemedComponent wrapper's selector
+Themeable components should be used via their ThemedComponent wrapper's selector
+```
+
+Result of `yarn lint --fix`:
+```html
+
+
+
+```
+
+
+##### base selectors are not allowed in HTML templates
+
+```html
+
+
+
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper's selector
+Themeable components should be used via their ThemedComponent wrapper's selector
+Themeable components should be used via their ThemedComponent wrapper's selector
+```
+
+Result of `yarn lint --fix`:
+```html
+
+
+
+```
+
+
+
diff --git a/docs/lint/ts/index.md b/docs/lint/ts/index.md
new file mode 100644
index 0000000000..ed060c946e
--- /dev/null
+++ b/docs/lint/ts/index.md
@@ -0,0 +1,6 @@
+[DSpace ESLint plugins](../../../lint/README.md) > TypeScript rules
+_______
+
+- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes
+- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention
+- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class
diff --git a/docs/lint/ts/rules/themed-component-classes.md b/docs/lint/ts/rules/themed-component-classes.md
new file mode 100644
index 0000000000..571e3f170b
--- /dev/null
+++ b/docs/lint/ts/rules/themed-component-classes.md
@@ -0,0 +1,253 @@
+[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-classes`
+_______
+
+Formatting rules for themeable component classes
+
+_______
+
+[Source code](../../../../lint/src/rules/ts/themed-component-classes.ts)
+
+### Examples
+
+
+#### Valid code
+
+##### Regular non-themeable component
+
+```typescript
+@Component({
+ selector: 'ds-something',
+ standalone: true,
+})
+class Something {
+}
+```
+
+##### Base component
+
+```typescript
+@Component({
+ selector: 'ds-base-test-themable',
+ standalone: true,
+})
+class TestThemeableTomponent {
+}
+```
+
+##### Wrapper component
+
+Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [
+ TestThemeableComponent,
+ ],
+})
+class ThemedTestThemeableTomponent extends ThemedComponent {
+}
+```
+
+##### Override component
+
+Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-themed-test-themable',
+ standalone: true,
+})
+class Override extends BaseComponent {
+}
+```
+
+
+
+
+#### Invalid code & automatic fixes
+
+##### Base component must be standalone
+
+```typescript
+@Component({
+ selector: 'ds-base-test-themable',
+})
+class TestThemeableComponent {
+}
+```
+Will produce the following error(s):
+```
+Themeable components must be standalone
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-base-test-themable',
+ standalone: true,
+})
+class TestThemeableComponent {
+}
+```
+
+
+##### Wrapper component must be standalone and import base component
+
+Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-test-themable',
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+Will produce the following error(s):
+```
+Themeable component wrapper classes must be standalone and import the base class
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [TestThemeableComponent],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+
+
+##### Wrapper component must import base component (array present but empty)
+
+Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+Will produce the following error(s):
+```
+Themed component wrapper classes must only import the base class
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [TestThemeableComponent],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+
+
+##### Wrapper component must import base component (array is wrong)
+
+Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
+
+```typescript
+import { SomethingElse } from './somewhere-else';
+
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [
+ SomethingElse,
+ ],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+Will produce the following error(s):
+```
+Themed component wrapper classes must only import the base class
+```
+
+Result of `yarn lint --fix`:
+```typescript
+import { SomethingElse } from './somewhere-else';
+
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [TestThemeableComponent],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+
+
+##### Wrapper component must import base component (array is wrong)
+
+Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
+
+```typescript
+import { Something, SomethingElse } from './somewhere-else';
+
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [
+ SomethingElse,
+ ],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+Will produce the following error(s):
+```
+Themed component wrapper classes must only import the base class
+```
+
+Result of `yarn lint --fix`:
+```typescript
+import { Something, SomethingElse } from './somewhere-else';
+
+@Component({
+ selector: 'ds-test-themable',
+ standalone: true,
+ imports: [TestThemeableComponent],
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+
+
+##### Override component must be standalone
+
+Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-themed-test-themable',
+})
+class Override extends BaseComponent {
+}
+```
+Will produce the following error(s):
+```
+Themeable components must be standalone
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-themed-test-themable',
+ standalone: true,
+})
+class Override extends BaseComponent {
+}
+```
+
+
+
diff --git a/docs/lint/ts/rules/themed-component-selectors.md b/docs/lint/ts/rules/themed-component-selectors.md
new file mode 100644
index 0000000000..f4d0ea177c
--- /dev/null
+++ b/docs/lint/ts/rules/themed-component-selectors.md
@@ -0,0 +1,156 @@
+[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-selectors`
+_______
+
+Themeable component selectors should follow the DSpace convention
+
+Each themeable component is comprised of a base component, a wrapper component and any number of themed components
+- Base components should have a selector starting with `ds-base-`
+- Themed components should have a selector starting with `ds-themed-`
+- Wrapper components should have a selector starting with `ds-`, but not `ds-base-` or `ds-themed-`
+ - This is the regular DSpace selector prefix
+ - **When making a regular component themeable, its selector prefix should be changed to `ds-base-`, and the new wrapper's component should reuse the previous selector**
+
+Unit tests are exempt from this rule, because they may redefine components using the same class name as other themeable components elsewhere in the source.
+
+
+_______
+
+[Source code](../../../../lint/src/rules/ts/themed-component-selectors.ts)
+
+### Examples
+
+
+#### Valid code
+
+##### Regular non-themeable component selector
+
+```typescript
+@Component({
+ selector: 'ds-something',
+})
+class Something {
+}
+```
+
+##### Themeable component selector should replace the original version, unthemed version should be changed to ds-base-
+
+```typescript
+@Component({
+ selector: 'ds-base-something',
+})
+class Something {
+}
+
+@Component({
+ selector: 'ds-something',
+})
+class ThemedSomething extends ThemedComponent {
+}
+
+@Component({
+ selector: 'ds-themed-something',
+})
+class OverrideSomething extends Something {
+}
+```
+
+##### Other themed component wrappers should not interfere
+
+```typescript
+@Component({
+ selector: 'ds-something',
+})
+class Something {
+}
+
+@Component({
+ selector: 'ds-something-else',
+})
+class ThemedSomethingElse extends ThemedComponent {
+}
+```
+
+
+
+
+#### Invalid code & automatic fixes
+
+##### Wrong selector for base component
+
+Filename: `lint/test/fixture/src/app/test/test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-something',
+})
+class TestThemeableComponent {
+}
+```
+Will produce the following error(s):
+```
+Unthemed version of themeable component should have a selector starting with 'ds-base-'
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-base-something',
+})
+class TestThemeableComponent {
+}
+```
+
+
+##### Wrong selector for wrapper component
+
+Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-themed-something',
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+Will produce the following error(s):
+```
+Themed component wrapper of themeable component shouldn't have a selector starting with 'ds-themed-'
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-something',
+})
+class ThemedTestThemeableComponent extends ThemedComponent {
+}
+```
+
+
+##### Wrong selector for theme override
+
+Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts`
+
+```typescript
+@Component({
+ selector: 'ds-something',
+})
+class TestThememeableComponent extends BaseComponent {
+}
+```
+Will produce the following error(s):
+```
+Theme override of themeable component should have a selector starting with 'ds-themed-'
+```
+
+Result of `yarn lint --fix`:
+```typescript
+@Component({
+ selector: 'ds-themed-something',
+})
+class TestThememeableComponent extends BaseComponent {
+}
+```
+
+
+
diff --git a/docs/lint/ts/rules/themed-component-usages.md b/docs/lint/ts/rules/themed-component-usages.md
new file mode 100644
index 0000000000..16ccb701c2
--- /dev/null
+++ b/docs/lint/ts/rules/themed-component-usages.md
@@ -0,0 +1,332 @@
+[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-usages`
+_______
+
+Themeable components should be used via their `ThemedComponent` wrapper class
+
+This ensures that custom themes can correctly override _all_ instances of this component.
+There are a few exceptions where the base class can still be used:
+- Class declaration expressions (otherwise we can't declare, extend or override the class in the first place)
+- Angular modules (except for routing modules)
+- Angular `@ViewChild` decorators
+- Type annotations
+
+
+_______
+
+[Source code](../../../../lint/src/rules/ts/themed-component-usages.ts)
+
+### Examples
+
+
+#### Valid code
+
+##### allow wrapper class usages
+
+```typescript
+import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component';
+
+const config = {
+ a: ThemedTestThemeableComponent,
+ b: ChipsComponent,
+}
+```
+
+##### allow base class in class declaration
+
+```typescript
+export class TestThemeableComponent {
+}
+```
+
+##### allow inheriting from base class
+
+```typescript
+import { TestThemeableComponent } from './app/test/test-themeable.component';
+
+export class ThemedAdminSidebarComponent extends ThemedComponent {
+}
+```
+
+##### allow base class in ViewChild
+
+```typescript
+import { TestThemeableComponent } from './app/test/test-themeable.component';
+
+export class Something {
+ @ViewChild(TestThemeableComponent) test: TestThemeableComponent;
+}
+```
+
+##### allow wrapper selectors in test queries
+
+Filename: `lint/test/fixture/src/app/test/test.component.spec.ts`
+
+```typescript
+By.css('ds-themeable');
+By.css('#test > ds-themeable > #nest');
+```
+
+##### allow wrapper selectors in cypress queries
+
+Filename: `lint/test/fixture/src/app/test/test.component.cy.ts`
+
+```typescript
+By.css('ds-themeable');
+By.css('#test > ds-themeable > #nest');
+```
+
+
+
+
+#### Invalid code & automatic fixes
+
+##### disallow direct usages of base class
+
+```typescript
+import { TestThemeableComponent } from './app/test/test-themeable.component';
+import { TestComponent } from './app/test/test.component';
+
+const config = {
+ a: TestThemeableComponent,
+ b: TestComponent,
+}
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component';
+import { TestComponent } from './app/test/test.component';
+
+const config = {
+ a: ThemedTestThemeableComponent,
+ b: TestComponent,
+}
+```
+
+
+##### disallow direct usages of base class, keep other imports
+
+```typescript
+import { Something, TestThemeableComponent } from './app/test/test-themeable.component';
+import { TestComponent } from './app/test/test.component';
+
+const config = {
+ a: TestThemeableComponent,
+ b: TestComponent,
+ c: Something,
+}
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+import { Something } from './app/test/test-themeable.component';
+import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component';
+import { TestComponent } from './app/test/test.component';
+
+const config = {
+ a: ThemedTestThemeableComponent,
+ b: TestComponent,
+ c: Something,
+}
+```
+
+
+##### handle array replacements correctly
+
+```typescript
+const DECLARATIONS = [
+ Something,
+ TestThemeableComponent,
+ Something,
+ ThemedTestThemeableComponent,
+];
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+const DECLARATIONS = [
+ Something,
+ Something,
+ ThemedTestThemeableComponent,
+];
+```
+
+
+##### disallow override selector in test queries
+
+Filename: `lint/test/fixture/src/app/test/test.component.spec.ts`
+
+```typescript
+By.css('ds-themed-themeable');
+By.css('#test > ds-themed-themeable > #nest');
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+By.css('ds-themeable');
+By.css('#test > ds-themeable > #nest');
+```
+
+
+##### disallow base selector in test queries
+
+Filename: `lint/test/fixture/src/app/test/test.component.spec.ts`
+
+```typescript
+By.css('ds-base-themeable');
+By.css('#test > ds-base-themeable > #nest');
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+By.css('ds-themeable');
+By.css('#test > ds-themeable > #nest');
+```
+
+
+##### disallow override selector in cypress queries
+
+Filename: `lint/test/fixture/src/app/test/test.component.cy.ts`
+
+```typescript
+cy.get('ds-themed-themeable');
+cy.get('#test > ds-themed-themeable > #nest');
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+cy.get('ds-themeable');
+cy.get('#test > ds-themeable > #nest');
+```
+
+
+##### disallow base selector in cypress queries
+
+Filename: `lint/test/fixture/src/app/test/test.component.cy.ts`
+
+```typescript
+cy.get('ds-base-themeable');
+cy.get('#test > ds-base-themeable > #nest');
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+cy.get('ds-themeable');
+cy.get('#test > ds-themeable > #nest');
+```
+
+
+##### edge case: unable to find usage node through usage token, but import is still flagged and fixed
+
+Filename: `lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts`
+
+```typescript
+import { Component } from '@angular/core';
+
+import { Context } from './app/core/shared/context.model';
+import { TestThemeableComponent } from '../../../../app/test/test-themeable.component';
+
+@Component({
+ standalone: true,
+ imports: [TestThemeableComponent],
+})
+export class UsageComponent {
+}
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+import { Component } from '@angular/core';
+
+import { Context } from './app/core/shared/context.model';
+import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component';
+
+@Component({
+ standalone: true,
+ imports: [ThemedTestThemeableComponent],
+})
+export class UsageComponent {
+}
+```
+
+
+##### edge case edge case: both are imported, only wrapper is retained
+
+Filename: `lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts`
+
+```typescript
+import { Component } from '@angular/core';
+
+import { Context } from './app/core/shared/context.model';
+import { TestThemeableComponent } from '../../../../app/test/test-themeable.component';
+import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component';
+
+@Component({
+ standalone: true,
+ imports: [TestThemeableComponent, ThemedTestThemeableComponent],
+})
+export class UsageComponent {
+}
+```
+Will produce the following error(s):
+```
+Themeable components should be used via their ThemedComponent wrapper
+Themeable components should be used via their ThemedComponent wrapper
+```
+
+Result of `yarn lint --fix`:
+```typescript
+import { Component } from '@angular/core';
+
+import { Context } from './app/core/shared/context.model';
+import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component';
+
+@Component({
+ standalone: true,
+ imports: [ThemedTestThemeableComponent],
+})
+export class UsageComponent {
+}
+```
+
+
+