/* =========================================================
   CarDealer.ai Style Guide — building blocks
   All primitives, components, motion demos, agent + bubble UI
   Exported to window for cross-file use.
   ========================================================= */

/* ---------- Section / Layout primitives ---------- */
function SGSection({ id, kicker, title, lead, alt, children }) {
  return (
    <section id={id} className={"sg-section" + (alt ? " alt" : "")}>
      <div className="sg-page">
        {kicker ? <div className="sg-kicker">{kicker}</div> : null}
        {title ? <h2>{title}</h2> : null}
        {lead ? <p className="sg-lead">{lead}</p> : null}
        {children}
      </div>
    </section>
  );
}

function SGGrid({ cols = 3, gap = 24, children, style }) {
  return (
    <div style={{
      display: "grid",
      gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,
      gap,
      ...(style || {}),
    }}>{children}</div>
  );
}

function SGCard({ children, padding = 24, bg, border = true, shadow, radius = 16, style }) {
  return (
    <div style={{
      background: bg || "var(--bg)",
      border: border ? "1px solid var(--line)" : "none",
      borderRadius: radius,
      padding,
      boxShadow: shadow || "none",
      ...(style || {}),
    }}>{children}</div>
  );
}

function SGRule({ label }) {
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 16, margin: "32px 0 24px",
    }}>
      <div style={{ flex: 1, height: 1, background: "var(--line)" }}></div>
      <div style={{
        fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.18em",
        textTransform: "uppercase", color: "var(--body)", fontWeight: 500,
      }}>{label}</div>
      <div style={{ flex: 1, height: 1, background: "var(--line)" }}></div>
    </div>
  );
}

/* ---------- Color chip ---------- */
function ColorChip({ name, hex, swatchStyle, contrast = "dark" }) {
  return (
    <div style={{
      borderRadius: 16,
      overflow: "hidden",
      border: "1px solid var(--line)",
      background: "var(--bg)",
    }}>
      <div style={{
        height: 96,
        background: swatchStyle || hex,
        color: contrast === "dark" ? "var(--ink)" : "#fff",
        position: "relative",
      }}></div>
      <div style={{ padding: "14px 16px" }}>
        <div style={{ fontWeight: 600, fontSize: 14, color: "var(--ink)" }}>{name}</div>
        <div style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--body)", marginTop: 4 }}>{hex}</div>
      </div>
    </div>
  );
}

