/* Оболочка портала: фон, бренд, сайдбар, топбар, экран входа, общие мелочи. */
(function () {
  const { Badge, Button, Input, TerminalLine } = window.DesignSystem_219642;
  const D = window.PortalData;

  // ---------- Фон: dot-grid + радиальные акценты + лёгкая схема ----------
  function Background({ dots = true }) {
    return (
      <div aria-hidden="true" style={{ position: 'fixed', inset: 0, zIndex: 0, pointerEvents: 'none', overflow: 'hidden' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--surface-base)' }} />
        <div style={{
          position: 'absolute', inset: 0,
          backgroundImage: 'var(--pattern-dots)', backgroundSize: 'var(--pattern-dots-size)',
          opacity: dots ? 0.5 : 0,
          maskImage: 'radial-gradient(ellipse 90% 70% at 70% 0%, #000 30%, transparent 75%)',
          WebkitMaskImage: 'radial-gradient(ellipse 90% 70% at 70% 0%, #000 30%, transparent 75%)',
        }} />
        <div style={{ position: 'absolute', top: '-20%', right: '-10%', width: '60%', height: '70%', background: 'radial-gradient(circle, rgba(37,99,235,0.10), transparent 70%)' }} />
        <div style={{ position: 'absolute', bottom: '-25%', left: '-5%', width: '50%', height: '60%', background: 'radial-gradient(circle, rgba(37,99,235,0.06), transparent 70%)' }} />
      </div>
    );
  }

  // ---------- Бренд ----------
  function Brand({ compact }) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
        <img src="assets/logo-ulitka-white.png" alt="ЛАН-ПРОЕКТ" style={{ width: '34px', height: '34px', objectFit: 'contain', filter: 'drop-shadow(0 0 8px rgba(59,130,246,0.35))' }} />
        {!compact && (
          <div style={{ lineHeight: 1.1 }}>
            <div style={{ fontWeight: 800, fontSize: '17px', letterSpacing: '-0.01em', color: 'var(--text-primary)' }}>
              ЛАН<span style={{ color: 'var(--accent-light)' }}>-ПРОЕКТ</span>
            </div>
            <div style={{ fontSize: '11px', letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--text-muted)', marginTop: '2px' }}>Портал поддержки</div>
          </div>
        )}
      </div>
    );
  }

  // ---------- Статусный бейдж (tone -> variant DS) ----------
  function StatusBadge({ tone, dot, icon, children }) {
    const map = { online: 'online', active: 'online', warning: 'neutral', danger: 'neutral', accent: 'accent' };
    const style =
      tone === 'warning'
        ? { background: 'rgba(245,158,11,0.12)', color: 'var(--amber-500)', border: '1px solid rgba(245,158,11,0.3)' }
        : tone === 'danger'
        ? { background: 'rgba(239,68,68,0.12)', color: 'var(--red-500)', border: '1px solid rgba(239,68,68,0.3)' }
        : {};
    return (
      <Badge variant={map[tone] || 'neutral'} dot={dot} icon={icon} style={style}>{children}</Badge>
    );
  }

  // ---------- Сайдбар ----------
  function NavItem({ active, icon, label, badge, soon, onClick }) {
    const [h, setH] = React.useState(false);
    return (
      <button
        onClick={soon ? undefined : onClick}
        onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
        style={{
          position: 'relative', display: 'flex', alignItems: 'center', gap: '12px', width: '100%',
          padding: '10px 14px', borderRadius: 'var(--radius)', border: '1px solid transparent',
          background: active ? 'var(--accent-muted)' : h && !soon ? 'var(--surface-overlay)' : 'transparent',
          borderColor: active ? 'var(--border-accent)' : 'transparent',
          color: active ? 'var(--text-primary)' : soon ? 'var(--text-muted)' : 'var(--text-secondary)',
          cursor: soon ? 'default' : 'pointer', font: 'inherit', fontSize: '14px', fontWeight: active ? 600 : 500,
          textAlign: 'left', transition: 'all var(--transition)',
        }}
      >
        {active && <span style={{ position: 'absolute', left: 0, top: '18%', height: '64%', width: '3px', borderRadius: '0 3px 3px 0', background: 'var(--accent)', boxShadow: 'var(--glow-blue-sm)' }} />}
        <i className={icon} style={{ width: '18px', textAlign: 'center', color: active ? 'var(--accent-light)' : 'inherit', fontSize: '15px' }} />
        <span style={{ flex: 1 }}>{label}</span>
        {badge != null && <span style={{ fontSize: '11px', fontWeight: 700, color: 'var(--accent-light)', background: 'var(--accent-soft)', borderRadius: '100px', padding: '1px 8px' }}>{badge}</span>}
        {soon && <span style={{ fontSize: '10px', letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--text-muted)', border: '1px solid var(--border)', borderRadius: '100px', padding: '1px 7px' }}>скоро</span>}
      </button>
    );
  }

  function NavGroup({ title, children }) {
    return (
      <div style={{ marginBottom: '20px' }}>
        <div style={{ fontSize: '11px', letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--text-muted)', padding: '0 14px', marginBottom: '8px' }}>{title}</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: '2px' }}>{children}</div>
      </div>
    );
  }

  function initials(name) {
    if (!name) return '—';
    return name.trim().split(/\s+/).map((s) => s[0]).slice(0, 2).join('').toUpperCase();
  }

  function Sidebar({ route, nav, role, user, onRoleSwitch, onLogout, updatesCount }) {
    const is = (s) => route.screen === s || (s === 'dashboard' && route.screen === 'product') || (s === 'updates' && route.screen === 'version');
    return (
      <aside style={{
        position: 'fixed', top: 0, left: 0, bottom: 0, width: '264px', zIndex: 20,
        display: 'flex', flexDirection: 'column', background: 'var(--surface-card)',
        borderRight: '1px solid var(--border)',
      }}>
        <div style={{ padding: '22px 20px 18px', borderBottom: '1px solid var(--border)' }}>
          <Brand />
        </div>

        <nav style={{ flex: 1, overflowY: 'auto', padding: '20px 14px' }}>
          {role === 'client' ? (
            <React.Fragment>
              <NavGroup title="Кабинет">
                <NavItem active={is('dashboard')} icon="fas fa-gauge-high" label="Обзор" onClick={() => nav({ screen: 'dashboard' })} />
                <NavItem active={is('updates')} icon="fas fa-cloud-arrow-down" label="Обновления" badge={updatesCount} onClick={() => nav({ screen: 'updates' })} />
                <NavItem active={is('profile')} icon="fas fa-id-badge" label="Профиль" onClick={() => nav({ screen: 'profile' })} />
              </NavGroup>
              <NavGroup title="Помощь">
                <NavItem icon="fas fa-headset" label="Техподдержка" soon />
                <NavItem icon="fas fa-book" label="База знаний" soon />
              </NavGroup>
            </React.Fragment>
          ) : (
            <NavGroup title="Управление">
              <NavItem active={is('admin-products')} icon="fas fa-cubes" label="Продукты" onClick={() => nav({ screen: 'admin-products' })} />
              <NavItem active={is('admin-versions')} icon="fas fa-code-branch" label="Версии" onClick={() => nav({ screen: 'admin-versions' })} />
              <NavItem active={is('admin-licenses')} icon="fas fa-key" label="Лицензии" onClick={() => nav({ screen: 'admin-licenses' })} />
              <NavItem active={is('admin-users')} icon="fas fa-users" label="Пользователи" onClick={() => nav({ screen: 'admin-users' })} />
              <NavItem active={is('admin-log')} icon="fas fa-list-check" label="Журнал выдач" onClick={() => nav({ screen: 'admin-log' })} />
            </NavGroup>
          )}
        </nav>

        <div style={{ padding: '14px', borderTop: '1px solid var(--border)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '11px', padding: '8px 6px 12px' }}>
            <div style={{ width: '38px', height: '38px', borderRadius: '50%', display: 'grid', placeItems: 'center', background: 'var(--accent-muted)', border: '1px solid var(--border-accent)', color: 'var(--accent-light)', fontWeight: 700, fontSize: '14px' }}>
              {initials(user && user.display_name)}
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: '13px', fontWeight: 600, color: 'var(--text-primary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{(user && user.display_name) || (role === 'admin' ? 'Администратор' : 'Клиент')}</div>
              <div style={{ fontSize: '11px', color: 'var(--text-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{(user && user.org) || (role === 'admin' ? 'ЛАН-ПРОЕКТ' : '')}</div>
            </div>
            <button title="Выйти" onClick={onLogout} style={{ background: 'transparent', border: '1px solid var(--border)', color: 'var(--text-secondary)', width: '30px', height: '30px', borderRadius: 'var(--radius)', cursor: 'pointer' }}>
              <i className="fas fa-right-from-bracket" />
            </button>
          </div>
        </div>
      </aside>
    );
  }

  // ---------- Топбар ----------
  function Crumbs({ items }) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '13px', minWidth: 0 }}>
        {items.map((it, i) => (
          <React.Fragment key={i}>
            {i > 0 && <i className="fas fa-chevron-right" style={{ fontSize: '9px', color: 'var(--text-muted)' }} />}
            <span style={{ color: i === items.length - 1 ? 'var(--text-primary)' : 'var(--text-secondary)', fontWeight: i === items.length - 1 ? 600 : 400, cursor: it.onClick ? 'pointer' : 'default', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} onClick={it.onClick}>
              {it.label}
            </span>
          </React.Fragment>
        ))}
      </div>
    );
  }

  function NotificationsBell({ items }) {
    const [open, setOpen] = React.useState(false);
    const count = items.length;
    const toneColor = { danger: 'var(--red-500)', warning: 'var(--amber-500)', accent: 'var(--accent-light)' };
    React.useEffect(() => {
      if (!open) return;
      const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
      window.addEventListener('keydown', onKey);
      return () => window.removeEventListener('keydown', onKey);
    }, [open]);
    return (
      <div style={{ position: 'relative' }}>
        <button title="Уведомления" onClick={() => setOpen((o) => !o)} style={{ position: 'relative', background: open ? 'var(--surface-overlay)' : 'transparent', border: `1px solid ${open ? 'var(--border-light)' : 'var(--border)'}`, color: 'var(--text-secondary)', width: '36px', height: '36px', borderRadius: 'var(--radius)', cursor: 'pointer', transition: 'all var(--transition)' }}>
          <i className="fas fa-bell" />
          {count > 0 && (
            <span style={{ position: 'absolute', top: '-4px', right: '-4px', minWidth: '16px', height: '16px', padding: '0 3px', boxSizing: 'border-box', borderRadius: '8px', background: 'var(--accent)', color: '#fff', fontSize: '10px', fontWeight: 700, display: 'grid', placeItems: 'center', border: '2px solid var(--surface-card)' }}>{count > 9 ? '9+' : count}</span>
          )}
        </button>
        {open && (
          <React.Fragment>
            <div onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 40 }} />
            <div style={{ position: 'absolute', top: '46px', right: 0, width: '340px', maxHeight: '60vh', overflowY: 'auto', zIndex: 41, background: 'var(--surface-overlay)', border: '1px solid var(--border-light)', borderRadius: 'var(--radius)', boxShadow: 'var(--shadow-lg)' }}>
              <div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                <span style={{ fontSize: '13px', fontWeight: 700, color: 'var(--text-primary)' }}>Уведомления</span>
                <span style={{ fontSize: '11px', color: 'var(--text-muted)' }}>{count}</span>
              </div>
              {count === 0 ? (
                <div style={{ padding: '28px 16px', textAlign: 'center', color: 'var(--text-muted)', fontSize: '13px' }}>
                  <i className="far fa-bell-slash" style={{ fontSize: '20px', display: 'block', marginBottom: '8px', opacity: 0.6 }} />
                  Нет новых уведомлений
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column' }}>
                  {items.map((n) => (
                    <button key={n.id} onClick={() => { setOpen(false); n.onClick && n.onClick(); }}
                      onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--surface-card-hover)'; }}
                      onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }}
                      style={{ display: 'flex', gap: '12px', alignItems: 'flex-start', textAlign: 'left', width: '100%', padding: '12px 16px', background: 'transparent', border: 'none', borderBottom: '1px solid var(--border)', cursor: 'pointer', font: 'inherit', transition: 'background var(--transition)' }}>
                      <i className={n.icon} style={{ marginTop: '2px', fontSize: '14px', color: toneColor[n.tone] || 'var(--accent-light)' }} />
                      <span style={{ flex: 1, fontSize: '13px', color: 'var(--text-secondary)', lineHeight: 1.45 }}>{n.title}</span>
                      <i className="fas fa-chevron-right" style={{ marginTop: '4px', fontSize: '10px', color: 'var(--text-muted)' }} />
                    </button>
                  ))}
                </div>
              )}
            </div>
          </React.Fragment>
        )}
      </div>
    );
  }

  function TopBar({ crumbs, notifications = [] }) {
    return (
      <header style={{
        position: 'sticky', top: 0, zIndex: 15, height: '75px', display: 'flex', alignItems: 'center',
        justifyContent: 'space-between', gap: '16px', padding: '0 32px',
        background: 'var(--surface-glass)', backdropFilter: 'var(--blur-glass)', WebkitBackdropFilter: 'var(--blur-glass)',
        borderBottom: '1px solid var(--border)',
      }}>
        <Crumbs items={crumbs} />
        <div style={{ display: 'flex', alignItems: 'center', gap: '18px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '12px', color: 'var(--text-secondary)', fontFamily: 'var(--font-mono)' }}>
            <span style={{ width: '7px', height: '7px', borderRadius: '50%', background: 'var(--green-500)', boxShadow: '0 0 8px 1px rgba(34,197,94,0.7)' }} />
            Защищённое соединение
          </div>
          <span style={{ width: '1px', height: '22px', background: 'var(--border)' }} />
          <NotificationsBell items={notifications} />
        </div>
      </header>
    );
  }

  // ---------- Заголовок страницы ----------
  function PageHeading({ eyebrow, title, subtitle, actions }) {
    return (
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: '24px', marginBottom: '28px', flexWrap: 'wrap' }}>
        <div>
          {eyebrow && <div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
            <span style={{ width: '24px', height: '2px', background: 'var(--accent)' }} />
            <span style={{ fontSize: '12px', letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--accent-light)', fontWeight: 600 }}>{eyebrow}</span>
          </div>}
          <h1 style={{ margin: 0, fontSize: '30px', fontWeight: 800, letterSpacing: '-0.02em', color: 'var(--text-primary)' }}>{title}</h1>
          {subtitle && <p style={{ margin: '8px 0 0', color: 'var(--text-secondary)', fontSize: '15px', maxWidth: '620px', lineHeight: 1.5 }}>{subtitle}</p>}
        </div>
        {actions && <div style={{ display: 'flex', gap: '10px' }}>{actions}</div>}
      </div>
    );
  }

  // ---------- Экран входа ----------
  // variant: 'client' (по умолчанию) | 'admin'. Админ-вход вынесен в отдельный файл.
  function LoginScreen({ onLogin, variant = 'client' }) {
    const isAdmin = variant === 'admin';
    const [email, setEmail] = React.useState('');
    const [password, setPassword] = React.useState('');
    const [error, setError] = React.useState('');
    const [busy, setBusy] = React.useState(false);

    const submit = async () => {
      if (busy) return;
      setError('');
      setBusy(true);
      try {
        // При успехе App переключит экран — busy не сбрасываем.
        await onLogin(email.trim(), password);
      } catch (e) {
        if (e && e.code === 'invalid_credentials') setError('Неверная почта или пароль.');
        else if (e && e.code === 'forbidden') setError('Эта учётная запись не имеет доступа сюда.');
        else if (e && (e.code === 'too_many_requests' || e.status === 429)) setError('Слишком много попыток входа. Подождите минуту и попробуйте снова.');
        else setError('Не удалось войти. Проверьте соединение и попробуйте снова.');
        setBusy(false);
      }
    };
    const onKey = (e) => { if (e.key === 'Enter') submit(); };

    return (
      <div style={{ position: 'relative', minHeight: '100vh', display: 'grid', placeItems: 'center', padding: '32px' }}>
        <Background />
        <div style={{ position: 'relative', zIndex: 1, width: '100%', maxWidth: '440px' }}>
          <div style={{ display: 'flex', justifyContent: 'center', marginBottom: '24px' }}><Brand /></div>
          <div style={{ background: 'var(--surface-card)', border: '1px solid var(--border)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', overflow: 'hidden' }}>
            <div style={{ borderTop: '2px solid var(--accent)', padding: '28px 32px 8px' }}>
              <TerminalLine command={isAdmin ? 'lan-portal --auth admin-console' : 'lan-portal --auth secure-session'} />
            </div>
            <div style={{ padding: '8px 32px 32px' }}>
              {isAdmin && (
                <div style={{ display: 'inline-flex', alignItems: 'center', gap: '8px', padding: '5px 12px', borderRadius: 'var(--radius-pill)', background: 'var(--accent-muted)', border: '1px solid var(--border-accent)', color: 'var(--accent-light)', fontSize: '11px', fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: '14px' }}>
                  <i className="fas fa-user-shield" /> Служебный доступ
                </div>
              )}
              <h2 style={{ margin: '4px 0 4px', fontSize: '22px', fontWeight: 800, color: 'var(--text-primary)', letterSpacing: '-0.01em' }}>
                {isAdmin ? 'Вход для администратора' : 'Вход в кабинет'}
              </h2>
              <p style={{ margin: '0 0 22px', fontSize: '13px', color: 'var(--text-secondary)' }}>
                {isAdmin ? 'Управление продуктами, версиями, лицензиями и журналом выдач' : 'Доступ к продуктам, лицензиям и обновлениям'}
              </p>

              <div style={{ marginBottom: '14px' }}><Input label="Электронная почта" icon="fas fa-envelope" placeholder={isAdmin ? 'admin@lan-project.ru' : 'name@org.gov'} type="email" value={email} onChange={(e) => setEmail(e.target.value)} onKeyDown={onKey} fullWidth /></div>
              <div style={{ marginBottom: error ? '14px' : '22px' }}><Input label="Пароль" icon="fas fa-lock" type="password" placeholder="••••••••" value={password} onChange={(e) => setPassword(e.target.value)} onKeyDown={onKey} fullWidth /></div>

              {error && (
                <div style={{ display: 'flex', alignItems: 'center', gap: '8px', padding: '10px 12px', marginBottom: '18px', borderRadius: 'var(--radius)', background: 'rgba(239,68,68,0.10)', border: '1px solid rgba(239,68,68,0.3)', color: 'var(--red-500)', fontSize: '12.5px' }}>
                  <i className="fas fa-triangle-exclamation" />{error}
                </div>
              )}

              <Button variant="primary" fullWidth iconRight={busy ? undefined : 'fas fa-arrow-right'} disabled={busy} onClick={submit}>
                {busy ? 'Вход…' : 'Войти'}
              </Button>

              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '16px', fontSize: '13px' }}>
                {isAdmin ? (
                  <a href="index.html" style={{ color: 'var(--accent-light)', textDecoration: 'none' }}>
                    <i className="fas fa-arrow-left" style={{ fontSize: '11px', marginRight: '6px' }} />Кабинет клиента
                  </a>
                ) : (
                  <a href="admin.html" style={{ color: 'var(--text-muted)', textDecoration: 'none' }}>
                    <i className="fas fa-user-shield" style={{ fontSize: '11px', marginRight: '6px' }} />Вход для администратора
                  </a>
                )}
                <span style={{ color: 'var(--text-muted)' }}>Забыли пароль?</span>
              </div>
            </div>
          </div>

          <p style={{ textAlign: 'center', marginTop: '18px', fontSize: '12px', color: 'var(--text-muted)', lineHeight: 1.6 }}>
            {isAdmin
              ? 'Служебный портал. Все действия фиксируются в журнале аудита.'
              : 'Размещение данных на территории РФ (152-ФЗ). Доступ к обновлениям — по\u00a0правам лицензии.'}
          </p>
        </div>
      </div>
    );
  }

  // ---------- Тёмный селект (нативный <select> не поддаётся теме списка) ----------
  // Совместим по API с DS Select: options = [{value,label}] | [string]; onChange
  // получает синтетическое { target: { value } } — чтобы существующие обработчики
  // (f.set / e.target.value) работали без изменений. Меню рендерится порталом в body
  // с fixed-позиционированием от триггера: не обрезается overflow модалки и не зависит
  // от трансформированных предков.
  function ThemedSelect({ label, options = [], value, onChange, placeholder, fullWidth = true, id }) {
    const [open, setOpen] = React.useState(false);
    const [pos, setPos] = React.useState(null);
    const [focus, setFocus] = React.useState(false);
    const btnRef = React.useRef(null);
    const norm = options.map((o) => (typeof o === 'string' ? { value: o, label: o } : o));
    const selected = norm.find((o) => String(o.value) === String(value));
    const selId = id || (label ? `sel-${label.replace(/\s+/g, '-').toLowerCase()}` : undefined);

    const place = () => {
      const r = btnRef.current.getBoundingClientRect();
      const spaceBelow = window.innerHeight - r.bottom;
      const dropUp = spaceBelow < 260 && r.top > spaceBelow;
      setPos({
        left: r.left, width: r.width,
        top: dropUp ? undefined : r.bottom + 6,
        bottom: dropUp ? window.innerHeight - r.top + 6 : undefined,
        maxHeight: Math.min(280, (dropUp ? r.top : spaceBelow) - 16),
      });
    };
    const toggle = () => { if (open) { setOpen(false); } else { place(); setOpen(true); } };

    React.useEffect(() => {
      if (!open) return;
      const close = () => setOpen(false);
      const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
      window.addEventListener('scroll', close, true);
      window.addEventListener('resize', close);
      window.addEventListener('keydown', onKey);
      return () => {
        window.removeEventListener('scroll', close, true);
        window.removeEventListener('resize', close);
        window.removeEventListener('keydown', onKey);
      };
    }, [open]);

    const pick = (v) => { onChange && onChange({ target: { value: v } }); setOpen(false); };

    const menu = open && pos && ReactDOM.createPortal(
      <div style={{ position: 'fixed', inset: 0, zIndex: 90 }}>
        <div onClick={() => setOpen(false)} style={{ position: 'absolute', inset: 0 }} />
        <div role="listbox" style={{
          position: 'fixed', left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width,
          maxHeight: pos.maxHeight, overflowY: 'auto',
          background: 'var(--surface-overlay)', border: '1px solid var(--border-light)',
          borderRadius: 'var(--radius)', boxShadow: 'var(--shadow-lg)', padding: '6px',
          display: 'flex', flexDirection: 'column', gap: '2px',
        }}>
          {norm.map((o) => {
            const on = String(o.value) === String(value);
            return (
              <button key={String(o.value)} type="button" role="option" aria-selected={on}
                onClick={() => pick(o.value)}
                onMouseEnter={(e) => { if (!on) e.currentTarget.style.background = 'var(--surface-card-hover)'; }}
                onMouseLeave={(e) => { if (!on) e.currentTarget.style.background = 'transparent'; }}
                style={{
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '10px',
                  width: '100%', textAlign: 'left', padding: '9px 12px', borderRadius: '6px',
                  border: '1px solid transparent', cursor: 'pointer', font: 'inherit', fontSize: '13.5px',
                  background: on ? 'var(--accent-muted)' : 'transparent',
                  borderColor: on ? 'var(--border-accent)' : 'transparent',
                  color: on ? 'var(--accent-light)' : 'var(--text-secondary)',
                  fontWeight: on ? 600 : 500, transition: 'background var(--transition)',
                }}>
                <span>{o.label}</span>
                {on && <i className="fas fa-check" style={{ fontSize: '11px' }} />}
              </button>
            );
          })}
        </div>
      </div>,
      document.body,
    );

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: '6px', width: fullWidth ? '100%' : 'auto', fontFamily: 'var(--font-sans)' }}>
        {label && <label htmlFor={selId} style={{ fontSize: 'var(--fs-xs)', fontWeight: 500, color: 'var(--text-secondary)' }}>{label}</label>}
        <button ref={btnRef} id={selId} type="button" onClick={toggle}
          onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
          style={{
            width: '100%', boxSizing: 'border-box', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '10px',
            padding: '12px 14px', background: 'var(--surface-base)',
            color: selected ? 'var(--text-primary)' : 'var(--text-muted)',
            border: `1px solid ${open || focus ? 'var(--accent)' : 'var(--border)'}`,
            borderRadius: 'var(--radius)', fontSize: 'var(--fs-sm)', fontFamily: 'var(--font-sans)',
            outline: 'none', cursor: 'pointer', textAlign: 'left',
            boxShadow: open || focus ? '0 0 0 3px var(--accent-soft)' : 'none', transition: 'all var(--transition)',
          }}>
          <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{selected ? selected.label : (placeholder || 'Выберите…')}</span>
          <i className="fas fa-chevron-down" style={{ fontSize: '12px', color: 'var(--text-muted)', transition: 'transform var(--transition)', transform: open ? 'rotate(180deg)' : 'none' }} />
        </button>
        {menu}
      </div>
    );
  }

  // ---------- Тёмный выбор даты (нативный календарь не поддаётся теме) ----------
  // Совместим по API с Input type="date": value — ISO 'YYYY-MM-DD' | '', onChange
  // получает { target: { value } }. Календарь рендерится порталом в body.
  function ThemedDate({ label, value, onChange, placeholder = 'дд.мм.гггг', fullWidth = true, icon = 'far fa-calendar', id }) {
    const [open, setOpen] = React.useState(false);
    const [pos, setPos] = React.useState(null);
    const [view, setView] = React.useState(null); // { y, m } отображаемый месяц
    const [focus, setFocus] = React.useState(false);
    const btnRef = React.useRef(null);
    const selId = id || (label ? `dt-${label.replace(/\s+/g, '-').toLowerCase()}` : undefined);

    const MONTHS = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
    const WD = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
    const pad = (n) => String(n).padStart(2, '0');
    const parse = (s) => { if (!s) return null; const [y, m, d] = String(s).slice(0, 10).split('-').map(Number); if (!y || !m || !d) return null; return { y, m: m - 1, d }; };
    const toISO = (y, m, d) => `${y}-${pad(m + 1)}-${pad(d)}`;
    const display = (s) => { const p = parse(s); return p ? `${pad(p.d)}.${pad(p.m + 1)}.${p.y}` : ''; };

    const sel = parse(value);
    const now = new Date();
    const TY = now.getFullYear(), TM = now.getMonth(), TD = now.getDate();

    const place = () => {
      const r = btnRef.current.getBoundingClientRect();
      const W = 300, H = 360;
      const spaceBelow = window.innerHeight - r.bottom;
      const dropUp = spaceBelow < H && r.top > spaceBelow;
      const left = Math.max(8, Math.min(r.left, window.innerWidth - W - 8));
      setPos({ left, width: W, top: dropUp ? undefined : r.bottom + 6, bottom: dropUp ? window.innerHeight - r.top + 6 : undefined });
    };
    const toggle = () => { if (open) { setOpen(false); } else { setView(sel ? { y: sel.y, m: sel.m } : { y: TY, m: TM }); place(); setOpen(true); } };

    React.useEffect(() => {
      if (!open) return;
      const close = () => setOpen(false);
      const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
      window.addEventListener('scroll', close, true);
      window.addEventListener('resize', close);
      window.addEventListener('keydown', onKey);
      return () => { window.removeEventListener('scroll', close, true); window.removeEventListener('resize', close); window.removeEventListener('keydown', onKey); };
    }, [open]);

    const emit = (v) => { onChange && onChange({ target: { value: v } }); setOpen(false); };
    const shift = (delta) => setView((v) => { let m = v.m + delta, y = v.y; if (m < 0) { m = 11; y--; } if (m > 11) { m = 0; y++; } return { y, m }; });

    const navBtn = { background: 'transparent', border: '1px solid var(--border)', color: 'var(--text-secondary)', width: '28px', height: '28px', borderRadius: '6px', cursor: 'pointer', fontSize: '11px' };

    const cells = [];
    if (view) {
      const lead = (new Date(view.y, view.m, 1).getDay() + 6) % 7;
      const days = new Date(view.y, view.m + 1, 0).getDate();
      for (let i = 0; i < lead; i++) cells.push(null);
      for (let d = 1; d <= days; d++) cells.push(d);
    }

    const menu = open && pos && view && ReactDOM.createPortal(
      <div style={{ position: 'fixed', inset: 0, zIndex: 90 }}>
        <div onClick={() => setOpen(false)} style={{ position: 'absolute', inset: 0 }} />
        <div style={{ position: 'fixed', left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, background: 'var(--surface-overlay)', border: '1px solid var(--border-light)', borderRadius: 'var(--radius)', boxShadow: 'var(--shadow-lg)', padding: '14px' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' }}>
            <div style={{ fontSize: '14px', fontWeight: 700, color: 'var(--text-primary)' }}>{MONTHS[view.m]} {view.y}</div>
            <div style={{ display: 'flex', gap: '6px' }}>
              <button type="button" title="Предыдущий месяц" onClick={() => shift(-1)} style={navBtn}><i className="fas fa-chevron-left" /></button>
              <button type="button" title="Следующий месяц" onClick={() => shift(1)} style={navBtn}><i className="fas fa-chevron-right" /></button>
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '2px', marginBottom: '4px' }}>
            {WD.map((w) => <div key={w} style={{ textAlign: 'center', fontSize: '11px', color: 'var(--text-muted)', fontWeight: 600, padding: '4px 0' }}>{w}</div>)}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '2px' }}>
            {cells.map((d, i) => {
              if (d === null) return <div key={i} />;
              const isSel = sel && sel.y === view.y && sel.m === view.m && sel.d === d;
              const isToday = TY === view.y && TM === view.m && TD === d;
              return (
                <button key={i} type="button" onClick={() => emit(toISO(view.y, view.m, d))}
                  onMouseEnter={(e) => { if (!isSel) e.currentTarget.style.background = 'var(--surface-card-hover)'; }}
                  onMouseLeave={(e) => { if (!isSel) e.currentTarget.style.background = 'transparent'; }}
                  style={{
                    height: '34px', borderRadius: '6px', cursor: 'pointer', font: 'inherit', fontSize: '13px',
                    border: `1px solid ${isToday && !isSel ? 'var(--border-accent)' : 'transparent'}`,
                    background: isSel ? 'var(--accent)' : 'transparent',
                    color: isSel ? '#fff' : 'var(--text-secondary)', fontWeight: isSel ? 700 : 500,
                    transition: 'background var(--transition)',
                  }}>{d}</button>
              );
            })}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: '12px', borderTop: '1px solid var(--border)', paddingTop: '12px' }}>
            <button type="button" onClick={() => emit('')} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', cursor: 'pointer', font: 'inherit', fontSize: '13px', padding: 0 }}>Очистить</button>
            <button type="button" onClick={() => emit(toISO(TY, TM, TD))} style={{ background: 'none', border: 'none', color: 'var(--accent-light)', cursor: 'pointer', font: 'inherit', fontSize: '13px', fontWeight: 600, padding: 0 }}>Сегодня</button>
          </div>
        </div>
      </div>,
      document.body,
    );

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: '6px', width: fullWidth ? '100%' : 'auto', fontFamily: 'var(--font-sans)' }}>
        {label && <label htmlFor={selId} style={{ fontSize: 'var(--fs-xs)', fontWeight: 500, color: 'var(--text-secondary)' }}>{label}</label>}
        <div style={{ position: 'relative', display: 'flex', alignItems: 'center' }}>
          {icon && <i className={icon} style={{ position: 'absolute', left: '14px', color: open || focus ? 'var(--accent)' : 'var(--text-muted)', fontSize: '14px', pointerEvents: 'none', transition: 'color var(--transition)' }} />}
          <button ref={btnRef} id={selId} type="button" onClick={toggle} onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
            style={{
              width: '100%', boxSizing: 'border-box', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: icon ? '12px 14px 12px 40px' : '12px 14px', background: 'var(--surface-base)',
              color: sel ? 'var(--text-primary)' : 'var(--text-muted)',
              border: `1px solid ${open || focus ? 'var(--accent)' : 'var(--border)'}`, borderRadius: 'var(--radius)',
              fontSize: 'var(--fs-sm)', fontFamily: 'var(--font-sans)', outline: 'none', cursor: 'pointer', textAlign: 'left',
              boxShadow: open || focus ? '0 0 0 3px var(--accent-soft)' : 'none', transition: 'all var(--transition)',
            }}>
            <span>{sel ? display(value) : placeholder}</span>
            <i className="fas fa-calendar-day" style={{ fontSize: '12px', color: 'var(--text-muted)' }} />
          </button>
        </div>
        {menu}
      </div>
    );
  }

  Object.assign(window, { Background, Brand, StatusBadge, Sidebar, TopBar, Crumbs, PageHeading, LoginScreen, ThemedSelect, ThemedDate });
})();
