// LPR Platform — Design system primitives
// All screens consume these. Tokens follow the brief: Tailwind 3.x baseColor=slate,
// primary=teal-500 (#14b8a6) with primary actions on teal-600 (#0d9488).
// Theme is driven by data-theme attribute on document root + the `palette` knob.

const LPR_TOKENS = {
  light: {
    bg: '#ffffff',
    surface: '#fafafa',
    surfaceAlt: '#f4f4f5',
    border: '#e5e7eb',
    borderStrong: '#d1d5db',
    text: '#1f2937',        // gray-800
    textSoft: '#4b5563',    // gray-600
    textMute: '#6b7280',    // gray-500
    textFaint: '#9ca3af',   // gray-400
    sidebar: '#f9fafb',
    sidebarActive: 'rgba(13,148,136,0.08)',
    chipBg: '#f3f4f6',
    overlay: 'rgba(15,23,42,0.45)',
  },
  dark: {
    bg: '#0b1220',
    surface: '#111827',
    surfaceAlt: '#1f2937',
    border: '#1f2937',
    borderStrong: '#374151',
    text: '#f9fafb',
    textSoft: '#d1d5db',
    textMute: '#9ca3af',
    textFaint: '#6b7280',
    sidebar: '#0f172a',
    sidebarActive: 'rgba(20,184,166,0.14)',
    chipBg: '#1f2937',
    overlay: 'rgba(2,6,23,0.65)',
  },
};

// Palette presets — only the brand hue changes; semantics stay constant.
const LPR_PALETTES = {
  teal: {
    name: 'Teal (default)',
    p50: '#f0fdfa', p100: '#ccfbf1', p200: '#99f6e4', p300: '#5eead4',
    p400: '#2dd4bf', p500: '#14b8a6', p600: '#0d9488', p700: '#0f766e',
    p800: '#115e59', p900: '#134e4a',
  },
  indigo: {
    name: 'Indigo (clinical)',
    p50: '#eef2ff', p100: '#e0e7ff', p200: '#c7d2fe', p300: '#a5b4fc',
    p400: '#818cf8', p500: '#6366f1', p600: '#4f46e5', p700: '#4338ca',
    p800: '#3730a3', p900: '#312e81',
  },
  slate: {
    name: 'Graphite (mono)',
    p50: '#f8fafc', p100: '#f1f5f9', p200: '#e2e8f0', p300: '#cbd5e1',
    p400: '#94a3b8', p500: '#475569', p600: '#334155', p700: '#1e293b',
    p800: '#0f172a', p900: '#020617',
  },
};

const LPR_SEM = {
  success: '#10b981',
  successBg: '#d1fae5',
  successBorder: '#a7f3d0',
  warning: '#f59e0b',
  warningBg: '#fef3c7',
  warningBorder: '#fde68a',
  error:   '#ef4444',
  errorBg: '#fee2e2',
  errorBorder: '#fecaca',
  info:    '#3b82f6',
  infoBg:  '#dbeafe',
  infoBorder: '#bfdbfe',
  neutral: '#94a3b8',
  neutralBg: '#f1f5f9',
};

// Returns a single tokens object, given theme+palette.
function getTokens({ theme = 'light', palette = 'teal' } = {}) {
  return {
    ...LPR_TOKENS[theme],
    ...LPR_PALETTES[palette],
    ...LPR_SEM,
    theme,
    paletteName: palette,
    fontUI: 'Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif',
    fontDisplay: 'Inter, ui-sans-serif, system-ui, sans-serif',
    fontMono: '"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace',
  };
}