/* ---------- Icons (filled / solid system — Material-inspired) ---------- */
// Single source of truth for the icon set.
const SG_ICONS = {
  dashboard: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <rect x="3" y="3" width="8" height="10" rx="2"/>
      <rect x="13" y="3" width="8" height="6" rx="2"/>
      <rect x="13" y="11" width="8" height="10" rx="2"/>
      <rect x="3" y="15" width="8" height="6" rx="2"/>
    </svg>
  ),
  chat: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M4 4h16a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H9l-5 4V6a2 2 0 0 1 2-2z"/>
    </svg>
  ),
  bolt: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M13 2 4 14h6l-1 8 9-12h-6l1-8z"/>
    </svg>
  ),
  calendar: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M7 2v3M17 2v3" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" fill="none"/>
      <rect x="3" y="5" width="18" height="16" rx="3"/>
      <rect x="3" y="5" width="18" height="5" rx="3" fill="rgba(255,255,255,0.25)"/>
    </svg>
  ),
  megaphone: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M3 10v4a2 2 0 0 0 2 2h2l9 4V4L7 8H5a2 2 0 0 0-2 2zM18 8a4 4 0 0 1 0 8"/>
    </svg>
  ),
  user: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <circle cx="12" cy="8" r="4"/>
      <path d="M4 21c1.5-4 4.5-6 8-6s6.5 2 8 6"/>
    </svg>
  ),
  phone: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M5 3h3l2 5-2.5 1.5a12 12 0 0 0 7 7L16 14l5 2v3a2 2 0 0 1-2 2A16 16 0 0 1 3 5a2 2 0 0 1 2-2z"/>
    </svg>
  ),
  settings: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M19.4 13.6a7.6 7.6 0 0 0 0-3.2l2-1.5-2-3.4-2.4.8a8 8 0 0 0-2.8-1.6l-.4-2.5h-4l-.4 2.5a8 8 0 0 0-2.8 1.6l-2.4-.8-2 3.4 2 1.5a7.6 7.6 0 0 0 0 3.2l-2 1.5 2 3.4 2.4-.8a8 8 0 0 0 2.8 1.6l.4 2.5h4l.4-2.5a8 8 0 0 0 2.8-1.6l2.4.8 2-3.4-2-1.5z"/>
      <circle cx="12" cy="12" r="3" fill="var(--bg)"/>
    </svg>
  ),
  check: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <circle cx="12" cy="12" r="10"/>
      <path d="M8 12.5l2.5 2.5L16 9.5" stroke="var(--bg)" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
    </svg>
  ),
  spark: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M12 2l1.8 6.2L20 10l-6.2 1.8L12 18l-1.8-6.2L4 10l6.2-1.8L12 2z"/>
    </svg>
  ),
  trending: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M3 17l6-6 4 4 8-8M14 7h7v7" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
    </svg>
  ),
  search: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <circle cx="11" cy="11" r="7" fill="none" stroke="currentColor" strokeWidth="2.4"/>
      <path d="M20 20l-4-4" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"/>
    </svg>
  ),
  envelope: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <rect x="2" y="5" width="20" height="14" rx="3"/>
      <path d="M3 7l9 6 9-6" stroke="var(--bg)" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  arrowRight: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" xmlns="http://www.w3.org/2000/svg">
      <path d="M5 12h14M13 6l6 6-6 6"/>
    </svg>
  ),
  close: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" xmlns="http://www.w3.org/2000/svg">
      <path d="M6 6l12 12M18 6l-12 12"/>
    </svg>
  ),
  inbox: (
    <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M3 13l3-9h12l3 9v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6z"/>
      <path d="M3 13h5l1.5 2h5l1.5-2h5" stroke="var(--bg)" strokeWidth="2" fill="none"/>
    </svg>
  ),
};

function Icon({ name, size = 24, color = "currentColor", background, padding = 0, radius = 8 }) {
  const svg = SG_ICONS[name];
  if (!svg) return null;
  const inner = (
    <div style={{
      width: size, height: size, color, display: "inline-flex",
      alignItems: "center", justifyContent: "center",
    }}>
      {React.cloneElement(svg, { width: size, height: size })}
    </div>
  );
  if (!background) return inner;
  return (
    <div style={{
      background, padding, borderRadius: radius,
      display: "inline-flex", alignItems: "center", justifyContent: "center",
    }}>{inner}</div>
  );
}

/* ---------- Buttons ---------- */
const DEMO_URL = "https://calendly.com/charles-cardealer/30min";
function Btn({ variant = "primary", size = "md", children, icon, fullWidth, style, href, target, onClick }) {
  const sizes = {
    sm: { pad: "8px 14px", fs: 13, h: 32, r: 8 },
    md: { pad: "10px 18px", fs: 14, h: 40, r: 10 },
    lg: { pad: "14px 24px", fs: 15, h: 48, r: 12 },
  };
  const s = sizes[size];
  const variants = {
    primary: { bg: "var(--cobalt-500)", color: "#fff", border: "none", shadow: "0 1px 0 rgba(11,27,43,0.08), 0 2px 4px rgba(31,93,255,0.18)" },
    secondary: { bg: "var(--bg)", color: "var(--ink)", border: "1px solid var(--line)", shadow: "none" },
    tonal: { bg: "var(--cobalt-50)", color: "var(--cobalt-600)", border: "none", shadow: "none" },
    ghost: { bg: "transparent", color: "var(--cobalt-600)", border: "none", shadow: "none" },
    danger: { bg: "var(--bg)", color: "#B91C1C", border: "1px solid #FECACA", shadow: "none" },
  };
  const v = variants[variant];
  const sharedStyle = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
    padding: s.pad, fontSize: s.fs, fontWeight: 600, height: s.h, borderRadius: s.r,
    background: v.bg, color: v.color, border: v.border, boxShadow: v.shadow,
    cursor: "pointer", fontFamily: "var(--font-body)", letterSpacing: "0.005em",
    whiteSpace: "nowrap", textDecoration: "none", boxSizing: "border-box",
    transition: "transform 120ms ease, box-shadow 120ms ease, background 120ms ease",
    width: fullWidth ? "100%" : undefined, ...(style || {}),
  };
  const content = (
    <React.Fragment>
      {icon ? <Icon name={icon} size={16} color="currentColor" /> : null}
      {children}
    </React.Fragment>
  );
  if (href) {
    const rel = target === "_blank" ? "noopener noreferrer" : undefined;
    return (
      <a href={href} target={target} rel={rel} onClick={onClick} style={sharedStyle}>
        {content}
      </a>
    );
  }
  return (
    <button onClick={onClick} style={sharedStyle}>
      {content}
    </button>
  );
}

