cfsa-antigravity 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,1121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sass-scss
|
|
3
|
+
description: Provides comprehensive SASS/SCSS patterns including the modern module system (@use/@forward), mixins, extends, functions, design token architecture, responsive breakpoint systems, theming with maps, nesting best practices, placeholder selectors, control directives, built-in modules, Dart Sass migration, CSS Modules integration, and performance considerations. Use when building maintainable stylesheets with SCSS preprocessing.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# SASS/SCSS Development Patterns
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Expert guide for building scalable, maintainable stylesheets with SCSS (Sassy CSS). Covers the modern module system (@use/@forward), design token architecture, responsive systems, theming, and best practices for Dart Sass (the only actively maintained implementation).
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- Building large-scale design systems with shared tokens
|
|
17
|
+
- Projects requiring complex responsive breakpoint logic
|
|
18
|
+
- Theming systems with multiple color schemes
|
|
19
|
+
- Teams that benefit from enforced code organization via the module system
|
|
20
|
+
- When you need computed values at build time (not runtime like CSS custom properties)
|
|
21
|
+
- Legacy codebases migrating from @import to @use/@forward
|
|
22
|
+
- CSS Modules integration with component frameworks
|
|
23
|
+
|
|
24
|
+
## Instructions
|
|
25
|
+
|
|
26
|
+
1. **Use @use and @forward exclusively** -- @import is deprecated and will be removed
|
|
27
|
+
2. **Organize tokens in maps** for systematic access and iteration
|
|
28
|
+
3. **Keep nesting to 3 levels maximum** -- deeper nesting is a code smell
|
|
29
|
+
4. **Prefer mixins over @extend** in most cases for predictable output
|
|
30
|
+
5. **Use the built-in modules** (math, color, list, map, string) instead of custom functions
|
|
31
|
+
6. **Namespace all @use imports** for clarity
|
|
32
|
+
7. **Generate CSS custom properties from SCSS maps** for runtime theming
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
### Project Structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
styles/
|
|
40
|
+
_index.scss # Main entry point (@forward all partials)
|
|
41
|
+
abstracts/
|
|
42
|
+
_index.scss # @forward all abstracts
|
|
43
|
+
_tokens.scss # Design tokens as maps
|
|
44
|
+
_breakpoints.scss # Responsive breakpoint system
|
|
45
|
+
_typography.scss # Type scale and font stacks
|
|
46
|
+
_functions.scss # Custom Sass functions
|
|
47
|
+
_mixins.scss # Reusable mixins
|
|
48
|
+
_placeholders.scss # Placeholder selectors (%)
|
|
49
|
+
base/
|
|
50
|
+
_index.scss # @forward all base
|
|
51
|
+
_reset.scss # CSS reset / normalize
|
|
52
|
+
_root.scss # :root custom properties
|
|
53
|
+
_typography.scss # Base type styles
|
|
54
|
+
components/
|
|
55
|
+
_index.scss # @forward all components
|
|
56
|
+
_button.scss # Button component
|
|
57
|
+
_card.scss # Card component
|
|
58
|
+
_form.scss # Form elements
|
|
59
|
+
layout/
|
|
60
|
+
_index.scss # @forward all layout
|
|
61
|
+
_grid.scss # Grid system
|
|
62
|
+
_header.scss # Header layout
|
|
63
|
+
_sidebar.scss # Sidebar layout
|
|
64
|
+
themes/
|
|
65
|
+
_index.scss # @forward all themes
|
|
66
|
+
_light.scss # Light theme tokens
|
|
67
|
+
_dark.scss # Dark theme tokens
|
|
68
|
+
utilities/
|
|
69
|
+
_index.scss # @forward all utilities
|
|
70
|
+
_spacing.scss # Spacing utility classes
|
|
71
|
+
_visibility.scss # Show/hide utilities
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Constraints and Warnings
|
|
75
|
+
|
|
76
|
+
- **@import is deprecated**: Dart Sass will remove @import support; migrate to @use/@forward
|
|
77
|
+
- **LibSass is dead**: Use Dart Sass only; LibSass does not support the module system
|
|
78
|
+
- **Ruby Sass is dead**: Has been unsupported since 2019
|
|
79
|
+
- **@extend across media queries**: Does not work; use mixins instead
|
|
80
|
+
- **Deep nesting**: More than 3 levels creates overly specific selectors
|
|
81
|
+
- **Large maps in loops**: Generating hundreds of utility classes bloats CSS output
|
|
82
|
+
- **Division operator**: Use math.div() instead of the `/` operator for division
|
|
83
|
+
- **CSS output size**: SCSS generates CSS; always check the compiled output size
|
|
84
|
+
|
|
85
|
+
## Core Concepts
|
|
86
|
+
|
|
87
|
+
### The Module System: @use
|
|
88
|
+
|
|
89
|
+
@use loads a module and makes its members available with a namespace:
|
|
90
|
+
|
|
91
|
+
```scss
|
|
92
|
+
// _tokens.scss
|
|
93
|
+
$brand-color: #3b82f6;
|
|
94
|
+
$spacing-unit: 0.25rem;
|
|
95
|
+
|
|
96
|
+
@mixin visually-hidden {
|
|
97
|
+
position: absolute;
|
|
98
|
+
width: 1px;
|
|
99
|
+
height: 1px;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
clip: rect(0, 0, 0, 0);
|
|
102
|
+
white-space: nowrap;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```scss
|
|
107
|
+
// _button.scss
|
|
108
|
+
@use "../abstracts/tokens";
|
|
109
|
+
|
|
110
|
+
.btn {
|
|
111
|
+
// Access with namespace
|
|
112
|
+
background-color: tokens.$brand-color;
|
|
113
|
+
padding: tokens.$spacing-unit * 4;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Custom namespace
|
|
117
|
+
@use "../abstracts/tokens" as t;
|
|
118
|
+
|
|
119
|
+
.btn-alt {
|
|
120
|
+
background-color: t.$brand-color;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// No namespace (use sparingly)
|
|
124
|
+
@use "../abstracts/tokens" as *;
|
|
125
|
+
|
|
126
|
+
.btn-flat {
|
|
127
|
+
background-color: $brand-color;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### The Module System: @forward
|
|
132
|
+
|
|
133
|
+
@forward re-exports members from another module:
|
|
134
|
+
|
|
135
|
+
```scss
|
|
136
|
+
// abstracts/_index.scss
|
|
137
|
+
// Re-export everything from all abstract partials
|
|
138
|
+
@forward "tokens";
|
|
139
|
+
@forward "breakpoints";
|
|
140
|
+
@forward "typography";
|
|
141
|
+
@forward "functions";
|
|
142
|
+
@forward "mixins";
|
|
143
|
+
@forward "placeholders";
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```scss
|
|
147
|
+
// components/_button.scss
|
|
148
|
+
// Now you only need one @use for all abstracts
|
|
149
|
+
@use "../abstracts" as a;
|
|
150
|
+
|
|
151
|
+
.btn {
|
|
152
|
+
background: a.$brand-color;
|
|
153
|
+
@include a.respond-to("md") {
|
|
154
|
+
padding: a.$spacing-unit * 6;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### @forward with Configuration
|
|
160
|
+
|
|
161
|
+
```scss
|
|
162
|
+
// abstracts/_tokens.scss
|
|
163
|
+
$brand-color: #3b82f6 !default;
|
|
164
|
+
$font-family: system-ui, sans-serif !default;
|
|
165
|
+
|
|
166
|
+
// themes/_dark.scss
|
|
167
|
+
@forward "../abstracts/tokens" with (
|
|
168
|
+
$brand-color: #60a5fa,
|
|
169
|
+
$font-family: "Inter", system-ui, sans-serif
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### @forward with show/hide
|
|
174
|
+
|
|
175
|
+
```scss
|
|
176
|
+
// Only expose specific members
|
|
177
|
+
@forward "tokens" show $brand-color, $spacing-unit;
|
|
178
|
+
|
|
179
|
+
// Hide internal members
|
|
180
|
+
@forward "mixins" hide _internal-mixin;
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Design Token Architecture
|
|
184
|
+
|
|
185
|
+
### Token Maps
|
|
186
|
+
|
|
187
|
+
```scss
|
|
188
|
+
// abstracts/_tokens.scss
|
|
189
|
+
@use "sass:map";
|
|
190
|
+
|
|
191
|
+
// --- Color Tokens ---
|
|
192
|
+
$colors: (
|
|
193
|
+
"primary": (
|
|
194
|
+
"100": #dbeafe,
|
|
195
|
+
"200": #bfdbfe,
|
|
196
|
+
"300": #93c5fd,
|
|
197
|
+
"400": #60a5fa,
|
|
198
|
+
"500": #3b82f6,
|
|
199
|
+
"600": #2563eb,
|
|
200
|
+
"700": #1d4ed8,
|
|
201
|
+
"800": #1e40af,
|
|
202
|
+
"900": #1e3a8a,
|
|
203
|
+
),
|
|
204
|
+
"neutral": (
|
|
205
|
+
"100": #f5f5f5,
|
|
206
|
+
"200": #e5e5e5,
|
|
207
|
+
"300": #d4d4d4,
|
|
208
|
+
"400": #a3a3a3,
|
|
209
|
+
"500": #737373,
|
|
210
|
+
"600": #525252,
|
|
211
|
+
"700": #404040,
|
|
212
|
+
"800": #262626,
|
|
213
|
+
"900": #171717,
|
|
214
|
+
),
|
|
215
|
+
"semantic": (
|
|
216
|
+
"success": #22c55e,
|
|
217
|
+
"warning": #f59e0b,
|
|
218
|
+
"error": #ef4444,
|
|
219
|
+
"info": #3b82f6,
|
|
220
|
+
),
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
// --- Spacing Tokens ---
|
|
224
|
+
$spacing: (
|
|
225
|
+
"xs": 0.25rem,
|
|
226
|
+
"sm": 0.5rem,
|
|
227
|
+
"md": 1rem,
|
|
228
|
+
"lg": 1.5rem,
|
|
229
|
+
"xl": 2rem,
|
|
230
|
+
"2xl": 3rem,
|
|
231
|
+
"3xl": 4rem,
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// --- Typography Tokens ---
|
|
235
|
+
$font-sizes: (
|
|
236
|
+
"xs": 0.75rem,
|
|
237
|
+
"sm": 0.875rem,
|
|
238
|
+
"base": 1rem,
|
|
239
|
+
"lg": 1.125rem,
|
|
240
|
+
"xl": 1.25rem,
|
|
241
|
+
"2xl": 1.5rem,
|
|
242
|
+
"3xl": 1.875rem,
|
|
243
|
+
"4xl": 2.25rem,
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
$font-weights: (
|
|
247
|
+
"regular": 400,
|
|
248
|
+
"medium": 500,
|
|
249
|
+
"semibold": 600,
|
|
250
|
+
"bold": 700,
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
// --- Radii ---
|
|
254
|
+
$radii: (
|
|
255
|
+
"sm": 0.25rem,
|
|
256
|
+
"md": 0.375rem,
|
|
257
|
+
"lg": 0.5rem,
|
|
258
|
+
"xl": 0.75rem,
|
|
259
|
+
"full": 9999px,
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// --- Shadows ---
|
|
263
|
+
$shadows: (
|
|
264
|
+
"sm": (0 1px 2px rgba(0, 0, 0, 0.05)),
|
|
265
|
+
"md": (0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.05)),
|
|
266
|
+
"lg": (0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05)),
|
|
267
|
+
);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Token Access Functions
|
|
271
|
+
|
|
272
|
+
```scss
|
|
273
|
+
// abstracts/_functions.scss
|
|
274
|
+
@use "sass:map";
|
|
275
|
+
@use "sass:list";
|
|
276
|
+
@use "tokens" as t;
|
|
277
|
+
|
|
278
|
+
// Get a color from the palette
|
|
279
|
+
@function color($group, $shade: null) {
|
|
280
|
+
@if $shade {
|
|
281
|
+
$group-map: map.get(t.$colors, $group);
|
|
282
|
+
@if not $group-map {
|
|
283
|
+
@error "Color group '#{$group}' not found.";
|
|
284
|
+
}
|
|
285
|
+
$result: map.get($group-map, "#{$shade}");
|
|
286
|
+
@if not $result {
|
|
287
|
+
@error "Shade '#{$shade}' not found in '#{$group}'.";
|
|
288
|
+
}
|
|
289
|
+
@return $result;
|
|
290
|
+
}
|
|
291
|
+
@return map.get(t.$colors, "semantic", $group);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Get spacing
|
|
295
|
+
@function space($size) {
|
|
296
|
+
$result: map.get(t.$spacing, $size);
|
|
297
|
+
@if not $result {
|
|
298
|
+
@error "Spacing '#{$size}' not found. Available: #{map.keys(t.$spacing)}";
|
|
299
|
+
}
|
|
300
|
+
@return $result;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Get font size
|
|
304
|
+
@function font-size($size) {
|
|
305
|
+
$result: map.get(t.$font-sizes, $size);
|
|
306
|
+
@if not $result {
|
|
307
|
+
@error "Font size '#{$size}' not found.";
|
|
308
|
+
}
|
|
309
|
+
@return $result;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Get radius
|
|
313
|
+
@function radius($size) {
|
|
314
|
+
@return map.get(t.$radii, $size);
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Generate CSS Custom Properties from Maps
|
|
319
|
+
|
|
320
|
+
```scss
|
|
321
|
+
// base/_root.scss
|
|
322
|
+
@use "sass:map";
|
|
323
|
+
@use "../abstracts" as a;
|
|
324
|
+
|
|
325
|
+
:root {
|
|
326
|
+
// Generate color custom properties
|
|
327
|
+
@each $group, $shades in a.$colors {
|
|
328
|
+
@if type-of($shades) == "map" {
|
|
329
|
+
@each $shade, $value in $shades {
|
|
330
|
+
--color-#{$group}-#{$shade}: #{$value};
|
|
331
|
+
}
|
|
332
|
+
} @else {
|
|
333
|
+
--color-#{$group}: #{$shades};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Generate spacing custom properties
|
|
338
|
+
@each $name, $value in a.$spacing {
|
|
339
|
+
--space-#{$name}: #{$value};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Generate font size custom properties
|
|
343
|
+
@each $name, $value in a.$font-sizes {
|
|
344
|
+
--text-#{$name}: #{$value};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Responsive Breakpoint System
|
|
350
|
+
|
|
351
|
+
### Breakpoint Map and Mixin
|
|
352
|
+
|
|
353
|
+
```scss
|
|
354
|
+
// abstracts/_breakpoints.scss
|
|
355
|
+
@use "sass:map";
|
|
356
|
+
|
|
357
|
+
$breakpoints: (
|
|
358
|
+
"sm": 640px,
|
|
359
|
+
"md": 768px,
|
|
360
|
+
"lg": 1024px,
|
|
361
|
+
"xl": 1280px,
|
|
362
|
+
"2xl": 1536px,
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
// Mobile-first (min-width)
|
|
366
|
+
@mixin respond-to($breakpoint) {
|
|
367
|
+
$value: map.get($breakpoints, $breakpoint);
|
|
368
|
+
@if not $value {
|
|
369
|
+
@error "Breakpoint '#{$breakpoint}' not found. Available: #{map.keys($breakpoints)}";
|
|
370
|
+
}
|
|
371
|
+
@media (min-width: $value) {
|
|
372
|
+
@content;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Desktop-first (max-width)
|
|
377
|
+
@mixin respond-below($breakpoint) {
|
|
378
|
+
$value: map.get($breakpoints, $breakpoint);
|
|
379
|
+
@if not $value {
|
|
380
|
+
@error "Breakpoint '#{$breakpoint}' not found.";
|
|
381
|
+
}
|
|
382
|
+
@media (max-width: ($value - 0.02px)) {
|
|
383
|
+
@content;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Between two breakpoints
|
|
388
|
+
@mixin respond-between($lower, $upper) {
|
|
389
|
+
$lower-val: map.get($breakpoints, $lower);
|
|
390
|
+
$upper-val: map.get($breakpoints, $upper);
|
|
391
|
+
@if not $lower-val or not $upper-val {
|
|
392
|
+
@error "Invalid breakpoints: '#{$lower}' or '#{$upper}'.";
|
|
393
|
+
}
|
|
394
|
+
@media (min-width: $lower-val) and (max-width: ($upper-val - 0.02px)) {
|
|
395
|
+
@content;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Using Breakpoints
|
|
401
|
+
|
|
402
|
+
```scss
|
|
403
|
+
@use "../abstracts" as a;
|
|
404
|
+
|
|
405
|
+
.sidebar {
|
|
406
|
+
display: none;
|
|
407
|
+
|
|
408
|
+
@include a.respond-to("lg") {
|
|
409
|
+
display: block;
|
|
410
|
+
width: 280px;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.card-grid {
|
|
415
|
+
display: grid;
|
|
416
|
+
gap: a.space("md");
|
|
417
|
+
grid-template-columns: 1fr;
|
|
418
|
+
|
|
419
|
+
@include a.respond-to("sm") {
|
|
420
|
+
grid-template-columns: repeat(2, 1fr);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
@include a.respond-to("lg") {
|
|
424
|
+
grid-template-columns: repeat(3, 1fr);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## Mixins vs Extends vs Functions
|
|
430
|
+
|
|
431
|
+
### When to Use Each
|
|
432
|
+
|
|
433
|
+
| Tool | Use When | Output |
|
|
434
|
+
|------|----------|--------|
|
|
435
|
+
| **@mixin** | Reusable blocks of declarations, accepts arguments | Duplicates CSS at each call site |
|
|
436
|
+
| **@extend / %placeholder** | Multiple selectors share identical styles, no arguments | Merges selectors (comma-separated) |
|
|
437
|
+
| **@function** | Computing and returning a single value | No CSS output, returns a value |
|
|
438
|
+
|
|
439
|
+
### Mixin Patterns
|
|
440
|
+
|
|
441
|
+
```scss
|
|
442
|
+
// abstracts/_mixins.scss
|
|
443
|
+
@use "sass:math";
|
|
444
|
+
@use "tokens" as t;
|
|
445
|
+
@use "breakpoints" as bp;
|
|
446
|
+
|
|
447
|
+
// Truncate text with ellipsis
|
|
448
|
+
@mixin truncate($lines: 1) {
|
|
449
|
+
overflow: hidden;
|
|
450
|
+
text-overflow: ellipsis;
|
|
451
|
+
@if $lines == 1 {
|
|
452
|
+
white-space: nowrap;
|
|
453
|
+
} @else {
|
|
454
|
+
display: -webkit-box;
|
|
455
|
+
-webkit-line-clamp: $lines;
|
|
456
|
+
-webkit-box-orient: vertical;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Visually hidden (accessible)
|
|
461
|
+
@mixin visually-hidden {
|
|
462
|
+
position: absolute;
|
|
463
|
+
width: 1px;
|
|
464
|
+
height: 1px;
|
|
465
|
+
padding: 0;
|
|
466
|
+
margin: -1px;
|
|
467
|
+
overflow: hidden;
|
|
468
|
+
clip: rect(0, 0, 0, 0);
|
|
469
|
+
white-space: nowrap;
|
|
470
|
+
border: 0;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Focus ring
|
|
474
|
+
@mixin focus-ring($color: map-get(t.$colors, "primary", "500"), $offset: 2px) {
|
|
475
|
+
&:focus-visible {
|
|
476
|
+
outline: 2px solid $color;
|
|
477
|
+
outline-offset: $offset;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Container
|
|
482
|
+
@mixin container($max-width: 1200px, $padding: map-get(t.$spacing, "md")) {
|
|
483
|
+
width: 100%;
|
|
484
|
+
max-width: $max-width;
|
|
485
|
+
margin-inline: auto;
|
|
486
|
+
padding-inline: $padding;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Aspect ratio (for older browser support)
|
|
490
|
+
@mixin aspect-ratio($width, $height) {
|
|
491
|
+
aspect-ratio: math.div($width, $height);
|
|
492
|
+
|
|
493
|
+
// Fallback for older browsers
|
|
494
|
+
@supports not (aspect-ratio: 1) {
|
|
495
|
+
&::before {
|
|
496
|
+
content: "";
|
|
497
|
+
display: block;
|
|
498
|
+
padding-top: math.percentage(math.div($height, $width));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Transition shorthand
|
|
504
|
+
@mixin transition($properties...) {
|
|
505
|
+
$result: ();
|
|
506
|
+
@each $prop in $properties {
|
|
507
|
+
$result: append($result, $prop 250ms cubic-bezier(0.22, 1, 0.36, 1), comma);
|
|
508
|
+
}
|
|
509
|
+
transition: $result;
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Placeholder Selectors (%)
|
|
514
|
+
|
|
515
|
+
```scss
|
|
516
|
+
// abstracts/_placeholders.scss
|
|
517
|
+
|
|
518
|
+
// Shared card base -- only output if extended
|
|
519
|
+
%card-base {
|
|
520
|
+
border-radius: 0.5rem;
|
|
521
|
+
overflow: hidden;
|
|
522
|
+
background: white;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
%reset-list {
|
|
526
|
+
list-style: none;
|
|
527
|
+
margin: 0;
|
|
528
|
+
padding: 0;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
%reset-button {
|
|
532
|
+
appearance: none;
|
|
533
|
+
background: none;
|
|
534
|
+
border: none;
|
|
535
|
+
cursor: pointer;
|
|
536
|
+
font: inherit;
|
|
537
|
+
color: inherit;
|
|
538
|
+
padding: 0;
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
```scss
|
|
543
|
+
// components/_card.scss
|
|
544
|
+
@use "../abstracts" as a;
|
|
545
|
+
|
|
546
|
+
.card {
|
|
547
|
+
@extend %card-base;
|
|
548
|
+
box-shadow: map-get(a.$shadows, "md");
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
.card--flat {
|
|
552
|
+
@extend %card-base;
|
|
553
|
+
border: 1px solid map-get(a.$colors, "neutral", "200");
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Compiled output:
|
|
557
|
+
// .card, .card--flat { border-radius: 0.5rem; overflow: hidden; background: white; }
|
|
558
|
+
// .card { box-shadow: ... }
|
|
559
|
+
// .card--flat { border: ... }
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Functions
|
|
563
|
+
|
|
564
|
+
```scss
|
|
565
|
+
// abstracts/_functions.scss
|
|
566
|
+
@use "sass:math";
|
|
567
|
+
@use "sass:color";
|
|
568
|
+
@use "sass:string";
|
|
569
|
+
|
|
570
|
+
// Convert px to rem
|
|
571
|
+
@function to-rem($px, $base: 16) {
|
|
572
|
+
@return math.div($px, $base) * 1rem;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Strip units
|
|
576
|
+
@function strip-unit($value) {
|
|
577
|
+
@return math.div($value, ($value * 0 + 1));
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Tint a color (mix with white)
|
|
581
|
+
@function tint($color, $percentage) {
|
|
582
|
+
@return color.mix(white, $color, $percentage);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Shade a color (mix with black)
|
|
586
|
+
@function shade($color, $percentage) {
|
|
587
|
+
@return color.mix(black, $color, $percentage);
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## Control Directives
|
|
592
|
+
|
|
593
|
+
### @each
|
|
594
|
+
|
|
595
|
+
```scss
|
|
596
|
+
@use "sass:map";
|
|
597
|
+
@use "../abstracts" as a;
|
|
598
|
+
|
|
599
|
+
// Generate utility classes from a map
|
|
600
|
+
@each $name, $value in a.$spacing {
|
|
601
|
+
.m-#{$name} { margin: $value; }
|
|
602
|
+
.p-#{$name} { padding: $value; }
|
|
603
|
+
.mx-#{$name} { margin-inline: $value; }
|
|
604
|
+
.my-#{$name} { margin-block: $value; }
|
|
605
|
+
.px-#{$name} { padding-inline: $value; }
|
|
606
|
+
.py-#{$name} { padding-block: $value; }
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Nested map iteration
|
|
610
|
+
@each $group, $shades in a.$colors {
|
|
611
|
+
@if type-of($shades) == "map" {
|
|
612
|
+
@each $shade, $value in $shades {
|
|
613
|
+
.text-#{$group}-#{$shade} { color: $value; }
|
|
614
|
+
.bg-#{$group}-#{$shade} { background-color: $value; }
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### @for
|
|
621
|
+
|
|
622
|
+
```scss
|
|
623
|
+
// Generate grid column classes
|
|
624
|
+
@for $i from 1 through 12 {
|
|
625
|
+
.col-#{$i} {
|
|
626
|
+
grid-column: span $i;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// Generate gap utilities
|
|
631
|
+
@for $i from 0 through 8 {
|
|
632
|
+
.gap-#{$i} {
|
|
633
|
+
gap: $i * 0.25rem;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### @while
|
|
639
|
+
|
|
640
|
+
```scss
|
|
641
|
+
// Less common -- mostly used for complex computed sequences
|
|
642
|
+
$columns: 12;
|
|
643
|
+
$i: 1;
|
|
644
|
+
|
|
645
|
+
@while $i <= $columns {
|
|
646
|
+
.col-offset-#{$i} {
|
|
647
|
+
grid-column-start: $i + 1;
|
|
648
|
+
}
|
|
649
|
+
$i: $i + 1;
|
|
650
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
## Built-In Modules
|
|
654
|
+
|
|
655
|
+
### sass:math
|
|
656
|
+
|
|
657
|
+
```scss
|
|
658
|
+
@use "sass:math";
|
|
659
|
+
|
|
660
|
+
.element {
|
|
661
|
+
// Division (/ operator is deprecated for division)
|
|
662
|
+
width: math.div(100%, 3);
|
|
663
|
+
|
|
664
|
+
// Rounding
|
|
665
|
+
border-radius: math.round(3.7px); // 4px
|
|
666
|
+
|
|
667
|
+
// Clamping
|
|
668
|
+
font-size: math.clamp(1rem, 2vw, 2rem);
|
|
669
|
+
|
|
670
|
+
// Min/Max
|
|
671
|
+
width: math.min(100%, 600px);
|
|
672
|
+
|
|
673
|
+
// Power
|
|
674
|
+
line-height: math.pow(1.25, 2); // 1.5625
|
|
675
|
+
|
|
676
|
+
// Percentage
|
|
677
|
+
flex-basis: math.percentage(math.div(1, 3)); // 33.33333%
|
|
678
|
+
|
|
679
|
+
// Constants
|
|
680
|
+
transform: rotate(math.$pi * 1rad);
|
|
681
|
+
}
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
### sass:color
|
|
685
|
+
|
|
686
|
+
```scss
|
|
687
|
+
@use "sass:color";
|
|
688
|
+
|
|
689
|
+
$base: #3b82f6;
|
|
690
|
+
|
|
691
|
+
.element {
|
|
692
|
+
// Lighten/darken
|
|
693
|
+
background: color.adjust($base, $lightness: 20%);
|
|
694
|
+
border-color: color.adjust($base, $lightness: -15%);
|
|
695
|
+
|
|
696
|
+
// Change specific channels
|
|
697
|
+
color: color.adjust($base, $saturation: -30%);
|
|
698
|
+
|
|
699
|
+
// Scale relative to current value
|
|
700
|
+
background: color.scale($base, $lightness: 30%);
|
|
701
|
+
|
|
702
|
+
// Mix two colors
|
|
703
|
+
border-color: color.mix($base, white, 50%);
|
|
704
|
+
|
|
705
|
+
// Get channel values
|
|
706
|
+
// $hue: color.hue($base);
|
|
707
|
+
// $lightness: color.lightness($base);
|
|
708
|
+
// $alpha: color.alpha($base);
|
|
709
|
+
|
|
710
|
+
// Change alpha
|
|
711
|
+
background: color.adjust($base, $alpha: -0.3);
|
|
712
|
+
}
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### sass:map
|
|
716
|
+
|
|
717
|
+
```scss
|
|
718
|
+
@use "sass:map";
|
|
719
|
+
|
|
720
|
+
$theme: (
|
|
721
|
+
"colors": (
|
|
722
|
+
"primary": #3b82f6,
|
|
723
|
+
"secondary": #10b981,
|
|
724
|
+
),
|
|
725
|
+
"spacing": (
|
|
726
|
+
"sm": 0.5rem,
|
|
727
|
+
"md": 1rem,
|
|
728
|
+
),
|
|
729
|
+
);
|
|
730
|
+
|
|
731
|
+
// Get nested values
|
|
732
|
+
$primary: map.get($theme, "colors", "primary");
|
|
733
|
+
|
|
734
|
+
// Check if key exists
|
|
735
|
+
$has-colors: map.has-key($theme, "colors"); // true
|
|
736
|
+
|
|
737
|
+
// Merge maps
|
|
738
|
+
$extended: map.merge($theme, ("breakpoints": ("sm": 640px)));
|
|
739
|
+
|
|
740
|
+
// Deep merge
|
|
741
|
+
$deep: map.deep-merge($theme, (
|
|
742
|
+
"colors": ("tertiary": #f59e0b),
|
|
743
|
+
));
|
|
744
|
+
|
|
745
|
+
// Get keys/values
|
|
746
|
+
$keys: map.keys($theme); // ("colors", "spacing")
|
|
747
|
+
$values: map.values(map.get($theme, "spacing")); // (0.5rem, 1rem)
|
|
748
|
+
|
|
749
|
+
// Remove a key
|
|
750
|
+
$without: map.remove($theme, "spacing");
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### sass:list
|
|
754
|
+
|
|
755
|
+
```scss
|
|
756
|
+
@use "sass:list";
|
|
757
|
+
|
|
758
|
+
$fonts: "Inter", "Helvetica", "Arial", sans-serif;
|
|
759
|
+
|
|
760
|
+
// Access by index (1-based)
|
|
761
|
+
$first: list.nth($fonts, 1); // "Inter"
|
|
762
|
+
|
|
763
|
+
// Length
|
|
764
|
+
$count: list.length($fonts); // 4
|
|
765
|
+
|
|
766
|
+
// Append
|
|
767
|
+
$extended: list.append($fonts, "Georgia");
|
|
768
|
+
|
|
769
|
+
// Join two lists
|
|
770
|
+
$combined: list.join(("a", "b"), ("c", "d")); // "a", "b", "c", "d"
|
|
771
|
+
|
|
772
|
+
// Find index
|
|
773
|
+
$idx: list.index($fonts, "Arial"); // 3
|
|
774
|
+
|
|
775
|
+
// Separator
|
|
776
|
+
$sep: list.separator($fonts); // comma
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### sass:string
|
|
780
|
+
|
|
781
|
+
```scss
|
|
782
|
+
@use "sass:string";
|
|
783
|
+
|
|
784
|
+
$class-name: "btn-primary";
|
|
785
|
+
|
|
786
|
+
// String operations
|
|
787
|
+
$upper: string.to-upper-case($class-name); // "BTN-PRIMARY"
|
|
788
|
+
$length: string.length($class-name); // 11
|
|
789
|
+
$slice: string.slice($class-name, 5); // "primary"
|
|
790
|
+
$index: string.index($class-name, "-"); // 4
|
|
791
|
+
$quoted: string.quote(hello); // "hello"
|
|
792
|
+
$unquoted: string.unquote("hello"); // hello
|
|
793
|
+
|
|
794
|
+
// Insert
|
|
795
|
+
$inserted: string.insert($class-name, "--large", 4); // "btn--large-primary"
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
## Theming with Maps
|
|
799
|
+
|
|
800
|
+
### Theme Definition
|
|
801
|
+
|
|
802
|
+
```scss
|
|
803
|
+
// themes/_light.scss
|
|
804
|
+
$light-theme: (
|
|
805
|
+
"surface": #ffffff,
|
|
806
|
+
"surface-raised": #f9fafb,
|
|
807
|
+
"text": #111827,
|
|
808
|
+
"text-muted": #6b7280,
|
|
809
|
+
"border": #e5e7eb,
|
|
810
|
+
"primary": #3b82f6,
|
|
811
|
+
"primary-text": #ffffff,
|
|
812
|
+
);
|
|
813
|
+
|
|
814
|
+
// themes/_dark.scss
|
|
815
|
+
$dark-theme: (
|
|
816
|
+
"surface": #111827,
|
|
817
|
+
"surface-raised": #1f2937,
|
|
818
|
+
"text": #f9fafb,
|
|
819
|
+
"text-muted": #9ca3af,
|
|
820
|
+
"border": #374151,
|
|
821
|
+
"primary": #60a5fa,
|
|
822
|
+
"primary-text": #111827,
|
|
823
|
+
);
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### Theme Application
|
|
827
|
+
|
|
828
|
+
```scss
|
|
829
|
+
// abstracts/_mixins.scss
|
|
830
|
+
@use "sass:map";
|
|
831
|
+
|
|
832
|
+
@mixin apply-theme($theme) {
|
|
833
|
+
@each $key, $value in $theme {
|
|
834
|
+
--color-#{$key}: #{$value};
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
```scss
|
|
840
|
+
// base/_root.scss
|
|
841
|
+
@use "../abstracts" as a;
|
|
842
|
+
@use "../themes/light" as light;
|
|
843
|
+
@use "../themes/dark" as dark;
|
|
844
|
+
|
|
845
|
+
:root {
|
|
846
|
+
@include a.apply-theme(light.$light-theme);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
@media (prefers-color-scheme: dark) {
|
|
850
|
+
:root {
|
|
851
|
+
@include a.apply-theme(dark.$dark-theme);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
[data-theme="dark"] {
|
|
856
|
+
@include a.apply-theme(dark.$dark-theme);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
[data-theme="light"] {
|
|
860
|
+
@include a.apply-theme(light.$light-theme);
|
|
861
|
+
}
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
```scss
|
|
865
|
+
// components/_card.scss
|
|
866
|
+
// Now components use CSS custom properties, not SCSS variables
|
|
867
|
+
.card {
|
|
868
|
+
background: var(--color-surface-raised);
|
|
869
|
+
color: var(--color-text);
|
|
870
|
+
border: 1px solid var(--color-border);
|
|
871
|
+
}
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
## Nesting Best Practices
|
|
875
|
+
|
|
876
|
+
### Good Nesting (Max 3 Levels)
|
|
877
|
+
|
|
878
|
+
```scss
|
|
879
|
+
// GOOD: Clear, shallow nesting
|
|
880
|
+
.nav {
|
|
881
|
+
display: flex;
|
|
882
|
+
gap: 1rem;
|
|
883
|
+
|
|
884
|
+
&__item {
|
|
885
|
+
position: relative;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
&__link {
|
|
889
|
+
color: var(--color-text);
|
|
890
|
+
text-decoration: none;
|
|
891
|
+
|
|
892
|
+
&:hover {
|
|
893
|
+
color: var(--color-primary);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
&--active {
|
|
897
|
+
font-weight: 600;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
### Bad Nesting (Too Deep)
|
|
904
|
+
|
|
905
|
+
```scss
|
|
906
|
+
// BAD: 5 levels deep -- creates .nav ul li a span selector
|
|
907
|
+
.nav {
|
|
908
|
+
ul {
|
|
909
|
+
li {
|
|
910
|
+
a {
|
|
911
|
+
span {
|
|
912
|
+
color: red;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
### Nesting Rules
|
|
921
|
+
|
|
922
|
+
1. Use `&` for BEM elements and modifiers
|
|
923
|
+
2. Use `&` for pseudo-classes and pseudo-elements
|
|
924
|
+
3. Nest media queries inside selectors (not selectors inside media queries)
|
|
925
|
+
4. Never nest more than 3 levels
|
|
926
|
+
5. If nesting feels deep, your component is too complex -- split it
|
|
927
|
+
|
|
928
|
+
## CSS Modules Integration
|
|
929
|
+
|
|
930
|
+
```scss
|
|
931
|
+
// Button.module.scss
|
|
932
|
+
@use "../abstracts" as a;
|
|
933
|
+
|
|
934
|
+
.root {
|
|
935
|
+
display: inline-flex;
|
|
936
|
+
align-items: center;
|
|
937
|
+
gap: a.space("xs");
|
|
938
|
+
padding: a.space("sm") a.space("md");
|
|
939
|
+
border-radius: a.radius("md");
|
|
940
|
+
font-weight: map-get(a.$font-weights, "semibold");
|
|
941
|
+
@include a.transition(background-color, color, box-shadow);
|
|
942
|
+
@include a.focus-ring;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
.primary {
|
|
946
|
+
composes: root;
|
|
947
|
+
background: a.color("primary", 500);
|
|
948
|
+
color: white;
|
|
949
|
+
|
|
950
|
+
&:hover {
|
|
951
|
+
background: a.color("primary", 600);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
.secondary {
|
|
956
|
+
composes: root;
|
|
957
|
+
background: transparent;
|
|
958
|
+
color: a.color("primary", 500);
|
|
959
|
+
border: 1px solid a.color("primary", 500);
|
|
960
|
+
|
|
961
|
+
&:hover {
|
|
962
|
+
background: a.color("primary", 100);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.small {
|
|
967
|
+
padding: a.space("xs") a.space("sm");
|
|
968
|
+
font-size: a.font-size("sm");
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
.large {
|
|
972
|
+
padding: a.space("md") a.space("lg");
|
|
973
|
+
font-size: a.font-size("lg");
|
|
974
|
+
}
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
```tsx
|
|
978
|
+
// Button.tsx
|
|
979
|
+
import styles from "./Button.module.scss";
|
|
980
|
+
|
|
981
|
+
function Button({ variant = "primary", size = "md", children }) {
|
|
982
|
+
const variantClass = styles[variant];
|
|
983
|
+
const sizeClass = size !== "md" ? styles[size] : "";
|
|
984
|
+
|
|
985
|
+
return (
|
|
986
|
+
<button className={`${variantClass} ${sizeClass}`}>
|
|
987
|
+
{children}
|
|
988
|
+
</button>
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
## Dart Sass Migration
|
|
994
|
+
|
|
995
|
+
### Migrating @import to @use/@forward
|
|
996
|
+
|
|
997
|
+
```scss
|
|
998
|
+
// OLD (deprecated):
|
|
999
|
+
@import "variables";
|
|
1000
|
+
@import "mixins";
|
|
1001
|
+
@import "components/button";
|
|
1002
|
+
|
|
1003
|
+
// NEW:
|
|
1004
|
+
@use "abstracts" as a;
|
|
1005
|
+
@use "components/button";
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
### Key Migration Differences
|
|
1009
|
+
|
|
1010
|
+
| @import | @use |
|
|
1011
|
+
|---------|------|
|
|
1012
|
+
| Global scope -- everything accessible everywhere | Namespaced -- must @use in each file that needs it |
|
|
1013
|
+
| Can @import same file multiple times | @use loads once, cached |
|
|
1014
|
+
| `$variable` accessible globally | `namespace.$variable` required |
|
|
1015
|
+
| Mixin available globally | `@include namespace.mixin` required |
|
|
1016
|
+
| Can cause duplicate CSS | Never duplicates |
|
|
1017
|
+
|
|
1018
|
+
### Migration Command
|
|
1019
|
+
|
|
1020
|
+
```bash
|
|
1021
|
+
# Use the official migrator
|
|
1022
|
+
npx sass-migrator module --migrate-deps style.scss
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
## Performance Considerations
|
|
1026
|
+
|
|
1027
|
+
### Selector Performance
|
|
1028
|
+
|
|
1029
|
+
```scss
|
|
1030
|
+
// AVOID: Universal selector in key position
|
|
1031
|
+
* { box-sizing: border-box; }
|
|
1032
|
+
// BETTER: Scope to reset layer, which is fine
|
|
1033
|
+
@layer reset { *, *::before, *::after { box-sizing: border-box; } }
|
|
1034
|
+
|
|
1035
|
+
// AVOID: Deep descendant selectors
|
|
1036
|
+
.page .content .sidebar .widget .title { }
|
|
1037
|
+
// BETTER: Direct class
|
|
1038
|
+
.widget__title { }
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
### Output Size Control
|
|
1042
|
+
|
|
1043
|
+
```scss
|
|
1044
|
+
// AVOID: Generating thousands of utility classes
|
|
1045
|
+
@each $prop in (margin, padding) {
|
|
1046
|
+
@each $side in (top, right, bottom, left) {
|
|
1047
|
+
@for $i from 0 through 100 {
|
|
1048
|
+
.#{$prop}-#{$side}-#{$i} {
|
|
1049
|
+
#{$prop}-#{$side}: $i * 1px;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
// This generates 800 classes. Do not do this.
|
|
1055
|
+
|
|
1056
|
+
// BETTER: Generate only what you use from a curated scale
|
|
1057
|
+
$spacing-scale: ("0": 0, "1": 0.25rem, "2": 0.5rem, "4": 1rem, "8": 2rem);
|
|
1058
|
+
@each $name, $value in $spacing-scale {
|
|
1059
|
+
.mt-#{$name} { margin-top: $value; }
|
|
1060
|
+
.mb-#{$name} { margin-bottom: $value; }
|
|
1061
|
+
}
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
### @extend vs @mixin Output
|
|
1065
|
+
|
|
1066
|
+
```scss
|
|
1067
|
+
// @extend: merges selectors (smaller output when many elements share styles)
|
|
1068
|
+
%sr-only { position: absolute; width: 1px; height: 1px; }
|
|
1069
|
+
.label-hidden { @extend %sr-only; }
|
|
1070
|
+
.skip-link { @extend %sr-only; }
|
|
1071
|
+
// Output: .label-hidden, .skip-link { position: absolute; width: 1px; height: 1px; }
|
|
1072
|
+
|
|
1073
|
+
// @mixin: duplicates declarations (larger output but more predictable)
|
|
1074
|
+
@mixin sr-only { position: absolute; width: 1px; height: 1px; }
|
|
1075
|
+
.label-hidden { @include sr-only; }
|
|
1076
|
+
.skip-link { @include sr-only; }
|
|
1077
|
+
// Output: .label-hidden { position: absolute; ... } .skip-link { position: absolute; ... }
|
|
1078
|
+
|
|
1079
|
+
// Rule of thumb:
|
|
1080
|
+
// - Use @extend / %placeholder for identical styles with no arguments
|
|
1081
|
+
// - Use @mixin for parameterized or conditional styles
|
|
1082
|
+
// - Prefer @mixin when in doubt -- it is more predictable
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
## Anti-Patterns
|
|
1086
|
+
|
|
1087
|
+
| Anti-Pattern | Why It Is Bad | Correct Approach |
|
|
1088
|
+
|--------------|---------------|------------------|
|
|
1089
|
+
| `@import "file"` | Deprecated, global scope pollution | `@use "file" as f` |
|
|
1090
|
+
| Nesting 4+ levels deep | Overly specific selectors | Max 3 levels, use BEM |
|
|
1091
|
+
| `$color / 2` for division | Deprecated slash division | `math.div($color, 2)` |
|
|
1092
|
+
| Hardcoded colors in components | Not themeable, inconsistent | Use token maps and functions |
|
|
1093
|
+
| `@extend` across media queries | Does not work in Sass | Use `@mixin` instead |
|
|
1094
|
+
| `@extend .existing-class` | Can create unexpected selectors | `@extend %placeholder` only |
|
|
1095
|
+
| Variables without `!default` in libraries | Cannot be overridden by consumers | Add `!default` to library variables |
|
|
1096
|
+
| Generating 1000+ utility classes | Bloated CSS output | Use curated scales |
|
|
1097
|
+
| Using LibSass or Ruby Sass | Dead projects, no module support | Use Dart Sass exclusively |
|
|
1098
|
+
| Storing runtime values in `$vars` | Cannot change after compilation | Use CSS custom properties for runtime |
|
|
1099
|
+
|
|
1100
|
+
## Best Practices
|
|
1101
|
+
|
|
1102
|
+
1. **@use everywhere**: Every file that needs a variable or mixin must @use it explicitly
|
|
1103
|
+
2. **@forward in _index.scss**: Each directory has an index that forwards its contents
|
|
1104
|
+
3. **Token maps, not loose variables**: Group tokens by category in maps
|
|
1105
|
+
4. **Generate CSS custom properties**: Bridge SCSS build-time power with CSS runtime flexibility
|
|
1106
|
+
5. **3-level nesting max**: If deeper, your component needs splitting
|
|
1107
|
+
6. **math.div() for division**: The `/` operator is deprecated for division
|
|
1108
|
+
7. **Prefer @mixin over @extend**: More predictable, works across media queries
|
|
1109
|
+
8. **Use built-in modules**: `sass:math`, `sass:color`, `sass:map` over custom functions
|
|
1110
|
+
9. **Error in functions**: Use `@error` and `@warn` for invalid inputs to functions
|
|
1111
|
+
10. **Audit compiled output**: Regularly check the generated CSS for bloat
|
|
1112
|
+
11. **Use !default for library code**: Allow consumers to override token values
|
|
1113
|
+
12. **Namespace imports**: `@use "tokens" as t` not `@use "tokens" as *`
|
|
1114
|
+
|
|
1115
|
+
## References
|
|
1116
|
+
|
|
1117
|
+
- Sass Documentation: https://sass-lang.com/documentation
|
|
1118
|
+
- Sass Module System: https://sass-lang.com/blog/the-module-system-is-launched
|
|
1119
|
+
- Sass Built-In Modules: https://sass-lang.com/documentation/modules
|
|
1120
|
+
- Sass Migrator: https://sass-lang.com/documentation/cli/migrator
|
|
1121
|
+
- Dart Sass: https://sass-lang.com/dart-sass
|