diff --git a/backend/static/css/components/base-app.css b/backend/static/css/components/base-app.css
new file mode 100644
index 00000000..135168a2
--- /dev/null
+++ b/backend/static/css/components/base-app.css
@@ -0,0 +1,278 @@
+/**
+ * base-app.css
+ * Базовые стили приложения: layout, navbar, sidebar, кнопки, feed-элементы
+ */
+
+:root {
+ --sidebar-w: 190px;
+ --rightbar-w: 350px;
+ --navbar-h: 60px;
+ --bs-primary: #007AFF;
+ --bs-link-color: var(--bs-primary);
+ --bs-link-hover-color: #0062CC;
+
+ /* feed tokens */
+ --feed-radius: 18px;
+ --feed-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 10px 30px rgba(0, 0, 0, .08);
+ --feed-shadow-hover: 0 4px 10px rgba(0, 0, 0, .06), 0 16px 40px rgba(0, 0, 0, .12);
+}
+
+[data-bs-theme="dark"] {
+ --bs-body-bg: #1C1C1E;
+ --bs-body-color: #F2F2F7;
+ --bs-border-color: #3A3A3C;
+ --bs-tertiary-bg: #2C2C2E;
+ --bs-primary: #0A84FF;
+ --bs-link-color: var(--bs-primary);
+ --bs-link-hover-color: #59AFFF;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+ font-size: 17px;
+ padding-top: var(--navbar-h);
+ overflow-x: hidden;
+ background-color: var(--bs-body-bg);
+}
+
+@supports(padding-top: env(safe-area-inset-top)) {
+ body {
+ padding-top: calc(var(--navbar-h) + env(safe-area-inset-top));
+ }
+}
+
+.btn {
+ border-radius: 10px;
+ min-height: 44px;
+ transition: background-color .3s, transform .1s;
+}
+
+.btn:hover {
+ transform: scale(1.02);
+}
+
+.form-control {
+ border-radius: 10px;
+ height: 44px;
+ font-size: 17px;
+}
+
+.form-control:focus {
+ box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .25);
+ border-color: var(--bs-primary);
+}
+
+.dropdown-menu {
+ border-radius: 13px;
+ box-shadow: 0 6px 24px rgba(0, 0, 0, .12);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ NAVBAR
+────────────────────────────────────────────────────────────── */
+.app-navbar {
+ position: fixed;
+ inset: 0 0 auto 0;
+ z-index: 1030;
+ border-bottom: .5px solid var(--bs-border-color);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ LAYOUT
+────────────────────────────────────────────────────────────── */
+.app-layout {
+ display: block;
+}
+
+@media (min-width: 992px) {
+ .app-layout.with-sidebar.with-rightbar {
+ display: grid;
+ grid-template-columns: var(--sidebar-w) 1fr var(--rightbar-w);
+ align-items: start;
+ }
+
+ .app-layout.with-sidebar:not(.with-rightbar) {
+ display: grid;
+ grid-template-columns: var(--sidebar-w) 1fr;
+ align-items: start;
+ }
+}
+
+/* ─────────────────────────────────────────────────────────────
+ SIDEBAR
+────────────────────────────────────────────────────────────── */
+#sidebar {
+ --bs-offcanvas-width: var(--sidebar-w);
+ border-radius: 0 13px 13px 0;
+}
+
+@media (min-width: 992px) {
+ #sidebar.offcanvas-lg {
+ position: sticky;
+ top: var(--navbar-h);
+ height: calc(100dvh - var(--navbar-h));
+ align-self: start;
+ overflow: auto;
+ border-right: .5px solid var(--bs-border-color);
+ background: var(--bs-body-bg);
+ transform: none !important;
+ visibility: visible !important;
+ }
+}
+
+/* ─────────────────────────────────────────────────────────────
+ NOTIFICATION BELL
+────────────────────────────────────────────────────────────── */
+.bell-wrapper {
+ position: relative;
+ line-height: 1;
+ display: inline-block;
+}
+
+.bell-dot {
+ position: absolute;
+ top: -2px;
+ right: -2px;
+ width: 9px;
+ height: 9px;
+ border-radius: 999px;
+ background: var(--bs-danger);
+ color: #fff;
+ font-size: 7px;
+ line-height: 9px;
+ font-weight: 700;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 0 0 1px rgba(255, 255, 255, .65);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ MOBILE FAB
+────────────────────────────────────────────────────────────── */
+.calendar-fab {
+ position: fixed;
+ right: 1rem;
+ bottom: 1rem;
+ z-index: 1060;
+ width: 52px;
+ height: 52px;
+ border-radius: 9999px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ BUTTONS & GHOST BUTTONS
+────────────────────────────────────────────────────────────── */
+.btn-ghost {
+ background: color-mix(in srgb, var(--bs-body-bg) 94%, transparent);
+ color: var(--bs-body-color);
+ padding: .35rem .6rem;
+ border-radius: 999px;
+ font-size: .9rem;
+}
+
+.btn-ghost:hover {
+ background: color-mix(in srgb, var(--bs-body-bg) 88%, transparent);
+}
+
+.btn-ghost .bi {
+ font-size: 1rem;
+ margin-right: .35rem;
+ vertical-align: -2px;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ FEED ELEMENTS
+────────────────────────────────────────────────────────────── */
+/* «Новые сотрудники» */
+.feed-new {
+ border-radius: var(--feed-radius);
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 10%);
+ background: var(--bs-body-bg);
+ box-shadow: var(--feed-shadow);
+ padding: .9rem 1rem;
+}
+
+/* stretched-link не перекрывает футер/формы */
+.feed-body .stretched-link::after,
+.feed-img .stretched-link::after {
+ z-index: 1;
+}
+
+.collapse {
+ position: relative;
+ z-index: 2;
+}
+
+/* подпись «Скрыть/число» у кнопки комментариев по aria-expanded */
+.btn-ghost .txt-close {
+ display: none;
+}
+
+.btn-ghost[aria-expanded="true"] .txt-open {
+ display: none;
+}
+
+.btn-ghost[aria-expanded="true"] .txt-close {
+ display: inline;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ ALPHA HEADERS (буквенные разделители)
+────────────────────────────────────────────────────────────── */
+.alpha-header {
+ position: sticky;
+ top: calc(var(--navbar-h) + 8px);
+ z-index: 1;
+ background: color-mix(in srgb, var(--bs-body-bg) 92%, transparent);
+ backdrop-filter: blur(6px);
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 30%);
+ color: var(--bs-secondary-color);
+ display: inline-flex;
+ align-items: center;
+ gap: .5rem;
+ padding: .2rem .6rem;
+ border-radius: 999px;
+ font-weight: 700;
+ font-size: .85rem;
+ margin: .25rem 0 .5rem .25rem;
+}
+
+.alpha-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: var(--bs-primary);
+ opacity: .6;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ ACTION BUTTONS
+────────────────────────────────────────────────────────────── */
+.action-btn {
+ min-height: unset;
+ padding: .35rem .6rem;
+}
+
+.action-btn .bi {
+ font-size: 1rem;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ TEXT UTILITIES
+────────────────────────────────────────────────────────────── */
+/* Переносим длинные слова/ссылки, сохраняем переносы строк */
+.feed-text,
+.feed-full {
+ overflow-wrap: anywhere;
+ width: 100%;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+/* чтобы кнопка «Подробнее» не была перекрыта stretched-link */
+.readmore-toggle {
+ position: relative;
+ z-index: 2;
+}
diff --git a/backend/static/css/components/ios-components.css b/backend/static/css/components/ios-components.css
new file mode 100644
index 00000000..f42a41ce
--- /dev/null
+++ b/backend/static/css/components/ios-components.css
@@ -0,0 +1,566 @@
+/**
+ * ios-components.css
+ * iOS-style компоненты: карточки, списки, аккордеоны, badges, кнопки-иконки
+ */
+
+/* ─────────────────────────────────────────────────────────────
+ BASE CARD
+────────────────────────────────────────────────────────────── */
+.ios-card {
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 10%);
+ border-radius: var(--feed-radius);
+ background: var(--bs-body-bg);
+ box-shadow: var(--feed-shadow);
+ transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
+ overflow: hidden;
+}
+
+.ios-card:hover {
+ box-shadow: var(--feed-shadow-hover);
+ transform: translateY(-1px);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ HEADER
+────────────────────────────────────────────────────────────── */
+.ios-header {
+ position: sticky;
+ top: var(--navbar-h, 0px);
+ z-index: 5;
+ padding: .75rem 0;
+ backdrop-filter: saturate(180%) blur(12px);
+ background: color-mix(in srgb, var(--bs-body-bg) 85%, transparent);
+ border-bottom: none !important;
+}
+
+.ios-title {
+ font-weight: 800;
+ letter-spacing: -.01em;
+}
+
+.row.g-ios {
+ align-items: flex-start;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ AVATAR
+────────────────────────────────────────────────────────────── */
+.ios-ava,
+.ios-ava--ph {
+ display: grid;
+ place-items: center;
+ background: var(--bs-tertiary-bg);
+ color: var(--bs-secondary-color);
+ font-size: 3rem;
+ line-height: 1;
+ width: 100%;
+ height: 100%;
+ border-radius: 28px;
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
+}
+
+.ava-wrap {
+ position: relative;
+ width: 132px;
+ height: 132px;
+ margin: 0 auto 12px;
+ display: block;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ ICON BUTTONS
+────────────────────────────────────────────────────────────── */
+.btn-icon {
+ width: 36px;
+ height: 36px;
+ padding: 0;
+ border-radius: 9999px;
+ display: grid;
+ place-items: center;
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 30%);
+ background: color-mix(in srgb, var(--bs-body-bg) 94%, transparent);
+ color: var(--bs-body-color);
+}
+
+.btn-icon:hover {
+ background: color-mix(in srgb, var(--bs-body-bg) 88%, transparent);
+}
+
+/* Варианты окраски */
+.btn-icon--primary {
+ color: var(--bs-primary);
+ border-color: color-mix(in srgb, var(--bs-primary) 30%, var(--bs-border-color));
+}
+
+.btn-icon--primary:hover {
+ background: color-mix(in srgb, var(--bs-primary) 16%, var(--bs-body-bg));
+}
+
+.btn-icon--success {
+ color: var(--bs-success);
+ border-color: color-mix(in srgb, var(--bs-success) 30%, var(--bs-border-color));
+}
+
+.btn-icon--success:hover {
+ background: color-mix(in srgb, var(--bs-success) 16%, var(--bs-body-bg));
+}
+
+.btn-icon--danger {
+ color: var(--bs-danger);
+ border-color: color-mix(in srgb, var(--bs-danger) 30%, var(--bs-border-color));
+}
+
+.btn-icon--danger:hover {
+ background: color-mix(in srgb, var(--bs-danger) 16%, var(--bs-body-bg));
+}
+
+.btn-icon:focus-visible {
+ outline: 2px solid color-mix(in srgb, currentColor 60%, transparent);
+ outline-offset: 2px;
+}
+
+.header-icon-group .btn-icon {
+ width: 36px;
+ height: 36px;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ NAME & ROLE
+────────────────────────────────────────────────────────────── */
+.ios-name {
+ font-weight: 800;
+ font-size: 1.25rem;
+}
+
+.ios-role {
+ font-size: .9rem;
+ color: var(--bs-secondary-color);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ CHIPS
+────────────────────────────────────────────────────────────── */
+.chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: .5rem;
+}
+
+.chip {
+ padding: .35rem .65rem;
+ border-radius: 9999px;
+ font-size: .85rem;
+ line-height: 1;
+ background: var(--bs-secondary-bg);
+ color: var(--bs-body-color);
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ COLLAPSE TRIGGERS
+────────────────────────────────────────────────────────────── */
+.ios-collapse-trigger {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: .75rem;
+ padding: .6rem .9rem;
+ cursor: pointer;
+ border-radius: 14px;
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
+ background: color-mix(in srgb, var(--bs-body-bg) 94%, transparent);
+ color: var(--bs-body-color);
+}
+
+.ios-collapse-caret {
+ transition: transform .25s ease;
+}
+
+.ios-collapse-trigger[aria-expanded="true"] .ios-collapse-caret {
+ transform: rotate(180deg);
+}
+
+.ios-collapse-trigger + .collapse {
+ margin-top: 0 !important;
+}
+
+.ios-collapse-trigger + .collapse > .ios-list,
+.ios-collapse-trigger + .collapse > .chips {
+ margin-top: .5rem;
+}
+
+.collapsing {
+ overflow: hidden;
+ transition: height .35s ease;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ LISTS
+────────────────────────────────────────────────────────────── */
+.ios-list {
+ border-radius: 14px;
+ overflow: hidden;
+ background: var(--bs-body-bg);
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 10%);
+}
+
+.ios-cell {
+ display: flex;
+ align-items: center;
+ gap: .75rem;
+ padding: .85rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 10%);
+}
+
+.ios-cell:last-child {
+ border-bottom: 0;
+}
+
+.ios-cell i {
+ width: 1.25rem;
+ text-align: center;
+ opacity: .9;
+}
+
+.ios-cell a {
+ text-decoration: none;
+ color: inherit;
+}
+
+.ios-section-title {
+ font-weight: 700;
+ font-size: 1rem;
+ margin-bottom: .5rem;
+}
+
+.rounded-ios {
+ border-radius: 14px !important;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ DEPARTMENTS LIST
+────────────────────────────────────────────────────────────── */
+.ios-cell.dept-item {
+ justify-content: space-between;
+}
+
+.ios-cell.dept-head {
+ border-left: 0;
+ background: transparent;
+}
+
+.dept-line {
+ display: flex;
+ align-items: center;
+ gap: .5rem;
+}
+
+.dept-name {
+ font-weight: 700;
+}
+
+.dept-role {
+ color: var(--bs-secondary-color);
+}
+
+/* ─────────────────────────────────────────────────────────────
+ BADGES (HEAD & GEAR)
+────────────────────────────────────────────────────────────── */
+.badge-head {
+ display: inline-flex;
+ align-items: center;
+ gap: .35rem;
+ padding: .2rem .55rem;
+ border-radius: 999px;
+ background: color-mix(in srgb, var(--bs-warning) 15%, var(--bs-body-bg));
+ color: color-mix(in srgb, var(--bs-warning) 60%, black 0%);
+ border: 1px solid color-mix(in srgb, var(--bs-warning) 35%, transparent);
+ font-weight: 700;
+ font-size: .8rem;
+ line-height: 1;
+ white-space: nowrap;
+}
+
+.badge-head .bi {
+ font-size: .95rem;
+ line-height: 1;
+}
+
+.badge-gear {
+ display: inline-flex;
+ align-items: center;
+ gap: .35rem;
+ padding: .2rem .55rem;
+ border-radius: 999px;
+ cursor: pointer;
+ background: color-mix(in srgb, var(--bs-primary) 15%, var(--bs-body-bg));
+ color: color-mix(in srgb, var(--bs-primary) 65%, black 0%);
+ border: 1px solid color-mix(in srgb, var(--bs-primary) 35%, transparent);
+ font-weight: 700;
+ font-size: .8rem;
+ line-height: 1;
+ white-space: nowrap;
+}
+
+.badge-gear .bi {
+ font-size: .95rem;
+ line-height: 1;
+}
+
+.badge-gear:hover {
+ background: color-mix(in srgb, var(--bs-primary) 20%, var(--bs-body-bg));
+}
+
+@media (max-width: 420px) {
+ .badge-head .lbl,
+ .badge-gear .lbl {
+ display: none;
+ }
+}
+
+/* ─────────────────────────────────────────────────────────────
+ ACCORDION (IOS-ACC)
+────────────────────────────────────────────────────────────── */
+.ios-acc {
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
+ border-radius: 14px;
+ background: var(--bs-body-bg);
+ overflow: hidden;
+}
+
+.ios-acc + .ios-acc {
+ margin-top: .75rem;
+}
+
+.ios-acc .ios-collapse-trigger {
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+ width: 100%;
+ padding: .6rem .9rem;
+}
+
+.ios-acc .ios-collapse-trigger:focus {
+ box-shadow: none;
+}
+
+.ios-acc .collapse {
+ margin: 0 !important;
+}
+
+.ios-acc .ios-list {
+ border: 0;
+ border-radius: 0;
+}
+
+.ios-acc .chips {
+ margin: 0;
+}
+
+.ios-acc .ios-acc-body {
+ padding: .5rem .25rem .75rem;
+ border-top: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
+}
+
+.ios-acc .ios-collapse-trigger + .collapse {
+ margin-top: 0 !important;
+}
+
+.ios-acc .ios-acc-body {
+ border-top: 0;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ ACTIVITY BLOCK
+────────────────────────────────────────────────────────────── */
+#activity .p-4 {
+ padding: 0 !important;
+}
+
+#activity .ios-section-title {
+ padding: 1rem 1rem .5rem !important;
+ margin: 0 !important;
+}
+
+#activity .activity-feed {
+ margin: 0 !important;
+}
+
+#activity .activity-feed .feed-card {
+ width: 100% !important;
+ max-width: none !important;
+ border: 0 !important;
+ box-shadow: none !important;
+ border-radius: 0 !important;
+ margin: 0 !important;
+}
+
+#activity .activity-feed {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+#activity .activity-feed .feed-stream {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+#activity .activity-feed .row > * {
+ flex: 0 0 100% !important;
+ max-width: 100% !important;
+}
+
+#activity .feed-actions {
+ border-top: 0 !important;
+}
+
+#activity .collapse .bg-body-tertiary.border {
+ border: 0 !important;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ SKILLS UI
+────────────────────────────────────────────────────────────── */
+#skillsBlock[data-editable="1"] .chip.chip-add {
+ display: inline-flex;
+ align-items: center;
+ cursor: pointer;
+ border-style: dashed;
+}
+
+#skillsBlock[data-editable="1"] .chip.chip-add.pulse {
+ transform: scale(.97);
+ transition: transform .15s ease;
+}
+
+#skillsBlock[data-editable="1"] .chip.chip-add .bi {
+ font-size: .95rem;
+}
+
+.chip.chip-skill {
+ position: relative;
+ padding: .35rem .65rem;
+}
+
+.chip.chip-skill .lbl {
+ transition: opacity .15s ease;
+}
+
+.chip.chip-skill .chip-del-btn {
+ position: absolute;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: transparent;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ cursor: pointer;
+ color: var(--bs-danger);
+ font-size: 1rem;
+ line-height: 1;
+ visibility: hidden;
+ opacity: 0;
+ transition: opacity .15s ease;
+ z-index: 1;
+}
+
+.chip.chip-skill .chip-del-btn .bi {
+ pointer-events: none;
+}
+
+#skillsBlock[data-editable="1"] .chip.chip-skill:hover .lbl {
+ opacity: 0;
+}
+
+#skillsBlock[data-editable="1"] .chip.chip-skill:hover .chip-del-btn,
+#skillsBlock[data-editable="1"] .chip.chip-skill:focus-within .chip-del-btn {
+ visibility: visible;
+ opacity: 1;
+}
+
+.skills-empty {
+ color: var(--bs-secondary-color);
+ font-size: .875rem;
+ margin-right: .25rem;
+}
+
+/* ─────────────────────────────────────────────────────────────
+ DEPT INLINE EDITOR
+────────────────────────────────────────────────────────────── */
+.dept-edit-btn {
+ width: 32px;
+ height: 32px;
+ padding: 0;
+ display: grid;
+ place-items: center;
+ border-radius: 999px;
+ border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 30%);
+ background: color-mix(in srgb, var(--bs-body-bg) 94%, transparent);
+}
+
+.dept-edit-btn:hover {
+ background: color-mix(in srgb, var(--bs-body-bg) 88%, transparent);
+}
+
+.dept-editor-wrap {
+ flex: 0 0 100%;
+ width: 100%;
+ margin-top: .5rem;
+}
+
+.dept-editor form {
+ display: flex;
+ align-items: center;
+ gap: .5rem;
+}
+
+.dept-role-select {
+ min-width: 180px;
+}
+
+/* полностью прячем роль, когда открыт редактор */
+.dept-item.is-editing .dept-role {
+ display: none !important;
+}
+
+/* Flex-управление элементами */
+.dept-item > .d-flex {
+ flex: 0 1 auto;
+ flex-wrap: wrap;
+ justify-content: flex-end;
+ gap: .35rem .5rem;
+ max-width: 100%;
+}
+
+.dept-line {
+ min-width: 0;
+}
+
+.badge-head,
+.badge-gear {
+ flex: 0 0 auto;
+}
+
+.ios-cell {
+ flex-wrap: wrap;
+}
+
+@media (max-width: 576px) {
+ .badge-head .lbl,
+ .badge-gear .lbl {
+ display: none;
+ }
+}
+
+/* ─────────────────────────────────────────────────────────────
+ CONTAINER
+────────────────────────────────────────────────────────────── */
+.container-xxl {
+ max-width: 1820px;
+ padding-inline: var(--bs-gutter-x, .75rem);
+}
diff --git a/backend/templates/base.html b/backend/templates/base.html
index 0863af58..4ee422fb 100644
--- a/backend/templates/base.html
+++ b/backend/templates/base.html
@@ -28,388 +28,8 @@
-
-
-
-
+
+
{% block extra_css %}{% endblock %}