/* ---------- Input ---------- */
function Input({ label, placeholder, defaultValue, icon, helper }) {
  return (
    <label style={{ display: "flex", flexDirection: "column", gap: 6 }}>
      {label ? <span style={{ fontSize: 13, fontWeight: 500, color: "var(--ink)" }}>{label}</span> : null}
      <div style={{
        display: "flex", alignItems: "center", gap: 10,
        background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 10,
        padding: "10px 14px", height: 44,
      }}>
        {icon ? <Icon name={icon} size={16} color="var(--body)" /> : null}
        <input type="text" placeholder={placeholder} defaultValue={defaultValue}
          style={{ border: "none", outline: "none", flex: 1, fontFamily: "var(--font-body)", fontSize: 14, color: "var(--ink)", background: "transparent" }} />
      </div>
      {helper ? <span style={{ fontSize: 12, color: "var(--body)" }}>{helper}</span> : null}
    </label>
  );
}

/* ---------- Badges / Tags / Sentiment chips ---------- */
function Badge({ tone = "default", children, dot, size = "md" }) {
  const palettes = {
    default:  { bg: "var(--neutral-bg)",  fg: "#374151" },
    info:     { bg: "var(--cobalt-50)",   fg: "var(--cobalt-700)" },
    positive: { bg: "var(--positive-bg)", fg: "var(--positive)" },
    warning:  { bg: "var(--warning-bg)",  fg: "var(--warning)" },
    mixed:    { bg: "var(--mixed-bg)",    fg: "var(--mixed)" },
    ink:      { bg: "var(--ink)",         fg: "#fff" },
  };
  const p = palettes[tone];
  const sizing = size === "sm"
    ? { pad: "3px 8px", fs: 11, gap: 5 }
    : { pad: "5px 10px", fs: 12, gap: 6 };
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: sizing.gap,
      background: p.bg, color: p.fg,
      borderRadius: 999, padding: sizing.pad,
      fontSize: sizing.fs, fontWeight: 600, letterSpacing: "0.01em",
      whiteSpace: "nowrap",
    }}>
      {dot ? <span style={{ width: 6, height: 6, borderRadius: 999, background: "currentColor", display: "inline-block" }}></span> : null}
      {children}
    </span>
  );
}

