// ui.jsx — 寵答 Cute&A design tokens + shared primitives
// All components exported to window at bottom.

// ---- token + base style injection ----
if (!document.getElementById('cca-tokens')) {
  const s = document.createElement('style');
  s.id = 'cca-tokens';
  s.textContent = `
  :root{
    --bg:#FBF5EC; --bgSoft:#F5EDDE; --surface:#FFFFFF;
    --ink:#2E1F14; --ink2:#6B5544; --ink3:#A08B75; --neutral:#B0A8A0;
    --line:#EADCC4; --line2:#F0E6D4;
    --brand:#E5845C; --brandSoft:#FADFC9; --brandDeep:#C6603A;
    --sage:#8BA888; --sageSoft:#DCE8D8;
    --butter:#F6C66A; --butterSoft:#FCE9B5;
    --rose:#E68B98; --roseSoft:#F8DCE0;
    --ok:#6FA978; --warn:#E5A24B; --err:#D06D5C;
    --rsm:10px; --rmd:16px; --rlg:22px; --rxl:28px; --rpill:999px;
    --accent:var(--brand); --accentSoft:var(--brandSoft); --accentDeep:var(--brandDeep);
  }
  .cca{font-family:"Noto Sans TC",-apple-system,system-ui,sans-serif;color:var(--ink);
       -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}
  .cca *{box-sizing:border-box;}
  .num{font-family:"Nunito","Noto Sans TC",sans-serif;font-variant-numeric:tabular-nums;}
  .cca ::-webkit-scrollbar{display:none;}
  @keyframes ccaIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  @keyframes ccaPop{0%{opacity:0;transform:scale(.92) translateY(6px)}100%{opacity:1;transform:none}}
  @keyframes ccaDots{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
  @keyframes ccaPulse{0%,100%{opacity:1}50%{opacity:.45}}
  .ccaTap{cursor:pointer;transition:transform .12s,background .15s,box-shadow .15s,border-color .15s,opacity .15s;}
  .ccaTap:active{transform:scale(.97);}
  .ccaRise{animation:ccaIn .32s cubic-bezier(.2,.7,.3,1) both;}
  .ccaPop{animation:ccaPop .34s cubic-bezier(.2,.8,.3,1) both;}
  `;
  document.head.appendChild(s);
}

const A = React.createElement;

