// atoms.jsx — Lasso shared primitives, icons, type system

// ─── Icon set (Lucide-style 2.2 stroke) ──────────────────────────────
const Ico = {
  search: (p={}) => <svg width={p.s||20} height={p.s||20} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>,
  slider: (p={}) => <svg width={p.s||20} height={p.s||20} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.2" strokeLinecap="round"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/><circle cx="9" cy="6" r="2.5" fill={p.c||'currentColor'}/><circle cx="15" cy="12" r="2.5" fill={p.c||'currentColor'}/><circle cx="8" cy="18" r="2.5" fill={p.c||'currentColor'}/></svg>,
  heart: (p={}) => <svg width={p.s||20} height={p.s||20} viewBox="0 0 24 24" fill={p.filled?(p.c||'currentColor'):'none'} stroke={p.c||'currentColor'} strokeWidth="2"><path d="M12 21s-7-4.35-9.5-9C1 8 3 4 7 4c2 0 3.5 1 5 3 1.5-2 3-3 5-3 4 0 6 4 4.5 8C19 16.65 12 21 12 21z"/></svg>,
  star: (p={}) => <svg width={p.s||14} height={p.s||14} viewBox="0 0 24 24" fill={p.c||'#F28C1B'}><path d="M12 2 14.9 8.6 22 9.3l-5.4 4.7L18.2 21 12 17.3 5.8 21l1.6-7L2 9.3l7.1-.7L12 2z"/></svg>,
  bell: (p={}) => <svg width={p.s||22} height={p.s||22} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10 21a2 2 0 0 0 4 0"/></svg>,
  home: (p={}) => <svg width={p.s||22} height={p.s||22} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><path d="M3 11 12 4l9 7"/><path d="M5 10v10h14V10"/></svg>,
  bag: (p={}) => <svg width={p.s||22} height={p.s||22} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><path d="M5 8h14l-1 12H6L5 8z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg>,
  user: (p={}) => <svg width={p.s||22} height={p.s||22} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-7 8-7s8 3 8 7"/></svg>,
  chev: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="m9 6 6 6-6 6"/></svg>,
  chevL: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="m15 6-6 6 6 6"/></svg>,
  chevD: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="m6 9 6 6 6-6"/></svg>,
  check: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.8" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5 10 17 19 7.5"/></svg>,
  pin: (p={}) => <svg width={p.s||22} height={p.s||22} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><path d="M12 22s-7-7.3-7-13a7 7 0 1 1 14 0c0 5.7-7 13-7 13z"/><circle cx="12" cy="9" r="2.5"/></svg>,
  clock: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>,
  phone: (p={}) => <svg width={p.s||20} height={p.s||20} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 4a2 2 0 0 1 2-2h2l2 5-3 2a11 11 0 0 0 6 6l2-3 5 2v2a2 2 0 0 1-2 2A16 16 0 0 1 5 4z"/></svg>,
  msg: (p={}) => <svg width={p.s||20} height={p.s||20} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><path d="M21 12a8 8 0 0 1-11.5 7.2L4 21l1.8-5.5A8 8 0 1 1 21 12z"/></svg>,
  arrow: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14m-6-6 6 6-6 6"/></svg>,
  plus: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.6" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>,
  minus: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.6" strokeLinecap="round"><path d="M5 12h14"/></svg>,
  x: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2.4" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>,
  flame: (p={}) => <svg width={p.s||16} height={p.s||16} viewBox="0 0 24 24" fill={p.c||'currentColor'}><path d="M12 2c1 5-3 5-3 9a3 3 0 0 0 6 0c0-1-1-2-1-3 2 1 4 3 4 6a6 6 0 1 1-12 0c0-4 4-6 6-12z"/></svg>,
  trophy: (p={}) => <svg width={p.s||16} height={p.s||16} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M8 21h8M12 17v4M7 4h10v4a5 5 0 0 1-10 0z"/><path d="M17 5h3v2a3 3 0 0 1-3 3M7 5H4v2a3 3 0 0 0 3 3"/></svg>,
  wallet: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 7h14a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4z"/><path d="M4 7V5a1 1 0 0 1 1-1h11"/><circle cx="16" cy="13.5" r="1.2" fill={p.c||'currentColor'}/></svg>,
  card: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20"/></svg>,
  google: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24"><path fill="#4285F4" d="M22.6 12.2c0-.8-.1-1.4-.2-2.1H12v4h6c-.3 1.4-1 2.6-2.3 3.4v2.8h3.7c2.2-2 3.4-5 3.4-8.1z"/><path fill="#34A853" d="M12 23c3 0 5.6-1 7.5-2.7l-3.7-2.8c-1 .7-2.3 1.1-3.8 1.1-2.9 0-5.4-2-6.3-4.6H1.9v2.9C3.8 20.6 7.6 23 12 23z"/><path fill="#FBBC04" d="M5.7 14c-.2-.7-.3-1.3-.3-2s.1-1.3.3-2V7.1H1.9C1.3 8.5 1 10.1 1 12s.3 3.5.9 4.9l3.8-2.9z"/><path fill="#EA4335" d="M12 5.4c1.7 0 3.2.6 4.3 1.7l3.2-3.2C17.5 2 14.9 1 12 1 7.6 1 3.8 3.4 1.9 7.1L5.7 10c.9-2.6 3.4-4.6 6.3-4.6z"/></svg>,
  email: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></svg>,
  lock: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2"><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>,
  eye: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2"><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></svg>,
  ticket: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><path d="M3 9V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 4v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-4z"/><path d="M13 5v14" strokeDasharray="2 2"/></svg>,
  filter: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 5h18l-7 9v6l-4-2v-4z"/></svg>,
  refresh: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/></svg>,
  receipt: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><path d="M5 3h14v18l-3-2-2 2-2-2-2 2-2-2-3 2z"/><path d="M8 8h8M8 12h8M8 16h5"/></svg>,
  ride: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinejoin="round"><circle cx="6" cy="17" r="3"/><circle cx="18" cy="17" r="3"/><path d="m6 17 4-9 4 3 4 6"/><path d="M9 5h3l1 3"/></svg>,
  badge: (p={}) => <svg width={p.s||18} height={p.s||18} viewBox="0 0 24 24" fill={p.c||'currentColor'}><path d="M12 2 9 5H5v4l-3 3 3 3v4h4l3 3 3-3h4v-4l3-3-3-3V5h-4z"/></svg>,
  leaf: (p={}) => <svg width={p.s||14} height={p.s||14} viewBox="0 0 24 24" fill={p.c||'currentColor'}><path d="M21 3c-7 0-13 4-15 11 0 4 3 7 7 7 7 0 11-6 11-15-1 0-2 0-3 1-2 1-4 3-5 6"/></svg>,
  horseshoe: (p={}) => <svg width={p.s||16} height={p.s||16} viewBox="0 0 24 24" fill="none" stroke={p.c||'currentColor'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6.5 20.5c-1.2-2-2.5-4.2-2.5-8.5a8 8 0 0 1 16 0c0 4.3-1.3 6.5-2.5 8.5"/><circle cx="6.3" cy="20.8" r="1.1" fill={p.c||'currentColor'} stroke="none"/><circle cx="17.7" cy="20.8" r="1.1" fill={p.c||'currentColor'} stroke="none"/></svg>,
};

// ─── Bull mark — PNG ─────────────────────────────────────────────────
function Bull({ size = 40, variant = 'twotone' }) {
  const res = window.__resources || {};
  const src = variant === 'orange'
    ? (res.bullOrange || 'assets/bull-orange.png')
    : (res.bullTwotone || 'assets/bull-twotone.png');
  return <img src={src} alt="Lasso bull" style={{ width: size, height: 'auto', display: 'block' }} draggable={false}/>;
}

// ─── Glass surface stock — standalone React Bits adaptation ───────────
function GlassSurfaceStock({
  children,
  width = '100%',
  height = '100%',
  borderRadius = 20,
  borderWidth = 0.07,
  brightness = 50,
  opacity = 0.93,
  blur = 11,
  displace = 0.5,
  backgroundOpacity = 0,
  saturation = 1,
  distortionScale = -180,
  redOffset = 0,
  greenOffset = 10,
  blueOffset = 20,
  xChannel = 'R',
  yChannel = 'G',
  mixBlendMode = 'screen',
  className = '',
  style = {},
  contentStyle = {},
}) {
  const uniqueId = React.useId().replace(/:/g, '-');
  const filterId = 'glass-filter-' + uniqueId;
  const redGradId = 'red-grad-' + uniqueId;
  const blueGradId = 'blue-grad-' + uniqueId;
  const [svgSupported, setSvgSupported] = React.useState(false);
  const containerRef = React.useRef(null);
  const feImageRef = React.useRef(null);
  const redChannelRef = React.useRef(null);
  const greenChannelRef = React.useRef(null);
  const blueChannelRef = React.useRef(null);
  const gaussianBlurRef = React.useRef(null);

  const generateDisplacementMap = () => {
    const rect = containerRef.current?.getBoundingClientRect();
    const actualWidth = rect?.width || 400;
    const actualHeight = rect?.height || 200;
    const edgeSize = Math.min(actualWidth, actualHeight) * (borderWidth * 0.5);
    const svgContent =
      '<svg viewBox="0 0 ' + actualWidth + ' ' + actualHeight + '" xmlns="http://www.w3.org/2000/svg">' +
      '<defs>' +
      '<linearGradient id="' + redGradId + '" x1="100%" y1="0%" x2="0%" y2="0%">' +
      '<stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="red"/>' +
      '</linearGradient>' +
      '<linearGradient id="' + blueGradId + '" x1="0%" y1="0%" x2="0%" y2="100%">' +
      '<stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="blue"/>' +
      '</linearGradient>' +
      '</defs>' +
      '<rect x="0" y="0" width="' + actualWidth + '" height="' + actualHeight + '" fill="black"></rect>' +
      '<rect x="0" y="0" width="' + actualWidth + '" height="' + actualHeight + '" rx="' + borderRadius + '" fill="url(#' + redGradId + ')" />' +
      '<rect x="0" y="0" width="' + actualWidth + '" height="' + actualHeight + '" rx="' + borderRadius + '" fill="url(#' + blueGradId + ')" style="mix-blend-mode: ' + mixBlendMode + '" />' +
      '<rect x="' + edgeSize + '" y="' + edgeSize + '" width="' + (actualWidth - edgeSize * 2) + '" height="' + (actualHeight - edgeSize * 2) + '" rx="' + borderRadius + '" fill="hsl(0 0% ' + brightness + '% / ' + opacity + ')" style="filter:blur(' + blur + 'px)" />' +
      '</svg>';
    return 'data:image/svg+xml,' + encodeURIComponent(svgContent);
  };

  const updateDisplacementMap = () => {
    feImageRef.current?.setAttribute('href', generateDisplacementMap());
  };

  React.useEffect(() => {
    updateDisplacementMap();
    [
      { ref: redChannelRef, offset: redOffset },
      { ref: greenChannelRef, offset: greenOffset },
      { ref: blueChannelRef, offset: blueOffset },
    ].forEach(({ ref, offset }) => {
      if (!ref.current) return;
      ref.current.setAttribute('scale', (distortionScale + offset).toString());
      ref.current.setAttribute('xChannelSelector', xChannel);
      ref.current.setAttribute('yChannelSelector', yChannel);
    });
    gaussianBlurRef.current?.setAttribute('stdDeviation', displace.toString());
  }, [width, height, borderRadius, borderWidth, brightness, opacity, blur, displace, distortionScale, redOffset, greenOffset, blueOffset, xChannel, yChannel, mixBlendMode]);

  React.useEffect(() => {
    if (!containerRef.current) return;
    const resizeObserver = new ResizeObserver(() => setTimeout(updateDisplacementMap, 0));
    resizeObserver.observe(containerRef.current);
    return () => resizeObserver.disconnect();
  }, []);

  React.useEffect(() => {
    if (typeof window === 'undefined' || typeof document === 'undefined') return;
    const isWebkit = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
    const isFirefox = /Firefox/.test(navigator.userAgent);
    if (isWebkit || isFirefox) {
      setSvgSupported(false);
      return;
    }
    const div = document.createElement('div');
    div.style.backdropFilter = 'url(#' + filterId + ')';
    setSvgSupported(div.style.backdropFilter !== '');
  }, []);

  const containerStyle = {
    position: 'relative',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    overflow: 'hidden',
    width: typeof width === 'number' ? width + 'px' : width,
    height: typeof height === 'number' ? height + 'px' : height,
    borderRadius,
    background: svgSupported ? 'hsl(0 0% 100% / ' + backgroundOpacity + ')' : 'rgba(255,255,255,0.18)',
    backdropFilter: svgSupported ? 'url(#' + filterId + ') saturate(' + saturation + ')' : 'blur(12px) saturate(1.8) brightness(1.1)',
    WebkitBackdropFilter: svgSupported ? 'url(#' + filterId + ') saturate(' + saturation + ')' : 'blur(12px) saturate(1.8) brightness(1.1)',
    border: '1px solid rgba(255,255,255,0.28)',
    boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.35), inset 0 -1px 0 rgba(255,255,255,0.14), 0 8px 24px rgba(27,18,13,0.20)',
    transition: 'opacity 0.26s ease-out',
    ...style,
  };

  return (
    <div ref={containerRef} data-glass-surface-stock="" className={className} style={containerStyle}>
      <svg aria-hidden="true" style={{ width:'100%', height:'100%', pointerEvents:'none', position:'absolute', inset:0, opacity:0, zIndex:-1 }} xmlns="http://www.w3.org/2000/svg">
        <defs>
          <filter id={filterId} colorInterpolationFilters="sRGB" x="0%" y="0%" width="100%" height="100%">
            <feImage ref={feImageRef} x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="map" />
            <feDisplacementMap ref={redChannelRef} in="SourceGraphic" in2="map" result="dispRed" />
            <feColorMatrix in="dispRed" type="matrix" values={'1 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 1 0'} result="red" />
            <feDisplacementMap ref={greenChannelRef} in="SourceGraphic" in2="map" result="dispGreen" />
            <feColorMatrix in="dispGreen" type="matrix" values={'0 0 0 0 0  0 1 0 0 0  0 0 0 0 0  0 0 0 1 0'} result="green" />
            <feDisplacementMap ref={blueChannelRef} in="SourceGraphic" in2="map" result="dispBlue" />
            <feColorMatrix in="dispBlue" type="matrix" values={'0 0 0 0 0  0 0 0 0 0  0 0 1 0 0  0 0 0 1 0'} result="blue" />
            <feBlend in="red" in2="green" mode="screen" result="rg" />
            <feBlend in="rg" in2="blue" mode="screen" result="output" />
            <feGaussianBlur ref={gaussianBlurRef} in="output" stdDeviation="0.7" />
          </filter>
        </defs>
      </svg>
      <div style={{ width:'100%', height:'100%', display:'flex', alignItems:'center', justifyContent:'center', borderRadius:'inherit', position:'relative', zIndex:1, ...contentStyle }}>
        {children}
      </div>
    </div>
  );
}

