fix(shell): compact communications header and theme sidebar

This commit is contained in:
ochenstarik 2026-09-12 12:27:19 +07:00
parent 42929d7284
commit f2ac97a841
17 changed files with 51 additions and 106 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 KiB

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View file

@ -1,5 +1,5 @@
{ {
"generatedAt": "2026-09-11T12:29:57.828Z", "generatedAt": "2026-09-12T05:25:45.504Z",
"module": "communications", "module": "communications",
"version": "v3.0", "version": "v3.0",
"referenceMockups": [ "referenceMockups": [
@ -68,13 +68,13 @@
"filename": "desktop-with-krona-ai.png", "filename": "desktop-with-krona-ai.png",
"theme": "state-capture", "theme": "state-capture",
"viewport": "desktop-with-krona-ai", "viewport": "desktop-with-krona-ai",
"capturedAt": "2026-09-11T12:29:50.764Z" "capturedAt": "2026-09-12T05:25:45.132Z"
}, },
{ {
"filename": "desktop-without-krona-ai.png", "filename": "desktop-without-krona-ai.png",
"theme": "state-capture", "theme": "state-capture",
"viewport": "desktop-without-krona-ai", "viewport": "desktop-without-krona-ai",
"capturedAt": "2026-09-11T12:29:49.887Z" "capturedAt": "2026-09-12T05:25:44.475Z"
}, },
{ {
"filename": "graphite-forest-dark-desktop-1280.png", "filename": "graphite-forest-dark-desktop-1280.png",
@ -86,7 +86,7 @@
"filename": "graphite-forest-dark-desktop-1440.png", "filename": "graphite-forest-dark-desktop-1440.png",
"theme": "graphite-forest-dark", "theme": "graphite-forest-dark",
"viewport": "desktop-1440", "viewport": "desktop-1440",
"capturedAt": "2026-09-11T12:22:07.332Z" "capturedAt": "2026-09-12T05:25:42.065Z"
}, },
{ {
"filename": "graphite-forest-dark-desktop-1920.png", "filename": "graphite-forest-dark-desktop-1920.png",
@ -104,7 +104,7 @@
"filename": "graphite-forest-dark-mobile-390.png", "filename": "graphite-forest-dark-mobile-390.png",
"theme": "graphite-forest-dark", "theme": "graphite-forest-dark",
"viewport": "mobile-390", "viewport": "mobile-390",
"capturedAt": "2026-09-11T12:21:02.940Z" "capturedAt": "2026-09-12T05:25:33.933Z"
}, },
{ {
"filename": "graphite-forest-dark-mobile-430.png", "filename": "graphite-forest-dark-mobile-430.png",
@ -128,19 +128,19 @@
"filename": "mobile-chat.png", "filename": "mobile-chat.png",
"theme": "state-capture", "theme": "state-capture",
"viewport": "mobile-chat", "viewport": "mobile-chat",
"capturedAt": "2026-09-11T12:29:13.147Z" "capturedAt": "2026-09-12T05:25:36.209Z"
}, },
{ {
"filename": "mobile-contact.png", "filename": "mobile-contact.png",
"theme": "state-capture", "theme": "state-capture",
"viewport": "mobile-contact", "viewport": "mobile-contact",
"capturedAt": "2026-09-11T12:29:13.337Z" "capturedAt": "2026-09-12T05:25:36.390Z"
}, },
{ {
"filename": "mobile-list.png", "filename": "mobile-list.png",
"theme": "state-capture", "theme": "state-capture",
"viewport": "mobile-list", "viewport": "mobile-list",
"capturedAt": "2026-09-11T12:29:12.902Z" "capturedAt": "2026-09-12T05:25:35.998Z"
}, },
{ {
"filename": "noble-green-desktop-1280.png", "filename": "noble-green-desktop-1280.png",
@ -152,7 +152,7 @@
"filename": "noble-green-desktop-1440.png", "filename": "noble-green-desktop-1440.png",
"theme": "noble-green", "theme": "noble-green",
"viewport": "desktop-1440", "viewport": "desktop-1440",
"capturedAt": "2026-09-11T12:22:06.701Z" "capturedAt": "2026-09-12T05:25:41.554Z"
}, },
{ {
"filename": "noble-green-desktop-1920.png", "filename": "noble-green-desktop-1920.png",
@ -170,7 +170,7 @@
"filename": "noble-green-mobile-390.png", "filename": "noble-green-mobile-390.png",
"theme": "noble-green", "theme": "noble-green",
"viewport": "mobile-390", "viewport": "mobile-390",
"capturedAt": "2026-09-11T12:21:02.534Z" "capturedAt": "2026-09-12T05:25:33.543Z"
}, },
{ {
"filename": "noble-green-mobile-430.png", "filename": "noble-green-mobile-430.png",
@ -200,7 +200,7 @@
"filename": "parchment-light-desktop-1440.png", "filename": "parchment-light-desktop-1440.png",
"theme": "parchment-light", "theme": "parchment-light",
"viewport": "desktop-1440", "viewport": "desktop-1440",
"capturedAt": "2026-09-11T12:22:06.120Z" "capturedAt": "2026-09-12T05:25:41.001Z"
}, },
{ {
"filename": "parchment-light-desktop-1920.png", "filename": "parchment-light-desktop-1920.png",
@ -218,7 +218,7 @@
"filename": "parchment-light-mobile-390.png", "filename": "parchment-light-mobile-390.png",
"theme": "parchment-light", "theme": "parchment-light",
"viewport": "mobile-390", "viewport": "mobile-390",
"capturedAt": "2026-09-11T12:21:02.124Z" "capturedAt": "2026-09-12T05:25:33.154Z"
}, },
{ {
"filename": "parchment-light-mobile-430.png", "filename": "parchment-light-mobile-430.png",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View file

@ -43,23 +43,16 @@ test.describe('Scenario 13: Communications Visual & Responsive Design System V3
} }
}); });
test('2. Header, Slogan Watermark, and Channel Switcher validation', async ({ page }) => { test('2. Compact header and channel switcher validation', async ({ page }) => {
const vp = page.viewportSize(); const vp = page.viewportSize();
const isMobile = (vp?.width ?? 1200) < 640; const isMobile = (vp?.width ?? 1200) < 640;
const isDesktop = (vp?.width ?? 1200) >= 1024;
// Check main header // Check main header
await expect(page.locator('h1', { hasText: 'Коммуникации' })).toBeVisible(); await expect(page.locator('h1', { hasText: 'Коммуникации' })).toBeVisible();
if (!isMobile) { await expect(page.getByText('Все сообщения, почта и каналы компании в одном пространстве')).toHaveCount(0);
await expect( await expect(page.getByText('Больше, чем общение с поддержкой')).toHaveCount(0);
page.locator('text=Все сообщения, почта и каналы компании в одном пространстве') await expect(page.getByRole('button', { name: /добавить канал/i })).toHaveCount(0);
).toBeVisible();
}
if (isDesktop) {
await expect(page.locator('text=Больше, чем общение с поддержкой')).toBeVisible();
}
// Check all 5 tabs // Check all 5 tabs
await expect(page.getByRole('tab', { name: /мессенджеры/i })).toBeVisible(); await expect(page.getByRole('tab', { name: /мессенджеры/i })).toBeVisible();

View file

@ -66,12 +66,12 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
return ( return (
<aside <aside
data-testid="sidebar" data-testid="sidebar"
className={`relative h-screen bg-[#252722] text-[#D8D8D0] hidden md:flex flex-col border-r border-[#3A3D35] transition-all duration-200 z-20 select-none ${ className={`relative h-screen bg-[var(--sidebar-bg)] text-[var(--sidebar-text)] hidden md:flex flex-col border-r border-[var(--sidebar-border)] transition-[width,background-color,color,border-color] duration-300 z-20 select-none ${
collapsed ? 'w-16' : 'w-56' collapsed ? 'w-16' : 'w-56'
}`} }`}
> >
{/* Brand Header */} {/* Brand Header */}
<div className="h-14 px-3.5 flex items-center justify-between border-b border-[#3A3D35] bg-[#20221E]"> <div className="h-14 px-3.5 flex items-center justify-between border-b border-[var(--sidebar-border)] bg-[var(--sidebar-deep)] transition-colors duration-300">
<div className="flex items-center gap-2.5 overflow-hidden"> <div className="flex items-center gap-2.5 overflow-hidden">
{/* Logo asset from public/branding/krona-symbol.png */} {/* Logo asset from public/branding/krona-symbol.png */}
<img <img
@ -81,10 +81,10 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
/> />
{!collapsed && ( {!collapsed && (
<div className="flex flex-col min-w-0 leading-tight select-none"> <div className="flex flex-col min-w-0 leading-tight select-none">
<span className="text-sm font-bold tracking-wider text-[#E5B842] uppercase truncate"> <span className="text-sm font-bold tracking-wider text-[var(--krona-gold)] uppercase truncate">
Крона Крона
</span> </span>
<span className="text-[9px] uppercase tracking-widest text-[#B78335] font-semibold"> <span className="text-[9px] uppercase tracking-widest text-[var(--krona-gold)] font-semibold">
Бизнес-платформа Бизнес-платформа
</span> </span>
</div> </div>
@ -93,7 +93,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
<button <button
onClick={() => setUserCollapsed(!collapsed)} onClick={() => setUserCollapsed(!collapsed)}
className="p-1 rounded text-[#858980] hover:text-[#D8D8D0] hover:bg-[#30332C] transition-colors" className="p-1 rounded text-[var(--sidebar-text-muted)] hover:text-[var(--sidebar-text)] hover:bg-[var(--sidebar-hover)] transition-colors"
title={collapsed ? 'Развернуть меню' : 'Свернуть меню'} title={collapsed ? 'Развернуть меню' : 'Свернуть меню'}
> >
{collapsed ? <ChevronRight className="w-4 h-4" /> : <ChevronLeft className="w-4 h-4" />} {collapsed ? <ChevronRight className="w-4 h-4" /> : <ChevronLeft className="w-4 h-4" />}
@ -110,8 +110,8 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
className={({ isActive }) => className={({ isActive }) =>
`group relative flex items-center gap-2.5 px-2.5 py-2 rounded-md text-xs font-medium transition-all ${ `group relative flex items-center gap-2.5 px-2.5 py-2 rounded-md text-xs font-medium transition-all ${
isActive isActive
? 'bg-[#34382F] text-[#F5F0E5] font-semibold' ? 'bg-[var(--sidebar-active)] text-[var(--sidebar-text-active)] font-semibold'
: 'text-[#BFC1B9] hover:text-[#F5F0E5] hover:bg-[#30332C]' : 'text-[var(--sidebar-text-secondary)] hover:text-[var(--sidebar-text)] hover:bg-[var(--sidebar-hover)]'
}` }`
} }
title={collapsed ? item.label : undefined} title={collapsed ? item.label : undefined}
@ -120,10 +120,10 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
<> <>
{/* Active indicator bar */} {/* Active indicator bar */}
{isActive && ( {isActive && (
<div className="absolute left-0 top-1.5 bottom-1.5 w-1 bg-[#B78335] rounded-r" /> <div className="absolute left-0 top-1.5 bottom-1.5 w-1 bg-[var(--sidebar-indicator)] rounded-r" />
)} )}
<div className={`shrink-0 ${isActive ? 'text-[#D4B16D]' : 'text-[#BFC1B9]'}`}> <div className={`shrink-0 ${isActive ? 'text-[var(--sidebar-icon-active)]' : 'text-[var(--sidebar-icon)]'}`}>
{ICON_MAP[item.iconName] || <LayoutDashboard className="w-4 h-4 shrink-0" />} {ICON_MAP[item.iconName] || <LayoutDashboard className="w-4 h-4 shrink-0" />}
</div> </div>
@ -131,7 +131,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
<div className="flex-1 flex items-center justify-between truncate"> <div className="flex-1 flex items-center justify-between truncate">
<span className="truncate">{item.label}</span> <span className="truncate">{item.label}</span>
{item.badge && ( {item.badge && (
<span className="text-[10px] px-1.5 py-0.5 rounded-full bg-[#3A3D35] text-[#D8D8D0] font-mono"> <span className="text-[10px] px-1.5 py-0.5 rounded-full bg-[var(--sidebar-surface)] text-[var(--sidebar-text)] font-mono">
{item.badge} {item.badge}
</span> </span>
)} )}
@ -144,9 +144,9 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
{/* Custom Entities Section */} {/* Custom Entities Section */}
{customEntities.length > 0 && ( {customEntities.length > 0 && (
<div className="pt-2 mt-2 border-t border-[#3A3D35]/80"> <div className="pt-2 mt-2 border-t border-[var(--sidebar-border)]">
{!collapsed && ( {!collapsed && (
<div className="px-2 pb-1 text-[10px] font-semibold uppercase tracking-wider text-[#858980]"> <div className="px-2 pb-1 text-[10px] font-semibold uppercase tracking-wider text-[var(--sidebar-text-muted)]">
Пользовательские модули Пользовательские модули
</div> </div>
)} )}
@ -157,8 +157,8 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
className={({ isActive }) => className={({ isActive }) =>
`group relative flex items-center gap-2.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${ `group relative flex items-center gap-2.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${
isActive isActive
? 'bg-[#34382F] text-[#F5F0E5] font-semibold' ? 'bg-[var(--sidebar-active)] text-[var(--sidebar-text-active)] font-semibold'
: 'text-[#BFC1B9] hover:text-[#F5F0E5] hover:bg-[#30332C]' : 'text-[var(--sidebar-text-secondary)] hover:text-[var(--sidebar-text)] hover:bg-[var(--sidebar-hover)]'
}` }`
} }
title={collapsed ? ent.name : undefined} title={collapsed ? ent.name : undefined}
@ -166,7 +166,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
{({ isActive }) => ( {({ isActive }) => (
<> <>
{isActive && ( {isActive && (
<div className="absolute left-0 top-1.5 bottom-1.5 w-1 bg-[#B78335] rounded-r" /> <div className="absolute left-0 top-1.5 bottom-1.5 w-1 bg-[var(--sidebar-indicator)] rounded-r" />
)} )}
<div className="shrink-0 text-krona-gold"> <div className="shrink-0 text-krona-gold">
<Sparkles className="w-3.5 h-3.5" /> <Sparkles className="w-3.5 h-3.5" />
@ -188,8 +188,8 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
className={({ isActive }) => className={({ isActive }) =>
`group relative flex items-center gap-2.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${ `group relative flex items-center gap-2.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-all ${
isActive isActive
? 'bg-[#34382F] text-[#F5F0E5] font-semibold' ? 'bg-[var(--sidebar-active)] text-[var(--sidebar-text-active)] font-semibold'
: 'text-[#BFC1B9] hover:text-[#F5F0E5] hover:bg-[#30332C]' : 'text-[var(--sidebar-text-secondary)] hover:text-[var(--sidebar-text)] hover:bg-[var(--sidebar-hover)]'
}` }`
} }
title={collapsed ? 'Конструктор сущностей' : undefined} title={collapsed ? 'Конструктор сущностей' : undefined}
@ -197,7 +197,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
{({ isActive }) => ( {({ isActive }) => (
<> <>
{isActive && ( {isActive && (
<div className="absolute left-0 top-1.5 bottom-1.5 w-1 bg-[#B78335] rounded-r" /> <div className="absolute left-0 top-1.5 bottom-1.5 w-1 bg-[var(--sidebar-indicator)] rounded-r" />
)} )}
<div className="shrink-0 text-krona-green"> <div className="shrink-0 text-krona-green">
<Workflow className="w-3.5 h-3.5" /> <Workflow className="w-3.5 h-3.5" />
@ -212,14 +212,14 @@ export const Sidebar: React.FC<SidebarProps> = ({ isTabletCompact = false }) =>
</div> </div>
{/* Footer / Role indicator */} {/* Footer / Role indicator */}
<div className="p-2.5 border-t border-[#3A3D35] bg-[#20221E]/60 text-xs"> <div className="p-2.5 border-t border-[var(--sidebar-border)] bg-[var(--sidebar-deep)] text-xs transition-colors duration-300">
{!collapsed ? ( {!collapsed ? (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-krona-green animate-pulse" /> <div className="w-2 h-2 rounded-full bg-krona-green animate-pulse" />
<div className="truncate"> <div className="truncate">
<div className="text-[11px] font-semibold text-[#F5F0E5] truncate">{role.label}</div> <div className="text-[11px] font-semibold text-[var(--sidebar-text)] truncate">{role.label}</div>
<div className="text-[9px] text-[#858980]">RBAC: {role.badge}</div> <div className="text-[9px] text-[var(--sidebar-text-muted)]">RBAC: {role.badge}</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -54,6 +54,7 @@ export const Topbar: React.FC = () => {
if (m.route === '/') return currentPath === '/'; if (m.route === '/') return currentPath === '/';
return currentPath.startsWith(m.route); return currentPath.startsWith(m.route);
}) || SYSTEM_MODULES[0]; }) || SYSTEM_MODULES[0];
const isCommunicationsModule = currentModule.id === 'communications';
// For operations, subtabs are dynamic based on active profile & capabilities // For operations, subtabs are dynamic based on active profile & capabilities
const getSubtabs = () => { const getSubtabs = () => {
@ -351,8 +352,16 @@ export const Topbar: React.FC = () => {
</div> </div>
</div> </div>
{/* Communications owns its local tabs inside the module. Keep only the
module title here so the shell does not render a duplicate menu. */}
{isCommunicationsModule && (
<div className="hidden md:flex h-10 px-5 border-t border-krona-border/60 bg-krona-workspace/40 items-center shrink-0">
<span className="font-serif text-lg font-bold text-krona-primary">Коммуникации</span>
</div>
)}
{/* Subheader / Subtabs Navigation Bar (Desktop & Tablet) */} {/* Subheader / Subtabs Navigation Bar (Desktop & Tablet) */}
{activeSubtabs.length > 0 && ( {!isCommunicationsModule && activeSubtabs.length > 0 && (
<div className="h-10 px-4 border-t border-krona-border/60 bg-krona-workspace/40 flex items-center overflow-x-auto gap-1 text-xs"> <div className="h-10 px-4 border-t border-krona-border/60 bg-krona-workspace/40 flex items-center overflow-x-auto gap-1 text-xs">
{activeSubtabs.map((tab) => { {activeSubtabs.map((tab) => {
const isActive = const isActive =

View file

@ -41,7 +41,6 @@ export function CommunicationsModule() {
<CommunicationsHeader <CommunicationsHeader
activeTab={currentTab} activeTab={currentTab}
onTabChange={handleTabChange} onTabChange={handleTabChange}
onAddChannel={() => setIsConnectChannelOpen(true)}
unreadChats={48} unreadChats={48}
unreadEmails={10} unreadEmails={10}
unreadChannels={4} unreadChannels={4}

View file

@ -1,12 +1,11 @@
import React from 'react'; import React from 'react';
import { MessageSquare, Mail, Hash, Users, Settings, Plus } from 'lucide-react'; import { MessageSquare, Mail, Hash, Users, Settings } from 'lucide-react';
import { CommunicationTab } from '../types'; import { CommunicationTab } from '../types';
import { Button, Tabs } from '@krona/ui'; import { Tabs } from '@krona/ui';
interface CommunicationsHeaderProps { interface CommunicationsHeaderProps {
activeTab: CommunicationTab; activeTab: CommunicationTab;
onTabChange: (tab: CommunicationTab) => void; onTabChange: (tab: CommunicationTab) => void;
onAddChannel: () => void;
unreadChats: number; unreadChats: number;
unreadEmails: number; unreadEmails: number;
unreadChannels: number; unreadChannels: number;
@ -15,7 +14,6 @@ interface CommunicationsHeaderProps {
export function CommunicationsHeader({ export function CommunicationsHeader({
activeTab, activeTab,
onTabChange, onTabChange,
onAddChannel,
unreadChats, unreadChats,
unreadEmails, unreadEmails,
unreadChannels, unreadChannels,
@ -52,51 +50,8 @@ export function CommunicationsHeader({
]; ];
return ( return (
<header className="relative bg-[var(--krona-surface)] border-b border-[var(--krona-border-subtle)] px-3 sm:px-6 pt-3 sm:pt-5 pb-2 sm:pb-3 shrink-0 overflow-hidden"> <header className="bg-[var(--krona-surface)] border-b border-[var(--krona-border-subtle)] px-3 sm:px-5 py-1.5 shrink-0 overflow-hidden">
<div className="hidden lg:flex items-center gap-3 absolute right-8 top-4 text-right pointer-events-none opacity-50 font-serif italic text-sm text-[var(--krona-text-secondary)]"> <h1 className="sr-only">Коммуникации</h1>
<span>Больше, чем общение с поддержкой</span>
<svg
className="w-8 h-8 text-[var(--krona-gold)] shrink-0"
viewBox="0 0 32 32"
fill="none"
stroke="currentColor"
strokeWidth="1.2"
aria-hidden="true"
>
<path d="M16 28C16 18 20 10 28 6" strokeLinecap="round" />
<path d="M16 24C12 20 8 18 4 17" strokeLinecap="round" />
<path d="M16 19C20 16 24 15 27 15" strokeLinecap="round" />
<path d="M16 14C12 11 9 10 6 10" strokeLinecap="round" />
<path d="M18 10C21 8 24 7 26 7" strokeLinecap="round" />
<circle cx="28" cy="6" r="1.5" fill="currentColor" />
<circle cx="4" cy="17" r="1.5" fill="currentColor" />
<circle cx="27" cy="15" r="1.5" fill="currentColor" />
<circle cx="6" cy="10" r="1.5" fill="currentColor" />
</svg>
</div>
<div className="flex items-center justify-between gap-3 mb-2 sm:mb-4">
<div>
<h1 className="text-xl sm:text-3xl font-bold font-serif text-[var(--krona-text-primary)]">
Коммуникации
</h1>
<p className="hidden sm:block text-sm text-[var(--krona-text-secondary)] mt-1">
Все сообщения, почта и каналы компании в одном пространстве
</p>
</div>
{/* Mobile compact action button */}
<button
type="button"
onClick={onAddChannel}
className="sm:hidden h-10 w-10 rounded-lg border border-[var(--krona-border)] bg-[var(--krona-surface)] hover:bg-[var(--krona-surface-hover)] text-[var(--krona-primary)] font-medium flex items-center justify-center shrink-0 transition-colors active:scale-95"
aria-label="Добавить канал"
>
<Plus className="w-4 h-4 text-[var(--krona-primary)]" />
<span className="sr-only">Добавить канал</span>
</button>
</div>
<div className="flex items-center justify-between gap-3 min-w-0"> <div className="flex items-center justify-between gap-3 min-w-0">
<div className="flex-1 min-w-0 overflow-x-auto scrollbar-none"> <div className="flex-1 min-w-0 overflow-x-auto scrollbar-none">
<Tabs <Tabs
@ -107,17 +62,6 @@ export function CommunicationsHeader({
/> />
</div> </div>
{/* Desktop / Tablet full button */}
<div className="hidden sm:flex items-center gap-2 shrink-0">
<Button
variant="secondary"
size="sm"
onClick={onAddChannel}
leftIcon={<Plus className="w-4 h-4 text-[var(--krona-primary)]" />}
>
Добавить канал
</Button>
</div>
</div> </div>
</header> </header>
); );