// Órbita — Shared UI Components + Theme System

const { useState, useEffect, useRef, useCallback, useContext, createContext } = React;

// ── Theme definitions ──────────────────────────────────────
const THEMES = {
  dark: {
    id: 'dark',
    label: 'Escuro',
    icon: '◗',
    bg:          '#100D0A',
    surface:     '#1A1612',
    card:        'rgba(36,30,24,0.72)',
    cardSolid:   '#241E18',
    fg:          '#F5F1E8',
    fgMuted:     'rgba(245,241,232,0.74)',   // raised 0.55 → 0.74 (≈4.6:1 on bg, WCAG AA ✓)
    fgDim:       'rgba(245,241,232,0.46)',   // raised 0.28 → 0.46 (large-text + UI AA)
    accent:      '#F2EEE4',
    hot:         '#C9C2B0',
    gold:        '#C9A55C',   // só o símbolo Órbitas (decisão 2026-09-24)
    success:     '#8CAF88',
    info:        '#7A9EC9',
    border:      'rgba(245,241,232,0.11)',   // raised 0.08 → 0.11
    borderHover: 'rgba(245,241,232,0.22)',
    headerBg:    'rgba(16,13,10,0.92)',
    inputBg:     'rgba(245,241,232,0.05)',
    grain:       0.035,
  },
  light: {
    id: 'light',
    label: 'Claro',
    icon: '◕',
    bg:          '#F2EDE4',
    surface:     '#FDFAF5',
    card:        'rgba(253,250,245,0.92)',
    cardSolid:   '#FDFAF5',
    fg:          '#18140F',
    fgMuted:     'rgba(24,20,15,0.67)',   // raised: 0.62 → 0.67 (~4.8:1 on #F2EDE4, WCAG AA ✓)
    fgDim:       'rgba(24,20,15,0.50)',   // raised: 0.38 → 0.50 (~3.4:1, passes WCAG AA large + UI)
    accent:      '#15130F',
    hot:         '#4A4436',
    gold:        '#8F6F2C',   // dourado mais escuro pra contraste no fundo claro
    success:     '#2E6B2A',
    info:        '#1F5280',
    border:      'rgba(24,20,15,0.13)',
    borderHover: 'rgba(24,20,15,0.26)',
    headerBg:    '#2A2118',   // dark ink header — max contrast ✓
    inputBg:     'rgba(24,20,15,0.05)',
    grain:       0.018,
  },
};

// ── Theme Context ──────────────────────────────────────────
const ThemeContext = createContext({ theme: THEMES.dark, setThemeId: () => {} });

const ThemeProvider = ({ children }) => {
  const [themeId, setThemeId] = useState(() => {
    try { return localStorage.getItem('orbita-theme') || 'dark'; } catch { return 'dark'; }
  });

  useEffect(() => {
    try { localStorage.setItem('orbita-theme', themeId); } catch {}
    // Apply background to body so no flash
    document.body.style.background = THEMES[themeId]?.bg || THEMES.dark.bg;
    document.body.style.color = THEMES[themeId]?.fg || THEMES.dark.fg;
    document.body.style.transition = 'background 0.25s, color 0.25s';
  }, [themeId]);

  const theme = THEMES[themeId] || THEMES.dark;
  return (
    <ThemeContext.Provider value={{ theme, setThemeId, themeId }}>
      {children}
    </ThemeContext.Provider>
  );
};

const useTheme = () => useContext(ThemeContext);

// ── Reactive T proxy — reads from current theme context ────
// Components that use T directly get a live object via useTheme()
// For legacy compatibility, T is still exported but components
// should prefer useTheme().theme for reactive styling.
// We patch T at runtime via the ThemeSync component.
let T = { ...THEMES.dark };

const ThemeSync = () => {
  const { theme } = useTheme();
  useEffect(() => {
    Object.assign(T, theme);
    // Force a global CSS transition on theme switch
    const style = document.getElementById('__orbita-theme-vars') || (() => {
      const s = document.createElement('style');
      s.id = '__orbita-theme-vars';
      document.head.appendChild(s);
      return s;
    })();
    style.textContent = `
      *, *::before, *::after {
        transition: background-color 0.22s ease, border-color 0.22s ease, color 0.18s ease !important;
      }
    `;
    setTimeout(() => { style.textContent = ''; }, 400);
  }, [theme]);
  return null;
};