// ─── Wordmark — Alfa Slab One ────────────────────────────────────────
function Wordmark({ color = 'var(--brand-orange)', size = 22 }) {
  return (
    <div style={{
      fontFamily: '"Alfa Slab One", Georgia, serif',
      fontWeight: 400, fontSize: size * 1.4, lineHeight: 1,
      letterSpacing: '0.02em', color, textTransform: 'uppercase',
      userSelect: 'none',
    }}>LASSO</div>
  );
}

// ─── Buttons ─────────────────────────────────────────────────────────
function Button({ kind = 'primary', children, onClick, full = false, size = 'md', icon, disabled = false, style = {} }) {
  const bgMap = {
    primary: 'var(--dark-chocolate)',
    accent:  'var(--brand-orange)',
    sun:     'var(--sun-orange)',
    ghost:   'transparent',
    cream:   'var(--bg-warm)',
    danger:  'var(--delayed-red)',
  };
  const fgMap = {
    primary: 'var(--dust-cream)', accent: '#fff', sun: '#fff',
    ghost: 'var(--fg-primary)', cream: 'var(--fg-primary)', danger: '#fff',
  };
  const padMap = { sm: '10px 14px', md: '14px 20px', lg: '17px 24px' };
  const fsMap = { sm: 12, md: 14, lg: 15 };
  return (
    <button onClick={disabled ? undefined : onClick} disabled={disabled} style={{
      background: bgMap[kind], color: fgMap[kind],
      border: kind === 'ghost' ? '1.5px solid var(--horse-brown)' : 'none',
      padding: padMap[size], borderRadius: 18,
      fontFamily: 'var(--font-display)', fontWeight: 800,
      fontSize: fsMap[size], letterSpacing: '0.02em',
      cursor: disabled ? 'not-allowed' : 'pointer',
      width: full ? '100%' : undefined, opacity: disabled ? 0.45 : 1,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      boxShadow: kind === 'accent' && !disabled ? 'var(--shadow-orange)' : 'none',
      transition: 'transform 140ms var(--ease-out), opacity 140ms, background 220ms',
      WebkitTapHighlightColor: 'transparent',
      ...style,
    }}
    onMouseDown={(e)=>!disabled&&(e.currentTarget.style.transform='scale(0.97)')}
    onMouseUp={(e)=>e.currentTarget.style.transform=''}
    onMouseLeave={(e)=>e.currentTarget.style.transform=''}>
      {children}{icon}
    </button>
  );
}

