// 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…'}) => (
{msg}
); 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;