opencode-skills-collection 3.1.0 → 3.1.1
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/bundled-skills/.antigravity-install-manifest.json +84 -1
- package/bundled-skills/android-ui-journey-testing/SKILL.md +191 -0
- package/bundled-skills/ask-matt/SKILL.md +92 -0
- package/bundled-skills/bugs-are-annoying/SKILL.md +137 -0
- package/bundled-skills/codebase-design/DEEPENING.md +37 -0
- package/bundled-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/bundled-skills/codebase-design/SKILL.md +145 -0
- package/bundled-skills/competitor-analysis/LICENSE.txt +21 -0
- package/bundled-skills/competitor-analysis/SKILL.md +434 -0
- package/bundled-skills/competitor-analysis/references/battle-card-subagent.md +127 -0
- package/bundled-skills/competitor-analysis/references/battle-card.md +91 -0
- package/bundled-skills/competitor-analysis/references/example-research.md +130 -0
- package/bundled-skills/competitor-analysis/references/report-template.html +127 -0
- package/bundled-skills/competitor-analysis/references/research-patterns.md +217 -0
- package/bundled-skills/competitor-analysis/references/workflow.md +434 -0
- package/bundled-skills/competitor-analysis/scripts/capture_screenshots.mjs +142 -0
- package/bundled-skills/competitor-analysis/scripts/compile_report.mjs +929 -0
- package/bundled-skills/competitor-analysis/scripts/extract_vs_names.mjs +140 -0
- package/bundled-skills/competitor-analysis/scripts/gate_candidates.mjs +194 -0
- package/bundled-skills/competitor-analysis/scripts/list_urls.mjs +90 -0
- package/bundled-skills/competitor-analysis/scripts/md_utils.mjs +50 -0
- package/bundled-skills/competitor-analysis/scripts/merge_partials.mjs +291 -0
- package/bundled-skills/competitor-analysis/scripts/package.json +6 -0
- package/bundled-skills/design-it/3d-ui/SKILL.md +259 -0
- package/bundled-skills/design-it/SKILL.md +170 -0
- package/bundled-skills/design-it/ai-native-ui/SKILL.md +295 -0
- package/bundled-skills/design-it/aurora-ui/SKILL.md +307 -0
- package/bundled-skills/design-it/bento-ui/SKILL.md +314 -0
- package/bundled-skills/design-it/brutalism/SKILL.md +270 -0
- package/bundled-skills/design-it/brutalist-typography/SKILL.md +287 -0
- package/bundled-skills/design-it/card-based-design/SKILL.md +262 -0
- package/bundled-skills/design-it/claymorphism/SKILL.md +287 -0
- package/bundled-skills/design-it/color-blocking/SKILL.md +278 -0
- package/bundled-skills/design-it/command-center-ui/SKILL.md +345 -0
- package/bundled-skills/design-it/cyber-y2k/SKILL.md +312 -0
- package/bundled-skills/design-it/cyberpunk-ui/SKILL.md +262 -0
- package/bundled-skills/design-it/dark-mode/SKILL.md +289 -0
- package/bundled-skills/design-it/dashboard-design/SKILL.md +331 -0
- package/bundled-skills/design-it/data-dense-design/SKILL.md +322 -0
- package/bundled-skills/design-it/duotone-design/SKILL.md +248 -0
- package/bundled-skills/design-it/editorial-design/SKILL.md +328 -0
- package/bundled-skills/design-it/flat-design/SKILL.md +221 -0
- package/bundled-skills/design-it/flat-design-2/SKILL.md +240 -0
- package/bundled-skills/design-it/floating-ui/SKILL.md +299 -0
- package/bundled-skills/design-it/frutiger-aero/SKILL.md +274 -0
- package/bundled-skills/design-it/glassmorphism/SKILL.md +272 -0
- package/bundled-skills/design-it/gradient-design/SKILL.md +309 -0
- package/bundled-skills/design-it/high-contrast/SKILL.md +288 -0
- package/bundled-skills/design-it/holographic-ui/SKILL.md +310 -0
- package/bundled-skills/design-it/isometric-design/SKILL.md +228 -0
- package/bundled-skills/design-it/layered-design/SKILL.md +247 -0
- package/bundled-skills/design-it/material-design/SKILL.md +275 -0
- package/bundled-skills/design-it/maximalism/SKILL.md +297 -0
- package/bundled-skills/design-it/minimalism/SKILL.md +267 -0
- package/bundled-skills/design-it/monochromatic-ui/SKILL.md +296 -0
- package/bundled-skills/design-it/neo-brutalism/SKILL.md +270 -0
- package/bundled-skills/design-it/neumorphism/SKILL.md +248 -0
- package/bundled-skills/design-it/retro-design/SKILL.md +283 -0
- package/bundled-skills/design-it/retro-futurism/SKILL.md +259 -0
- package/bundled-skills/design-it/sci-fi-interface/SKILL.md +309 -0
- package/bundled-skills/design-it/skeuomorphism/SKILL.md +280 -0
- package/bundled-skills/design-it/soft-pastel/SKILL.md +307 -0
- package/bundled-skills/design-it/spatial-computing-ui/SKILL.md +300 -0
- package/bundled-skills/design-it/spatial-design/SKILL.md +268 -0
- package/bundled-skills/design-it/swiss-design/SKILL.md +293 -0
- package/bundled-skills/design-it/synthwave/SKILL.md +257 -0
- package/bundled-skills/design-it/tile-design/SKILL.md +297 -0
- package/bundled-skills/design-it/typography-first/SKILL.md +247 -0
- package/bundled-skills/design-it/vaporwave/SKILL.md +331 -0
- package/bundled-skills/design-it/vibrant-maximalism/SKILL.md +291 -0
- package/bundled-skills/design-it/widget-based-design/SKILL.md +274 -0
- package/bundled-skills/design-it/y2k-design/SKILL.md +268 -0
- package/bundled-skills/diagnosing-bugs/SKILL.md +165 -0
- package/bundled-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/bundled-skills/docs/contributors/skill-scoring.md +235 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/getting-started.md +1 -1
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +4 -4
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/bundled-skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/bundled-skills/domain-modeling/SKILL.md +105 -0
- package/bundled-skills/grill-me/SKILL.md +36 -0
- package/bundled-skills/grill-with-docs/SKILL.md +36 -0
- package/bundled-skills/grilling/SKILL.md +39 -0
- package/bundled-skills/handoff/SKILL.md +45 -0
- package/bundled-skills/image-generator/.env.example +7 -0
- package/bundled-skills/image-generator/SKILL.md +509 -0
- package/bundled-skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
- package/bundled-skills/improve-codebase-architecture/SKILL.md +97 -0
- package/bundled-skills/learn/SKILL.md +156 -0
- package/bundled-skills/lesson-generator/SKILL.md +90 -0
- package/bundled-skills/llm-council/.env.example +7 -0
- package/bundled-skills/llm-council/SKILL.md +602 -0
- package/bundled-skills/loop-library/SKILL.md +205 -0
- package/bundled-skills/loop-library/agents/openai.yaml +4 -0
- package/bundled-skills/loop-library/references/catalog.md +270 -0
- package/bundled-skills/mailtrap-managing-contacts/SKILL.md +112 -0
- package/bundled-skills/mailtrap-sending-emails/SKILL.md +167 -0
- package/bundled-skills/mailtrap-setting-up-sending-domain/SKILL.md +77 -0
- package/bundled-skills/mailtrap-testing-with-sandbox/SKILL.md +110 -0
- package/bundled-skills/prototype/LOGIC.md +79 -0
- package/bundled-skills/prototype/SKILL.md +62 -0
- package/bundled-skills/prototype/UI.md +112 -0
- package/bundled-skills/setup-matt-pocock-skills/SKILL.md +158 -0
- package/bundled-skills/setup-matt-pocock-skills/domain.md +51 -0
- package/bundled-skills/setup-matt-pocock-skills/issue-tracker-github.md +34 -0
- package/bundled-skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +35 -0
- package/bundled-skills/setup-matt-pocock-skills/issue-tracker-local.md +19 -0
- package/bundled-skills/setup-matt-pocock-skills/triage-labels.md +15 -0
- package/bundled-skills/survey-generator/LICENSE +21 -0
- package/bundled-skills/survey-generator/SKILL.md +143 -0
- package/bundled-skills/survey-generator/build_artifact.py +208 -0
- package/bundled-skills/survey-generator/examples/agentic-engineering/research_bundle.json +1196 -0
- package/bundled-skills/survey-generator/examples/agentic-engineering/survey.html +706 -0
- package/bundled-skills/survey-generator/style_spec.json +85 -0
- package/bundled-skills/survey-generator/templates/research_bundle_template.json +69 -0
- package/bundled-skills/tdd/SKILL.md +139 -0
- package/bundled-skills/tdd/mocking.md +59 -0
- package/bundled-skills/tdd/refactoring.md +10 -0
- package/bundled-skills/tdd/tests.md +61 -0
- package/bundled-skills/teach/GLOSSARY-FORMAT.md +35 -0
- package/bundled-skills/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/bundled-skills/teach/MISSION-FORMAT.md +31 -0
- package/bundled-skills/teach/RESOURCES-FORMAT.md +32 -0
- package/bundled-skills/teach/SKILL.md +169 -0
- package/bundled-skills/to-issues/SKILL.md +115 -0
- package/bundled-skills/to-prd/SKILL.md +104 -0
- package/bundled-skills/tools-page-seo-optimizer/SKILL.md +616 -0
- package/bundled-skills/triage/AGENT-BRIEF.md +207 -0
- package/bundled-skills/triage/OUT-OF-SCOPE.md +105 -0
- package/bundled-skills/triage/SKILL.md +143 -0
- package/bundled-skills/vibecode-production-qa-validator/SKILL.md +371 -141
- package/bundled-skills/wiki-builder/SKILL.md +157 -0
- package/bundled-skills/wiki-builder/agents/openai.yaml +5 -0
- package/bundled-skills/wiki-builder/references/wiki-flavors.md +98 -0
- package/bundled-skills/wiki-builder/scripts/init_wiki.sh +105 -0
- package/bundled-skills/wiki-builder/templates/index.md +20 -0
- package/bundled-skills/wiki-builder/templates/maintenance-log.md +7 -0
- package/bundled-skills/wiki-builder/templates/prompts/compile-concept-page.md +12 -0
- package/bundled-skills/wiki-builder/templates/prompts/compile-index.md +11 -0
- package/bundled-skills/wiki-builder/templates/prompts/compile-source-page.md +12 -0
- package/bundled-skills/wiki-builder/templates/prompts/lint-wiki.md +10 -0
- package/bundled-skills/wiki-builder/templates/prompts/query-and-file.md +11 -0
- package/bundled-skills/wiki-builder/templates/sources.md +9 -0
- package/bundled-skills/wiki-builder/templates/wiki.config.md +53 -0
- package/bundled-skills/writing-great-skills/GLOSSARY.md +181 -0
- package/bundled-skills/writing-great-skills/SKILL.md +111 -0
- package/bundled-skills/yao-meta-skill/SKILL.md +86 -0
- package/bundled-skills/yao-meta-skill/agents/interface.yaml +26 -0
- package/bundled-skills/yao-meta-skill/manifest.json +24 -0
- package/bundled-skills/yao-meta-skill/references/artifact-design-doctrine.md +49 -0
- package/bundled-skills/yao-meta-skill/references/authoring-discipline.md +78 -0
- package/bundled-skills/yao-meta-skill/references/autonomous-adaptation.md +65 -0
- package/bundled-skills/yao-meta-skill/references/distribution-registry-method.md +60 -0
- package/bundled-skills/yao-meta-skill/references/eval-playbook.md +69 -0
- package/bundled-skills/yao-meta-skill/references/gate-selection.md +68 -0
- package/bundled-skills/yao-meta-skill/references/governance.md +134 -0
- package/bundled-skills/yao-meta-skill/references/human-review-template.md +54 -0
- package/bundled-skills/yao-meta-skill/references/intent-dialogue.md +138 -0
- package/bundled-skills/yao-meta-skill/references/iteration-philosophy.md +30 -0
- package/bundled-skills/yao-meta-skill/references/non-skill-decision-tree.md +39 -0
- package/bundled-skills/yao-meta-skill/references/operating-modes.md +107 -0
- package/bundled-skills/yao-meta-skill/references/output-eval-method.md +113 -0
- package/bundled-skills/yao-meta-skill/references/output-quality-risk.md +41 -0
- package/bundled-skills/yao-meta-skill/references/output-visual-quality.md +53 -0
- package/bundled-skills/yao-meta-skill/references/packaging-contracts.md +70 -0
- package/bundled-skills/yao-meta-skill/references/pattern-extraction-doctrine.md +76 -0
- package/bundled-skills/yao-meta-skill/references/platform-capability-matrix.md +49 -0
- package/bundled-skills/yao-meta-skill/references/prompt-engineering-doctrine.md +76 -0
- package/bundled-skills/yao-meta-skill/references/qa-ladder.md +57 -0
- package/bundled-skills/yao-meta-skill/references/reference-scan.md +126 -0
- package/bundled-skills/yao-meta-skill/references/regression-cause-taxonomy.md +80 -0
- package/bundled-skills/yao-meta-skill/references/resource-boundaries.md +120 -0
- package/bundled-skills/yao-meta-skill/references/review-studio-method.md +87 -0
- package/bundled-skills/yao-meta-skill/references/review-waiver-method.md +76 -0
- package/bundled-skills/yao-meta-skill/references/runtime-conformance-method.md +21 -0
- package/bundled-skills/yao-meta-skill/references/skill-archetypes.md +86 -0
- package/bundled-skills/yao-meta-skill/references/skill-atlas-method.md +35 -0
- package/bundled-skills/yao-meta-skill/references/skill-engineering-method.md +210 -0
- package/bundled-skills/yao-meta-skill/references/skill-ir-method.md +41 -0
- package/bundled-skills/yao-meta-skill/references/skillops-decision-policy.md +53 -0
- package/bundled-skills/yao-meta-skill/references/systems-thinking-doctrine.md +75 -0
- package/bundled-skills/yao-meta-skill/references/telemetry-drift-method.md +182 -0
- package/bundled-skills/yao-meta-skill/references/trust-security-method.md +79 -0
- package/bundled-skills/yao-meta-skill/references/user-memory-policy.md +35 -0
- package/bundled-skills/youtube-notetaker/SKILL.md +209 -0
- package/bundled-skills/youtube-notetaker/reference/artifact.html +269 -0
- package/bundled-skills/youtube-notetaker/scripts/contact_sheet.py +53 -0
- package/bundled-skills/youtube-notetaker/scripts/detect_slides.sh +19 -0
- package/bundled-skills/youtube-notetaker/scripts/download.sh +24 -0
- package/bundled-skills/youtube-notetaker/scripts/extract_slides.py +43 -0
- package/bundled-skills/youtube-notetaker/scripts/serve.py +173 -0
- package/bundled-skills/youtube-notetaker/scripts/setup.sh +27 -0
- package/bundled-skills/youtube-notetaker/scripts/verify.sh +31 -0
- package/bundled-skills/youtube-notetaker/scripts/vtt_to_transcript.py +59 -0
- package/bundled-skills/youtube-notetaker/scripts/write_library_item.py +69 -0
- package/package.json +1 -1
- package/skills_index.json +1956 -286
- package/bundled-skills/ai-md/SKILL.md +0 -523
- package/bundled-skills/atlas-contract/SKILL.md +0 -650
- package/bundled-skills/busybox-on-windows/SKILL.md +0 -40
- package/bundled-skills/monte-carlo-prevent/SKILL.md +0 -257
- package/bundled-skills/monte-carlo-prevent/references/TROUBLESHOOTING.md +0 -23
- package/bundled-skills/monte-carlo-prevent/references/parameters.md +0 -32
- package/bundled-skills/monte-carlo-prevent/references/workflows.md +0 -478
- package/bundled-skills/monte-carlo-push-ingestion/SKILL.md +0 -372
- package/bundled-skills/monte-carlo-push-ingestion/references/anomaly-detection.md +0 -87
- package/bundled-skills/monte-carlo-push-ingestion/references/custom-lineage.md +0 -203
- package/bundled-skills/monte-carlo-push-ingestion/references/direct-http-api.md +0 -207
- package/bundled-skills/monte-carlo-push-ingestion/references/prerequisites.md +0 -150
- package/bundled-skills/monte-carlo-push-ingestion/references/push-lineage.md +0 -160
- package/bundled-skills/monte-carlo-push-ingestion/references/push-metadata.md +0 -158
- package/bundled-skills/monte-carlo-push-ingestion/references/push-query-logs.md +0 -219
- package/bundled-skills/monte-carlo-push-ingestion/references/validation.md +0 -257
- package/bundled-skills/monte-carlo-push-ingestion/scripts/sample_verify.py +0 -357
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_and_push_lineage.py +0 -70
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_and_push_metadata.py +0 -65
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_and_push_query_logs.py +0 -70
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_lineage.py +0 -214
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_metadata.py +0 -160
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/collect_query_logs.py +0 -164
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/push_lineage.py +0 -198
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/push_metadata.py +0 -193
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery/push_query_logs.py +0 -207
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_and_push_metadata.py +0 -71
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_and_push_query_logs.py +0 -64
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_metadata.py +0 -253
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/collect_query_logs.py +0 -149
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/push_metadata.py +0 -190
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/bigquery-iceberg/push_query_logs.py +0 -208
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_and_push_lineage.py +0 -83
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_and_push_metadata.py +0 -77
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_and_push_query_logs.py +0 -83
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_lineage.py +0 -240
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_metadata.py +0 -212
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/collect_query_logs.py +0 -204
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/push_lineage.py +0 -192
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/push_metadata.py +0 -178
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/databricks/push_query_logs.py +0 -200
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_and_push_lineage.py +0 -119
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_and_push_metadata.py +0 -119
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_and_push_query_logs.py +0 -117
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_lineage.py +0 -265
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_metadata.py +0 -313
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/collect_query_logs.py +0 -284
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/push_lineage.py +0 -309
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/push_metadata.py +0 -245
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/hive/push_query_logs.py +0 -255
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_and_push_lineage.py +0 -78
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_and_push_metadata.py +0 -80
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_and_push_query_logs.py +0 -88
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_lineage.py +0 -235
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_metadata.py +0 -219
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/collect_query_logs.py +0 -239
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/push_lineage.py +0 -178
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/push_metadata.py +0 -178
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/redshift/push_query_logs.py +0 -196
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_and_push_lineage.py +0 -154
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_and_push_metadata.py +0 -137
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_and_push_query_logs.py +0 -137
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_lineage.py +0 -349
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_metadata.py +0 -329
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/collect_query_logs.py +0 -254
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/push_lineage.py +0 -307
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/push_metadata.py +0 -228
- package/bundled-skills/monte-carlo-push-ingestion/scripts/templates/snowflake/push_query_logs.py +0 -248
- package/bundled-skills/monte-carlo-push-ingestion/scripts/test_template_sdk_usage.py +0 -340
- package/bundled-skills/skill-optimizer/SKILL.md +0 -271
- package/bundled-skills/using-superpowers/SKILL.md +0 -98
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dark-mode
|
|
3
|
+
description: Web and App implementation guide for Dark Mode Design. Trigger when user wants dark surfaces, reduced eye strain, and premium sleek aesthetics.
|
|
4
|
+
date_added: "2026-06-17"
|
|
5
|
+
risk: safe
|
|
6
|
+
source: self
|
|
7
|
+
source_type: self
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Dark Mode Design
|
|
11
|
+
|
|
12
|
+
> "Not just inverted colors. A carefully constructed hierarchy of light on dark."
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
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.
|
|
17
|
+
|
|
18
|
+
## Core Principles
|
|
19
|
+
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`).
|
|
20
|
+
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.
|
|
21
|
+
3. **Desaturated Accents**: Saturated colors vibrate painfully against dark backgrounds. Tone down the saturation of brand colors.
|
|
22
|
+
|
|
23
|
+
## Visual DNA
|
|
24
|
+
- **Colors**: **Midnight Luxury** or **Minimalist Slate** (inverted). Background `#121212`. Elevated cards `#1E1E1E`, `#252525`. Primary text `#E1E1E1` (not `#FFFFFF`).
|
|
25
|
+
- **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.
|
|
26
|
+
- **Shadows**: Pure black shadows, but with much lower opacity, mostly to separate slightly different shades of grey.
|
|
27
|
+
|
|
28
|
+
## Web Implementation
|
|
29
|
+
- **CSS Example**:
|
|
30
|
+
```css
|
|
31
|
+
:root {
|
|
32
|
+
--bg-base: #121212;
|
|
33
|
+
--bg-elevated-1: #1E1E1E;
|
|
34
|
+
--bg-elevated-2: #242424;
|
|
35
|
+
--text-high-emphasis: rgba(255, 255, 255, 0.87);
|
|
36
|
+
--text-medium-emphasis: rgba(255, 255, 255, 0.60);
|
|
37
|
+
|
|
38
|
+
/* Accent color: Desaturated purple instead of bright purple */
|
|
39
|
+
--accent-color: #BB86FC;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
body {
|
|
43
|
+
background-color: var(--bg-base);
|
|
44
|
+
color: var(--text-high-emphasis);
|
|
45
|
+
font-weight: 300; /* Thinner weight for dark mode */
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.dark-card {
|
|
49
|
+
background-color: var(--bg-elevated-1);
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
padding: 24px;
|
|
52
|
+
|
|
53
|
+
/* Very subtle border can help separate dark surfaces */
|
|
54
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.dark-card:hover {
|
|
58
|
+
/* On hover, the element moves closer to the user, so it gets lighter */
|
|
59
|
+
background-color: var(--bg-elevated-2);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.dark-btn {
|
|
63
|
+
background-color: var(--accent-color);
|
|
64
|
+
color: #000; /* Dark text on light accent is highly readable */
|
|
65
|
+
font-weight: 600;
|
|
66
|
+
border: none;
|
|
67
|
+
padding: 12px 24px;
|
|
68
|
+
border-radius: 4px;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## App Implementation
|
|
73
|
+
|
|
74
|
+
### SwiftUI
|
|
75
|
+
```swift
|
|
76
|
+
struct DarkModeView: View {
|
|
77
|
+
// Force Dark Mode on this specific view (or use system settings)
|
|
78
|
+
@Environment(\.colorScheme) var colorScheme
|
|
79
|
+
|
|
80
|
+
var body: some View {
|
|
81
|
+
ScrollView {
|
|
82
|
+
VStack(spacing: 20) {
|
|
83
|
+
// Primary elevated card
|
|
84
|
+
VStack(alignment: .leading, spacing: 12) {
|
|
85
|
+
Text("Elevation via Lightness")
|
|
86
|
+
.font(.headline)
|
|
87
|
+
.foregroundColor(.primary) // Auto-adapts
|
|
88
|
+
Text("In dark mode, elevated surfaces are lighter grey, not shadowed.")
|
|
89
|
+
.font(.subheadline)
|
|
90
|
+
.foregroundColor(.secondary) // Auto-adapts
|
|
91
|
+
}
|
|
92
|
+
.padding()
|
|
93
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
94
|
+
// Use native semantic colors. .secondarySystemBackground is lighter than .systemBackground
|
|
95
|
+
.background(Color(UIColor.secondarySystemBackground))
|
|
96
|
+
.cornerRadius(12)
|
|
97
|
+
|
|
98
|
+
// Desaturated Accent Button
|
|
99
|
+
Button(action: {}) {
|
|
100
|
+
Text("Desaturated Accent")
|
|
101
|
+
.fontWeight(.semibold)
|
|
102
|
+
.foregroundColor(.black) // Dark text on light accent
|
|
103
|
+
.padding()
|
|
104
|
+
.frame(maxWidth: .infinity)
|
|
105
|
+
.background(Color(red: 0.73, green: 0.52, blue: 0.98)) // #BB86FC (Desaturated purple)
|
|
106
|
+
.cornerRadius(8)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
.padding()
|
|
110
|
+
}
|
|
111
|
+
// #121212 is the standard dark mode background, which systemBackground maps to closely
|
|
112
|
+
.background(Color(UIColor.systemBackground))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// .preferredColorScheme(.dark) to force
|
|
116
|
+
```
|
|
117
|
+
- **Rely on Semantics**: SwiftUI's `Color.primary`, `Color.secondary`, `Color(UIColor.systemBackground)` and `Color(UIColor.secondarySystemBackground)` handle perfect dark mode transitions automatically.
|
|
118
|
+
- Avoid forcing explicit hex codes for backgrounds unless you are building a custom-themed app.
|
|
119
|
+
|
|
120
|
+
### Flutter
|
|
121
|
+
```dart
|
|
122
|
+
import 'package:flutter/material.dart';
|
|
123
|
+
|
|
124
|
+
class DarkModeApp extends StatelessWidget {
|
|
125
|
+
@override
|
|
126
|
+
Widget build(BuildContext context) {
|
|
127
|
+
return MaterialApp(
|
|
128
|
+
// Configure the Dark Theme
|
|
129
|
+
themeMode: ThemeMode.dark,
|
|
130
|
+
darkTheme: ThemeData.dark().copyWith(
|
|
131
|
+
scaffoldBackgroundColor: const Color(0xFF121212), // Standard dark background
|
|
132
|
+
cardColor: const Color(0xFF1E1E1E), // Elevated surface
|
|
133
|
+
colorScheme: const ColorScheme.dark().copyWith(
|
|
134
|
+
primary: const Color(0xFFBB86FC), // Desaturated accent
|
|
135
|
+
onPrimary: Colors.black, // Dark text on light accent
|
|
136
|
+
surface: const Color(0xFF1E1E1E),
|
|
137
|
+
),
|
|
138
|
+
),
|
|
139
|
+
home: Scaffold(
|
|
140
|
+
appBar: AppBar(title: const Text('Dark Mode', style: TextStyle(color: Colors.white70))),
|
|
141
|
+
body: ListView(
|
|
142
|
+
padding: const EdgeInsets.all(16),
|
|
143
|
+
children: [
|
|
144
|
+
Card(
|
|
145
|
+
elevation: 0, // Shadows don't show well anyway
|
|
146
|
+
shape: RoundedRectangleBorder(
|
|
147
|
+
borderRadius: BorderRadius.circular(12),
|
|
148
|
+
side: BorderSide(color: Colors.white.withOpacity(0.05)), // Subtle border
|
|
149
|
+
),
|
|
150
|
+
child: const Padding(
|
|
151
|
+
padding: EdgeInsets.all(16.0),
|
|
152
|
+
child: Column(
|
|
153
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
154
|
+
children: [
|
|
155
|
+
Text('Elevation via Lightness', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
|
156
|
+
SizedBox(height: 8),
|
|
157
|
+
Text('Elevated surfaces use lighter greys.', style: TextStyle(color: Colors.white60)),
|
|
158
|
+
],
|
|
159
|
+
),
|
|
160
|
+
),
|
|
161
|
+
),
|
|
162
|
+
const SizedBox(height: 20),
|
|
163
|
+
ElevatedButton(
|
|
164
|
+
onPressed: () {},
|
|
165
|
+
child: const Text('Desaturated Accent'),
|
|
166
|
+
),
|
|
167
|
+
],
|
|
168
|
+
),
|
|
169
|
+
),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
- When using `ThemeData.dark()`, actively override `scaffoldBackgroundColor` to `#121212` and `cardColor` to `#1E1E1E`.
|
|
175
|
+
- Ensure your `colorScheme.onPrimary` is black so text is readable when placed on top of your desaturated primary accent button.
|
|
176
|
+
|
|
177
|
+
### React Native
|
|
178
|
+
```jsx
|
|
179
|
+
import { useColorScheme } from 'react-native';
|
|
180
|
+
|
|
181
|
+
const DarkModeScreen = () => {
|
|
182
|
+
const isDark = useColorScheme() === 'dark';
|
|
183
|
+
|
|
184
|
+
// Custom dark theme dictionary
|
|
185
|
+
const theme = {
|
|
186
|
+
bgBase: isDark ? '#121212' : '#FFFFFF',
|
|
187
|
+
bgElevated: isDark ? '#1E1E1E' : '#F5F5F5',
|
|
188
|
+
textHigh: isDark ? 'rgba(255, 255, 255, 0.87)' : 'rgba(0, 0, 0, 0.87)',
|
|
189
|
+
textMedium: isDark ? 'rgba(255, 255, 255, 0.60)' : 'rgba(0, 0, 0, 0.60)',
|
|
190
|
+
accent: isDark ? '#BB86FC' : '#6200EE', // Desaturated for dark, vibrant for light
|
|
191
|
+
onAccent: isDark ? '#000' : '#FFF',
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<View style={{ flex: 1, backgroundColor: theme.bgBase, padding: 16 }}>
|
|
196
|
+
<View style={{
|
|
197
|
+
backgroundColor: theme.bgElevated,
|
|
198
|
+
padding: 24,
|
|
199
|
+
borderRadius: 12,
|
|
200
|
+
borderWidth: isDark ? 1 : 0,
|
|
201
|
+
borderColor: 'rgba(255,255,255,0.05)',
|
|
202
|
+
marginBottom: 20
|
|
203
|
+
}}>
|
|
204
|
+
<Text style={{ color: theme.textHigh, fontSize: 18, fontWeight: 'bold', marginBottom: 8 }}>
|
|
205
|
+
Elevation via Lightness
|
|
206
|
+
</Text>
|
|
207
|
+
<Text style={{ color: theme.textMedium }}>
|
|
208
|
+
Elevated surfaces use lighter greys.
|
|
209
|
+
</Text>
|
|
210
|
+
</View>
|
|
211
|
+
|
|
212
|
+
<TouchableOpacity style={{
|
|
213
|
+
backgroundColor: theme.accent,
|
|
214
|
+
padding: 16,
|
|
215
|
+
borderRadius: 8,
|
|
216
|
+
alignItems: 'center'
|
|
217
|
+
}}>
|
|
218
|
+
<Text style={{ color: theme.onAccent, fontWeight: 'bold' }}>Desaturated Accent</Text>
|
|
219
|
+
</TouchableOpacity>
|
|
220
|
+
</View>
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
```
|
|
224
|
+
- Rely on `useColorScheme()` hook from React Native.
|
|
225
|
+
- 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.
|
|
226
|
+
|
|
227
|
+
### Jetpack Compose
|
|
228
|
+
```kotlin
|
|
229
|
+
@Composable
|
|
230
|
+
fun DarkModeScreen() {
|
|
231
|
+
// Typically this logic lives in your Theme.kt
|
|
232
|
+
val darkColors = darkColorScheme(
|
|
233
|
+
background = Color(0xFF121212),
|
|
234
|
+
surface = Color(0xFF1E1E1E),
|
|
235
|
+
primary = Color(0xFFBB86FC),
|
|
236
|
+
onPrimary = Color.Black,
|
|
237
|
+
onBackground = Color.White.copy(alpha = 0.87f),
|
|
238
|
+
onSurface = Color.White.copy(alpha = 0.87f)
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
MaterialTheme(colorScheme = darkColors) {
|
|
242
|
+
Column(
|
|
243
|
+
modifier = Modifier
|
|
244
|
+
.fillMaxSize()
|
|
245
|
+
.background(MaterialTheme.colorScheme.background)
|
|
246
|
+
.padding(16.dp)
|
|
247
|
+
) {
|
|
248
|
+
Card(
|
|
249
|
+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
|
|
250
|
+
shape = RoundedCornerShape(12.dp),
|
|
251
|
+
border = BorderStroke(1.dp, Color.White.copy(alpha = 0.05f))
|
|
252
|
+
) {
|
|
253
|
+
Column(modifier = Modifier.padding(24.dp)) {
|
|
254
|
+
Text("Elevation via Lightness",
|
|
255
|
+
style = MaterialTheme.typography.titleMedium,
|
|
256
|
+
color = MaterialTheme.colorScheme.onSurface)
|
|
257
|
+
Spacer(Modifier.height(8.dp))
|
|
258
|
+
Text("Elevated surfaces use lighter greys.",
|
|
259
|
+
style = MaterialTheme.typography.bodyMedium,
|
|
260
|
+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f))
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
Spacer(Modifier.height(20.dp))
|
|
265
|
+
|
|
266
|
+
Button(
|
|
267
|
+
onClick = {},
|
|
268
|
+
colors = ButtonDefaults.buttonColors(
|
|
269
|
+
containerColor = MaterialTheme.colorScheme.primary,
|
|
270
|
+
contentColor = MaterialTheme.colorScheme.onPrimary
|
|
271
|
+
),
|
|
272
|
+
modifier = Modifier.fillMaxWidth().height(50.dp)
|
|
273
|
+
) {
|
|
274
|
+
Text("Desaturated Accent", fontWeight = FontWeight.Bold)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
- Material 3 handles Dark Mode semantics perfectly. Define your `darkColorScheme`.
|
|
281
|
+
- Use `Color(0xFF1E1E1E)` for `surface` and `Color(0xFF121212)` for `background`. Compose will automatically map these to `Card`s and Scaffolds.
|
|
282
|
+
|
|
283
|
+
## Do's and Don'ts
|
|
284
|
+
- **DO**: Meet WCAG contrast standards. Just because it's dark doesn't mean the text should be illegibly dim.
|
|
285
|
+
- **DON'T**: Use bright, highly saturated primary colors.
|
|
286
|
+
|
|
287
|
+
## Limitations
|
|
288
|
+
- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
|
|
289
|
+
- Ensure appropriate contrast ratios and responsive behaviors are verified separately.
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dashboard-design
|
|
3
|
+
description: Web and App implementation guide for Dashboard Design. Trigger when user wants analytics-focused layouts, data visualization, and modular overview screens.
|
|
4
|
+
date_added: "2026-06-17"
|
|
5
|
+
risk: safe
|
|
6
|
+
source: self
|
|
7
|
+
source_type: self
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Dashboard Design
|
|
11
|
+
|
|
12
|
+
> "Data at a glance. Organized, scannable, and highly functional."
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
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.
|
|
17
|
+
|
|
18
|
+
## Core Principles
|
|
19
|
+
1. **Modular Grid**: The screen is broken down into functional "widgets" or cards. Usually a sidebar on the left and a top nav.
|
|
20
|
+
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.
|
|
21
|
+
3. **Muted Backgrounds**: A soft grey or off-white background so the white data cards stand out clearly.
|
|
22
|
+
|
|
23
|
+
## Visual DNA
|
|
24
|
+
- **Colors**: **Minimalist Slate** or **Earth-Grounded Elegance**. Avoid too many colors. Use red/green strictly for positive/negative trends.
|
|
25
|
+
- **Typography**: Clean, tabular sans-serifs (`Inter`, `Roboto Mono` for numbers).
|
|
26
|
+
- **Styling**: Very subtle shadows or 1px borders to separate cards.
|
|
27
|
+
|
|
28
|
+
## Web Implementation
|
|
29
|
+
- Use CSS Grid for the macro layout (Sidebar, Header, Main).
|
|
30
|
+
- **CSS Example**:
|
|
31
|
+
```css
|
|
32
|
+
body {
|
|
33
|
+
background-color: #F8F9FA;
|
|
34
|
+
color: #212529;
|
|
35
|
+
font-family: 'Inter', sans-serif;
|
|
36
|
+
margin: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.dashboard-layout {
|
|
40
|
+
display: grid;
|
|
41
|
+
grid-template-columns: 250px 1fr;
|
|
42
|
+
grid-template-rows: 70px 1fr;
|
|
43
|
+
height: 100vh;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sidebar {
|
|
47
|
+
grid-row: 1 / 3;
|
|
48
|
+
background-color: #ffffff;
|
|
49
|
+
border-right: 1px solid #e9ecef;
|
|
50
|
+
padding: 20px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.header {
|
|
54
|
+
background-color: #ffffff;
|
|
55
|
+
border-bottom: 1px solid #e9ecef;
|
|
56
|
+
padding: 0 30px;
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.main-content {
|
|
62
|
+
padding: 30px;
|
|
63
|
+
display: grid;
|
|
64
|
+
grid-template-columns: repeat(4, 1fr);
|
|
65
|
+
gap: 20px;
|
|
66
|
+
overflow-y: auto;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* KPI Card */
|
|
70
|
+
.kpi-card {
|
|
71
|
+
background: #fff;
|
|
72
|
+
border-radius: 8px;
|
|
73
|
+
padding: 24px;
|
|
74
|
+
border: 1px solid #e9ecef;
|
|
75
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.02);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.kpi-title { font-size: 0.9rem; color: #6c757d; }
|
|
79
|
+
.kpi-value { font-size: 2rem; font-weight: 700; margin-top: 8px; }
|
|
80
|
+
.kpi-trend.positive { color: #28a745; }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## App Implementation
|
|
84
|
+
|
|
85
|
+
### SwiftUI
|
|
86
|
+
```swift
|
|
87
|
+
struct DashboardView: View {
|
|
88
|
+
// For iPad/Mac, NavigationSplitView is ideal.
|
|
89
|
+
// For iPhone, we use a scrolling VGrid.
|
|
90
|
+
let columns = [
|
|
91
|
+
GridItem(.adaptive(minimum: 150), spacing: 16)
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
var body: some View {
|
|
95
|
+
NavigationView {
|
|
96
|
+
ScrollView {
|
|
97
|
+
LazyVGrid(columns: columns, spacing: 16) {
|
|
98
|
+
KPICard(title: "Revenue", value: "$45,231", trend: "+12.5%", isPositive: true)
|
|
99
|
+
KPICard(title: "Active Users", value: "2,405", trend: "+4.1%", isPositive: true)
|
|
100
|
+
KPICard(title: "Churn Rate", value: "1.2%", trend: "-0.4%", isPositive: false)
|
|
101
|
+
KPICard(title: "Avg. Session", value: "4m 12s", trend: "+0.1%", isPositive: true)
|
|
102
|
+
}
|
|
103
|
+
.padding()
|
|
104
|
+
|
|
105
|
+
// Placeholder for Chart
|
|
106
|
+
RoundedRectangle(cornerRadius: 12)
|
|
107
|
+
.fill(Color.white)
|
|
108
|
+
.frame(height: 250)
|
|
109
|
+
.overlay(Text("Chart Area").foregroundColor(.gray))
|
|
110
|
+
.padding(.horizontal)
|
|
111
|
+
}
|
|
112
|
+
.background(Color(UIColor.systemGroupedBackground))
|
|
113
|
+
.navigationTitle("Overview")
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
struct KPICard: View {
|
|
119
|
+
let title: String
|
|
120
|
+
let value: String
|
|
121
|
+
let trend: String
|
|
122
|
+
let isPositive: Bool
|
|
123
|
+
|
|
124
|
+
var body: some View {
|
|
125
|
+
VStack(alignment: .leading, spacing: 8) {
|
|
126
|
+
Text(title).font(.subheadline).foregroundColor(.secondary)
|
|
127
|
+
Text(value).font(.title2).fontWeight(.bold)
|
|
128
|
+
Text(trend)
|
|
129
|
+
.font(.caption)
|
|
130
|
+
.fontWeight(.semibold)
|
|
131
|
+
.foregroundColor(isPositive ? .green : .red)
|
|
132
|
+
}
|
|
133
|
+
.padding()
|
|
134
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
135
|
+
.background(Color.white)
|
|
136
|
+
.cornerRadius(12)
|
|
137
|
+
.shadow(color: Color.black.opacity(0.02), radius: 4, y: 2)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
- Dashboards require `.adaptive` grids. `LazyVGrid` handles rearranging 4 cards in a row on iPad down to 2 cards on iPhone automatically.
|
|
142
|
+
- Use `Color(UIColor.systemGroupedBackground)` to provide that subtle off-white contrast against stark white cards.
|
|
143
|
+
|
|
144
|
+
### Flutter
|
|
145
|
+
```dart
|
|
146
|
+
class DashboardScreen extends StatelessWidget {
|
|
147
|
+
@override
|
|
148
|
+
Widget build(BuildContext context) {
|
|
149
|
+
return Scaffold(
|
|
150
|
+
backgroundColor: const Color(0xFFF8F9FA),
|
|
151
|
+
appBar: AppBar(
|
|
152
|
+
title: const Text('Overview', style: TextStyle(color: Colors.black)),
|
|
153
|
+
backgroundColor: Colors.white,
|
|
154
|
+
elevation: 1,
|
|
155
|
+
),
|
|
156
|
+
// On tablets, use a Row with NavigationRail. On mobile, use Drawer.
|
|
157
|
+
drawer: const Drawer(),
|
|
158
|
+
body: CustomScrollView(
|
|
159
|
+
slivers: [
|
|
160
|
+
SliverPadding(
|
|
161
|
+
padding: const EdgeInsets.all(16),
|
|
162
|
+
sliver: SliverGrid.extent(
|
|
163
|
+
maxCrossAxisExtent: 200, // Adapts layout based on width
|
|
164
|
+
mainAxisSpacing: 16,
|
|
165
|
+
crossAxisSpacing: 16,
|
|
166
|
+
childAspectRatio: 1.5,
|
|
167
|
+
children: [
|
|
168
|
+
_buildKPI('Revenue', '\$45,231', '+12.5%', true),
|
|
169
|
+
_buildKPI('Active Users', '2,405', '+4.1%', true),
|
|
170
|
+
_buildKPI('Churn Rate', '1.2%', '-0.4%', false),
|
|
171
|
+
_buildKPI('Avg. Session', '4m 12s', '+0.1%', true),
|
|
172
|
+
],
|
|
173
|
+
),
|
|
174
|
+
),
|
|
175
|
+
SliverPadding(
|
|
176
|
+
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
177
|
+
sliver: SliverToBoxAdapter(
|
|
178
|
+
child: Container(
|
|
179
|
+
height: 250,
|
|
180
|
+
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)),
|
|
181
|
+
child: const Center(child: Text('Chart Area', style: TextStyle(color: Colors.grey))),
|
|
182
|
+
),
|
|
183
|
+
),
|
|
184
|
+
),
|
|
185
|
+
],
|
|
186
|
+
),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
Widget _buildKPI(String title, String value, String trend, bool isPositive) {
|
|
191
|
+
return Container(
|
|
192
|
+
padding: const EdgeInsets.all(16),
|
|
193
|
+
decoration: BoxDecoration(
|
|
194
|
+
color: Colors.white,
|
|
195
|
+
borderRadius: BorderRadius.circular(12),
|
|
196
|
+
border: Border.all(color: Colors.grey[200]!),
|
|
197
|
+
),
|
|
198
|
+
child: Column(
|
|
199
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
200
|
+
mainAxisAlignment: MainAxisAlignment.center,
|
|
201
|
+
children: [
|
|
202
|
+
Text(title, style: const TextStyle(color: Colors.grey, fontSize: 14)),
|
|
203
|
+
const SizedBox(height: 8),
|
|
204
|
+
Text(value, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
|
|
205
|
+
Text(trend, style: TextStyle(color: isPositive ? Colors.green : Colors.red, fontWeight: FontWeight.w600)),
|
|
206
|
+
],
|
|
207
|
+
),
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
- `SliverGrid.extent` with a `maxCrossAxisExtent` is the responsive magic bullet for Flutter dashboards. It handles varying screen widths flawlessly.
|
|
213
|
+
- For charts, the `fl_chart` package is the gold standard in Flutter.
|
|
214
|
+
|
|
215
|
+
### React Native
|
|
216
|
+
```jsx
|
|
217
|
+
const DashboardScreen = () => {
|
|
218
|
+
return (
|
|
219
|
+
<ScrollView style={{ flex: 1, backgroundColor: '#F8F9FA' }}>
|
|
220
|
+
<View style={{ padding: 16, flexDirection: 'row', flexWrap: 'wrap', gap: 16 }}>
|
|
221
|
+
<KPICard title="Revenue" value="$45,231" trend="+12.5%" isPositive={true} />
|
|
222
|
+
<KPICard title="Users" value="2,405" trend="+4.1%" isPositive={true} />
|
|
223
|
+
<KPICard title="Churn" value="1.2%" trend="-0.4%" isPositive={false} />
|
|
224
|
+
<KPICard title="Session" value="4m 12s" trend="+0.1%" isPositive={true} />
|
|
225
|
+
</View>
|
|
226
|
+
|
|
227
|
+
<View style={{ paddingHorizontal: 16, paddingBottom: 32 }}>
|
|
228
|
+
<View style={{ height: 250, backgroundColor: '#FFF', borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}>
|
|
229
|
+
<Text style={{ color: '#999' }}>Chart Area</Text>
|
|
230
|
+
</View>
|
|
231
|
+
</View>
|
|
232
|
+
</ScrollView>
|
|
233
|
+
);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const KPICard = ({ title, value, trend, isPositive }) => (
|
|
237
|
+
<View style={{
|
|
238
|
+
backgroundColor: '#FFF',
|
|
239
|
+
padding: 16,
|
|
240
|
+
borderRadius: 8,
|
|
241
|
+
borderWidth: 1,
|
|
242
|
+
borderColor: '#E9ECEF',
|
|
243
|
+
flexBasis: '47%', // roughly half width minus gap
|
|
244
|
+
minWidth: 150
|
|
245
|
+
}}>
|
|
246
|
+
<Text style={{ color: '#6C757D', fontSize: 14, marginBottom: 4 }}>{title}</Text>
|
|
247
|
+
<Text style={{ fontSize: 22, fontWeight: '700', marginBottom: 4 }}>{value}</Text>
|
|
248
|
+
<Text style={{ color: isPositive ? '#28A745' : '#DC3545', fontWeight: '600', fontSize: 12 }}>{trend}</Text>
|
|
249
|
+
</View>
|
|
250
|
+
);
|
|
251
|
+
```
|
|
252
|
+
- To make responsive flex grids in React Native, use `flexDirection: 'row'`, `flexWrap: 'wrap'`, and set the children to `flexBasis: '47%'`.
|
|
253
|
+
- For heavy data visualization, look into `victory-native` or `@shopify/react-native-skia`.
|
|
254
|
+
|
|
255
|
+
### Jetpack Compose
|
|
256
|
+
```kotlin
|
|
257
|
+
@Composable
|
|
258
|
+
fun DashboardScreen() {
|
|
259
|
+
Column(
|
|
260
|
+
modifier = Modifier
|
|
261
|
+
.fillMaxSize()
|
|
262
|
+
.background(Color(0xFFF8F9FA))
|
|
263
|
+
.verticalScroll(rememberScrollState())
|
|
264
|
+
) {
|
|
265
|
+
// Top App Bar substitute
|
|
266
|
+
Text(
|
|
267
|
+
text = "Overview",
|
|
268
|
+
style = MaterialTheme.typography.headlineSmall,
|
|
269
|
+
fontWeight = FontWeight.Bold,
|
|
270
|
+
modifier = Modifier.padding(16.dp)
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
// KPI Grid
|
|
274
|
+
LazyVerticalGrid(
|
|
275
|
+
columns = GridCells.Adaptive(minSize = 150.dp),
|
|
276
|
+
contentPadding = PaddingValues(horizontal = 16.dp),
|
|
277
|
+
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
|
278
|
+
verticalArrangement = Arrangement.spacedBy(16.dp),
|
|
279
|
+
modifier = Modifier.heightIn(max = 400.dp) // Bound the grid height in scrollview
|
|
280
|
+
) {
|
|
281
|
+
item { KPICard("Revenue", "$45,231", "+12.5%", true) }
|
|
282
|
+
item { KPICard("Active Users", "2,405", "+4.1%", true) }
|
|
283
|
+
item { KPICard("Churn Rate", "1.2%", "-0.4%", false) }
|
|
284
|
+
item { KPICard("Avg. Session", "4m 12s", "+0.1%", true) }
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
Spacer(Modifier.height(16.dp))
|
|
288
|
+
|
|
289
|
+
// Chart Area
|
|
290
|
+
Box(
|
|
291
|
+
modifier = Modifier
|
|
292
|
+
.fillMaxWidth()
|
|
293
|
+
.padding(horizontal = 16.dp)
|
|
294
|
+
.height(250.dp)
|
|
295
|
+
.background(Color.White, RoundedCornerShape(12.dp))
|
|
296
|
+
.border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(12.dp)),
|
|
297
|
+
contentAlignment = Alignment.Center
|
|
298
|
+
) {
|
|
299
|
+
Text("Chart Area", color = Color.Gray)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
Spacer(Modifier.height(32.dp))
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
@Composable
|
|
307
|
+
fun KPICard(title: String, value: String, trend: String, isPositive: Boolean) {
|
|
308
|
+
Column(
|
|
309
|
+
modifier = Modifier
|
|
310
|
+
.background(Color.White, RoundedCornerShape(8.dp))
|
|
311
|
+
.border(1.dp, Color(0xFFE9ECEF), RoundedCornerShape(8.dp))
|
|
312
|
+
.padding(16.dp)
|
|
313
|
+
) {
|
|
314
|
+
Text(title, color = Color.Gray, fontSize = 14.sp)
|
|
315
|
+
Spacer(Modifier.height(4.dp))
|
|
316
|
+
Text(value, fontSize = 22.sp, fontWeight = FontWeight.Bold)
|
|
317
|
+
Spacer(Modifier.height(4.dp))
|
|
318
|
+
Text(trend, color = if (isPositive) Color(0xFF28A745) else Color(0xFFDC3545), fontWeight = FontWeight.SemiBold, fontSize = 12.sp)
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
- `GridCells.Adaptive(minSize = 150.dp)` creates the responsive card layout automatically.
|
|
323
|
+
- 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.
|
|
324
|
+
|
|
325
|
+
## Do's and Don'ts
|
|
326
|
+
- **DO**: Right-align numbers in tables so they are easier to scan and compare.
|
|
327
|
+
- **DON'T**: Clutter cards with unnecessary decorative images. The data is the decoration.
|
|
328
|
+
|
|
329
|
+
## Limitations
|
|
330
|
+
- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
|
|
331
|
+
- Ensure appropriate contrast ratios and responsive behaviors are verified separately.
|