/* Maison Silya — website kit local primitives. These mirror the system components (Button, Tag, Input, Divider) and add website chrome (icons, placeholders). Kept kit-local so the kit renders standalone; production should consume the published library at window.MaisonSilyaDesignSystem_db0f02. */ const C = (v) => `var(--ms-${v})`; /* True only on devices with a real hovering pointer (mouse / trackpad). On touch screens a tap emulates mouseenter and it sticks — which made rug cards swap to their in-situ photo and zoom in. Hover effects are gated on this so phones keep the flat, un-zoomed image. */ const MS_CAN_HOVER = !(window.matchMedia && window.matchMedia('(hover: none)').matches); /* ---- Thin hairline icons (~1.25px stroke, currentColor) ---- */ function Icon({ name, size = 20, style = {} }) { const p = { fill: 'none', stroke: 'currentColor', strokeWidth: 1.25, strokeLinecap: 'square' }; const paths = { menu: , close: , search: , account: , arrow: , chevron: , plus: , minus: , }; return ; } /* ---- Button (mirrors system Button) ---- */ function Btn({ children, variant = 'primary', size = 'md', as = 'button', style = {}, ...rest }) { const sizes = { sm: { padding: '10px 22px', fontSize: 10, letterSpacing: '0.24em' }, md: { padding: '15px 32px', fontSize: 11, letterSpacing: '0.26em' }, lg: { padding: '19px 44px', fontSize: 12, letterSpacing: '0.28em' }, }; const variants = { primary: { background: C('ink'), color: C('ivory'), borderColor: C('ink') }, secondary: { background: 'transparent', color: C('ink'), borderColor: C('line-strong') }, ghost: { background: 'transparent', color: C('ink'), borderColor: 'transparent', padding: `${sizes[size].padding.split(' ')[0]} 0` }, inverse: { background: C('ivory'), color: C('ink'), borderColor: C('ivory') }, 'ghost-inverse': { background: 'transparent', color: C('ivory'), borderColor: 'transparent', padding: `${sizes[size].padding.split(' ')[0]} 0` }, }; const Tag = as; const enter = (e) => { if (variant === 'primary') Object.assign(e.currentTarget.style, { background: C('stone-800'), borderColor: C('stone-800') }); if (variant === 'secondary') e.currentTarget.style.borderColor = C('ink'); if (variant === 'ghost') e.currentTarget.style.color = C('accent'); if (variant === 'ghost-inverse') e.currentTarget.style.opacity = 0.7; if (variant === 'inverse') Object.assign(e.currentTarget.style, { background: C('champagne'), borderColor: C('champagne') }); }; const leave = (e) => { Object.assign(e.currentTarget.style, { ...variants[variant], opacity: 1 }); }; return ( {children} ); } /* ---- Filter tag (mirrors system Tag) ---- */ function FilterTag({ children, selected, onClick }) { const [h, setH] = React.useState(false); return ( ); } /* ---- Underline field (mirrors system Input) ---- */ function Field({ label, type = 'text', placeholder, defaultValue, name, required }) { const [f, setF] = React.useState(false); return ( ); } function Diamond({ size = 5, color = C('accent') }) { return ; } /* ---- Stone placeholder for imagery (no stock photos available) ---- */ function Plate({ ratio = '4 / 5', label = 'Silya', tone = 'stone-200', radius = 'sm', image, children, style = {} }) { return (
{image && {label}} {!image &&
{label}
} {children}
); } /* ---- Chapter masthead: a monograph-style page opener. Replaces the bronze-eyebrow + giant-italic formula. A diamond + optional chapter numeral + section label + hairline, then the title. ---- */ function Chapter({ index, label, title, lede, max = 920 }) { return (
{index && N° {index}} {label && {label}}

{title}

{lede &&

{lede}

}
); } Object.assign(window, { Icon, Btn, FilterTag, Field, Diamond, Plate, Chapter, C, MS_CAN_HOVER });