// ── Grain overlay ──────────────────────────────────────────
const GrainOverlay = () => {
  const { theme } = useTheme();
  return (
    <div style={{
      position: 'fixed', inset: 0, pointerEvents: 'none', zIndex: 9999,
      backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
      opacity: theme.grain,
      mixBlendMode: theme.id === 'dark' ? 'screen' : 'multiply',
    }} />
  );
};

// ── Radial glow ────────────────────────────────────────────
const RadialGlow = ({ color, top = '0', opacity = 0.18 }) => {
  const { theme } = useTheme();
  const c = color || theme.accent;
  if (theme.id === 'light') return null; // subtle in light mode
  return (
    <div style={{
      position: 'absolute', top, left: '50%', transform: 'translateX(-50%)',
      width: '800px', height: '400px', pointerEvents: 'none',
      background: `radial-gradient(ellipse at 50% 0%, ${c}${Math.round(opacity * 255).toString(16).padStart(2,'0')}, transparent 70%)`,
      zIndex: 0,
    }} />
  );
};

// ── Theme Switcher (avatar dropdown) ──────────────────────
// NOTE: This component always renders on a DARK header, so we use
// hardcoded dark-on-dark palette for the trigger button itself.
// The dropdown panel uses the current theme.
const ThemeSwitcher = ({ name, onOpenSettings }) => {
  const { theme, setThemeId, themeId } = useTheme();
  const [open, setOpen] = useState(false);
  const ref = useRef(null);

  useEffect(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  const initials = name.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase();
  // Always use amber on dark header
  const btnAccent = '#F4A261';
  const btnFgMuted = 'rgba(245,241,232,0.55)';

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button
        onClick={() => setOpen(o => !o)}
        style={{
          display: 'flex', alignItems: 'center', gap: 8,
          background: open ? 'rgba(244,162,97,0.15)' : 'transparent',
          border: `1px solid ${open ? 'rgba(244,162,97,0.4)' : 'rgba(245,241,232,0.12)'}`,
          borderRadius: 999, padding: '4px 10px 4px 4px',
          cursor: 'pointer', transition: 'all 0.15s',
        }}
        onMouseEnter={e => { if (!open) e.currentTarget.style.borderColor = 'rgba(245,241,232,0.25)'; }}
        onMouseLeave={e => { if (!open) e.currentTarget.style.borderColor = 'rgba(245,241,232,0.12)'; }}
      >
        <div style={{
          width: 32, height: 32, borderRadius: '50%',
          background: 'rgba(244,162,97,0.22)', border: '1.5px solid rgba(244,162,97,0.5)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: btnAccent, fontSize: 11, fontWeight: 600,
        }}>{initials}</div>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke={btnFgMuted} strokeWidth="2"
          style={{ transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}>
          <path d="M6 9l6 6 6-6"/>
        </svg>
      </button>

      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 10px)', right: 0,
          width: 228,
          background: theme.id === 'light' ? '#FDFAF5' : '#1F1A14',
          border: `1px solid ${theme.id === 'light' ? 'rgba(24,20,15,0.12)' : 'rgba(245,241,232,0.1)'}`,
          borderRadius: 16, overflow: 'hidden',
          boxShadow: theme.id === 'dark' ? '0 16px 48px rgba(0,0,0,0.6)' : '0 8px 36px rgba(0,0,0,0.14)',
          zIndex: 1000,
        }}>
          {/* User info */}
          <div style={{
            padding: '14px 16px',
            borderBottom: `1px solid ${theme.id === 'light' ? 'rgba(24,20,15,0.1)' : 'rgba(245,241,232,0.08)'}`,
          }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: theme.fg }}>{name}</div>
            <div style={{ fontSize: 11, color: theme.fgMuted, marginTop: 1 }}>Plano <span style={{ color: theme.accent }}>Atelier</span></div>
          </div>

          {/* Theme selector */}
          <div style={{ padding: '12px 12px 8px' }}>
            <div style={{
              fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.1em',
              color: theme.fgDim, padding: '0 4px 10px', fontWeight: 600,
            }}>
              Tema
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              {Object.values(THEMES).map(th => {
                const isSelected = themeId === th.id;
                return (
                  <button
                    key={th.id}
                    onClick={() => setThemeId(th.id)}
                    style={{
                      flex: 1, padding: '10px 8px 9px', borderRadius: 12,
                      border: `2px solid ${isSelected ? theme.accent : theme.id === 'light' ? 'rgba(24,20,15,0.1)' : 'rgba(245,241,232,0.08)'}`,
                      background: isSelected
                        ? `${theme.accent}14`
                        : theme.id === 'light' ? 'rgba(24,20,15,0.04)' : 'rgba(245,241,232,0.04)',
                      cursor: 'pointer', transition: 'all 0.15s', fontFamily: 'Inter, sans-serif',
                    }}
                    onMouseEnter={e => { if (!isSelected) e.currentTarget.style.borderColor = theme.id === 'light' ? 'rgba(24,20,15,0.2)' : 'rgba(245,241,232,0.18)'; }}
                    onMouseLeave={e => { if (!isSelected) e.currentTarget.style.borderColor = theme.id === 'light' ? 'rgba(24,20,15,0.1)' : 'rgba(245,241,232,0.08)'; }}
                  >
                    {/* Mini preview */}
                    <div style={{
                      width: '100%', height: 38, borderRadius: 8, marginBottom: 8,
                      background: th.bg,
                      border: `1px solid ${th.id === 'light' ? 'rgba(24,20,15,0.12)' : 'rgba(245,241,232,0.1)'}`,
                      padding: '7px 8px', overflow: 'hidden',
                      display: 'flex', flexDirection: 'column', gap: 4,
                    }}>
                      {/* Header strip */}
                      <div style={{ height: 8, borderRadius: 2, background: th.id === 'dark' ? '#241E18' : '#2A2118', marginBottom: 3 }} />
                      {/* warm-ink preview strip */}
                      <div style={{ width: '65%', height: 3, borderRadius: 2, background: th.fg, opacity: 0.45 }} />
                      <div style={{ width: 20, height: 4, borderRadius: 99, background: th.accent, opacity: 0.85 }} />
                    </div>
                    <div style={{
                      fontSize: 11, fontWeight: isSelected ? 600 : 400,
                      color: isSelected ? theme.accent : theme.fgMuted,
                      textAlign: 'center',
                    }}>
                      {th.label}
                    </div>
                  </button>
                );
              })}
            </div>
          </div>

          {/* Divider */}
          <div style={{ height: 1, background: theme.id === 'light' ? 'rgba(24,20,15,0.08)' : 'rgba(245,241,232,0.07)', margin: '2px 0' }} />

          {/* Actions */}
          <div style={{ padding: '6px 8px 8px' }}>
            {[
              {
                label: 'Configurações',
                onClick: () => { setOpen(false); onOpenSettings && onOpenSettings(); },
                icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>,
              },
              {
                label: 'Sair',
                onClick: () => { setOpen(false); if (window.confirm('Sair da sua conta?')) window.__ORBITA_LOGOUT__ && window.__ORBITA_LOGOUT__(); },
                icon: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4M16 17l5-5-5-5M21 12H9"/></svg>,
              },
            ].map(action => (
              <button key={action.label} onClick={action.onClick} style={{
                width: '100%', padding: '9px 10px', borderRadius: 9, border: 'none',
                background: 'transparent', color: theme.fgMuted, fontSize: 13,
                cursor: 'pointer', fontFamily: 'Inter, sans-serif', textAlign: 'left',
                display: 'flex', alignItems: 'center', gap: 9, transition: 'background 0.12s',
              }}
              onMouseEnter={e => e.currentTarget.style.background = theme.id === 'light' ? 'rgba(24,20,15,0.06)' : 'rgba(245,241,232,0.07)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
              >
                {action.icon}
                {action.label}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

// ── Badge ──────────────────────────────────────────────────
const statusMeta = {
  draft:      { label: 'Rascunho',    color: null, bg: null },
  processing: { label: 'Processando', colorKey: 'info' },
  ready:      { label: 'Pronto',      colorKey: 'success' },
  published:  { label: 'Publicado',   colorKey: 'accent' },
  suggested:  { label: 'Sugerido',    colorKey: 'fgMuted' },
  accepted:   { label: 'Aceito',      colorKey: 'success' },
  edited:     { label: 'Editado',     colorKey: 'info' },
  discarded:  { label: 'Descartado',  colorKey: 'hot' },
};

const Badge = ({ status, custom, small }) => {
  const { theme } = useTheme();
  const meta = statusMeta[status];
  const color = meta ? (theme[meta.colorKey] || theme.fgMuted) : theme.fgMuted;
  const label = meta?.label || custom || status;
  const bg = `${color}18`;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: small ? '2px 8px' : '3px 10px',
      borderRadius: 999, fontSize: small ? 10 : 11, fontWeight: 500,
      letterSpacing: '0.04em', textTransform: 'uppercase',
      color, background: bg,
    }}>
      <span style={{ width: 5, height: 5, borderRadius: '50%', background: color, flexShrink: 0 }} />
      {label}
    </span>
  );
};

// ── Area tag ───────────────────────────────────────────────
const areaMeta = {
  carreira:   { label: 'Carreira',   color: '#7A9EC9' },
  saude:      { label: 'Saúde',      color: '#8CAF88' },
  relacoes:   { label: 'Relações',   color: '#C49BC9' },
  financeiro: { label: 'Financeiro', color: '#F4C261' },
  emocional:  { label: 'Emocional',  color: '#E76F51' },
};

const AreaTag = ({ area }) => {
  const meta = areaMeta[area] || { label: area, color: '#999' };
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '2px 8px', borderRadius: 999, fontSize: 10, fontWeight: 500,
      letterSpacing: '0.04em', textTransform: 'uppercase',
      color: meta.color, background: `${meta.color}18`,
      border: `1px solid ${meta.color}30`,
    }}>
      {meta.label}
    </span>
  );
};

