/* AshopNexa storefront kit — primitives + ProductCard, styled from design tokens.
Cosmetic versions faithful to the real DS components (so the kit verifies
standalone). Exposes window.AXUI. */
const I = () => window.AXIcons;
function Button({ variant='primary', size='md', full=false, iconLeft, iconRight, children, style={}, ...rest }) {
const sizes = { sm:{height:36,padding:'0 14px',fontSize:'var(--fs-sm)',radius:'var(--radius-sm)'}, md:{height:44,padding:'0 20px',fontSize:'var(--fs-base)',radius:'var(--radius-md)'}, lg:{height:54,padding:'0 28px',fontSize:'var(--fs-md)',radius:'var(--radius-md)'} };
const s = sizes[size]||sizes.md;
const v = {
primary:{background:'var(--action-primary)',color:'#fff',border:'1px solid transparent',boxShadow:'var(--shadow-accent-glow)'},
accent:{background:'linear-gradient(120deg,var(--blue-600),var(--cyan-500))',color:'#fff',border:'1px solid transparent',boxShadow:'var(--shadow-accent-glow)'},
dark:{background:'var(--action-dark)',color:'var(--text-on-dark)',border:'1px solid transparent',boxShadow:'var(--shadow-md)'},
soft:{background:'var(--surface-accent-soft)',color:'var(--blue-700)',border:'1px solid var(--blue-100)'},
outline:{background:'var(--surface-card)',color:'var(--text-strong)',border:'1px solid var(--border-strong)',boxShadow:'var(--shadow-xs)'},
ghost:{background:'transparent',color:'var(--text-strong)',border:'1px solid transparent'},
}[variant]||{};
return ;
}
function IconButton({ variant='ghost', badge, label, children, style={}, ...rest }) {
const v = { ghost:{background:'transparent'}, soft:{background:'var(--surface-sunken)',border:'1px solid var(--border-subtle)'} }[variant]||{};
return ;
}
const badgeTone = {
'Best Seller':['var(--star-on)','#3a2400'], New:['linear-gradient(120deg,var(--blue-600),var(--cyan-500))','#fff'],
Sale:['var(--sale)','#fff'], Limited:['var(--blue-600)','#fff'],
};
function Badge({ children, tone, soft=false, style={} }) {
let bg='var(--slate-100)', fg='var(--slate-700)';
if (tone && badgeTone[tone]) { bg=badgeTone[tone][0]; fg=badgeTone[tone][1]; }
else if (tone==='success'){bg='var(--status-success-soft)';fg='var(--status-success)';}
else if (tone==='danger'){bg='var(--status-danger-soft)';fg='var(--status-danger)';}
else if (tone==='sale'){bg='var(--sale-100)';fg='var(--sale)';}
return {children};
}
function Stars({ value=0, size=15 }) {
return {[0,1,2,3,4].map(i=>{
const f=Math.max(0,Math.min(1,value-i));
return ;
})};
}
function Rating({ value=0, count, showValue=false, size=15 }) {
return
{showValue && {value.toFixed(1)}}
{count!=null && ({count.toLocaleString()})}
;
}
function PriceTag({ price, compareAt, size='md' }) {
const sz={sm:['var(--fs-base)','var(--fs-xs)'],md:['var(--fs-lg)','var(--fs-sm)'],lg:['var(--fs-2xl)','var(--fs-md)'],xl:['var(--fs-3xl)','var(--fs-lg)']}[size];
const sale=compareAt&&compareAt>price; const pct=sale?Math.round((1-price/compareAt)*100):0;
const fmt=n=>'$'+n.toFixed(2);
return
{fmt(price)}
{sale && {fmt(compareAt)}}
{sale && −{pct}%}
;
}
function QuantityStepper({ value, onChange, min=1, max=99 }) {
const set=n=>onChange&&onChange(Math.max(min,Math.min(max,n)));
const btn=(lbl,fn,dis)=> ;
return
{btn('−',()=>set(value-1),value<=min)}
{value}
{btn('+',()=>set(value+1),value>=max)}
;
}
function Input({ label, hint, error, iconLeft, iconRight, style={}, containerStyle={}, ...rest }) {
const [f,setF]=React.useState(false);
const bc=error?'var(--status-danger)':f?'var(--border-focus)':'var(--border-default)';
return
{label &&
}
{iconLeft && {iconLeft}}
{setF(true);rest.onFocus&&rest.onFocus(e);}} onBlur={e=>{setF(false);rest.onBlur&&rest.onBlur(e);}} style={{flex:1,minWidth:0,border:'none',outline:'none',background:'transparent',fontFamily:'var(--font-body)',fontSize:'var(--fs-base)',color:'var(--text-strong)',...style}}/>
{iconRight && {iconRight}}
{(error||hint) &&
{error||hint}}
;
}
function Eyebrow({ children, style={} }) {
return {children};
}
function SectionHeader({ eyebrow, title, action, onAction }) {
return
{eyebrow && {eyebrow}}
{title}
{action &&
}
;
}
function ProductCard({ product, onAdd, onView }) {
const [hover,setHover]=React.useState(false);
const Ic=I();
return setHover(true)} onMouseLeave={()=>setHover(false)}
style={{display:'flex',flexDirection:'column',background:'var(--surface-card)',border:'1px solid var(--border-subtle)',borderRadius:'var(--radius-xl)',overflow:'hidden',boxShadow:hover?'var(--shadow-card-hover)':'var(--shadow-sm)',transform:hover?'translateY(-4px)':'none',transition:'transform .2s var(--ease-out),box-shadow .2s var(--ease-out)'}}>
onView&&onView(product)}>
{product.image
?

:
{product.name.charAt(0)}
}
{product.badge &&
{product.badge}
}
{product.category}
onView&&onView(product)} style={{fontFamily:'var(--font-display)',fontSize:'var(--fs-md)',fontWeight:600,color:'var(--text-strong)',lineHeight:1.3,cursor:'pointer',margin:0,letterSpacing:'-0.01em'}}>{product.name}
;
}
window.AXUI = { Button, IconButton, Badge, Stars, Rating, PriceTag, QuantityStepper, Input, Eyebrow, SectionHeader, ProductCard };