/* eslint-disable */
/* components.jsx — EZ-C redesigned primitives, sidebar, page header. */

const T = window.React;
const { useState } = T;

/* ============================================================
   Icon — inline lucide-style SVG paths at 1.5 stroke
   Only the icons we actually use across the redesign.
   ============================================================ */

const ICON_PATHS = {
  // navigation
  layoutGrid: 'M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z',
  target: 'M12 2v2 M22 12h-2 M12 22v-2 M2 12h2',
  targetCircle: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 18a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4z',
  checkSquare: 'M9 11l3 3 8-8 M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11',
  listChecks: 'M3 6h2 M9 6h12 M3 12h2 M9 12h12 M3 18h2 M9 18h12',
  users: 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2 M22 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75 M13 7a4 4 0 1 1-8 0 4 4 0 0 1 8 0z',
  wallet: 'M21 12V7H5a2 2 0 0 1 0-4h14v4 M3 5v14a2 2 0 0 0 2 2h16v-5 M18 12a2 2 0 0 0 0 4h4v-4z',
  fileText: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M16 13H8 M16 17H8 M10 9H8',
  folder: 'M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z',
  clock: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 6v6l4 2',
  calendar: 'M8 2v4 M16 2v4 M3 10h18 M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z',
  plane: 'M17.8 19.2L16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z',
  database: 'M12 8a9 3 0 1 0 0-6 9 3 0 0 0 0 6z M21 12c0 1.66-4 3-9 3s-9-1.34-9-3 M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5',
  messageSquare: 'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z',
  trendingUp: 'M22 7l-8.5 8.5-5-5L2 17 M16 7h6v6',
  trendingDown: 'M22 17l-8.5-8.5-5 5L2 7 M16 17h6v-6',
  pieChart: 'M21.21 15.89A10 10 0 1 1 8 2.83 M22 12A10 10 0 0 0 12 2v10z',
  briefcase: 'M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16 M21 21V8a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v13z',
  // ui
  search: 'M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z M21 21l-4.35-4.35',
  plus: 'M12 5v14 M5 12h14',
  bell: 'M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9 M10.3 21a1.94 1.94 0 0 0 3.4 0',
  chevronDown: 'M6 9l6 6 6-6',
  chevronRight: 'M9 18l6-6-6-6',
  chevronLeft: 'M15 18l-6-6 6-6',
  chevronsUpDown: 'M7 15l5 5 5-5 M7 9l5-5 5 5',
  filter: 'M22 3H2l8 9.46V19l4 2v-8.54L22 3z',
  moreHorizontal: 'M12 12h.01 M19 12h.01 M5 12h.01',
  star: 'M12 2l3.09 6.26 6.91 1-5 4.87 1.18 6.88L12 17.77 5.82 21l1.18-6.88-5-4.87 6.91-1z',
  sparkles: 'M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z M5 3v4 M3 5h4 M19 17v4 M17 19h4',
  alertCircle: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 8v4 M12 16h.01',
  arrowDownLeft: 'M17 7L7 17 M17 17H7V7',
  arrowUpRight: 'M7 17L17 7 M7 7h10v10',
  arrowRight: 'M5 12h14 M12 5l7 7-7 7',
  arrowLeft: 'M19 12H5 M12 19l-7-7 7-7',
  check: 'M20 6L9 17l-5-5',
  x: 'M18 6L6 18 M6 6l12 12',
  flag: 'M4 22V4a2 2 0 0 1 2-2h12l-2 5 2 5H4',
  paperclip: 'M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48',
  command: 'M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z',
  logout: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4 M16 17l5-5-5-5 M21 12H9',
  grip: 'M9 5h.01 M9 12h.01 M9 19h.01 M15 5h.01 M15 12h.01 M15 19h.01',
  edit: 'M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4z',
  eye: 'M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  trash: 'M3 6h18 M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6 M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2 M10 11v6 M14 11v6',
  bot: 'M12 8V4H8 M2 14h2 M20 14h2 M15 13v2 M9 13v2 M6 8h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2z',
  pieChartSmall: 'M21.21 15.89A10 10 0 1 1 8 2.83v9.17h10.83z',
  mail: 'M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z M22 6l-10 7L2 6',
  menu: 'M3 6h18 M3 12h18 M3 18h18',
  undo: 'M9 14L4 9l5-5 M4 9h11a4 4 0 1 1 0 8h-3',
  redo: 'M15 14l5-5-5-5 M20 9H9a4 4 0 1 0 0 8h3',
  copy: 'M9 9h10a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2z M5 15a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2',
  save: 'M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z M17 21v-8H7v8 M7 3v4h8',
};