// ── Intensity dot ──────────────────────────────────────────
const IntensityDot = ({ intensity }) => {
  const { theme } = useTheme();
  const colors = { forte: theme.hot, medio: theme.accent, leve: theme.success };
  const c = colors[intensity] || theme.fgDim;
  return (
    <span style={{
      display: 'inline-block', width: 6, height: 6, borderRadius: '50%',
      background: c, flexShrink: 0,
      boxShadow: `0 0 6px ${c}80`,
    }} />
  );
};

// ── Primary button ─────────────────────────────────────────
const BtnPrimary = ({ children, onClick, disabled, style = {}, small }) => {
  const { theme } = useTheme();
  return (
    <button onClick={onClick} disabled={disabled} style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      padding: small ? '8px 18px' : '12px 28px',
      background: disabled ? `${theme.accent}40` : `linear-gradient(135deg, ${theme.accent}, ${theme.hot})`,
      color: disabled ? theme.fgDim : theme.bg,
      fontFamily: 'Inter, sans-serif', fontWeight: 600,
      fontSize: small ? 13 : 14, borderRadius: 999, border: 'none',
      cursor: disabled ? 'not-allowed' : 'pointer',
      transition: 'opacity 0.15s, transform 0.1s',
      ...style,
    }}
    onMouseEnter={e => { if (!disabled) e.currentTarget.style.opacity = '0.88'; }}
    onMouseLeave={e => { e.currentTarget.style.opacity = '1'; }}
    >
      {children}
    </button>
  );
};