/* ---------- Agent profile picture treatment ---------- */
function AgentAvatar({ src, name, size = 96, status, ring = true, animate = false }) {
  const statusColor = status === "live" ? "#10B26C" : status === "idle" ? "#9CA3AF" : status === "busy" ? "#F59E0B" : null;
  const dot = size * 0.20;
  return (
    <div style={{ position: "relative", width: size, height: size, display: "inline-block" }}>
      <div style={{
        width: size, height: size, borderRadius: "50%",
        background: ring ? "var(--cobalt-gradient)" : "transparent",
        padding: ring ? Math.max(2, size * 0.025) : 0,
        boxSizing: "border-box",
        boxShadow: "var(--e-2)",
      }}>
        <div style={{
          width: "100%", height: "100%", borderRadius: "50%",
          background: "var(--bg)", padding: ring ? Math.max(2, size * 0.025) : 0,
          boxSizing: "border-box",
        }}>
          <img src={src} alt={name} style={{
            width: "100%", height: "100%", borderRadius: "50%", objectFit: "cover", display: "block",
          }}/>
        </div>
      </div>
      {animate && status === "live" ? (
        <span style={{
          position: "absolute", inset: -4, borderRadius: "50%",
          border: "2px solid #10B26C", opacity: 0.6,
          animation: "sgPulse 1.6s ease-out infinite",
          pointerEvents: "none",
        }}></span>
      ) : null}
      {statusColor ? (
        <span style={{
          position: "absolute", right: size * 0.02, bottom: size * 0.02,
          width: dot, height: dot, borderRadius: "50%",
          background: statusColor, border: `${Math.max(2, size * 0.04)}px solid var(--bg)`,
        }}></span>
      ) : null}
    </div>
  );
}

function AgentCard({ src, name, role, status = "live", live = false }) {
  return (
    <div style={{
      display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center",
      padding: 24, background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 16,
      gap: 14, boxShadow: "var(--e-1)",
    }}>
      <AgentAvatar src={src} name={name} size={112} status={status} animate={live} ring />
      <div>
        <div style={{ fontSize: 18, fontWeight: 700, color: "var(--ink)", letterSpacing: "-0.005em" }}>{name}</div>
        <div style={{ fontSize: 13, color: "var(--body)", marginTop: 2 }}>{role}</div>
      </div>
      {live ? (
        <Badge tone="positive" dot size="sm">On a call</Badge>
      ) : status === "idle" ? (
        <Badge tone="default" dot size="sm">Standing by</Badge>
      ) : null}
    </div>
  );
}

/* ---------- Conversation bubbles (iMessage-style pills) ---------- */
function Bubble({ side = "in", text, voice, src }) {
  const isIn = side === "in";
  return (
    <div style={{
      display: "flex", alignItems: "flex-end", gap: 8,
      flexDirection: isIn ? "row" : "row-reverse",
      animation: "sgRise 320ms ease both",
    }}>
      {isIn && src ? <AgentAvatar src={src} size={28} ring={false} /> : null}
      <div style={{
        background: isIn ? "var(--bg-alt)" : "var(--cobalt-500)",
        color: isIn ? "var(--ink)" : "#fff",
        padding: voice ? "10px 14px" : "10px 14px",
        borderRadius: 22,
        fontSize: 14,
        lineHeight: 1.4,
        maxWidth: 320,
        fontWeight: 400,
      }}>
        {voice ? <VoiceBars on={!isIn} /> : text}
      </div>
    </div>
  );
}

function VoiceBars({ on = true, count = 16, color }) {
  const bars = [];
  const heights = [0.4, 0.7, 1.0, 0.5, 0.8, 0.9, 0.6, 1.0, 0.7, 0.5, 0.9, 0.8, 0.4, 0.7, 1.0, 0.5];
  for (let i = 0; i < count; i++) {
    bars.push(
      <span key={i} style={{
        display: "inline-block", width: 3, height: 16 * heights[i % heights.length],
        borderRadius: 2, background: color || "currentColor",
        margin: "0 1.5px", transformOrigin: "center",
        animation: on ? `sgWave 0.9s ease-in-out infinite ${i * 0.06}s` : "none",
      }}></span>
    );
  }
  return (
    <span style={{ display: "inline-flex", alignItems: "center", height: 18, gap: 0 }}>
      {bars}
    </span>
  );
}