// ─── Status pill ─────────────────────────────────────────────────────
function StatusPill({ kind = 'live', children, dot = true }) {
  const bgMap = {
    live: '#2E8B4E', cooking: '#F28C1B', delayed: '#C13B1F', closed: '#7C675B',
    gold: '#D6A63A', orange: '#D85A14', amber: '#E8A82A', blue: '#4B7EA8',
    gray: '#7C675B', red: '#C83A2D', dark: '#1B120D',
  };
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '5px 10px', borderRadius: 999,
      background: bgMap[kind] || bgMap.live, color: '#fff',
      fontFamily: 'var(--font-display)', fontWeight: 800,
      fontSize: 10, letterSpacing: '0.08em', textTransform: 'uppercase',
    }}>
      {dot && <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#fff', opacity: 0.95 }}/>}
      {children}
    </div>
  );
}

// ─── Quantity stepper ───────────────────────────────────────────────
function Stepper({ value, onChange, dark = false, size = 'md' }) {
  const bg = dark ? 'var(--dark-chocolate)' : '#fff';
  const fg = dark ? 'var(--dust-cream)' : 'var(--dark-chocolate)';
  const h = size === 'sm' ? 26 : 30;
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center',
      background: bg, color: fg,
      border: dark ? 'none' : '1.5px solid var(--soft-line)',
      borderRadius: 12, overflow: 'hidden',
    }}>
      <button onClick={() => onChange(Math.max(0, value - 1))} style={btnStepStyle(fg, h)}>−</button>
      <span style={{ minWidth: 22, textAlign: 'center', fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13 }}>{value}</span>
      <button onClick={() => onChange(value + 1)} style={btnStepStyle(fg, h)}>+</button>
    </div>
  );
}
function btnStepStyle(c, h) {
  return { width: h, height: h, border: 'none', background: 'transparent', color: c, fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 16, cursor: 'pointer' };
}

// ─── Pill (small data chip) ──────────────────────────────────────────
function Pill({ bg = 'var(--dust-cream)', fg = 'var(--dark-chocolate)', children, style = {} }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '4px 9px', borderRadius: 999, background: bg, color: fg,
      fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 11, whiteSpace: 'nowrap',
      ...style,
    }}>{children}</div>
  );
}

function placeholderDishFor(hue = 'orange', glyph = 'bowl') {
  if (glyph === 'drink') return 'drink';
  if (glyph === 'cake') return 'cake';
  if (glyph === 'taco' || glyph === 'pizza') return 'taco';
  const map = {
    bbq: 'brisket',
    bun: 'burger',
    green: 'bowl',
    coffee: 'iced-latte',
    sweet: 'cake',
    red: 'taco',
    cream: 'iced-latte',
    orange: 'taco',
  };
  return map[hue] || 'taco';
}