// Single global stylesheet for rare cases that need real CSS (focus ring, scrollbars).
function ensureLPRStyles() {
  if (typeof document === 'undefined') return;
  if (document.getElementById('lpr-base-styles')) return;
  const s = document.createElement('style');
  s.id = 'lpr-base-styles';
  s.textContent = `
    @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
    .lpr-scroll{scrollbar-width:thin;scrollbar-color:rgba(100,116,139,.35) transparent}
    .lpr-scroll::-webkit-scrollbar{width:8px;height:8px}
    .lpr-scroll::-webkit-scrollbar-thumb{background:rgba(100,116,139,.35);border-radius:4px}
    .lpr-scroll::-webkit-scrollbar-track{background:transparent}
    .lpr-btn{transition:background .12s,box-shadow .12s,transform .12s,border-color .12s}
    .lpr-btn:active{transform:translateY(0.5px)}
    .lpr-row{transition:background .12s}
    .lpr-input:focus-within{box-shadow:0 0 0 3px rgba(20,184,166,.18)}
    .lpr-spark path{fill:none;stroke-linecap:round;stroke-linejoin:round}
    .lpr-pulse{animation:lprPulse 2s cubic-bezier(.4,0,.6,1) infinite}
    @keyframes lprPulse{0%,100%{opacity:1}50%{opacity:.55}}
    .lpr-link{color:inherit;text-decoration:none;cursor:pointer}
    .lpr-link:hover{text-decoration:underline;text-underline-offset:2px}
  `;
  document.head.appendChild(s);
}
ensureLPRStyles();

// ─────────────────────────────────────────────────────────────
// Icons — minimal stroke set (lucide-style). Pass {size, color, strokeWidth}.
// ─────────────────────────────────────────────────────────────
const Icon = ({ d, size = 16, color = 'currentColor', strokeWidth = 1.75, fill = 'none', children, viewBox = '0 0 24 24', style }) => (
  <svg width={size} height={size} viewBox={viewBox} fill={fill} stroke={color}
       strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
       style={{ flexShrink: 0, display: 'inline-block', verticalAlign: '-2px', ...style }}>
    {d ? <path d={d} /> : children}
  </svg>
);