// ---------- icons ----------
const ICON = {
  explore:'M12 3a9 9 0 100 18 9 9 0 000-18zM15.5 8.5l-2 5-5 2 2-5z',
  message:'M4 5h16v11H8l-4 4z',
  calendar:'M4 7h16v13H4zM4 7l0-3M20 7l0-3M8 4v3M16 4v3M4 11h16',
  user:'M12 12a4 4 0 100-8 4 4 0 000 8zM4.5 20a7.5 7.5 0 0115 0',
  search:'M11 4a7 7 0 100 14 7 7 0 000-14zM20 20l-4-4',
  mic:'M12 3a3 3 0 013 3v5a3 3 0 01-6 0V6a3 3 0 013-3zM5 11a7 7 0 0014 0M12 18v3',
  plus:'M12 5v14M5 12h14',
  camera:'M4 8h3l2-2.5h6L17 8h3v11H4zM12 16a3.2 3.2 0 100-6.4 3.2 3.2 0 000 6.4z',
  image:'M4 5h16v14H4zM4 15l4.5-4.5 4 4L15 11l5 5M9 9.5a1.3 1.3 0 11-2.6 0 1.3 1.3 0 012.6 0z',
  send:'M5 12l15-7-5 16-3.5-6z',
  chevR:'M9 5l7 7-7 7',
  chevL:'M15 5l-7 7 7 7',
  chevD:'M5 9l7 7 7-7',
  star:'M12 3.5l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 17l-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z',
  pin:'M12 21s7-6.3 7-11a7 7 0 10-14 0c0 4.7 7 11 7 11zM12 12.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z',
  paw:'M7 13.5a3 3 0 013-1.5h4a3 3 0 110 6 6 6 0 01-4 0 3 3 0 01-3-4.5zM6.5 9.5a1.4 1.4 0 100-2.8 1.4 1.4 0 000 2.8zM17.5 9.5a1.4 1.4 0 100-2.8 1.4 1.4 0 000 2.8zM9.5 6.8a1.3 1.3 0 100-2.6 1.3 1.3 0 000 2.6zM14.5 6.8a1.3 1.3 0 100-2.6 1.3 1.3 0 000 2.6z',
  heart:'M12 20s-7-4.6-7-9.5A3.8 3.8 0 0112 7a3.8 3.8 0 017 3.5C19 15.4 12 20 12 20z',
  check:'M5 12.5l4.5 4.5L19 7',
  bell:'M12 4a5 5 0 015 5c0 5 2 6 2 6H5s2-1 2-6a5 5 0 015-5zM10 20a2 2 0 004 0',
  grid:'M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM14 14h6v6h-6z',
  clock:'M12 3a9 9 0 100 18 9 9 0 000-18zM12 7.5V12l3 2',
  arrowR:'M5 12h14M13 6l6 6-6 6',
  arrowL:'M19 12H5M11 6l-6 6 6 6',
  x:'M6 6l12 12M18 6L6 18',
  sliders:'M4 8h10M18 8h2M4 16h2M10 16h10M14 5v6M8 13v6',
  video:'M4 7h11v10H4zM15 11l5-3v8l-5-3z',
  edit:'M4 20l1-4L16 5l3 3L8 19zM14 7l3 3',
  trend:'M4 16l4-4 3 3 6-7M21 8h-4M21 8v4',
  swap:'M7 4v13M7 4L4 7M7 4l3 3M17 20V7M17 20l3-3M17 20l-3-3',
  phone:'M5 4h4l1.5 4-2 1.5a11 11 0 005 5l1.5-2 4 1.5v4a1.5 1.5 0 01-1.7 1.5A16 16 0 014.5 5.7 1.5 1.5 0 015 4z',
  map:'M9 4L4 6v14l5-2 6 2 5-2V4l-5 2-6-2zM9 4v14M15 6v14',
  cat:'M5 9c0-3 .4-5 .4-5l3.1 2.4a8.5 8.5 0 017 0L18.6 4s.4 2 .4 5c1.2 1 2 2.6 2 4.4 0 3.8-4 6.6-9 6.6s-9-2.8-9-6.6C3 11.6 3.8 10 5 9z',
  list:'M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01',
  shield:'M12 3l7 3v5c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6z',
  wallet:'M4 7h14a2 2 0 012 2v8a2 2 0 01-2 2H4zM4 7V6a2 2 0 012-2h10M17 13h.01',
  gift:'M4 9h16v4H4zM4 13h16v7H4zM12 9v11M12 9S9 9 8 7.5 9 5 10 5.5 12 9 12 9zm0 0s3 0 4-1.5S15 5 14 5.5 12 9 12 9z',
  settings:'M12 9a3 3 0 100 6 3 3 0 000-6zM19.4 13a1.6 1.6 0 00.3 1.8l.1.1a2 2 0 11-2.8 2.8l-.1-.1a1.6 1.6 0 00-2.7 1.1V19a2 2 0 11-4 0v-.1a1.6 1.6 0 00-2.7-1.1l-.1.1a2 2 0 11-2.8-2.8l.1-.1A1.6 1.6 0 004.6 13H4a2 2 0 110-4h.1a1.6 1.6 0 001.1-2.7l-.1-.1a2 2 0 112.8-2.8l.1.1A1.6 1.6 0 0011 4.6V4a2 2 0 114 0v.1a1.6 1.6 0 002.7 1.1l.1-.1a2 2 0 112.8 2.8l-.1.1A1.6 1.6 0 0019.4 11H20a2 2 0 110 4z',
  scissors:'M6 6a2 2 0 100 4 2 2 0 000-4zM6 14a2 2 0 100 4 2 2 0 000-4zM8 8l12 8M8 16l12-8',
  bowl:'M4 11h16a8 8 0 01-16 0zM9 7c0-1 1-2 1-2M13 7c0-1 1-2 1-2',
  drop:'M12 4s5 6 5 9.5a5 5 0 01-10 0C7 10 12 4 12 4z',
  doc:'M6 3h8l4 4v14H6zM14 3v4h4',
};
function Icon({ name, size = 22, color = 'currentColor', sw = 1.8, fill = false, style }) {
  const d = ICON[name] || '';
  return A('svg', { width: size, height: size, viewBox: '0 0 24 24',
    fill: fill ? color : 'none', stroke: fill ? 'none' : color,
    strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round', style },
    A('path', { d }));
}

// ---------- placeholder ----------
function Ph({ w = '100%', h = 80, r = 14, icon = 'paw', label, style, dark }) {
  return A('div', { style: {
    width: w, height: h, borderRadius: r,
    background: dark ? '#E7DDCB' : 'repeating-linear-gradient(135deg,#EFE7D8 0 10px,#EBE2D1 10px 20px)',
    display: 'flex', flexDirection: 'column', gap: 4, alignItems: 'center', justifyContent: 'center',
    color: '#C2B49C', flexShrink: 0, ...style } },
    icon && A(Icon, { name: icon, size: Math.min(28, typeof h === 'number' ? h * 0.34 : 24), color: '#C7B9A1', sw: 1.6 }),
    label && A('div', { style: { fontSize: 10, color: '#B6A88F', fontWeight: 600 } }, label));
}

// ---------- phone frame ----------
function Phone({ children, accent = 'brand', bg = 'var(--bg)', noBar, statusDark = true }) {
  const accentVars = accent === 'sage'
    ? { '--accent': 'var(--sage)', '--accentSoft': 'var(--sageSoft)', '--accentDeep': '#6E8C6B' }
    : { '--accent': 'var(--brand)', '--accentSoft': 'var(--brandSoft)', '--accentDeep': 'var(--brandDeep)' };
  return A('div', { className: 'cca', style: {
    width: 390, height: 844, background: bg, position: 'relative', overflow: 'hidden',
    display: 'flex', flexDirection: 'column', ...accentVars } },
    !noBar && A(StatusBar, { dark: statusDark }),
    children);
}

function StatusBar({ dark = true }) {
  const c = dark ? 'var(--ink)' : '#fff';
  return A('div', { style: {
    height: 44, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between',
    padding: '0 22px 0 26px', position: 'relative', zIndex: 5 } },
    A('div', { className: 'num', style: { fontSize: 15, fontWeight: 700, color: c, letterSpacing: 0.4 } }, '9:41'),
    A('div', { style: { display: 'flex', alignItems: 'center', gap: 6 } },
      // signal
      A('svg', { width: 18, height: 11, viewBox: '0 0 18 11', fill: c },
        [3, 7, 11, 15].map((x, i) => A('rect', { key: i, x, y: 8 - i * 2.2, width: 3, height: 3 + i * 2.2, rx: 1 }))),
      // wifi
      A('svg', { width: 16, height: 11, viewBox: '0 0 16 11', fill: 'none', stroke: c, strokeWidth: 1.5, strokeLinecap: 'round' },
        A('path', { d: 'M1 3.5a10 10 0 0114 0M3.5 6a6.5 6.5 0 019 0' }), A('circle', { cx: 8, cy: 9, r: 1, fill: c, stroke: 'none' })),
      // battery
      A('svg', { width: 26, height: 13, viewBox: '0 0 26 13', fill: 'none' },
        A('rect', { x: 0.5, y: 0.5, width: 22, height: 12, rx: 3, stroke: c, opacity: 0.4 }),
        A('rect', { x: 2.5, y: 2.5, width: 16, height: 8, rx: 1.5, fill: c }),
        A('rect', { x: 24, y: 4, width: 2, height: 5, rx: 1, fill: c, opacity: 0.4 }))));
}

// ---------- buttons / chips ----------
function Btn({ children, variant = 'primary', full, size = 'lg', onClick, icon, iconR, disabled, style }) {
  const pad = size === 'sm' ? '8px 14px' : size === 'md' ? '11px 18px' : '14px 22px';
  const fs = size === 'sm' ? 13 : size === 'md' ? 14 : 15;
  const base = {
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    padding: pad, fontSize: fs, fontWeight: 700, borderRadius: 'var(--rpill)', border: 'none',
    width: full ? '100%' : 'auto', fontFamily: 'inherit', opacity: disabled ? 0.5 : 1,
    pointerEvents: disabled ? 'none' : 'auto',
  };
  const vmap = {
    primary: { background: 'var(--accent)', color: '#fff' },
    deep: { background: 'var(--accentDeep)', color: '#fff' },
    ghost: { background: 'transparent', color: 'var(--accent)', boxShadow: 'inset 0 0 0 1.5px var(--accent)' },
    soft: { background: 'var(--accentSoft)', color: 'var(--accentDeep)' },
    neutral: { background: 'var(--surface)', color: 'var(--ink)', boxShadow: 'inset 0 0 0 1px var(--line)' },
  };
  return A('button', { className: 'ccaTap', onClick, style: { ...base, ...vmap[variant], ...style } },
    icon && A(Icon, { name: icon, size: 17, sw: 2 }),
    children,
    iconR && A(Icon, { name: iconR, size: 17, sw: 2 }));
}

function Chip({ children, active, onClick, icon, accent, style }) {
  return A('button', { className: 'ccaTap', onClick, style: {
    display: 'inline-flex', alignItems: 'center', gap: 6, padding: '8px 14px', whiteSpace: 'nowrap',
    fontSize: 13, fontWeight: 600, fontFamily: 'inherit', borderRadius: 'var(--rpill)',
    border: 'none', flexShrink: 0,
    background: active ? 'var(--accentSoft)' : 'var(--surface)',
    color: active ? 'var(--accentDeep)' : 'var(--ink2)',
    boxShadow: active ? 'inset 0 0 0 1.5px var(--accent)' : 'inset 0 0 0 1px var(--line)', ...style } },
    icon && A(Icon, { name: icon, size: 15, sw: 2 }), children);
}

// ---------- card ----------
function Card({ children, pad = 16, onClick, style, accent }) {
  return A('div', { className: onClick ? 'ccaTap' : '', onClick, style: {
    background: 'var(--surface)', borderRadius: 'var(--rlg)', border: '1px solid var(--line2)',
    padding: pad, ...style } }, children);
}

// ---------- avatar ----------
function Avatar({ size = 44, kind = 'cat', accent, photo, ring, style }) {
  // kind: 'ai' = brand mascot bubble; 'cat'/'person' = gray photo placeholder
  if (kind === 'ai') {
    return A('div', { style: {
      width: size, height: size, borderRadius: '50%', flexShrink: 0,
      background: 'radial-gradient(120% 120% at 35% 25%, #FBC9A8 0%, var(--brand) 70%)',
      display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff',
      boxShadow: ring ? '0 0 0 3px #fff,0 0 0 5px var(--brandSoft)' : 'none', ...style } },
      A(Icon, { name: 'cat', size: size * 0.56, color: '#fff', sw: 1.7 }));
  }
  return A('div', { style: {
    width: size, height: size, borderRadius: '50%', flexShrink: 0, overflow: 'hidden',
    background: 'repeating-linear-gradient(135deg,#EFE7D8 0 8px,#EBE2D1 8px 16px)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    boxShadow: ring ? '0 0 0 2px #fff,0 0 0 3.5px var(--accent)' : 'none', ...style } },
    A(Icon, { name: kind === 'person' ? 'user' : 'paw', size: size * 0.42, color: '#C7B9A1', sw: 1.6 }));
}

// ---------- misc ----------
function Tag({ children, color = 'butter', solid, icon, style }) {
  const map = {
    butter: ['var(--butterSoft)', '#9A6B12'], sage: ['var(--sageSoft)', '#4E6B4B'],
    rose: ['var(--roseSoft)', '#B4566A'], brand: ['var(--brandSoft)', 'var(--brandDeep)'],
    ok: ['#DBEFDD', '#3E7A4A'], warn: ['#FBE8CC', '#9A6B12'], ink: ['var(--bgSoft)', 'var(--ink2)'],
  };
  const [bg, fg] = map[color] || map.butter;
  return A('span', { style: {
    display: 'inline-flex', alignItems: 'center', gap: 4, padding: '3px 9px', borderRadius: 'var(--rpill)',
    fontSize: 11, fontWeight: 700, background: solid ? fg : bg, color: solid ? '#fff' : fg, ...style } },
    icon && A(Icon, { name: icon, size: 12, sw: 2.2 }), children);
}

function Stars({ value = 5, size = 13 }) {
  return A('div', { style: { display: 'inline-flex', gap: 1, alignItems: 'center' } },
    [0, 1, 2, 3, 4].map(i => A(Icon, { key: i, name: 'star', size, fill: true,
      color: i < Math.round(value) ? 'var(--rose)' : '#EADCC4' })));
}

function Toggle({ on, onClick }) {
  return A('button', { onClick, className: 'ccaTap', style: {
    width: 44, height: 26, borderRadius: 'var(--rpill)', border: 'none', padding: 0, flexShrink: 0,
    background: on ? 'var(--accent)' : '#E2D6C2', position: 'relative', transition: 'background .2s' } },
    A('div', { style: {
      width: 20, height: 20, borderRadius: '50%', background: '#fff', position: 'absolute', top: 3,
      left: on ? 21 : 3, transition: 'left .2s', boxShadow: '0 1px 3px rgba(0,0,0,.2)' } }));
}

function Stepper({ value, onChange, min = 0, max = 9 }) {
  const b = (d, lbl) => A('button', { className: 'ccaTap', onClick: () => onChange(Math.max(min, Math.min(max, value + d))), style: {
    width: 32, height: 32, borderRadius: '50%', border: '1.5px solid var(--line)', background: 'var(--surface)',
    color: 'var(--accentDeep)', fontSize: 18, fontWeight: 700, fontFamily: 'inherit', lineHeight: 1, padding: 0 } }, lbl);
  return A('div', { style: { display: 'flex', alignItems: 'center', gap: 12 } },
    b(-1, '–'),
    A('span', { className: 'num', style: { fontSize: 16, fontWeight: 800, minWidth: 16, textAlign: 'center' } }, value),
    b(1, '+'));
}

// scrollable content region inside a phone
function Scroll({ children, style, onScroll }) {
  return A('div', { onScroll, style: { flex: 1, overflowY: 'auto', overflowX: 'hidden', ...style } }, children);
}

// simple top app bar
function AppBar({ title, left = 'back', right, accent, onLeft, sub, center = true }) {
  return A('div', { style: {
    height: 52, flexShrink: 0, display: 'flex', alignItems: 'center', gap: 8, padding: '0 14px',
    position: 'relative', zIndex: 4 } },
    left && A('button', { className: 'ccaTap', onClick: onLeft, style: {
      width: 38, height: 38, borderRadius: '50%', border: 'none', background: 'var(--surface)',
      boxShadow: 'inset 0 0 0 1px var(--line2)', display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0, color: 'var(--ink)' } }, A(Icon, { name: left === 'back' ? 'chevL' : left, size: 20 })),
    A('div', { style: { flex: 1, textAlign: center ? 'center' : 'left' } },
      A('div', { style: { fontSize: 16, fontWeight: 700 } }, title),
      sub && A('div', { style: { fontSize: 11, color: 'var(--ink3)', marginTop: 1 } }, sub)),
    right || A('div', { style: { width: 38 } }));
}

// home indicator bar (bottom)
function HomeBar({ dark }) {
  return A('div', { style: { height: 22, display: 'flex', alignItems: 'flex-end', justifyContent: 'center', paddingBottom: 8, flexShrink: 0 } },
    A('div', { style: { width: 134, height: 5, borderRadius: 3, background: dark ? 'rgba(255,255,255,.85)' : 'var(--ink)', opacity: dark ? 1 : 0.85 } }));
}

Object.assign(window, {
  A, Icon, ICON, Ph, Phone, StatusBar, Btn, Chip, Card, Avatar, Tag, Stars, Toggle, Stepper, Scroll, AppBar, HomeBar,
});