function Icon({ name, size = 16, stroke = 1.5, color = 'currentColor', style }) {
  const d = ICON_PATHS[name];
  if (!d) return null;
  // some paths use multi-subpath M ... separated by spaces — treat as one path
  const subpaths = d.split(' M').map((p, i) => (i === 0 ? p : 'M' + p));
  return (
    <svg
      width={size} height={size}
      viewBox="0 0 24 24"
      fill="none"
      stroke={color}
      strokeWidth={stroke}
      strokeLinecap="round"
      strokeLinejoin="round"
      style={{ flex: '0 0 auto', display: 'block', ...style }}
    >
      {subpaths.map((p, i) => <path key={i} d={p} />)}
    </svg>
  );
}

/* ============================================================
   Button
   ============================================================ */

function Button({ variant = 'primary', size = 'md', leftIcon, rightIcon, children, style, ...rest }) {
  const base = {
    display: 'inline-flex', alignItems: 'center', gap: 6,
    padding: size === 'sm' ? '6px 10px' : '8px 14px',
    fontSize: size === 'sm' ? 12 : 13,
    fontWeight: 500,
    borderRadius: 'var(--radius-card)',
    border: '1px solid transparent',
    transition: 'background .15s',
    whiteSpace: 'nowrap',
    lineHeight: 1.2,
  };
  const variants = {
    primary: {
      background: 'var(--color-accent-500)',
      color: '#fff',
    },
    secondary: {
      background: 'var(--color-surface)',
      color: 'var(--color-ink-700)',
      borderColor: 'var(--color-line-subtle)',
    },
    ghost: {
      background: 'transparent',
      color: 'var(--color-ink-700)',
    },
    danger: {
      background: 'var(--color-danger-500)',
      color: '#fff',
    },
    ai: {
      background: 'var(--color-ai-50)',
      color: 'var(--color-ai-700)',
      border: '1px solid rgba(168,114,54,0.18)',
    },
  };
  return (
    <button style={{ ...base, ...variants[variant], ...style }} {...rest}>
      {leftIcon ? <Icon name={leftIcon} size={size === 'sm' ? 13 : 14} /> : null}
      {children}
      {rightIcon ? <Icon name={rightIcon} size={size === 'sm' ? 13 : 14} /> : null}
    </button>
  );
}

/* ============================================================
   Badge / Chip / StatusDot
   ============================================================ */

function Badge({ tone = 'muted', children, icon, style }) {
  const tones = {
    accent: ['#EEF1F6', 'var(--color-accent-700)'],
    success: ['var(--color-success-50)', 'var(--color-success-700)'],
    warning: ['var(--color-warning-50)', 'var(--color-warning-700)'],
    danger: ['var(--color-danger-50)', 'var(--color-danger-700)'],
    info: ['var(--color-info-50)', 'var(--color-info-700)'],
    muted: ['var(--color-muted-50)', 'var(--color-ink-700)'],
    ai: ['var(--color-ai-50)', 'var(--color-ai-700)'],
  };
  const [bg, fg] = tones[tone];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '2px 8px', borderRadius: 'var(--radius-pill)',
      background: bg, color: fg,
      fontSize: 11.5, fontWeight: 500, lineHeight: 1.4,
      whiteSpace: 'nowrap',
      ...style,
    }}>
      {icon ? <Icon name={icon} size={11} /> : null}
      {children}
    </span>
  );
}

function StatusDot({ tone, size = 8 }) {
  const tones = {
    planned: 'var(--color-info-500)',
    paid: 'var(--color-success-500)',
    overdue: 'var(--color-danger-500)',
    draft: 'var(--color-ink-400)',
    active: 'var(--color-accent-500)',
    success: 'var(--color-success-500)',
    warning: 'var(--color-warning-500)',
    danger: 'var(--color-danger-500)',
    info: 'var(--color-info-500)',
    muted: 'var(--color-ink-400)',
  };
  return (
    <span style={{
      display: 'inline-block', width: size, height: size, borderRadius: '50%',
      background: tones[tone] || 'var(--color-ink-400)',
      flex: '0 0 auto',
    }} />
  );
}