function TypingDots({ color = "var(--body)" }) {
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 4,
      padding: "10px 14px", background: "var(--bg-alt)", borderRadius: 22,
    }}>
      {[0,1,2].map(i => (
        <span key={i} style={{
          width: 6, height: 6, borderRadius: 999, background: color,
          display: "inline-block",
          animation: `sgBlink 1.2s ease-in-out infinite ${i * 0.15}s`,
        }}></span>
      ))}
    </span>
  );
}

/* ---------- Motion demo tiles ---------- */
function MotionTile({ name, description, children }) {
  return (
    <div style={{
      background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 16,
      padding: 0, overflow: "hidden", display: "flex", flexDirection: "column",
    }}>
      <div style={{
        height: 200, background: "var(--bg-soft)",
        display: "flex", alignItems: "center", justifyContent: "center",
        borderBottom: "1px solid var(--line)",
      }}>{children}</div>
      <div style={{ padding: "16px 20px" }}>
        <div style={{ fontSize: 15, fontWeight: 600, color: "var(--ink)" }}>{name}</div>
        <div style={{ fontSize: 13, color: "var(--body)", marginTop: 4, lineHeight: 1.5 }}>{description}</div>
      </div>
    </div>
  );
}

/* Motion demo: pulse */
function MotionPulse() {
  return (
    <div style={{ position: "relative", width: 100, height: 100 }}>
      {[0, 0.5, 1.0].map((d, i) => (
        <span key={i} style={{
          position: "absolute", inset: 30, borderRadius: "50%",
          border: "2px solid var(--cobalt-500)",
          animation: `sgPulse 2s ease-out infinite ${d}s`,
        }}></span>
      ))}
      <span style={{
        position: "absolute", inset: 38, borderRadius: "50%",
        background: "var(--cobalt-500)", boxShadow: "var(--e-2)",
      }}></span>
    </div>
  );
}

/* Motion demo: float */
function MotionFloat() {
  return (
    <div style={{ animation: "sgFloat 3s ease-in-out infinite" }}>
      <div style={{
        width: 96, height: 96, borderRadius: 22,
        background: "var(--cobalt-gradient)", boxShadow: "var(--e-3)",
        display: "flex", alignItems: "center", justifyContent: "center", color: "#fff",
      }}>
        <Icon name="spark" size={42} color="#fff" />
      </div>
    </div>
  );
}

/* Motion demo: routing path (dashed line traveling) */
function MotionPath() {
  return (
    <svg width="280" height="120" viewBox="0 0 280 120" fill="none" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="sgPathGrad" x1="0" x2="1">
          <stop offset="0" stopColor="#1F5DFF"/>
          <stop offset="1" stopColor="#7CA5FF"/>
        </linearGradient>
      </defs>
      <circle cx="30" cy="60" r="10" fill="#1F5DFF"/>
      <circle cx="140" cy="40" r="6" fill="#7CA5FF"/>
      <circle cx="250" cy="80" r="10" fill="#1F5DFF"/>
      <path d="M 40 60 Q 90 40 134 40 T 244 80" stroke="url(#sgPathGrad)" strokeWidth="3" strokeLinecap="round" strokeDasharray="6 8" fill="none" style={{ animation: "sgDash 1.5s linear infinite" }}/>
      <text x="30" y="100" textAnchor="middle" fontSize="11" fill="#7B7C7E" fontFamily="Roboto">Lead</text>
      <text x="140" y="22" textAnchor="middle" fontSize="11" fill="#7B7C7E" fontFamily="Roboto">Call</text>
      <text x="250" y="105" textAnchor="middle" fontSize="11" fill="#7B7C7E" fontFamily="Roboto">Appointment</text>
    </svg>
  );
}

/* Motion demo: voice waveform */
function MotionWave() {
  return (
    <div style={{
      display: "flex", alignItems: "center", justifyContent: "center", gap: 4,
      padding: "20px 28px", borderRadius: 999, background: "var(--cobalt-500)", color: "#fff",
      boxShadow: "var(--e-3)",
    }}>
      <VoiceBars on={true} count={20} color="#fff" />
    </div>
  );
}