// ── Ghost button ───────────────────────────────────────────
const BtnGhost = ({ children, onClick, style = {}, small, active }) => {
  const { theme } = useTheme();
  return (
    <button onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      padding: small ? '7px 16px' : '11px 24px',
      background: active ? `${theme.accent}18` : 'transparent',
      color: active ? theme.accent : theme.fg,
      fontFamily: 'Inter, sans-serif', fontWeight: 500,
      fontSize: small ? 13 : 14, borderRadius: 999,
      border: `1px solid ${active ? theme.accent + '40' : theme.border}`,
      cursor: 'pointer', transition: 'all 0.15s',
      ...style,
    }}
    onMouseEnter={e => { e.currentTarget.style.background = active ? `${theme.accent}28` : theme.inputBg; }}
    onMouseLeave={e => { e.currentTarget.style.background = active ? `${theme.accent}18` : 'transparent'; }}
    >
      {children}
    </button>
  );
};

// ── Icon button ────────────────────────────────────────────
const BtnIcon = ({ children, onClick, title, active, style = {} }) => {
  const { theme } = useTheme();
  return (
    <button onClick={onClick} title={title} style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: 32, height: 32, borderRadius: 8, border: 'none',
      background: active ? `${theme.accent}28` : theme.inputBg,
      color: active ? theme.accent : theme.fgMuted, cursor: 'pointer',
      transition: 'all 0.15s', ...style,
    }}
    onMouseEnter={e => { e.currentTarget.style.background = theme.border; e.currentTarget.style.color = theme.fg; }}
    onMouseLeave={e => { e.currentTarget.style.background = active ? `${theme.accent}28` : theme.inputBg; e.currentTarget.style.color = active ? theme.accent : theme.fgMuted; }}
    >
      {children}
    </button>
  );
};