/* Filter chip group used in headers */
function ChipGroup({ options, value, onChange }) {
  return (
    <div style={{ display: 'inline-flex', gap: 4 }}>
      {options.map(opt => {
        const active = opt.value === value;
        return (
          <button
            key={opt.value}
            onClick={() => onChange && onChange(opt.value)}
            style={{
              padding: '6px 10px',
              borderRadius: 'var(--radius-card)',
              border: '1px solid ' + (active ? 'transparent' : 'var(--color-line-subtle)'),
              background: active ? 'var(--color-ink-900)' : 'var(--color-surface)',
              color: active ? '#fff' : 'var(--color-ink-700)',
              fontSize: 12, fontWeight: 500,
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
            {opt.icon ? <Icon name={opt.icon} size={12} /> : null}
            {opt.label}
            {opt.count != null && (
              <span style={{
                fontSize: 11, opacity: .7,
                background: active ? 'rgba(255,255,255,.16)' : 'var(--color-muted-50)',
                padding: '1px 6px', borderRadius: 999,
              }}>{opt.count}</span>
            )}
          </button>
        );
      })}
    </div>
  );
}

/* ============================================================
   Card
   ============================================================ */

function Card({ children, padding = 16, style, hoverable }) {
  return (
    <div style={{
      background: 'var(--color-surface)',
      border: '1px solid var(--color-line-subtle)',
      borderRadius: 'var(--radius-card)',
      boxShadow: 'var(--shadow-card)',
      padding,
      ...style,
    }}>
      {children}
    </div>
  );
}

/* ============================================================
   Sidebar
   ============================================================ */

const NAV_GROUPS = [
  {
    label: null,
    items: [
      { id: 'dashboard',  icon: 'pieChartSmall', label: 'Дашборд' },
    ],
  },
  {
    label: 'РАБОТА',
    items: [
      { id: 'projects',   icon: 'briefcase',    label: 'Проекты', count: 17 },
      { id: 'tenders',    icon: 'targetCircle', label: 'Тендеры', count: 14 },
      { id: 'leads',      icon: 'trendingUp',   label: 'Лиды', count: 38, badge: 'AI' },
      { id: 'mytasks',    icon: 'checkSquare',  label: 'Мои задачи', count: 2 },
      { id: 'teamtasks',  icon: 'listChecks',   label: 'Задачи команды' },
    ],
  },
  {
    label: 'ФИНАНСЫ',
    items: [
      { id: 'payments',   icon: 'wallet',     label: 'Оплаты' },
      { id: 'docs',       icon: 'fileText',   label: 'АВР / СФ' },
    ],
  },
  {
    label: 'СПРАВОЧНИКИ',
    items: [
      { id: 'clients',    icon: 'users',      label: 'Клиенты' },
      { id: 'suppliers',  icon: 'users',      label: 'Подрядчики' },
      { id: 'prices',     icon: 'database',   label: 'База цен' },
      { id: 'files',      icon: 'folder',     label: 'Файлы' },
    ],
  },
  {
    label: 'ВРЕМЯ',
    items: [
      { id: 'timetrack',  icon: 'clock',      label: 'Тайм-трекер' },
      { id: 'timesheet',  icon: 'calendar',   label: 'Табель' },
      { id: 'vacations',  icon: 'plane',      label: 'Отпуска' },
    ],
  },
  {
    label: null,
    items: [
      { id: 'feedback',   icon: 'messageSquare', label: 'Обратная связь' },
    ],
  },
];

function Sidebar({ active = 'projects', dense = false }) {
  return (
    <aside style={{
      width: dense ? 220 : 240,
      flex: '0 0 auto',
      background: 'var(--color-canvas)',
      borderRight: '1px solid var(--color-line-subtle)',
      display: 'flex', flexDirection: 'column',
    }}>
      {/* Brand */}
      <div style={{
        padding: '18px 20px 16px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{
            width: 26, height: 26, borderRadius: 7,
            background: 'var(--color-ink-900)',
            color: '#FBFAF7',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontWeight: 700, fontSize: 11, letterSpacing: '.02em',
          }}>EZ</div>
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <span style={{ fontWeight: 600, fontSize: 14, color: 'var(--color-ink-900)', lineHeight: 1.1 }}>EZ‑C</span>
            <span style={{ fontSize: 11, color: 'var(--color-ink-500)' }}>EZS Events</span>
          </div>
        </div>
        <button style={{
          width: 26, height: 26, borderRadius: 6, border: 0, background: 'transparent',
          color: 'var(--color-ink-500)', display: 'flex', alignItems: 'center', justifyContent: 'center',
          position: 'relative',
        }}>
          <Icon name="bell" size={14} />
          <span style={{
            position: 'absolute', top: 5, right: 6, width: 5, height: 5,
            borderRadius: '50%', background: 'var(--color-danger-500)',
          }}/>
        </button>
      </div>

      {/* Nav */}
      <nav style={{ flex: 1, padding: '4px 12px 8px', overflowY: 'auto' }}>
        {NAV_GROUPS.map((group, gi) => (
          <div key={gi} style={{ marginBottom: 14 }}>
            {group.label ? (
              <div style={{
                fontSize: 10, fontWeight: 600, letterSpacing: '.09em',
                color: 'var(--color-ink-400)',
                padding: '6px 10px 4px',
                textTransform: 'uppercase',
              }}>{group.label}</div>
            ) : null}
            {group.items.map(item => {
              const isActive = item.id === active;
              return (
                <a key={item.id} style={{
                  display: 'flex', alignItems: 'center', gap: 10,
                  padding: '7px 10px', borderRadius: 'var(--radius-card)',
                  color: isActive ? 'var(--color-ink-900)' : 'var(--color-ink-700)',
                  background: isActive ? 'rgba(44,58,87,0.06)' : 'transparent',
                  fontWeight: isActive ? 600 : 500,
                  fontSize: 13,
                  marginBottom: 1,
                  textDecoration: 'none',
                  cursor: 'pointer',
                  position: 'relative',
                }}>
                  {isActive && (
                    <span style={{
                      position: 'absolute', left: -12, top: 7, bottom: 7, width: 2,
                      background: 'var(--color-accent-500)', borderRadius: 2,
                    }}/>
                  )}
                  <Icon name={item.icon} size={15} color={isActive ? 'var(--color-accent-500)' : 'var(--color-ink-500)'} />
                  <span style={{ flex: 1 }}>{item.label}</span>
                  {item.badge && (
                    <span style={{
                      fontSize: 9.5, fontWeight: 600, letterSpacing: '.04em',
                      padding: '1px 5px', borderRadius: 4,
                      background: 'var(--color-ai-50)',
                      color: 'var(--color-ai-700)',
                    }}>{item.badge}</span>
                  )}
                  {item.count != null && (
                    <span style={{
                      fontSize: 11, color: 'var(--color-ink-500)',
                      fontVariantNumeric: 'tabular-nums',
                    }}>{item.count}</span>
                  )}
                </a>
              );
            })}
          </div>
        ))}
      </nav>

      {/* AI ask */}
      <div style={{ padding: '8px 12px' }}>
        <button style={{
          width: '100%', display: 'flex', alignItems: 'center', gap: 8,
          padding: '8px 10px',
          background: 'var(--color-surface)',
          border: '1px solid var(--color-line-subtle)',
          borderRadius: 'var(--radius-card)',
          color: 'var(--color-ink-700)',
          fontSize: 12.5, fontWeight: 500,
          textAlign: 'left',
        }}>
          <Icon name="sparkles" size={14} color="var(--color-ai-500)" />
          <span style={{ flex: 1 }}>Спросить AI</span>
          <kbd style={{
            fontSize: 10, fontFamily: 'var(--font-mono)',
            padding: '1px 5px', borderRadius: 3,
            background: 'var(--color-muted-50)', color: 'var(--color-ink-500)',
          }}>⌘J</kbd>
        </button>
      </div>

      {/* Profile */}
      <div style={{
        padding: '10px 16px 14px',
        borderTop: '1px solid var(--color-line-subtle)',
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <div style={{
          width: 28, height: 28, borderRadius: '50%',
          background: '#E8E1D2', color: 'var(--color-ink-700)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 11, fontWeight: 600,
        }}>СУ</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--color-ink-900)', lineHeight: 1.2 }}>Санжар Усман</div>
          <div style={{ fontSize: 11, color: 'var(--color-ink-500)' }}>admin</div>
        </div>
        <button style={{
          width: 24, height: 24, borderRadius: 5, border: 0, background: 'transparent',
          color: 'var(--color-ink-500)',
        }}>
          <Icon name="logout" size={14} />
        </button>
      </div>
    </aside>
  );
}

/* ============================================================
   App page header with breadcrumbs
   ============================================================ */

function PageHeader({ crumbs = [], title, subtitle, actions, viewSwitch }) {
  return (
    <header style={{
      padding: '18px 32px 16px',
      borderBottom: '1px solid var(--color-line-subtle)',
      background: 'var(--color-canvas)',
    }}>
      {crumbs.length > 0 && (
        <div style={{
          display: 'flex', alignItems: 'center', gap: 4,
          fontSize: 12, color: 'var(--color-ink-500)',
          marginBottom: 6,
        }}>
          {crumbs.map((c, i) => (
            <T.Fragment key={i}>
              <span style={{
                color: i === crumbs.length - 1 ? 'var(--color-ink-700)' : 'var(--color-ink-500)',
                fontWeight: i === crumbs.length - 1 ? 500 : 400,
              }}>{c}</span>
              {i < crumbs.length - 1 && (
                <Icon name="chevronRight" size={12} color="var(--color-ink-400)" />
              )}
            </T.Fragment>
          ))}
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16 }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <h1 style={{
            margin: 0, fontSize: 22, fontWeight: 600,
            color: 'var(--color-ink-900)',
            letterSpacing: '-0.01em',
            lineHeight: 1.15,
          }}>{title}</h1>
          {subtitle && (
            <div style={{ fontSize: 13, color: 'var(--color-ink-500)', marginTop: 4 }}>{subtitle}</div>
          )}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          {viewSwitch}
          {actions}
        </div>
      </div>
    </header>
  );
}

/* View switcher segmented control */
function ViewSwitch({ options, value, onChange }) {
  return (
    <div style={{
      display: 'inline-flex',
      background: 'var(--color-muted-50)',
      borderRadius: 'var(--radius-card)',
      padding: 3,
      gap: 2,
    }}>
      {options.map(opt => {
        const active = opt.value === value;
        return (
          <button key={opt.value} onClick={() => onChange && onChange(opt.value)}
            style={{
              padding: '5px 10px', borderRadius: 5, border: 0,
              background: active ? 'var(--color-surface)' : 'transparent',
              color: active ? 'var(--color-ink-900)' : 'var(--color-ink-500)',
              fontSize: 12, fontWeight: 500,
              boxShadow: active ? '0 1px 2px rgba(20,18,14,.05)' : 'none',
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
            <Icon name={opt.icon} size={12} />
            {opt.label}
          </button>
        );
      })}
    </div>
  );
}

/* ============================================================
   Search input / Select pill
   ============================================================ */

function FilterBar({ children, style }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8,
      marginBottom: 16,
      ...style,
    }}>
      {children}
    </div>
  );
}

function SearchInput({ placeholder = 'Поиск…', value, onChange, width = 240 }) {
  return (
    <div style={{ position: 'relative', width }}>
      <Icon name="search" size={13} color="var(--color-ink-400)"
        style={{ position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)' }} />
      <input
        placeholder={placeholder}
        value={value || ''}
        onChange={e => onChange && onChange(e.target.value)}
        style={{
          width: '100%',
          padding: '7px 10px 7px 30px',
          fontSize: 13,
          background: 'var(--color-surface)',
          border: '1px solid var(--color-line-subtle)',
          borderRadius: 'var(--radius-input)',
          color: 'var(--color-ink-700)',
          outline: 'none',
        }} />
    </div>
  );
}

function SelectPill({ label, value, width }) {
  return (
    <button style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '7px 8px 7px 10px',
      background: 'var(--color-surface)',
      border: '1px solid var(--color-line-subtle)',
      borderRadius: 'var(--radius-input)',
      fontSize: 13, color: 'var(--color-ink-700)',
      minWidth: width,
    }}>
      {label && <span style={{ color: 'var(--color-ink-500)' }}>{label}:</span>}
      <span style={{ flex: 1, textAlign: 'left' }}>{value}</span>
      <Icon name="chevronDown" size={13} color="var(--color-ink-400)" />
    </button>
  );
}

/* ============================================================
   StatTile — used in dashboards and detail headers
   ============================================================ */

function StatTile({ label, value, sub, tone = 'neutral', icon, delta, deltaTone, style }) {
  const toneBg = {
    neutral: 'var(--color-surface)',
    accent: 'var(--color-accent-50)',
    success: 'var(--color-success-50)',
    warning: 'var(--color-warning-50)',
    danger: 'var(--color-danger-50)',
    info: 'var(--color-info-50)',
  }[tone];
  const toneIcon = {
    neutral: 'var(--color-ink-500)',
    accent: 'var(--color-accent-500)',
    success: 'var(--color-success-500)',
    warning: 'var(--color-warning-500)',
    danger: 'var(--color-danger-500)',
    info: 'var(--color-info-500)',
  }[tone];
  return (
    <div style={{
      flex: 1, minWidth: 0,
      background: toneBg,
      border: '1px solid var(--color-line-subtle)',
      borderRadius: 'var(--radius-card)',
      padding: '14px 16px',
      ...style,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 8 }}>
        {icon && <Icon name={icon} size={13} color={toneIcon} />}
        <span style={{ fontSize: 12, color: 'var(--color-ink-500)', fontWeight: 500 }}>{label}</span>
        {delta && (
          <span style={{
            marginLeft: 'auto',
            fontSize: 11, fontWeight: 600,
            color: deltaTone === 'down' ? 'var(--color-danger-700)' : 'var(--color-success-700)',
            display: 'inline-flex', alignItems: 'center', gap: 2,
          }}>
            <Icon name={deltaTone === 'down' ? 'trendingDown' : 'trendingUp'} size={11} />
            {delta}
          </span>
        )}
      </div>
      <div style={{
        fontSize: 22, fontWeight: 600,
        color: 'var(--color-ink-900)',
        letterSpacing: '-0.01em',
        fontVariantNumeric: 'tabular-nums',
        lineHeight: 1.1,
      }}>{value}</div>
      {sub && (
        <div style={{ fontSize: 11.5, color: 'var(--color-ink-500)', marginTop: 4 }}>{sub}</div>
      )}
    </div>
  );
}

/* ============================================================
   Avatar + AvatarStack
   ============================================================ */

const AVATAR_COLORS = ['#E8E1D2','#DDE5DD','#E0DCEA','#EADBD6','#DAE4EC','#EAE2D1'];

function Avatar({ name, size = 22 }) {
  const initials = (name || '?').split(' ').map(s => s[0]).slice(0,2).join('');
  const colorIdx = (name || '').length % AVATAR_COLORS.length;
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: AVATAR_COLORS[colorIdx],
      color: 'var(--color-ink-700)',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.4, fontWeight: 600,
      flex: '0 0 auto',
    }}>{initials}</div>
  );
}

