diff --git a/docs/bell-alignment/README.md b/docs/bell-alignment/README.md
new file mode 100644
index 000000000..28e3ddf3a
--- /dev/null
+++ b/docs/bell-alignment/README.md
@@ -0,0 +1,13 @@
+
+
+# Выравнивание колокольчика в панели профиля
+
+Проверка в браузере на 1440, 1280 и 1024 px использует разметку панели, SVG-иконки и скомпилированные стили компонента. Контейнер уведомлений теперь центрирует SVG независимо от текстовой базовой линии, а красный индикатор расположен относительно него и не влияет на размеры строки. Локальный `viewBox` колокольчика приведён к размеру исходного символа 17 × 19 без изменения внешнего размера 15 × 17, чтобы рисунок не обрезался.
+
+| Ширина | Центр SVG колокольчика | Центр SVG выхода | Центр аватара | Центр блока действий | Скриншот |
+| ------- | ---------------------: | ---------------: | ------------: | -------------------: | ---------------------- |
+| 1440 px | 34,5 px | 34,5 px | 34,5 px | 34,5 px | [1440](after-1440.png) |
+| 1280 px | 34,5 px | 34,5 px | 34,5 px | 34,5 px | [1280](after-1280.png) |
+| 1024 px | 34,5 px | 34,5 px | 34,5 px | 34,5 px | [1024](after-1024.png) |
+
+Снимки показывают изолированную панель без пользовательских данных; работу выпадающего блока, clickOutside, выхода и перехода в профиль проверяют компонентные тесты.
diff --git a/docs/bell-alignment/after-1024.png b/docs/bell-alignment/after-1024.png
new file mode 100644
index 000000000..1d8f29af1
Binary files /dev/null and b/docs/bell-alignment/after-1024.png differ
diff --git a/docs/bell-alignment/after-1280.png b/docs/bell-alignment/after-1280.png
new file mode 100644
index 000000000..f5bc33996
Binary files /dev/null and b/docs/bell-alignment/after-1280.png differ
diff --git a/docs/bell-alignment/after-1440.png b/docs/bell-alignment/after-1440.png
new file mode 100644
index 000000000..ed04b86ee
Binary files /dev/null and b/docs/bell-alignment/after-1440.png differ
diff --git a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html
index 7727bd3eb..23e34392a 100644
--- a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html
+++ b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.html
@@ -3,11 +3,14 @@
-
+
@if (hasNotifications() || hasInvites) {
}
-
+
@if (invites().length) {
}
diff --git a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss
index d0652ceab..3605c3121 100644
--- a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss
+++ b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.scss
@@ -50,6 +50,23 @@
&__bell {
position: relative;
+ &--notifications {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ line-height: 0;
+
+ > .attention {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 7px;
+ height: 7px;
+ background-color: var(--red);
+ border-radius: 50%;
+ }
+ }
+
&--hasInvites {
position: absolute;
top: -5%;
diff --git a/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.spec.ts b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.spec.ts
new file mode 100644
index 000000000..c8dc6a7b1
--- /dev/null
+++ b/projects/ui/src/lib/components/layout/profile-control-panel/profile-control-panel.component.spec.ts
@@ -0,0 +1,59 @@
+/** @format */
+
+import { provideRouter } from "@angular/router";
+import { TestBed } from "@angular/core/testing";
+import { User } from "@domain/auth/user.model";
+import { ProfileControlPanelComponent } from "./profile-control-panel.component";
+
+describe("ProfileControlPanelComponent: колокольчик", () => {
+ function render(hasNotifications = false) {
+ TestBed.configureTestingModule({
+ providers: [provideRouter([])],
+ });
+ const fixture = TestBed.createComponent(ProfileControlPanelComponent);
+ fixture.componentRef.setInput("user", { id: 42, personal: {} } as User);
+ fixture.componentRef.setInput("invites", []);
+ fixture.componentRef.setInput("hasNotifications", hasNotifications);
+ fixture.detectChanges();
+ return fixture;
+ }
+
+ it("оставляет индикатор уведомлений внутри локально центрируемого контейнера", () => {
+ const element = render(true).nativeElement as HTMLElement;
+ const bell = element.querySelector(".control-panel__bell--notifications");
+
+ expect(bell?.querySelector('i[appIcon][icon="bell"]')).not.toBeNull();
+ expect(bell?.querySelector("svg")?.getAttribute("viewBox")).toBe("0 0 17 19");
+ expect(bell?.querySelector("svg")?.getAttribute("width")).toBe("15");
+ expect(bell?.querySelector("svg")?.getAttribute("height")).toBe("17");
+ expect(bell?.querySelector(".attention")).not.toBeNull();
+ expect(element.querySelectorAll(".control-panel__bell--notifications")).toHaveLength(1);
+ });
+
+ it("открывает уведомления и закрывает их через clickOutside", async () => {
+ const fixture = render();
+ const element = fixture.nativeElement as HTMLElement;
+
+ element.querySelector
(".control-panel__bell--notifications")?.click();
+ fixture.detectChanges();
+ expect(element.querySelector(".control-panel__notifications")).not.toBeNull();
+
+ document.body.click();
+ await fixture.whenStable();
+ fixture.detectChanges();
+ expect(fixture.componentInstance.showNotifications).toBe(false);
+ expect(element.querySelector(".control-panel__notifications")).toBeNull();
+ });
+
+ it("сохраняет действие выхода и ссылку аватара на профиль", () => {
+ const fixture = render();
+ const element = fixture.nativeElement as HTMLElement;
+ const emitLogout = vi.spyOn(fixture.componentInstance.logout, "emit");
+ const actions = element.querySelectorAll(".control-panel__action");
+
+ expect(actions[1].querySelector(".control-panel__bell--notifications")).toBeNull();
+ actions[1].click();
+ expect(emitLogout).toHaveBeenCalledOnce();
+ expect(element.querySelector(".user")?.getAttribute("href")).toBe("/office/profile/42");
+ });
+});