// Gurukool shared components — React + inline styles via CSS variables // All components consume tokens.css. // ─── Iconography ────────────────────────────────────────────────────── // Simple line icons (stroke 1.75), not complex SVG art. function Icon({ name, size = 20, color = 'currentColor', strokeWidth = 1.75, style = {} }) { const s = size; const p = { fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' }; const paths = { home: <>, check: , x: , bell: <>, calendar: <>, book: , user: <>, users: <>, star: , chart: <>, settings: <>, logout: <>, chevronRight: , chevronDown: , chevronLeft: , plus: , search: <>, filter: , clock: <>, pencil: <>, trash: <>, upload: <>, download: <>, gift: <>, sparkles: <>, flame: , trophy: <>, eye: <>, lock: <>, menu: , grid: <>, building: <>, tag: <>, clipboard: <>, message: , sun: <>, moon: , globe: <>, arrowRight: , arrowUp: , target: <>, play: , megaphone: <>, shield: , rupee: <>, focus: <>, heart: , alert: <>, arrowDown: , }; return ( {paths[name] || paths.x} ); } // ─── Button ──────────────────────────────────────────────────────────── function Button({ children, variant = 'primary', size = 'md', leftIcon, rightIcon, block, onClick, style = {}, disabled }) { const sizes = { sm: { h: 32, px: 12, fs: 13, gap: 6, r: 8 }, md: { h: 40, px: 16, fs: 14, gap: 8, r: 10 }, lg: { h: 48, px: 20, fs: 15, gap: 10, r: 12 }, }[size]; const variants = { primary: { bg: 'var(--accent)', fg: '#fff', border: 'transparent', hover: 'brightness(1.08)' }, secondary: { bg: 'var(--accent-soft)', fg: 'var(--accent-ink)', border: 'transparent' }, ghost: { bg: 'transparent', fg: 'var(--text)', border: 'transparent' }, outline: { bg: 'transparent', fg: 'var(--text)', border: 'var(--border-strong)' }, danger: { bg: 'var(--gk-danger)', fg: '#fff', border: 'transparent' }, }[variant]; return ( ); } // ─── Badge ───────────────────────────────────────────────────────────── function Badge({ children, tone = 'neutral', size = 'md', style = {} }) { const tones = { neutral: { bg: 'var(--gk-stone-100)', fg: 'var(--gk-stone-700)' }, green: { bg: 'var(--accent-soft)', fg: 'var(--accent-ink)' }, success: { bg: 'color-mix(in oklch, var(--gk-success) 15%, transparent)', fg: 'oklch(38% 0.13 145)' }, warn: { bg: 'color-mix(in oklch, var(--gk-warn) 22%, transparent)', fg: 'oklch(40% 0.12 75)' }, danger: { bg: 'color-mix(in oklch, var(--gk-danger) 15%, transparent)', fg: 'oklch(42% 0.15 25)' }, info: { bg: 'color-mix(in oklch, var(--gk-info) 12%, transparent)', fg: 'oklch(38% 0.13 230)' }, lime: { bg: 'color-mix(in oklch, var(--gk-lime-400) 25%, transparent)', fg: 'oklch(32% 0.12 128)' }, accent: { bg: 'var(--accent-soft)', fg: 'var(--accent-ink)' }, }[tone]; const sizes = { sm: { fs: 11, px: 8, h: 20 }, md: { fs: 12, px: 10, h: 24 }, lg: { fs: 13, px: 12, h: 28 }, }[size]; return ( {children} ); } // ─── Card ────────────────────────────────────────────────────────────── function Card({ children, padding = 20, style = {}, interactive, onClick }) { return (
interactive && (e.currentTarget.style.boxShadow = 'var(--sh-md)', e.currentTarget.style.borderColor = 'var(--border-strong)')} onMouseLeave={e => interactive && (e.currentTarget.style.boxShadow = '', e.currentTarget.style.borderColor = 'var(--border)')} > {children}
); } // ─── Avatar ──────────────────────────────────────────────────────────── function Avatar({ name = '?', size = 40, tone }) { const initials = name.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase(); // Generate tone from name hash for variety const hash = name.split('').reduce((a, c) => a + c.charCodeAt(0), 0); const hues = [152, 128, 95, 55, 25, 270, 195, 340]; const h = tone !== undefined ? tone : hues[hash % hues.length]; return (
{initials}
); } // ─── Input ───────────────────────────────────────────────────────────── function Input({ label, hint, error, leftIcon, rightIcon, ...props }) { return ( ); } // ─── Progress ────────────────────────────────────────────────────────── function Progress({ value = 0, tone = 'green', height = 8 }) { const toneMap = { green: 'var(--accent)', lime: 'var(--gk-lime-500)', warn: 'var(--gk-warn)', danger: 'var(--gk-danger)' }; return (
); } // ─── Divider w/ optional jali motif ──────────────────────────────────── function JaliDivider({ label }) { return (
{label && {label}}
); } // ─── Logo ────────────────────────────────────────────────────────────── function GurukoolLogo({ size = 28, withWordmark = true, color }) { const c = color || 'var(--accent)'; return (
{/* stylized lotus/banyan leaf — 3 leaf forms around center, geometric */} {withWordmark && ( Gurukool )}
); } // Export Object.assign(window, { Icon, Button, Badge, Card, Avatar, Input, Progress, JaliDivider, GurukoolLogo });