const Icons = {
  Activity: (p) => <Icon {...p}><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></Icon>,
  Heart:    (p) => <Icon {...p} d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>,
  Users:    (p) => <Icon {...p}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></Icon>,
  User:     (p) => <Icon {...p}><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></Icon>,
  Bell:     (p) => <Icon {...p}><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></Icon>,
  Search:   (p) => <Icon {...p}><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></Icon>,
  Filter:   (p) => <Icon {...p}><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></Icon>,
  ChevronD: (p) => <Icon {...p}><polyline points="6 9 12 15 18 9"/></Icon>,
  ChevronR: (p) => <Icon {...p}><polyline points="9 18 15 12 9 6"/></Icon>,
  ChevronL: (p) => <Icon {...p}><polyline points="15 18 9 12 15 6"/></Icon>,
  ChevronU: (p) => <Icon {...p}><polyline points="18 15 12 9 6 15"/></Icon>,
  Plus:     (p) => <Icon {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></Icon>,
  Check:    (p) => <Icon {...p}><polyline points="20 6 9 17 4 12"/></Icon>,
  X:        (p) => <Icon {...p}><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></Icon>,
  AlertTri: (p) => <Icon {...p}><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></Icon>,
  AlertCir: (p) => <Icon {...p}><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></Icon>,
  Shield:   (p) => <Icon {...p}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></Icon>,
  ShieldChk:(p) => <Icon {...p}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></Icon>,
  ShieldX:  (p) => <Icon {...p}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><line x1="9" y1="9" x2="15" y2="15"/><line x1="15" y1="9" x2="9" y2="15"/></Icon>,
  Clock:    (p) => <Icon {...p}><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></Icon>,
  Calendar: (p) => <Icon {...p}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></Icon>,
  FileText: (p) => <Icon {...p}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="15" y2="17"/></Icon>,
  Upload:   (p) => <Icon {...p}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></Icon>,
  Settings: (p) => <Icon {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></Icon>,
  Layers:   (p) => <Icon {...p}><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></Icon>,
  TrendUp:  (p) => <Icon {...p}><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></Icon>,
  TrendDn:  (p) => <Icon {...p}><polyline points="23 18 13.5 8.5 8.5 13.5 1 6"/><polyline points="17 18 23 18 23 12"/></Icon>,
  Minus:    (p) => <Icon {...p}><line x1="5" y1="12" x2="19" y2="12"/></Icon>,
  Moon:     (p) => <Icon {...p}><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></Icon>,
  Sun:      (p) => <Icon {...p}><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></Icon>,
  Logout:   (p) => <Icon {...p}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></Icon>,
  Mail:     (p) => <Icon {...p}><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></Icon>,
  Lock:     (p) => <Icon {...p}><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></Icon>,
  Eye:      (p) => <Icon {...p}><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></Icon>,
  Pill:     (p) => <Icon {...p}><path d="M10.5 20.5a4.95 4.95 0 0 1-7-7l11-11a4.95 4.95 0 0 1 7 7Z"/><line x1="8.5" y1="8.5" x2="15.5" y2="15.5"/></Icon>,
  Brain:    (p) => <Icon {...p}><path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2Z"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2Z"/></Icon>,
  Moon2:    (p) => <Icon {...p}><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></Icon>,
  Flame:    (p) => <Icon {...p}><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/></Icon>,
  Apple:    (p) => <Icon {...p}><path d="M12 20.94c1.5 0 2.75-1.06 4-1.06 1.25 0 2.5 1.06 4 1.06s4-1.5 4-7.94S20 4 16 4c-1.5 0-2.5.5-4 .5S9.5 4 8 4c-4 0-8 2.56-8 9s2.5 7.94 4 7.94 2.75-1.06 4-1.06 2.5 1.06 4 1.06z"/><path d="M10 2c1 .5 2 2 2 5"/></Icon>,
  Dumbbell: (p) => <Icon {...p}><path d="m6.5 6.5 11 11"/><path d="m21 21-1-1"/><path d="m3 3 1 1"/><path d="m18 22 4-4"/><path d="m2 6 4-4"/><path d="m3 10 7-7"/><path d="m14 21 7-7"/></Icon>,
  Drop:     (p) => <Icon {...p}><path d="M12 2.69 17.66 8.34a8 8 0 1 1-11.31 0z"/></Icon>,
  Stethoscope: (p) => <Icon {...p}><path d="M11 2v2"/><path d="M5 2v2"/><path d="M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1"/><path d="M8 15a6 6 0 0 0 12 0v-3"/><circle cx="20" cy="10" r="2"/></Icon>,
  Database: (p) => <Icon {...p}><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></Icon>,
  Download: (p) => <Icon {...p}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></Icon>,
  Edit:     (p) => <Icon {...p}><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></Icon>,
  Plus2:    (p) => <Icon {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></Icon>,
  Info:     (p) => <Icon {...p}><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></Icon>,
  Zap:      (p) => <Icon {...p}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></Icon>,
  Target:   (p) => <Icon {...p}><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></Icon>,
  GitBranch:(p) => <Icon {...p}><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></Icon>,
  Send:     (p) => <Icon {...p}><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></Icon>,
  Smile:    (p) => <Icon {...p}><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></Icon>,
  More:     (p) => <Icon {...p}><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></Icon>,
  Home:     (p) => <Icon {...p}><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></Icon>,
  Building: (p) => <Icon {...p}><rect x="4" y="2" width="16" height="20" rx="2"/><path d="M9 22v-4h6v4"/><path d="M8 6h.01"/><path d="M16 6h.01"/><path d="M12 6h.01"/><path d="M12 10h.01"/><path d="M12 14h.01"/><path d="M16 10h.01"/><path d="M16 14h.01"/><path d="M8 10h.01"/><path d="M8 14h.01"/></Icon>,
};

// ─────────────────────────────────────────────────────────────
// Status / semáforo helpers
// ─────────────────────────────────────────────────────────────
const STATUS_COLOR = (T) => ({
  green:  { fg: T.success, bg: T.successBg, border: T.successBorder, label: 'Verde' },
  yellow: { fg: T.warning, bg: T.warningBg, border: T.warningBorder, label: 'Amarelo' },
  red:    { fg: T.error,   bg: T.errorBg,   border: T.errorBorder,   label: 'Vermelho' },
  gray:   { fg: T.textMute,bg: T.neutralBg, border: T.border,        label: 'Sem dados' },
  blue:   { fg: T.info,    bg: T.infoBg,    border: T.infoBorder,    label: 'Info' },
});

function Dot({ status = 'green', size = 10, T, pulse }) {
  const c = STATUS_COLOR(T)[status];
  return (
    <span className={pulse ? 'lpr-pulse' : ''} style={{
      display: 'inline-block', width: size, height: size, borderRadius: '50%',
      background: c.fg, boxShadow: `0 0 0 3px ${c.bg}`, flexShrink: 0,
    }}/>
  );
}

function Semaphore({ status = 'green', size = 8, T }) {
  // 3 stacked dots; the active one full color, the others dimmed.
  const order = ['red', 'yellow', 'green'];
  const active = order.indexOf(status);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 3, padding: 4, borderRadius: 6, background: T.surfaceAlt, border: `1px solid ${T.border}` }}>
      {order.map((s, i) => {
        const c = STATUS_COLOR(T)[s];
        const on = i === active;
        return <span key={s} style={{ width: size, height: size, borderRadius: '50%', background: on ? c.fg : T.borderStrong, opacity: on ? 1 : 0.35 }}/>;
      })}
    </div>
  );
}