// ─── Food placeholder — resolves to the fake food pack, with SVG fallback ──
function FoodPh({ height = 130, hue = 'orange', radius = 18, glyph = 'bowl' }) {
  return <FoodArt dish={placeholderDishFor(hue, glyph)} height={height} radius={radius}/>;
}

// ─── Skeleton block (warm shimmer) ──────────────────────────────────
function Skeleton({ w = '100%', h = 14, r = 8, style = {} }) {
  return <div style={{
    width: w, height: h, borderRadius: r,
    background: 'linear-gradient(90deg,#EDE3D6 0%,#F5EFE7 50%,#EDE3D6 100%)',
    backgroundSize: '200% 100%', animation: 'lasso-shimmer 1.4s linear infinite',
    ...style,
  }}/>;
}

// ─── Toast — bottom-center on mobile ────────────────────────────────
function Toast({ msg, kind = 'success', onDone }) {
  React.useEffect(() => {
    if (!msg) return;
    const t = setTimeout(onDone, 2200);
    return () => clearTimeout(t);
  }, [msg]);
  if (!msg) return null;
  const colors = {
    success: { bg: 'var(--dark-chocolate)', accent: 'var(--live-green)' },
    error:   { bg: 'var(--dark-chocolate)', accent: 'var(--delayed-red)' },
    info:    { bg: 'var(--dark-chocolate)', accent: 'var(--sun-orange)' },
  }[kind];
  return (
    <div style={{
      position: 'absolute', bottom: 110, left: 20, right: 20, zIndex: 600,
      background: colors.bg, color: 'var(--dust-cream)', borderRadius: 18,
      padding: '12px 16px', display: 'flex', alignItems: 'center', gap: 12,
      boxShadow: 'var(--shadow-lg)', animation: 'lasso-toast-in 280ms var(--ease-out)',
    }}>
      <div style={{ width: 8, height: 8, borderRadius: '50%', background: colors.accent }}/>
      <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 13, flex: 1 }}>{msg}</div>
    </div>
  );
}

// ─── Eyebrow label ──────────────────────────────────────────────────
function Eyebrow({ children, color = 'var(--warm-stone)', style = {} }) {
  return <div style={{
    fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 10,
    letterSpacing: '0.18em', textTransform: 'uppercase', color, ...style,
  }}>{children}</div>;
}

// ─── Section title ──────────────────────────────────────────────────
function SectionTitle({ eyebrow, title, action, onAction }) {
  return (
    <div style={{ padding: '0 20px 10px', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
      <div>
        {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 22, marginTop: 4, letterSpacing: '-0.01em', color: 'var(--fg-primary)' }}>{title}</div>
      </div>
      {action && <div onClick={onAction} style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 12, color: 'var(--brand-orange)', cursor: 'pointer' }}>{action}</div>}
    </div>
  );
}

// ─── Input field ────────────────────────────────────────────────────
function Input({ label, type = 'text', placeholder, value, onChange, icon, error, hint, autoFocus }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {label && <Eyebrow color="var(--fg-secondary)">{label}</Eyebrow>}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, height: 50,
        background: '#fff', border: `1.5px solid ${error ? 'var(--delayed-red)' : 'var(--soft-line)'}`,
        borderRadius: 16, padding: '0 14px', boxShadow: 'var(--shadow-sm)',
        transition: 'border-color 220ms',
      }}>
        {icon}
        <input
          type={type} placeholder={placeholder} value={value || ''}
          autoFocus={autoFocus}
          onChange={(e)=>onChange && onChange(e.target.value)}
          style={{
            border: 'none', outline: 'none', flex: 1, background: 'transparent',
            fontFamily: 'var(--font-body)', fontSize: 15, color: 'var(--fg-primary)',
            minWidth: 0,
          }}/>
      </div>
      {error && <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--delayed-red)' }}>{error}</div>}
      {hint && !error && <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--fg-secondary)' }}>{hint}</div>}
    </div>
  );
}

// ─── App header — wordmark + nav actions ─────────────────────────────
function AppHeader({ onBell, onProfile, initials = 'JM' }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 20px 8px' }}>
      <Wordmark size={22}/>
      <HeaderActions onBell={onBell} onProfile={onProfile} initials={initials}/>
    </div>
  );
}

// Bell + avatar cluster — reused standalone in the sticky home header
function HeaderActions({ onBell, onProfile, initials = 'JM', authed = true }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <button data-notifications-trigger="" onClick={onBell} style={{
        width: 40, height: 40, borderRadius: 14, border: '1.5px solid var(--soft-line)',
        background: 'var(--bg-surface)', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', cursor: 'pointer',
      }}>
        <Ico.bell c="var(--fg-primary)" s={20}/>
        <span style={{ position: 'absolute', top: 7, right: 7, width: 8, height: 8, borderRadius: '50%', background: 'var(--brand-orange)', border: '2px solid var(--bg-surface)' }}/>
      </button>
      {authed ? (
        <button data-user-menu-trigger="" onClick={onProfile} title="Your account" style={{
          width: 40, height: 40, borderRadius: '50%', border: 'none', cursor: 'pointer',
          background: 'linear-gradient(135deg,#F28C1B,#D85A14)', color: '#fff',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 13,
        }}>{initials}</button>
      ) : (
        <button data-user-menu-trigger="" data-customer-auth-entry="" onClick={onProfile} title="Sign in" style={{
          height: 40, padding: '0 14px', borderRadius: 14, border: 'none', cursor: 'pointer',
          background: 'var(--dark-chocolate)', color: 'var(--dust-cream)', display: 'flex', alignItems: 'center', gap: 7,
          fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 12.5,
        }}><Ico.user c="var(--dust-cream)" s={16}/> Sign in</button>
      )}
    </div>
  );
}