/* ---------- Illustration tiles (the three approved styles) ---------- */
function IllRouting() {
  // Path metaphor with floating nodes
  return (
    <svg width="100%" height="100%" viewBox="0 0 320 200" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
      <defs>
        <linearGradient id="illR" x1="0" x2="1">
          <stop offset="0" stopColor="#1F5DFF"/>
          <stop offset="1" stopColor="#7CA5FF"/>
        </linearGradient>
      </defs>
      <path d="M 24 150 Q 80 60 160 100 T 296 50" stroke="url(#illR)" strokeWidth="3" strokeLinecap="round" strokeDasharray="6 8" fill="none" style={{ animation: "sgDash 1.6s linear infinite" }}/>
      <g style={{ animation: "sgFloat 3.2s ease-in-out infinite" }}>
        <circle cx="24" cy="150" r="14" fill="#1F5DFF"/>
        <circle cx="24" cy="150" r="6" fill="#fff"/>
      </g>
      <g style={{ animation: "sgFloat 3.2s ease-in-out infinite 0.4s" }}>
        <circle cx="160" cy="100" r="10" fill="#7CA5FF"/>
      </g>
      <g style={{ animation: "sgFloat 3.2s ease-in-out infinite 0.8s" }}>
        <circle cx="296" cy="50" r="14" fill="#1F5DFF"/>
        <circle cx="296" cy="50" r="6" fill="#fff"/>
      </g>
    </svg>
  );
}

function IllGeometric() {
  // Line/geometric — overlapping circles + line
  return (
    <svg width="100%" height="100%" viewBox="0 0 320 200" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
      <g style={{ animation: "sgBob 4s ease-in-out infinite", transformOrigin: "center" }}>
        <circle cx="120" cy="100" r="60" stroke="#1F5DFF" strokeWidth="3" fill="none"/>
        <circle cx="120" cy="100" r="36" stroke="#1F5DFF" strokeWidth="2" fill="none" opacity="0.4"/>
      </g>
      <g style={{ animation: "sgBob 4s ease-in-out infinite 0.5s", transformOrigin: "center" }}>
        <circle cx="200" cy="100" r="60" stroke="#1F5DFF" strokeWidth="3" fill="none"/>
        <circle cx="200" cy="100" r="36" stroke="#1F5DFF" strokeWidth="2" fill="none" opacity="0.4"/>
      </g>
      <circle cx="160" cy="100" r="6" fill="#1F5DFF"/>
    </svg>
  );
}

function IllOrb() {
  // 3D-ish gradient sphere with breathing motion
  return (
    <svg width="100%" height="100%" viewBox="0 0 320 200" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
      <defs>
        <radialGradient id="illOrb" cx="40%" cy="35%" r="65%">
          <stop offset="0" stopColor="#FFFFFF" stopOpacity="0.9"/>
          <stop offset="0.4" stopColor="#7CA5FF"/>
          <stop offset="1" stopColor="#1F5DFF"/>
        </radialGradient>
        <radialGradient id="illOrbHalo" cx="50%" cy="50%" r="50%">
          <stop offset="0.7" stopColor="#1F5DFF" stopOpacity="0"/>
          <stop offset="1" stopColor="#1F5DFF" stopOpacity="0.18"/>
        </radialGradient>
      </defs>
      <circle cx="160" cy="100" r="90" fill="url(#illOrbHalo)" style={{ transformOrigin: "160px 100px", animation: "sgBreathe 4s ease-in-out infinite" }}/>
      <circle cx="160" cy="100" r="62" fill="url(#illOrb)" style={{ transformOrigin: "160px 100px", animation: "sgBreathe 4s ease-in-out infinite 0.5s" }}/>
      <ellipse cx="142" cy="80" rx="14" ry="8" fill="#fff" opacity="0.4"/>
    </svg>
  );
}