// Pill — used everywhere for status + counts
function Pill({ children, tone = 'neutral', T, icon, style, soft = true }) {
  const map = {
    success: { fg: T.success, bg: T.successBg, border: T.successBorder },
    warning: { fg: T.warning, bg: T.warningBg, border: T.warningBorder },
    error:   { fg: T.error,   bg: T.errorBg,   border: T.errorBorder },
    info:    { fg: T.info,    bg: T.infoBg,    border: T.infoBorder },
    neutral: { fg: T.textSoft,bg: T.chipBg,    border: T.border },
    primary: { fg: T.p700,    bg: T.p50,       border: T.p200 },
  };
  const c = map[tone] || map.neutral;
  const dark = T.theme === 'dark';
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '2px 8px', borderRadius: 999,
      fontSize: 11, fontWeight: 500, letterSpacing: 0.1,
      color: dark && soft ? c.fg : c.fg,
      background: dark && soft ? `color-mix(in oklab, ${c.fg} 14%, transparent)` : c.bg,
      border: `1px solid ${dark ? `color-mix(in oklab, ${c.fg} 28%, transparent)` : c.border}`,
      whiteSpace: 'nowrap',
      ...style,
    }}>
      {icon ? <span style={{ display: 'inline-flex' }}>{icon}</span> : null}
      {children}
    </span>
  );
}

// Card — primary container
function Card({ children, T, style, padding = 16, hover, onClick, title, action, subtitle }) {
  return (
    <div onClick={onClick} style={{
      background: T.bg, border: `1px solid ${T.border}`, borderRadius: 10,
      boxShadow: T.theme === 'light' ? '0 1px 2px rgba(15,23,42,0.04)' : 'none',
      cursor: onClick ? 'pointer' : 'default',
      ...style,
    }}>
      {title ? (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: `14px ${padding}px ${subtitle ? 0 : 10}px ${padding}px` }}>
          <div>
            <div style={{ fontSize: 13, fontWeight: 600, color: T.text, letterSpacing: -0.1 }}>{title}</div>
            {subtitle ? <div style={{ fontSize: 12, color: T.textMute, marginTop: 2 }}>{subtitle}</div> : null}
          </div>
          {action}
        </div>
      ) : null}
      <div style={{ padding: title ? `12px ${padding}px ${padding}px ${padding}px` : padding }}>
        {children}
      </div>
    </div>
  );
}