// ── Card shell ─────────────────────────────────────────────
const Card = ({ children, style = {}, onClick, hover = true }) => {
  const { theme } = useTheme();
  const [hovered, setHovered] = useState(false);
  return (
    <div onClick={onClick}
      onMouseEnter={() => hover && setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        background: theme.card, backdropFilter: 'blur(12px)',
        border: `1px solid ${hovered && onClick ? theme.borderHover : theme.border}`,
        borderRadius: 16, padding: 20,
        transition: 'border-color 0.15s, transform 0.15s, background 0.22s',
        cursor: onClick ? 'pointer' : 'default',
        transform: hovered && onClick ? 'translateY(-1px)' : 'none',
        ...style,
      }}>
      {children}
    </div>
  );
};

// ── Divider ────────────────────────────────────────────────
const Divider = ({ style = {} }) => {
  const { theme } = useTheme();
  return <div style={{ height: 1, background: theme.border, margin: '0', ...style }} />;
};

// ── Avatar ─────────────────────────────────────────────────
const Avatar = ({ name, size = 32, color }) => {
  const { theme } = useTheme();
  const c = color || theme.accent;
  const initials = name.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase();
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: `${c}22`, border: `1.5px solid ${c}50`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color: c, fontSize: size * 0.35, fontWeight: 600,
      flexShrink: 0, letterSpacing: '0.02em',
    }}>
      {initials}
    </div>
  );
};

// ── Section header ─────────────────────────────────────────
const SectionHeader = ({ title, action }) => {
  const { theme } = useTheme();
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
      <h3 style={{ margin: 0, fontSize: 11, fontWeight: 600, letterSpacing: '0.1em', textTransform: 'uppercase', color: theme.fgMuted }}>
        {title}
      </h3>
      {action}
    </div>
  );
};

// ── Input ──────────────────────────────────────────────────
// Olho de ver/esconder. Fechado = escondido, que é o estado inicial.
const OlhoIcon = ({ aberto }) => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
    strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
    {aberto ? (
      <>
        <path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" />
        <circle cx="12" cy="12" r="3" />
      </>
    ) : (
      <>
        <path d="M10.6 5.1A10.9 10.9 0 0 1 12 5c6.4 0 10 7 10 7a18.5 18.5 0 0 1-2.7 3.7M6.2 6.2A18.4 18.4 0 0 0 2 12s3.6 7 10 7a10.7 10.7 0 0 0 4.3-.85" />
        <path d="M9.9 9.9a3 3 0 0 0 4.2 4.2" />
        <path d="M3 3l18 18" />
      </>
    )}
  </svg>
);