// ─── Bottom nav — floats with margin ─────────────────────────────────
function BottomNav({ active = 'home', onChange, cartCount = 0 }) {
  const tabs = [
    { id: 'home', label: 'Home', icon: Ico.home },
    { id: 'orders', label: 'Orders', icon: Ico.bag, badge: cartCount },
    { id: 'shootout', label: 'Shootout', icon: Ico.flame },
    { id: 'rewards', label: 'Rewards', icon: Ico.trophy },
    { id: 'profile', label: 'Profile', icon: Ico.user },
  ];
  return (
    <GlassSurfaceStock
      width="calc(100% - 36px)"
      height="auto"
      borderRadius={22}
      displace={0.5}
      distortionScale={-180}
      redOffset={0}
      greenOffset={10}
      blueOffset={20}
      brightness={50}
      opacity={0.93}
      mixBlendMode="screen"
      backgroundOpacity={0.04}
      saturation={1.2}
      style={{
        margin: '0 18px',
        minHeight: 74,
        background: 'rgba(27,18,13,0.48)',
        borderColor: 'rgba(255,255,255,0.16)',
      }}
      contentStyle={{
        padding: 5,
        display: 'grid',
        gridTemplateColumns: 'repeat(5,1fr)',
        gap: 4,
      }}
    >
      <div data-production-mobile-tabbar="" style={{ display:'contents' }}>
      {tabs.map(t => {
        const on = active === t.id;
        return (
          <button key={t.id} onClick={() => onChange && onChange(t.id)} style={{
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
            padding: '8px 4px', borderRadius: 14, border: 'none', position: 'relative',
            background: 'transparent', color: on ? 'var(--brand-orange)' : '#9F8979',
            fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 10,
            letterSpacing: '0.06em', textTransform: 'uppercase', cursor: 'pointer',
          }}>
            <span data-production-mobile-tab-link="" style={{
              minHeight: 48,
              width: '100%',
              borderRadius: 14,
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center',
              justifyContent: 'center',
              gap: 4,
              padding: '5px 4px',
              background: on ? 'rgba(255,255,255,0.14)' : 'rgba(255,255,255,0.055)',
              border: on ? '1px solid rgba(255,255,255,0.22)' : '1px solid rgba(255,255,255,0.08)',
              backdropFilter: 'blur(12px) saturate(1.45)',
              WebkitBackdropFilter: 'blur(12px) saturate(1.45)',
              boxShadow: on ? 'inset 0 1px 0 rgba(255,255,255,0.22)' : 'none',
            }}>
              <t.icon c={on ? 'var(--brand-orange)' : '#9F8979'} s={20}/>
              <span>{t.label}</span>
            </span>
            {t.badge > 0 && (
              <span style={{
                position: 'absolute', top: 4, right: '50%', marginRight: -16,
                minWidth: 16, height: 16, borderRadius: 8, padding: '0 5px',
                background: 'var(--brand-orange)', color: '#fff',
                fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 10,
                display: 'flex', alignItems: 'center', justifyContent: 'center', border: '1.5px solid var(--dark-chocolate)',
              }}>{t.badge}</span>
            )}
          </button>
        );
      })}
      </div>
    </GlassSurfaceStock>
  );
}

// ─── Search bar ──────────────────────────────────────────────────────
function SearchBar({ placeholder = 'Catch your craving…', value, onChange, onFilter, onActivate, filterCount = 0, elevated = false }) {
  return (
    <div data-lasso="search-input" onClick={onActivate} style={{
      display: 'flex', alignItems: 'center', gap: 10,
      background: 'rgba(255,255,255,0.68)',
      border: '1px solid rgba(255,255,255,0.72)',
      borderRadius: 18, padding: '10px 14px', height: 48, margin: '0 20px',
      boxShadow: elevated ? '0 10px 26px -6px rgba(27,18,13,0.28)' : '0 12px 30px -18px rgba(27,18,13,0.42)',
      backdropFilter: 'blur(18px) saturate(165%)',
      WebkitBackdropFilter: 'blur(18px) saturate(165%)',
      cursor: onActivate ? 'pointer' : 'text',
    }}>
      <Ico.search c="var(--warm-stone)" s={20}/>
      <input
        placeholder={placeholder} value={value || ''}
        readOnly={!!onActivate}
        onFocus={onActivate ? (e) => { e.target.blur(); onActivate(); } : undefined}
        onChange={(e)=>onChange && onChange(e.target.value)}
        style={{
          border: 'none', outline: 'none', flex: 1, background: 'transparent',
          fontFamily: 'var(--font-body)', fontSize: 14, color: 'var(--fg-primary)',
          cursor: onActivate ? 'pointer' : 'text',
        }}/>
      <button onClick={(e)=>{ e.stopPropagation(); onFilter && onFilter(); }} style={{
        position: 'relative',
        width: 32, height: 32, borderRadius: 10, border: 'none',
        background: 'var(--dark-chocolate)', color: 'var(--dust-cream)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
      }}>
        <Ico.slider c="var(--dust-cream)" s={16}/>
        {filterCount > 0 && (
          <span style={{
            position: 'absolute', top: -5, right: -5, minWidth: 16, height: 16, padding: '0 4px',
            borderRadius: 8, background: 'var(--brand-orange)', color: '#fff',
            fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 10, lineHeight: '16px',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            border: '1.5px solid var(--bg-surface)',
          }}>{filterCount}</span>
        )}
      </button>
    </div>
  );
}

// ─── Chips ───────────────────────────────────────────────────────────
function Chips({ items, active, onChange }) {
  return (
    <div data-lasso="cuisine-filter" style={{ display: 'flex', gap: 8, overflowX: 'auto', padding: '0 20px', scrollbarWidth: 'none' }}>
      <style>{`[data-lasso="cuisine-filter"]::-webkit-scrollbar{display:none}`}</style>
      {items.map(i => {
        const on = i === active;
        return (
          <button key={i} onClick={() => onChange && onChange(i)} style={{
            padding: '8px 14px', borderRadius: 14,
            background: on ? 'var(--dark-chocolate)' : 'var(--bg-surface)',
            color: on ? 'var(--dust-cream)' : 'var(--fg-primary)',
            border: on ? '1.5px solid var(--dark-chocolate)' : '1.5px solid var(--soft-line)',
            fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 12, letterSpacing: '0.04em',
            whiteSpace: 'nowrap', cursor: 'pointer', flexShrink: 0,
          }}>{i}</button>
        );
      })}
    </div>
  );
}