// Button
function Button({ children, T, kind = 'primary', size = 'md', icon, iconRight, onClick, style, disabled, full, type = 'button' }) {
  const sizes = {
    sm: { fs: 12, py: 5, px: 10, gap: 6, ic: 13 },
    md: { fs: 13, py: 7, px: 14, gap: 7, ic: 15 },
    lg: { fs: 14, py: 11, px: 18, gap: 8, ic: 17 },
  };
  const sz = sizes[size];
  const styles = {
    primary: { bg: T.p600, fg: '#fff', border: T.p600, hoverBg: T.p700 },
    secondary: { bg: T.bg, fg: T.text, border: T.borderStrong, hoverBg: T.surfaceAlt },
    ghost: { bg: 'transparent', fg: T.text, border: 'transparent', hoverBg: T.surfaceAlt },
    danger: { bg: T.error, fg: '#fff', border: T.error, hoverBg: '#dc2626' },
    warning: { bg: T.warning, fg: '#78350f', border: T.warning, hoverBg: '#d97706' },
    soft: { bg: T.p50, fg: T.p700, border: T.p100, hoverBg: T.p100 },
  };
  const k = styles[kind] || styles.primary;
  return (
    <button type={type} disabled={disabled} onClick={onClick} className="lpr-btn"
      onMouseEnter={(e) => !disabled && (e.currentTarget.style.background = k.hoverBg)}
      onMouseLeave={(e) => !disabled && (e.currentTarget.style.background = k.bg)}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: sz.gap,
        fontFamily: T.fontUI, fontSize: sz.fs, fontWeight: 500, lineHeight: 1.2, letterSpacing: 0,
        padding: `${sz.py}px ${sz.px}px`, borderRadius: 8,
        background: k.bg, color: k.fg, border: `1px solid ${k.border}`,
        cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
        width: full ? '100%' : 'auto',
        ...style,
      }}>
      {icon ? React.cloneElement(icon, { size: sz.ic }) : null}
      {children}
      {iconRight ? React.cloneElement(iconRight, { size: sz.ic }) : null}
    </button>
  );
}

// Input
function Input({ T, icon, value, onChange, placeholder, type = 'text', style, full, onKeyDown }) {
  return (
    <div className="lpr-input" style={{
      display: 'inline-flex', alignItems: 'center', gap: 8,
      padding: '7px 10px', borderRadius: 8,
      background: T.bg, border: `1px solid ${T.borderStrong}`,
      width: full ? '100%' : 'auto', ...style,
    }}>
      {icon ? React.cloneElement(icon, { size: 14, color: T.textMute }) : null}
      <input value={value || ''} type={type} onChange={(e) => onChange && onChange(e.target.value)}
        placeholder={placeholder} onKeyDown={onKeyDown}
        style={{
          flex: 1, border: 0, outline: 'none', background: 'transparent', color: T.text,
          fontFamily: T.fontUI, fontSize: 13, padding: 0, minWidth: 0,
        }}/>
    </div>
  );
}

// Avatar (initials)
function Avatar({ name = '?', size = 28, T, color }) {
  const init = name.split(' ').filter(Boolean).slice(0, 2).map((s) => s[0]).join('').toUpperCase();
  // Hash to one of a few teal-aligned tints
  const tints = [T.p100, '#fef3c7', '#dbeafe', '#fce7f3', '#e0e7ff', '#dcfce7'];
  const fgs   = [T.p700,  '#92400e', '#1e40af', '#9d174d', '#3730a3', '#166534'];
  let h = 0; for (const c of name) h = (h * 31 + c.charCodeAt(0)) >>> 0;
  const i = h % tints.length;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: size, height: size, borderRadius: '50%',
      background: color || tints[i], color: fgs[i],
      fontFamily: T.fontUI, fontSize: Math.round(size * 0.4), fontWeight: 600,
      flexShrink: 0,
    }}>{init || '?'}</span>
  );
}

