Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Design intelligence for professional web and mobile interfaces: styles, palettes, typography, UX checks, and design-system guidance.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
core.py
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3"""4UI/UX Pro Max Core - BM25 search engine for UI/UX style guides5"""67import csv8import re9from pathlib import Path10from math import log11from collections import defaultdict1213# ============ CONFIGURATION ============14DATA_DIR = Path(__file__).parent.parent / "data"15MAX_RESULTS = 31617CSV_CONFIG = {18"style": {19"file": "styles.csv",20"search_cols": ["Style Category", "Keywords", "Best For", "Type", "AI Prompt Keywords"],21"output_cols": ["Style Category", "Type", "Keywords", "Primary Colors", "Effects & Animation", "Best For", "Performance", "Accessibility", "Framework Compatibility", "Complexity", "AI Prompt Keywords", "CSS/Technical Keywords", "Implementation Checklist", "Design System Variables"]22},23"color": {24"file": "colors.csv",25"search_cols": ["Product Type", "Notes"],26"output_cols": ["Product Type", "Primary", "On Primary", "Secondary", "On Secondary", "Accent", "On Accent", "Background", "Foreground", "Card", "Card Foreground", "Muted", "Muted Foreground", "Border", "Destructive", "On Destructive", "Ring", "Notes"]27},28"chart": {29"file": "charts.csv",30"search_cols": ["Data Type", "Keywords", "Best Chart Type", "When to Use", "When NOT to Use", "Accessibility Notes"],31"output_cols": ["Data Type", "Keywords", "Best Chart Type", "Secondary Options", "When to Use", "When NOT to Use", "Data Volume Threshold", "Color Guidance", "Accessibility Grade", "Accessibility Notes", "A11y Fallback", "Library Recommendation", "Interactive Level"]32},33"landing": {34"file": "landing.csv",35"search_cols": ["Pattern Name", "Keywords", "Conversion Optimization", "Section Order"],36"output_cols": ["Pattern Name", "Keywords", "Section Order", "Primary CTA Placement", "Color Strategy", "Conversion Optimization"]37},38"product": {39"file": "products.csv",40"search_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Key Considerations"],41"output_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Secondary Styles", "Landing Page Pattern", "Dashboard Style (if applicable)", "Color Palette Focus"]42},43"ux": {44"file": "ux-guidelines.csv",45"search_cols": ["Category", "Issue", "Description", "Platform"],46"output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]47},48"typography": {49"file": "typography.csv",50"search_cols": ["Font Pairing Name", "Category", "Mood/Style Keywords", "Best For", "Heading Font", "Body Font"],51"output_cols": ["Font Pairing Name", "Category", "Heading Font", "Body Font", "Mood/Style Keywords", "Best For", "Google Fonts URL", "CSS Import", "Tailwind Config", "Notes"]52},53"icons": {54"file": "icons.csv",55"search_cols": ["Category", "Icon Name", "Keywords", "Best For"],56"output_cols": ["Category", "Icon Name", "Keywords", "Library", "Import Code", "Usage", "Best For", "Style"]57},58"react": {59"file": "react-performance.csv",60"search_cols": ["Category", "Issue", "Keywords", "Description"],61"output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]62},63"web": {64"file": "app-interface.csv",65"search_cols": ["Category", "Issue", "Keywords", "Description"],66"output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]67},68"google-fonts": {69"file": "google-fonts.csv",70"search_cols": ["Family", "Category", "Stroke", "Classifications", "Keywords", "Subsets", "Designers"],71"output_cols": ["Family", "Category", "Stroke", "Classifications", "Styles", "Variable Axes", "Subsets", "Designers", "Popularity Rank", "Google Fonts URL"]72}73}7475STACK_CONFIG = {76"react-native": {"file": "stacks/react-native.csv"},77}7879# Common columns for all stacks80_STACK_COLS = {81"search_cols": ["Category", "Guideline", "Description", "Do", "Don't"],82"output_cols": ["Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"]83}8485AVAILABLE_STACKS = list(STACK_CONFIG.keys())868788# ============ BM25 IMPLEMENTATION ============89class BM25:90"""BM25 ranking algorithm for text search"""9192def __init__(self, k1=1.5, b=0.75):93self.k1 = k194self.b = b95self.corpus = []96self.doc_lengths = []97self.avgdl = 098self.idf = {}99self.doc_freqs = defaultdict(int)100self.N = 0101102def tokenize(self, text):103"""Lowercase, split, remove punctuation, filter short words"""104text = re.sub(r'[^\w\s]', ' ', str(text).lower())105return [w for w in text.split() if len(w) > 2]106107def fit(self, documents):108"""Build BM25 index from documents"""109self.corpus = [self.tokenize(doc) for doc in documents]110self.N = len(self.corpus)111if self.N == 0:112return113self.doc_lengths = [len(doc) for doc in self.corpus]114self.avgdl = sum(self.doc_lengths) / self.N115116for doc in self.corpus:117seen = set()118for word in doc:119if word not in seen:120self.doc_freqs[word] += 1121seen.add(word)122123for word, freq in self.doc_freqs.items():124self.idf[word] = log((self.N - freq + 0.5) / (freq + 0.5) + 1)125126def score(self, query):127"""Score all documents against query"""128query_tokens = self.tokenize(query)129scores = []130131for idx, doc in enumerate(self.corpus):132score = 0133doc_len = self.doc_lengths[idx]134term_freqs = defaultdict(int)135for word in doc:136term_freqs[word] += 1137138for token in query_tokens:139if token in self.idf:140tf = term_freqs[token]141idf = self.idf[token]142numerator = tf * (self.k1 + 1)143denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)144score += idf * numerator / denominator145146scores.append((idx, score))147148return sorted(scores, key=lambda x: x[1], reverse=True)149150151# ============ SEARCH FUNCTIONS ============152def _load_csv(filepath):153"""Load CSV and return list of dicts"""154with open(filepath, 'r', encoding='utf-8') as f:155return list(csv.DictReader(f))156157158def _search_csv(filepath, search_cols, output_cols, query, max_results):159"""Core search function using BM25"""160if not filepath.exists():161return []162163data = _load_csv(filepath)164165# Build documents from search columns166documents = [" ".join(str(row.get(col, "")) for col in search_cols) for row in data]167168# BM25 search169bm25 = BM25()170bm25.fit(documents)171ranked = bm25.score(query)172173# Get top results with score > 0174results = []175for idx, score in ranked[:max_results]:176if score > 0:177row = data[idx]178results.append({col: row.get(col, "") for col in output_cols if col in row})179180return results181182183def detect_domain(query):184"""Auto-detect the most relevant domain from query"""185query_lower = query.lower()186187domain_keywords = {188"color": ["color", "palette", "hex", "#", "rgb", "token", "semantic", "accent", "destructive", "muted", "foreground"],189"chart": ["chart", "graph", "visualization", "trend", "bar", "pie", "scatter", "heatmap", "funnel"],190"landing": ["landing", "page", "cta", "conversion", "hero", "testimonial", "pricing", "section"],191"product": ["saas", "ecommerce", "e-commerce", "fintech", "healthcare", "gaming", "portfolio", "crypto", "dashboard", "fitness", "restaurant", "hotel", "travel", "music", "education", "learning", "legal", "insurance", "medical", "beauty", "pharmacy", "dental", "pet", "dating", "wedding", "recipe", "delivery", "ride", "booking", "calendar", "timer", "tracker", "diary", "note", "chat", "messenger", "crm", "invoice", "parking", "transit", "vpn", "alarm", "weather", "sleep", "meditation", "fasting", "habit", "grocery", "meme", "wardrobe", "plant care", "reading", "flashcard", "puzzle", "trivia", "arcade", "photography", "streaming", "podcast", "newsletter", "marketplace", "freelancer", "coworking", "airline", "museum", "theater", "church", "non-profit", "charity", "kindergarten", "daycare", "senior care", "veterinary", "florist", "bakery", "brewery", "construction", "automotive", "real estate", "logistics", "agriculture", "coding bootcamp"],192"style": ["style", "design", "ui", "minimalism", "glassmorphism", "neumorphism", "brutalism", "dark mode", "flat", "aurora", "prompt", "css", "implementation", "variable", "checklist", "tailwind"],193"ux": ["ux", "usability", "accessibility", "wcag", "touch", "scroll", "animation", "keyboard", "navigation", "mobile"],194"typography": ["font pairing", "typography pairing", "heading font", "body font"],195"google-fonts": ["google font", "font family", "font weight", "font style", "variable font", "noto", "font for", "find font", "font subset", "font language", "monospace font", "serif font", "sans serif font", "display font", "handwriting font", "font", "typography", "serif", "sans"],196"icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],197"react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],198"web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]199}200201scores = {domain: sum(1 for kw in keywords if re.search(r'\b' + re.escape(kw) + r'\b', query_lower)) for domain, keywords in domain_keywords.items()}202best = max(scores, key=scores.get)203return best if scores[best] > 0 else "style"204205206def search(query, domain=None, max_results=MAX_RESULTS):207"""Main search function with auto-domain detection"""208if domain is None:209domain = detect_domain(query)210211config = CSV_CONFIG.get(domain, CSV_CONFIG["style"])212filepath = DATA_DIR / config["file"]213214if not filepath.exists():215return {"error": f"File not found: {filepath}", "domain": domain}216217results = _search_csv(filepath, config["search_cols"], config["output_cols"], query, max_results)218219return {220"domain": domain,221"query": query,222"file": config["file"],223"count": len(results),224"results": results225}226227228def search_stack(query, stack, max_results=MAX_RESULTS):229"""Search stack-specific guidelines"""230if stack not in STACK_CONFIG:231return {"error": f"Unknown stack: {stack}. Available: {', '.join(AVAILABLE_STACKS)}"}232233filepath = DATA_DIR / STACK_CONFIG[stack]["file"]234235if not filepath.exists():236return {"error": f"Stack file not found: {filepath}", "stack": stack}237238results = _search_csv(filepath, _STACK_COLS["search_cols"], _STACK_COLS["output_cols"], query, max_results)239240return {241"domain": "stack",242"stack": stack,243"query": query,244"file": STACK_CONFIG[stack]["file"],245"count": len(results),246"results": results247}248