/* ---------- Mini metric tile (used in dashboard preview AND component lib) ---------- */
function StatTile({ icon, label, value, delta, tone = "info" }) {
  return (
    <div style={{
      background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 16,
      padding: 20, display: "flex", flexDirection: "column", gap: 16, boxShadow: "var(--e-1)",
    }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <Icon name={icon} size={20} color={tone === "info" ? "var(--cobalt-600)" : "var(--ink)"}
              background={tone === "info" ? "var(--cobalt-50)" : "var(--bg-alt)"} padding={10} radius={10} />
        {delta ? <Badge tone="positive" size="sm">{delta}</Badge> : null}
      </div>
      <div>
        <div style={{ fontSize: 32, fontWeight: 700, color: "var(--ink)", letterSpacing: "-0.02em", lineHeight: 1.1 }}>{value}</div>
        <div style={{ fontSize: 13, color: "var(--body)", marginTop: 4 }}>{label}</div>
      </div>
    </div>
  );
}

/* ---------- Agent registry (shared between guide + dashboard) ---------- */
const AGENTS = [
  { id: "summer", name: "Summer", role: "AI Sales Agent",                 src: "assets/agents/summer.jpg", video: "assets/agents/summer.mp4", audio: "assets/agents/summer.mp3", status: "live",
    descriptor: "Drives more sales appointments.",
    description: "Makes outbound calls to dormant and trade-cycle customers, engages hot internet leads the moment they arrive, and schedules sales appointments directly into your CRM." },
  { id: "april",  name: "April",  role: "AI Service Reactivation Agent",  src: "assets/agents/april.jpg",  video: "assets/agents/april.mp4",  audio: "assets/agents/april.mp3",  status: "live",
    descriptor: "Brings back lost service customers.",
    description: "Reaches out to overdue and lapsed customers, handles objections, and schedules service appointments. She helps dealerships unlock revenue they already paid for." },
  { id: "taylor", name: "Taylor", role: "AI Inbound Service Scheduler",   src: "assets/agents/taylor.jpg", video: "assets/agents/taylor.mp4", audio: "assets/agents/taylor.mp3", status: "live",
    descriptor: "Answers calls and books service.",
    description: "Answers every service call 24/7 and books real appointments. She accesses history and transfers calls when needed." },
  { id: "avery",  name: "Avery",  role: "AI Receptionist",                src: "assets/agents/avery.jpg",  video: "assets/agents/avery.mp4", audio: "assets/agents/avery.wav",  status: "live",
    descriptor: "Greets, routes calls, and connects instantly.",
    description: "Answers inbound calls, routes customers, and schedules sales appointments. Delivers a consistent first impression day, night, weekends, and holidays." },
  { id: "riley",  name: "Riley",  role: "AI Recall Agent",                src: "assets/agents/riley.jpg",  video: "assets/agents/riley.mp4",  audio: "assets/agents/riley.mp3",  status: "live",
    descriptor: "Converts recalls into service visits.",
    description: "Proactively contacts customers with open recalls, explains the free repair, and schedules appointments. Improves compliance, safety, and fixed-ops revenue." },
  { id: "lily",   name: "Lily",   role: "AI Service-to-Sales Agent",       src: "assets/agents/lily.jpg",   video: "assets/agents/lily.mp4",   audio: "assets/agents/lily.wav",   status: "live",
    descriptor: "Turns service visits into sales conversations.",
    description: "Identifies positive-equity customers sitting in the service drive, opens the trade-in conversation, and hands warm prospects to the sales team with a booked appointment." },
];

/* ---------- Expose to other scripts ---------- */
const AGENT_BY = AGENTS.reduce((acc, a) => { acc[a.id] = a; return acc; }, {});
Object.assign(window, {
  SGSection, SGGrid, SGCard, SGRule, ColorChip, Icon, SG_ICONS,
  Btn, Input, Badge, DEMO_URL,
  AgentAvatar, AgentCard, AGENTS, AGENT_BY,
  Bubble, VoiceBars, TypingDots,
  MotionTile, MotionPulse, MotionFloat, MotionPath, MotionWave,
  IllRouting, IllGeometric, IllOrb,
  StatTile,
});