function AvatarStack({ names, size = 22, max = 4 }) {
  const shown = names.slice(0, max);
  const overflow = names.length - shown.length;
  return (
    <div style={{ display: 'inline-flex' }}>
      {shown.map((n, i) => (
        <div key={i} style={{
          marginLeft: i === 0 ? 0 : -6,
          boxShadow: '0 0 0 2px var(--color-surface)',
          borderRadius: '50%',
        }}>
          <Avatar name={n} size={size} />
        </div>
      ))}
      {overflow > 0 && (
        <div style={{
          marginLeft: -6,
          width: size, height: size, borderRadius: '50%',
          background: 'var(--color-muted-50)',
          color: 'var(--color-ink-700)',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          fontSize: size * 0.38, fontWeight: 600,
          boxShadow: '0 0 0 2px var(--color-surface)',
        }}>+{overflow}</div>
      )}
    </div>
  );
}

/* ============================================================
   AppShell — wraps Sidebar + content with PageHeader
   ============================================================ */

function AppShell({ active, crumbs, title, subtitle, actions, viewSwitch, children }) {
  return (
    <div className="ezc-screen">
      <Sidebar active={active} />
      <div className="ezc-content">
        <PageHeader
          crumbs={crumbs}
          title={title}
          subtitle={subtitle}
          actions={actions}
          viewSwitch={viewSwitch}
        />
        <div className="ezc-main">{children}</div>
      </div>
    </div>
  );
}

/* Export all */
Object.assign(window, {
  Icon, Button, Badge, StatusDot, ChipGroup, Card,
  Sidebar, PageHeader, ViewSwitch, FilterBar, SearchInput, SelectPill,
  StatTile, Avatar, AvatarStack, AppShell,
});