// Sparkline — pass values [...], optional area fill
function Sparkline({ values = [], width = 80, height = 24, color, fill, T, strokeWidth = 1.5 }) {
  if (!values.length) return null;
  const min = Math.min(...values), max = Math.max(...values);
  const range = max - min || 1;
  const dx = width / (values.length - 1 || 1);
  const pts = values.map((v, i) => [i * dx, height - 2 - ((v - min) / range) * (height - 4)]);
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(' ');
  const area = `${d} L${width},${height} L0,${height} Z`;
  return (
    <svg width={width} height={height} className="lpr-spark">
      {fill ? <path d={area} fill={fill} stroke="none"/> : null}
      <path d={d} stroke={color || T.p600} strokeWidth={strokeWidth}/>
    </svg>
  );
}

// Trend mini — number + arrow
function Trend({ value, T, suffix = '', positiveIsGood = true }) {
  const positive = value > 0;
  const neutral = value === 0;
  const good = neutral ? null : (positive === positiveIsGood);
  const c = neutral ? T.textMute : (good ? T.success : T.error);
  const Ic = neutral ? Icons.Minus : (positive ? Icons.TrendUp : Icons.TrendDn);
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, color: c, fontSize: 11, fontWeight: 600 }}>
      <Ic size={11}/>{Math.abs(value)}{suffix}
    </span>
  );
}

// Section header used inside dashboards
function SectionHeader({ title, subtitle, action, T, style }) {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 12, ...style }}>
      <div>
        <div style={{ fontFamily: T.fontDisplay, fontSize: 16, fontWeight: 600, color: T.text, letterSpacing: -0.2 }}>{title}</div>
        {subtitle ? <div style={{ fontSize: 12, color: T.textMute, marginTop: 2 }}>{subtitle}</div> : null}
      </div>
      {action}
    </div>
  );
}

// LPR wordmark — typography only, per brief.
function LPRMark({ size = 18, color, T, sub = 'Platform' }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'baseline', gap: 8, fontFamily: T.fontDisplay }}>
      <span style={{
        fontSize: size, fontWeight: 700, letterSpacing: -0.4, color: color || T.text,
        display: 'inline-flex', alignItems: 'baseline', gap: 1,
      }}>
        <span>L</span>
        <span style={{ color: T.p600 }}>P</span>
        <span>R</span>
      </span>
      {sub ? <span style={{
        fontSize: Math.round(size * 0.55), fontWeight: 500, letterSpacing: 0.4, textTransform: 'uppercase',
        color: T.textMute,
      }}>{sub}</span> : null}
    </div>
  );
}

// Bigger logo for login + nav
function LPRLogo({ size = 32, T }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'baseline', gap: 10, fontFamily: T.fontDisplay }}>
      <span style={{
        fontSize: size, fontWeight: 700, letterSpacing: -0.8, color: T.text,
      }}>
        L<span style={{ color: T.p600 }}>P</span>R
      </span>
      <span style={{
        fontSize: Math.round(size * 0.4), fontWeight: 500, letterSpacing: 0.6, textTransform: 'uppercase',
        color: T.textMute, paddingBottom: 4,
      }}>Platform</span>
    </div>
  );
}

// Tabs (controlled)
function Tabs({ tabs, active, onChange, T, style }) {
  return (
    <div style={{ display: 'flex', gap: 2, borderBottom: `1px solid ${T.border}`, ...style }}>
      {tabs.map((t) => {
        const on = (t.id || t) === active;
        const id = t.id || t;
        const label = t.label || t;
        const count = t.count;
        return (
          <button key={id} onClick={() => onChange && onChange(id)}
            style={{
              border: 0, background: 'transparent', cursor: 'pointer',
              padding: '10px 14px',
              fontFamily: T.fontUI, fontSize: 13, fontWeight: on ? 600 : 500,
              color: on ? T.text : T.textMute,
              borderBottom: `2px solid ${on ? T.p600 : 'transparent'}`,
              marginBottom: -1, display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
            {label}
            {count != null ? (
              <span style={{
                fontSize: 11, fontWeight: 600, padding: '0 6px', borderRadius: 999,
                background: on ? T.p50 : T.surfaceAlt, color: on ? T.p700 : T.textMute,
              }}>{count}</span>
            ) : null}
          </button>
        );
      })}
    </div>
  );
}

// Meter / progress bar
function Meter({ value = 0, max = 100, T, color, height = 6, label, right }) {
  const pct = Math.max(0, Math.min(100, (value / max) * 100));
  return (
    <div style={{ width: '100%' }}>
      {(label || right) ? (
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 }}>
          {label ? <span style={{ fontSize: 12, color: T.textSoft }}>{label}</span> : <span/>}
          {right ? <span style={{ fontSize: 11, color: T.textMute, fontVariantNumeric: 'tabular-nums' }}>{right}</span> : null}
        </div>
      ) : null}
      <div style={{ width: '100%', height, background: T.surfaceAlt, borderRadius: 999, overflow: 'hidden' }}>
        <div style={{ width: `${pct}%`, height: '100%', background: color || T.p500, borderRadius: 999, transition: 'width .4s ease' }}/>
      </div>
    </div>
  );
}