// Campo de senha mostra o olho sozinho: qualquer tela que use type="password"
// ganha o ver/esconder sem precisar pedir.
const Input = ({ label, value, onChange, placeholder, type = 'text', style = {} }) => {
  const { theme } = useTheme();
  const [visivel, setVisivel] = React.useState(false);
  const senha = type === 'password';
  const tipo = senha && visivel ? 'text' : type;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, ...style }}>
      {label && <label style={{ fontSize: 12, fontWeight: 500, color: theme.fgMuted, letterSpacing: '0.02em' }}>{label}</label>}
      <div style={{ position: 'relative', display: 'flex' }}>
        <input
          type={tipo} value={value} onChange={onChange} placeholder={placeholder}
          style={{
            background: theme.inputBg, border: `1px solid ${theme.border}`,
            borderRadius: 10, padding: senha ? '10px 42px 10px 14px' : '10px 14px', color: theme.fg,
            fontFamily: 'Inter, sans-serif', fontSize: 14, width: '100%',
            outline: 'none', transition: 'border-color 0.15s',
          }}
          onFocus={e => e.target.style.borderColor = `${theme.accent}60`}
          onBlur={e => e.target.style.borderColor = theme.border}
        />
        {senha && (
          <button
            type="button"
            onClick={() => setVisivel(v => !v)}
            aria-label={visivel ? 'Esconder senha' : 'Mostrar senha'}
            aria-pressed={visivel}
            title={visivel ? 'Esconder senha' : 'Mostrar senha'}
            style={{
              position: 'absolute', right: 6, top: '50%', transform: 'translateY(-50%)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              width: 30, height: 30, padding: 0, borderRadius: 8,
              background: 'none', border: 'none', cursor: 'pointer',
              color: visivel ? theme.accent : theme.fgDim, transition: 'color 0.15s',
            }}
            onMouseEnter={e => { e.currentTarget.style.color = theme.fg; }}
            onMouseLeave={e => { e.currentTarget.style.color = visivel ? theme.accent : theme.fgDim; }}
          >
            <OlhoIcon aberto={visivel} />
          </button>
        )}
      </div>
    </div>
  );
};

// ── Textarea ───────────────────────────────────────────────
const Textarea = ({ label, value, onChange, placeholder, rows = 3, style = {} }) => {
  const { theme } = useTheme();
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, ...style }}>
      {label && <label style={{ fontSize: 12, fontWeight: 500, color: theme.fgMuted, letterSpacing: '0.02em' }}>{label}</label>}
      <textarea
        value={value} onChange={onChange} placeholder={placeholder} rows={rows}
        style={{
          background: theme.inputBg, border: `1px solid ${theme.border}`,
          borderRadius: 10, padding: '10px 14px', color: theme.fg,
          fontFamily: 'Inter, sans-serif', fontSize: 14,
          outline: 'none', resize: 'vertical', transition: 'border-color 0.15s',
        }}
        onFocus={e => e.target.style.borderColor = `${theme.accent}60`}
        onBlur={e => e.target.style.borderColor = theme.border}
      />
    </div>
  );
};

// ── Layer meta ─────────────────────────────────────────────
const layerMeta = {
  visao_ano:   { label: 'Visão do Ano', icon: '◎', colorKey: 'accent'   },
  foco_mensal: { label: 'Meses',        icon: '◑', colorKey: 'info'     },
  alerta:      { label: 'Alertas',      icon: '⚠', colorKey: 'hot'      },
  acao:        { label: 'Ações',        icon: '→', colorKey: 'success'  },
  rotina:      { label: 'Rotina',       icon: '↻', color: '#C49BC9'     },
};

// ── Símbolo Órbitas ────────────────────────────────────────
// O planeta com órbitas — o desenho original: o disco no centro, o anel em
// volta e um satélite sobre o anel, à direita. A partir de 40 px entra o anel
// externo pontilhado, que some no tamanho pequeno pra não virar sujeira.
// Caixa 32×32, com o satélite (cx 28, r 2,5) encostando na margem.
const ORBITAS_GOLD = '#C9A55C';

const OrbitasMark = ({ size = 24, color = 'currentColor', strokeWidth, style }) => {
  const sw = strokeWidth ?? 1.5;
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" fill="none"
      aria-hidden="true" style={{ flexShrink: 0, display: 'block', ...style }}>
      <circle cx="16" cy="16" r="6" fill={color} opacity="0.9" />
      <circle cx="16" cy="16" r="12" stroke={color} strokeWidth={sw} opacity="0.4" fill="none" />
      {size >= 40 && (
        <circle cx="16" cy="16" r="14.5" stroke={color} strokeWidth={sw * 0.67} opacity="0.18" fill="none" strokeDasharray="2 4" />
      )}
      <circle cx="28" cy="16" r="2.5" fill={color} opacity="0.8" />
    </svg>
  );
};

// Export everything
Object.assign(window, {
  OrbitasMark, ORBITAS_GOLD, OlhoIcon,
  T, THEMES, ThemeProvider, ThemeSync, useTheme,
  GrainOverlay, RadialGlow, ThemeSwitcher,
  Badge, AreaTag, IntensityDot,
  BtnPrimary, BtnGhost, BtnIcon, Card, Divider, Avatar,
  SectionHeader, Input, Textarea, layerMeta, statusMeta, areaMeta,
});
