// Palette · v2 shared icons + tiny components (ported from mockup 3.2)
const V2Icon = ({name, size=14, color='currentColor', strokeWidth=1.6}) => {
const s = size;
const props = {width:s, height:s, viewBox:'0 0 24 24', fill:'none', stroke:color, strokeWidth, strokeLinecap:'round', strokeLinejoin:'round'};
switch(name){
case 'doc': return ;
case 'image': return ;
case 'video': return ;
case 'audio': return ;
case 'url': return ;
case 'ppt': return ;
case 'plus': return ;
case 'x': return ;
case 'pin': return ;
case 'pencil': return ;
case 'eye': return ;
case 'sparkles': return ;
case 'wand': return ;
case 'arrow-up': return ;
case 'arrow-swap': return ;
case 'approx': return ;
case 'arrow-down': return ;
case 'send': return ;
case 'search': return ;
case 'chevron-down': return ;
case 'chevron-right': return ;
case 'grip': return ;
case 'folder': return ;
case 'check': return ;
case 'refresh': return ;
case 'more': return ;
case 'spark': return ;
case 'play': return ;
case 'mail': return ;
case 'link': return ;
default: return null;
}
};
const v2FileMeta = (kind) => ({
pdf: {icon:'doc', tint:'#1A1A1A', label:'PDF'},
doc: {icon:'doc', tint:'#1A1A1A', label:'DOC'},
image: {icon:'image', tint:'#3A3630', label:'IMG'},
video: {icon:'video', tint:'#1A1A1A', label:'VID'},
audio: {icon:'audio', tint:'#5F594E', label:'AUD'},
url: {icon:'url', tint:'#857E70', label:'URL'},
ppt: {icon:'ppt', tint:'#3A3630', label:'PPT'},
}[kind] || {icon:'doc', tint:'#888', label:'FILE'});
const V2StatusPill = ({status, progress})=>{
const map={
not_analyzed:{label:'not analyzed',color:'#7B6A2A', bg:'rgba(255,182,0,.18)'},
pending:{label:'pending',color:'#7B867F', bg:'#EAE6E1'},
analyzing:{label:`analyzing · ${Math.round((progress||0)*100)}%`,color:'#006747', bg:'rgba(0,103,71,.10)'},
analyzed:{label:'analyzed',color:'#004D35', bg:'rgba(0,103,71,.14)'},
failed:{label:'failed',color:'#A33C16', bg:'rgba(217,69,69,.10)'},
idle:{label:'idle',color:'#888', bg:'#EDEAE2'},
};
const s = map[status]||map.pending;
return
{status==='analyzing' && }
{status==='not_analyzed' && }
{s.label}
;
};
// Shared loading primitives — used everywhere we wait on the network.
const V2Spinner = ({size='md', color, style={}}) => (
);
const V2Skeleton = ({w='100%', h=12, style={}}) => (
);
const V2LoadingOverlay = ({msg='Loading…'}) => (
);
const V2EmptyHint = ({icon='sparkles', title, hint, action}) => (
{title}
{hint &&
{hint}
}
{action}
);
window.V2Icon = V2Icon;
window.v2FileMeta = v2FileMeta;
window.V2StatusPill = V2StatusPill;
window.V2Spinner = V2Spinner;
window.V2Skeleton = V2Skeleton;
window.V2LoadingOverlay = V2LoadingOverlay;
window.V2EmptyHint = V2EmptyHint;