// KPI tile
function KPI({ label, value, sub, tone = 'neutral', icon, T, trend, onClick, active }) {
  const tones = {
    neutral: { fg: T.text, accent: T.textMute },
    primary: { fg: T.p700, accent: T.p600 },
    error:   { fg: T.error, accent: T.error },
    warning: { fg: T.warning, accent: T.warning },
    success: { fg: T.success, accent: T.success },
    info:    { fg: T.info, accent: T.info },
  };
  const tk = tones[tone];
  return (
    <div onClick={onClick} className="lpr-btn" style={{
      background: T.bg, border: `1px solid ${active ? tk.accent : T.border}`, borderRadius: 10,
      padding: 14, cursor: onClick ? 'pointer' : 'default',
      display: 'flex', flexDirection: 'column', gap: 6,
      boxShadow: T.theme === 'light' ? '0 1px 2px rgba(15,23,42,0.04)' : 'none',
      position: 'relative', overflow: 'hidden',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <span style={{ fontSize: 11.5, color: T.textMute, fontWeight: 500, letterSpacing: 0.1, textTransform: 'uppercase' }}>{label}</span>
        {icon ? <span style={{ color: tk.accent, opacity: 0.9 }}>{React.cloneElement(icon, { size: 15 })}</span> : null}
      </div>
      <div style={{
        fontFamily: T.fontDisplay, fontSize: 28, fontWeight: 700, color: tk.fg,
        letterSpacing: -0.6, lineHeight: 1, fontVariantNumeric: 'tabular-nums',
      }}>{value}</div>
      {sub != null || trend != null ? (
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 11.5, color: T.textMute }}>
          {trend != null ? trend : null}
          {sub}
        </div>
      ) : null}
    </div>
  );
}

// Domain icon dictionary
const DOMAIN_META = {
  metabolic:    { label: 'Metabólico',         short: 'Metab',     icon: Icons.Activity },
  gut:          { label: 'Intestinal',         short: 'Intest',    icon: Icons.Apple },
  mito:         { label: 'Mitocondrial/Energia',short: 'Mito',     icon: Icons.Zap },
  inflam:       { label: 'Inflamatório',       short: 'Inflam',    icon: Icons.Flame },
  hormone:      { label: 'Neuroendócrino/Hormonal', short: 'Hormon', icon: Icons.Brain },
  circadian:    { label: 'Circadiano/Sono',    short: 'Circad',    icon: Icons.Moon2 },
  body:         { label: 'Composição/Movimento', short: 'Corpo',   icon: Icons.Dumbbell },
  behavior:     { label: 'Comportamental/Adesão', short: 'Comport', icon: Icons.Target },
};

// Make all of the above globally available so screen scripts can reach them.
Object.assign(window, {
  LPR_TOKENS, LPR_PALETTES, LPR_SEM, getTokens,
  Icon, Icons, STATUS_COLOR, Dot, Semaphore, Pill, Card, Button, Input,
  Avatar, Sparkline, Trend, SectionHeader, LPRMark, LPRLogo, Tabs, Meter, KPI,
  DOMAIN_META,
});