// ─── Bottom sheet ────────────────────────────────────────────────────
// Renders into a non-scrolling layer pinned to the phone frame (via portal)
// so the sheet anchors to the viewport bottom, not the scrolling screen, and
// scrolling stays inside the sheet instead of leaking to the page behind.
function BottomSheet({ open, onClose, children, title, maxHeight = '85%' }) {
  const [layer, setLayer] = React.useState(null);
  const [dragY, setDragY] = React.useState(0);
  const dragStart = React.useRef(null);
  React.useEffect(() => { setLayer(document.getElementById('lasso-sheet-layer')); }, []);
  React.useEffect(() => {
    if (!open) setDragY(0);
  }, [open]);
  const beginSwipeClose = (event) => {
    if (!open) return;
    dragStart.current = { y: event.clientY, at: performance.now() };
    setDragY(0);
    event.currentTarget.setPointerCapture?.(event.pointerId);
  };
  const moveSwipeClose = (event) => {
    if (!dragStart.current) return;
    setDragY(Math.max(0, event.clientY - dragStart.current.y));
  };
  const endSwipeClose = (event) => {
    if (!dragStart.current) return;
    const distance = Math.max(0, event.clientY - dragStart.current.y);
    const elapsed = Math.max(1, performance.now() - dragStart.current.at);
    const velocity = distance / elapsed;
    dragStart.current = null;
    setDragY(0);
    if (distance > 86 || velocity > 0.62) onClose();
  };

  const body = (
    <>
      {/* overlay */}
      <div className="lasso-sheet-overlay" onClick={onClose} style={{
        position: 'absolute', inset: 0, background: 'rgba(27,18,13,0.55)',
        zIndex: 400, opacity: open ? 1 : 0, pointerEvents: open ? 'auto' : 'none',
        transition: 'opacity 280ms var(--ease-out)',
      }}/>
      {/* sheet */}
      <div className="lasso-sheet" style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 410,
        background: 'var(--bg-app)', borderRadius: '28px 28px 0 0',
        boxShadow: '0 -20px 50px -10px rgba(0,0,0,0.35)',
        maxHeight, display: 'flex', flexDirection: 'column',
        transform: open ? `translateY(${dragY}px)` : 'translateY(101%)',
        pointerEvents: open ? 'auto' : 'none',
        transition: dragStart.current ? 'none' : 'transform 320ms var(--ease-out)',
      }}>
        <div
          onClick={onClose}
          onPointerDown={beginSwipeClose}
          onPointerMove={moveSwipeClose}
          onPointerUp={endSwipeClose}
          onPointerCancel={endSwipeClose}
          title="Close"
          style={{ padding: '12px 0 4px', display: 'flex', justifyContent: 'center', flexShrink: 0, cursor: 'grab', touchAction: 'none' }}
        >
          <div style={{ width: 44, height: 4, borderRadius: 2, background: 'var(--soft-line)' }}/>
        </div>
        {title && (
          <div style={{ padding: '6px 20px 8px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexShrink: 0 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 18, color: 'var(--fg-primary)' }}>{title}</div>
            <button onClick={onClose} style={{ width: 32, height: 32, borderRadius: 10, border: 'none', background: 'var(--bg-warm)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
              <Ico.x c="var(--fg-primary)" s={18}/>
            </button>
          </div>
        )}
        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', overflowX: 'hidden', overscrollBehavior: 'contain', WebkitOverflowScrolling: 'touch' }}>{children}</div>
      </div>
    </>
  );

  // Portal into the frame-level layer when available; fall back to inline.
  return layer ? ReactDOM.createPortal(body, layer) : body;
}

// ─── Page transitions (slide-in screens) ─────────────────────────────
function Screen({ children, dir = 'right', scroll = true }) {
  // dir: 'right' (push), 'left' (back). scroll: whether the screen itself scrolls.
  return (
    <div data-lasso-screen="" style={{
      animation: `lasso-slide-${dir} 320ms var(--ease-out)`,
      flex: 1, minHeight: 0, position: 'relative',
      overflowY: scroll ? 'auto' : 'hidden', overflowX: 'hidden',
      display: 'flex', flexDirection: 'column',
    }}>{children}</div>
  );
}

// ─── Sheriff's medallion — knurled coin, beveled rim, embossed star ──
const STAR_PTS = 'M50,6 L60.6,35.4 L91.9,36.4 L67.1,55.6 L75.9,85.6 L50,68 L24.1,85.6 L32.9,55.6 L8.2,36.4 L39.4,35.4 Z';
function SheriffStar({ size = 74, value, sub = 'RATED', tone = 'gold' }) {
  const uid = React.useMemo(() => 'sh' + Math.random().toString(36).slice(2, 7), []);
  const tones = {
    gold:  { rimHi:'#FBE39A', rimMid:'#E3A622', rimLo:'#9A6410', fieldHi:'#6E4310', fieldLo:'#341E06', starHi:'#FFEDB0', starLo:'#C98A1E', txt:'#FFF2D2', sub:'#EFC979', edge:'#2A1705' },
    steel: { rimHi:'#EEF3F7', rimMid:'#AFC0CC', rimLo:'#6E8290', fieldHi:'#46555F', fieldLo:'#212B32', starHi:'#FBFEFF', starLo:'#9FB2BE', txt:'#F2F7FA', sub:'#C3D2DC', edge:'#171F25' },
  };
  const c = tones[tone] || tones.gold;
  const ticks = Array.from({ length: 60 }, (_, i) => i * 6);
  const star = (cx, cy, s, fill, stroke) => (
    <path d={STAR_PTS} fill={fill} stroke={stroke || 'none'} strokeWidth={stroke ? 1.2 : 0} strokeLinejoin="round"
      transform={`translate(${cx} ${cy}) scale(${s}) translate(-50 -46)`}/>
  );
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" style={{ display: 'block' }}>
      <defs>
        <linearGradient id={uid + 'rim'} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={c.rimHi}/>
          <stop offset="48%" stopColor={c.rimMid}/>
          <stop offset="100%" stopColor={c.rimLo}/>
        </linearGradient>
        <linearGradient id={uid + 'rimR'} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={c.rimLo}/>
          <stop offset="100%" stopColor={c.rimHi}/>
        </linearGradient>
        <radialGradient id={uid + 'field'} cx="50%" cy="36%" r="72%">
          <stop offset="0%" stopColor={c.fieldHi}/>
          <stop offset="100%" stopColor={c.fieldLo}/>
        </radialGradient>
        <linearGradient id={uid + 'star'} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={c.starHi}/>
          <stop offset="100%" stopColor={c.starLo}/>
        </linearGradient>
      </defs>
      {/* outer coin */}
      <circle cx="50" cy="50" r="49" fill={c.edge}/>
      <circle cx="50" cy="50" r="48" fill={`url(#${uid}rim)`}/>
      {/* knurled coin edge */}
      <g stroke={c.edge} strokeWidth="1" opacity="0.4" strokeLinecap="round">
        {ticks.map((a, i) => {
          const rad = a * Math.PI / 180;
          return <line key={i} x1={50 + Math.cos(rad) * 44.6} y1={50 + Math.sin(rad) * 44.6} x2={50 + Math.cos(rad) * 47.6} y2={50 + Math.sin(rad) * 47.6}/>;
        })}
      </g>
      {/* bevel chamfer (reverse gradient) + inner shadow ring */}
      <circle cx="50" cy="50" r="41" fill={`url(#${uid}rimR)`}/>
      <circle cx="50" cy="50" r="39.5" fill={c.edge} opacity="0.92"/>
      {/* recessed field */}
      <circle cx="50" cy="50" r="37" fill={`url(#${uid}field)`}/>
      <circle cx="50" cy="50" r="37" fill="none" stroke={c.starLo} strokeWidth="0.6" opacity="0.45"/>
      {/* engraved dotted ring */}
      <circle cx="50" cy="50" r="32.5" fill="none" stroke={c.starHi} strokeWidth="0.8" strokeDasharray="0.4 3.4" opacity="0.45"/>
      {value != null ? (
        <>
          {star(50, 27.5, 0.30, c.edge)}
          {star(50, 26.5, 0.30, `url(#${uid}star)`)}
          <text x="50" y="58" textAnchor="middle" fontFamily="var(--font-display)" fontWeight="900" fontSize="20" fill={c.txt}>{value}</text>
          <text x="50" y="70" textAnchor="middle" fontFamily="var(--font-display)" fontWeight="800" fontSize="6.4" letterSpacing="1.6" fill={c.sub}>{sub}</text>
        </>
      ) : (
        <>
          {star(50, 52, 0.62, c.edge)}
          {star(50, 50.5, 0.62, `url(#${uid}star)`)}
          {star(50, 50.5, 0.62, 'none', c.starHi)}
        </>
      )}
      {/* top sheen */}
      <ellipse cx="38" cy="23" rx="25" ry="10" fill="rgba(255,255,255,0.16)"/>
    </svg>
  );
}

// ─── Illustrated food image — warm board + layered dish art ─────────
function FoodArt({ dish = 'taco', height = 92, radius = 14, style = {} }) {
  const uid = React.useMemo(() => 'fa' + Math.random().toString(36).slice(2, 7), []);
  const photo = {
    taco: 'assets/food/taco.png',
    'steak-taco': 'assets/food/steak-taco.png',
    nachos: 'assets/food/nachos.png',
    quesadilla: 'assets/food/quesadilla.png',
    burger: 'assets/food/burger.png',
    'double-burger': 'assets/food/double-burger.png',
    'veggie-burger': 'assets/food/veggie-burger.png',
    fries: 'assets/food/fries.png',
    'onion-rings': 'assets/food/onion-rings.png',
    shake: 'assets/food/shake.png',
    coffee: 'assets/food/coffee.png',
    'iced-latte': 'assets/food/iced-latte.png',
    cinnamon: 'assets/food/cinnamon.png',
    croissant: 'assets/food/croissant.png',
    pastry: 'assets/food/pastry.png',
    brisket: 'assets/food/brisket.png',
    burntends: 'assets/food/burntends.png',
    'pulled-pork': 'assets/food/pulled-pork.png',
    sandwich: 'assets/food/sandwich.png',
    wings: 'assets/food/wings.png',
    'wings-bowl': 'assets/food/wings-bowl.png',
    ribs: 'assets/food/ribs.png',
    bowl: 'assets/food/bowl.png',
    slaw: 'assets/food/slaw.png',
    drink: 'assets/food/drink.png',
    lemonade: 'assets/food/lemonade.png',
    cake: 'assets/food/cake.png',
    pizza: 'assets/food/pizza.png',
    sushi: 'assets/food/sushi.png',
    chinese: 'assets/food/chinese.png',
    noodles: 'assets/food/noodles.png',
    kebab: 'assets/food/kebab.png',
    grocery: 'assets/food/grocery.png',
  }[dish];
  const objectPosition = {
    taco: 'center 50%',
    brisket: 'center 50%',
    burntends: 'center 50%',
    burger: 'center 52%',
    sandwich: 'center 52%',
    wings: 'center 48%',
    ribs: 'center 48%',
    slaw: 'center 50%',
    drink: 'center 48%',
    cake: 'center 48%',
  }[dish] || 'center';
  if (photo) {
    return (
      <div style={{ height, borderRadius: radius, position: 'relative', overflow: 'hidden', background: 'var(--bg-warm)', ...style }}>
        <img
          src={photo}
          alt=""
          loading="lazy"
          onError={(e) => { e.currentTarget.style.display = 'none'; }}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition }}
        />
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg,rgba(27,18,13,0.02) 35%,rgba(27,18,13,0.18) 100%)' }}/>
      </div>
    );
  }
  const boards = {
    char:  ['#3A1B0D', '#5A2C13'],   // dark smoked board
    oak:   ['#C68A4A', '#9A5E28'],   // wood plank
    cream: ['#E9DCC4', '#CDA876'],   // light plate
    slate: ['#5A4636', '#3A2A1E'],
  };
  const D = {
    taco:    { board: 'char', art: (
      <g>
        <path d="M14 64 Q50 24 86 64 Q50 50 14 64Z" fill="#F0C070"/>
        <path d="M14 64 Q50 24 86 64 Q50 50 14 64Z" fill="none" stroke="#C98A2E" strokeWidth="1.6"/>
        <path d="M22 62 Q50 40 78 62 Q50 78 22 62Z" fill="#7A3618"/>
        <path d="M30 60 Q50 50 70 60 Q50 70 30 60Z" fill="#A8421E"/>
        <circle cx="40" cy="58" r="3" fill="#5A8A2E"/><circle cx="58" cy="60" r="3" fill="#5A8A2E"/>
        <circle cx="50" cy="55" r="2.4" fill="#E8C34A"/>
      </g>) },
    burger:  { board: 'oak', art: (
      <g>
        <path d="M22 38 Q50 18 78 38 Q78 44 50 44 Q22 44 22 38Z" fill="#E2A65A"/>
        <ellipse cx="44" cy="33" rx="1.6" ry="1.6" fill="#F4DCA0"/><ellipse cx="54" cy="30" rx="1.6" ry="1.6" fill="#F4DCA0"/><ellipse cx="60" cy="35" rx="1.6" ry="1.6" fill="#F4DCA0"/>
        <rect x="22" y="44" width="56" height="7" rx="3" fill="#3E7A2E"/>
        <rect x="20" y="49" width="60" height="8" rx="3" fill="#5A2E16"/>
        <path d="M22 56 Q50 52 78 56 L74 60 Q50 64 26 60Z" fill="#E8B83A"/>
        <rect x="22" y="62" width="56" height="9" rx="4" fill="#E2A65A"/>
      </g>) },
    ribs:    { board: 'char', art: (
      <g>
        <rect x="20" y="30" width="60" height="44" rx="8" fill="#6E2E14"/>
        {[28,40,52,64].map((x,i)=>(<rect key={i} x={x} y="32" width="8" height="40" rx="4" fill="#4A1C0A"/>))}
        <rect x="20" y="30" width="60" height="44" rx="8" fill="none" stroke="#2A0E04" strokeWidth="2"/>
        <path d="M26 36 Q50 32 74 36" stroke="#C24A1E" strokeWidth="2" fill="none" opacity="0.7"/>
      </g>) },
    brisket: { board: 'oak', art: (
      <g>
        <path d="M20 44 Q50 30 80 44 Q80 64 50 70 Q20 64 20 44Z" fill="#5A2410"/>
        <path d="M20 44 Q50 36 80 44" stroke="#2A0E04" strokeWidth="2" fill="none"/>
        <path d="M22 50 Q50 44 78 50" stroke="#8A3A18" strokeWidth="2" fill="none" opacity="0.8"/>
        <rect x="20" y="42" width="60" height="5" rx="2" fill="#1B0A04"/>
        <circle cx="34" cy="58" r="2.4" fill="#E8C34A"/><circle cx="62" cy="60" r="2.4" fill="#5A8A2E"/>
      </g>) },
    wings:   { board: 'slate', art: (
      <g>
        {[[34,44],[58,40],[44,60],[66,58]].map((p,i)=>(
          <g key={i}><ellipse cx={p[0]} cy={p[1]} rx="11" ry="8" fill="#A8521E" transform={`rotate(${i*30-20} ${p[0]} ${p[1]})`}/>
          <ellipse cx={p[0]} cy={p[1]} rx="11" ry="8" fill="none" stroke="#E08A2A" strokeWidth="1.4" opacity="0.6" transform={`rotate(${i*30-20} ${p[0]} ${p[1]})`}/></g>
        ))}
        <circle cx="50" cy="52" r="2.4" fill="#D8C0A0" opacity="0.7"/>
      </g>) },
    sandwich:{ board: 'cream', art: (
      <g>
        <path d="M24 40 Q50 26 76 40 Q76 46 50 46 Q24 46 24 40Z" fill="#E2A65A"/>
        <rect x="24" y="45" width="52" height="6" rx="2" fill="#7A3618"/>
        <path d="M24 50 Q50 47 76 50 L72 54 Q50 58 28 54Z" fill="#C7D86A"/>
        <rect x="24" y="55" width="52" height="8" rx="3" fill="#E8B83A"/>
        <rect x="22" y="61" width="56" height="9" rx="4" fill="#E2A65A"/>
      </g>) },
    mac:     { board: 'cream', art: (
      <g>
        <ellipse cx="50" cy="56" rx="32" ry="22" fill="#E8A93A"/>
        <ellipse cx="50" cy="54" rx="28" ry="18" fill="#F2C96A"/>
        {[[40,50],[52,48],[60,54],[44,60],[56,60],[48,55]].map((p,i)=>(<circle key={i} cx={p[0]} cy={p[1]} r="3.4" fill="#E8B83A" stroke="#C98A2E" strokeWidth="0.8"/>))}
        <rect x="36" y="44" width="6" height="4" rx="2" fill="#5A2410"/><rect x="58" y="46" width="6" height="4" rx="2" fill="#5A2410"/>
      </g>) },
    slaw:    { board: 'cream', art: (
      <g>
        <ellipse cx="50" cy="56" rx="30" ry="20" fill="#EFE6D2"/>
        <ellipse cx="50" cy="54" rx="26" ry="16" fill="#F4EEDF"/>
        {[[38,52,'#8AB84A'],[58,50,'#A8C85A'],[48,58,'#7AA83E'],[62,58,'#C8D87A'],[42,60,'#9AC04E']].map((p,i)=>(<path key={i} d={`M${p[0]} ${p[1]} q6 -4 10 1 q-5 4 -10 -1Z`} fill={p[2]}/>))}
        <circle cx="46" cy="55" r="1.6" fill="#C24A1E"/><circle cx="56" cy="57" r="1.6" fill="#C24A1E"/>
      </g>) },
    drink:   { board: 'oak', art: (
      <g>
        <path d="M36 30 L64 30 L60 76 L40 76 Z" fill="#F4E2B0" opacity="0.5"/>
        <path d="M37 34 L63 34 L59.5 74 L40.5 74 Z" fill="#F2C84A"/>
        <ellipse cx="50" cy="34" rx="13" ry="3.4" fill="#F8E08A"/>
        <rect x="52" y="20" width="3" height="22" rx="1.5" fill="#C13B1F" transform="rotate(12 53 30)"/>
        <circle cx="44" cy="50" r="2.2" fill="#F8E8B0" opacity="0.7"/><circle cx="55" cy="60" r="2.2" fill="#F8E8B0" opacity="0.7"/>
      </g>) },
    burntends:{ board: 'char', art: (
      <g>
        {[[36,46],[52,42],[46,58],[62,52],[40,62],[58,64]].map((p,i)=>(
          <rect key={i} x={p[0]} y={p[1]} width="13" height="12" rx="3" fill={i%2?'#4A1C0A':'#6E2E14'} transform={`rotate(${i*18-15} ${p[0]} ${p[1]})`}/>
        ))}
        <rect x="40" y="48" width="11" height="10" rx="3" fill="#8A3A18"/>
        <circle cx="52" cy="54" r="2" fill="#E8C34A" opacity="0.8"/>
      </g>) },
  };
  const spec = D[dish] || D.taco;
  const [b0, b1] = boards[spec.board] || boards.char;
  return (
    <div style={{ height, borderRadius: radius, overflow: 'hidden', position: 'relative', ...style }}>
      <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%', display: 'block' }}>
        <defs>
          <radialGradient id={uid + 'bd'} cx="38%" cy="30%" r="85%">
            <stop offset="0%" stopColor={b1}/>
            <stop offset="100%" stopColor={b0}/>
          </radialGradient>
          <radialGradient id={uid + 'vig'} cx="50%" cy="42%" r="70%">
            <stop offset="55%" stopColor="rgba(0,0,0,0)"/>
            <stop offset="100%" stopColor="rgba(20,12,6,0.42)"/>
          </radialGradient>
        </defs>
        <rect width="100" height="100" fill={`url(#${uid}bd)`}/>
        {/* board grain */}
        <g opacity="0.12" stroke="#1B120D" strokeWidth="0.8">
          <line x1="0" y1="22" x2="100" y2="20"/><line x1="0" y1="48" x2="100" y2="50"/><line x1="0" y1="74" x2="100" y2="72"/>
        </g>
        {/* soft plate glow under food */}
        <ellipse cx="50" cy="54" rx="40" ry="30" fill="rgba(255,240,210,0.10)"/>
        {spec.art}
        <rect width="100" height="100" fill={`url(#${uid}vig)`}/>
        {/* top sheen */}
        <ellipse cx="38" cy="22" rx="34" ry="14" fill="rgba(255,255,255,0.12)"/>
      </svg>
    </div>
  );
}

Object.assign(window, {
  Ico, Bull, Wordmark, Button, StatusPill, Stepper, Pill, FoodPh, FoodArt, SheriffStar, Skeleton,
  GlassSurfaceStock,
  Toast, Eyebrow, SectionTitle, Input, AppHeader, HeaderActions, BottomNav, SearchBar, Chips,
  BottomSheet, Screen,
});
