zugzbot 1.0.21 → 1.0.22
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/.opencode/agents/sdd-coder.md +1 -0
- package/.opencode/agents/sdd-orchestrator.md +1 -0
- package/.opencode/skills/sdd-methodology/SKILL.md +8 -0
- package/.opencode/skills/sdd-tester-quickstart/SKILL.md +6 -0
- package/.opencode/tools/sdd_testing.ts +93 -0
- package/opencode.json +8 -0
- package/package.json +14 -4
- package/.opencode/active-brief.md +0 -38
- package/.opencode/docs/shadcn/agents/openai.yml +0 -5
- package/.opencode/docs/shadcn/assets/shadcn-small.png +0 -0
- package/.opencode/docs/shadcn/assets/shadcn.png +0 -0
- package/.opencode/docs/shadcn/cli.md +0 -290
- package/.opencode/docs/shadcn/customization.md +0 -209
- package/.opencode/docs/shadcn/evals/evals.json +0 -47
- package/.opencode/docs/shadcn/mcp.md +0 -105
- package/.opencode/docs/shadcn/registry.md +0 -277
- package/.opencode/docs/shadcn/rules/base-vs-radix.md +0 -306
- package/.opencode/docs/shadcn/rules/composition.md +0 -195
- package/.opencode/docs/shadcn/rules/forms.md +0 -192
- package/.opencode/docs/shadcn/rules/icons.md +0 -101
- package/.opencode/docs/shadcn/rules/styling.md +0 -162
- package/.opencode/oh-my-design/.agents/skills/google-analytics/EXAMPLES.md +0 -441
- package/.opencode/oh-my-design/.agents/skills/google-analytics/REFERENCE.md +0 -342
- package/.opencode/oh-my-design/.agents/skills/google-analytics/SKILL.md +0 -153
- package/.opencode/oh-my-design/.agents/skills/google-analytics/requirements.txt +0 -6
- package/.opencode/oh-my-design/.agents/skills/google-analytics/scripts/analyze.py +0 -459
- package/.opencode/oh-my-design/.agents/skills/google-analytics/scripts/ga_client.py +0 -345
- package/.opencode/oh-my-design/.claude/agents/omd-a11y-auditor.md +0 -98
- package/.opencode/oh-my-design/.claude/agents/omd-asset-curator.md +0 -99
- package/.opencode/oh-my-design/.claude/agents/omd-codex-image.md +0 -49
- package/.opencode/oh-my-design/.claude/agents/omd-critic.md +0 -142
- package/.opencode/oh-my-design/.claude/agents/omd-designer-review.md +0 -38
- package/.opencode/oh-my-design/.claude/agents/omd-final-qa.md +0 -40
- package/.opencode/oh-my-design/.claude/agents/omd-kr-writer.md +0 -35
- package/.opencode/oh-my-design/.claude/agents/omd-locale-adapter.md +0 -32
- package/.opencode/oh-my-design/.claude/agents/omd-master.md +0 -317
- package/.opencode/oh-my-design/.claude/agents/omd-microcopy.md +0 -64
- package/.opencode/oh-my-design/.claude/agents/omd-orchestrator.md +0 -34
- package/.opencode/oh-my-design/.claude/agents/omd-persona-tester.md +0 -119
- package/.opencode/oh-my-design/.claude/agents/omd-ui-junior.md +0 -130
- package/.opencode/oh-my-design/.claude/agents/omd-ux-researcher.md +0 -63
- package/.opencode/oh-my-design/.claude/data/opt-out-corpus.json +0 -141
- package/.opencode/oh-my-design/.claude/data/reference-fingerprints.json +0 -6142
- package/.opencode/oh-my-design/.claude/data/reference-tags.md +0 -104
- package/.opencode/oh-my-design/.claude/data/synonyms.json +0 -79
- package/.opencode/oh-my-design/.claude/data/vocabulary.json +0 -516
- package/.opencode/oh-my-design/.claude/hooks/lib/preferences-parser.cjs +0 -91
- package/.opencode/oh-my-design/.claude/hooks/lib/preferences-writer.cjs +0 -118
- package/.opencode/oh-my-design/.claude/hooks/post-edit-watch.cjs +0 -295
- package/.opencode/oh-my-design/.claude/hooks/session-end-foldin.cjs +0 -149
- package/.opencode/oh-my-design/.claude/hooks/session-state-loader.cjs +0 -113
- package/.opencode/oh-my-design/.claude/hooks/skill-activation.cjs +0 -108
- package/.opencode/oh-my-design/.claude/settings.json +0 -55
- package/.opencode/oh-my-design/.claude/skills/omd/SKILL.md +0 -133
- package/.opencode/oh-my-design/.claude/skills/omd-add-reference/SKILL.md +0 -381
- package/.opencode/oh-my-design/.claude/skills/omd-add-reference/batch-instructions.md +0 -111
- package/.opencode/oh-my-design/.claude/skills/omd-apply/SKILL.md +0 -87
- package/.opencode/oh-my-design/.claude/skills/omd-batch-launch/SKILL.md +0 -270
- package/.opencode/oh-my-design/.claude/skills/omd-codex-image/SKILL.md +0 -162
- package/.opencode/oh-my-design/.claude/skills/omd-component-harvest/SKILL.md +0 -59
- package/.opencode/oh-my-design/.claude/skills/omd-designer-review/SKILL.md +0 -146
- package/.opencode/oh-my-design/.claude/skills/omd-final-qa/SKILL.md +0 -153
- package/.opencode/oh-my-design/.claude/skills/omd-harness/SKILL.md +0 -234
- package/.opencode/oh-my-design/.claude/skills/omd-init/SKILL.md +0 -169
- package/.opencode/oh-my-design/.claude/skills/omd-kr-writer/SKILL.md +0 -229
- package/.opencode/oh-my-design/.claude/skills/omd-lab-01-designmd-impact/SKILL.md +0 -53
- package/.opencode/oh-my-design/.claude/skills/omd-lab-01-designmd-impact/playbooks/compare.md +0 -30
- package/.opencode/oh-my-design/.claude/skills/omd-lab-01-designmd-impact/playbooks/v1.md +0 -42
- package/.opencode/oh-my-design/.claude/skills/omd-lab-01-designmd-impact/playbooks/v2.md +0 -34
- package/.opencode/oh-my-design/.claude/skills/omd-lab-01-designmd-impact/playbooks/v3.md +0 -33
- package/.opencode/oh-my-design/.claude/skills/omd-lab-01-designmd-impact/playbooks/v4.md +0 -37
- package/.opencode/oh-my-design/.claude/skills/omd-lab-02-design-harness/SKILL.md +0 -131
- package/.opencode/oh-my-design/.claude/skills/omd-learn/SKILL.md +0 -83
- package/.opencode/oh-my-design/.claude/skills/omd-locale-adapter/SKILL.md +0 -124
- package/.opencode/oh-my-design/.claude/skills/omd-migrate/SKILL.md +0 -307
- package/.opencode/oh-my-design/.claude/skills/omd-orchestrator/SKILL.md +0 -124
- package/.opencode/oh-my-design/.claude/skills/omd-release-hygiene/SKILL.md +0 -113
- package/.opencode/oh-my-design/.claude/skills/omd-remember/SKILL.md +0 -46
- package/.opencode/oh-my-design/.claude/skills/omd-sync/SKILL.md +0 -40
- package/.opencode/oh-my-design/.claude/skills/omd-token-backfill/SKILL.md +0 -57
- package/.opencode/oh-my-design/.claude/skills/skill-rules.json +0 -84
- package/.opencode/oh-my-design/.github/ISSUE_TEMPLATE/agent-fidelity.md +0 -59
- package/.opencode/oh-my-design/.github/ISSUE_TEMPLATE/bug-report.md +0 -36
- package/.opencode/oh-my-design/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.opencode/oh-my-design/.github/ISSUE_TEMPLATE/feature-request.md +0 -26
- package/.opencode/oh-my-design/.github/PULL_REQUEST_TEMPLATE.md +0 -134
- package/.opencode/oh-my-design/.github/assets/logo-bg.png +0 -0
- package/.opencode/oh-my-design/.github/workflows/release.yml +0 -55
- package/.opencode/oh-my-design/.husky/pre-commit +0 -23
- package/.opencode/oh-my-design/.mcp.json +0 -12
- package/.opencode/oh-my-design/AGENTS.md +0 -112
- package/.opencode/oh-my-design/CHANGELOG.md +0 -385
- package/.opencode/oh-my-design/LICENSE +0 -21
- package/.opencode/oh-my-design/README.ja.md +0 -74
- package/.opencode/oh-my-design/README.ko.md +0 -112
- package/.opencode/oh-my-design/README.md +0 -112
- package/.opencode/oh-my-design/README.zh-TW.md +0 -74
- package/.opencode/oh-my-design/agents/AGENT.md +0 -53
- package/.opencode/oh-my-design/agents/omd-a11y-auditor.md +0 -97
- package/.opencode/oh-my-design/agents/omd-asset-curator.md +0 -255
- package/.opencode/oh-my-design/agents/omd-codex-image.md +0 -49
- package/.opencode/oh-my-design/agents/omd-critic.md +0 -181
- package/.opencode/oh-my-design/agents/omd-designer-review.md +0 -38
- package/.opencode/oh-my-design/agents/omd-final-qa.md +0 -40
- package/.opencode/oh-my-design/agents/omd-kr-writer.md +0 -35
- package/.opencode/oh-my-design/agents/omd-locale-adapter.md +0 -32
- package/.opencode/oh-my-design/agents/omd-master.md +0 -559
- package/.opencode/oh-my-design/agents/omd-microcopy.md +0 -63
- package/.opencode/oh-my-design/agents/omd-orchestrator.md +0 -34
- package/.opencode/oh-my-design/agents/omd-persona-tester.md +0 -118
- package/.opencode/oh-my-design/agents/omd-ui-junior.md +0 -129
- package/.opencode/oh-my-design/agents/omd-ux-engineer.md +0 -267
- package/.opencode/oh-my-design/agents/omd-ux-researcher.md +0 -62
- package/.opencode/oh-my-design/agents/omd-ux-writer.md +0 -181
- package/.opencode/oh-my-design/bin/oh-my-design.ts +0 -77
- package/.opencode/oh-my-design/data/architecture-proposals/1.7.2-recommend-install-feedback.md +0 -614
- package/.opencode/oh-my-design/data/architecture-proposals/2026-05-13-thin-install-fresh-fetch.md +0 -189
- package/.opencode/oh-my-design/data/issues/2026-05-13-multi-surface-schema-rfc.md +0 -67
- package/.opencode/oh-my-design/data/opt-out-corpus.json +0 -141
- package/.opencode/oh-my-design/data/reference-audits/2026-05-13-kr10.md +0 -132
- package/.opencode/oh-my-design/data/reference-audits/2026-05-14-kr10.md +0 -72
- package/.opencode/oh-my-design/data/reference-audits/2026-05-15-kr10.md +0 -124
- package/.opencode/oh-my-design/data/reference-fingerprints.json +0 -6142
- package/.opencode/oh-my-design/data/reference-tags.md +0 -118
- package/.opencode/oh-my-design/data/synonyms.json +0 -79
- package/.opencode/oh-my-design/data/vocabulary.json +0 -516
- package/.opencode/oh-my-design/packages/mcp/README.md +0 -172
- package/.opencode/oh-my-design/packages/mcp/__tests__/smoke.test.ts +0 -64
- package/.opencode/oh-my-design/packages/mcp/data/.gitkeep +0 -0
- package/.opencode/oh-my-design/packages/mcp/scripts/sync-data.mjs +0 -38
- package/.opencode/oh-my-design/packages/mcp/src/data.ts +0 -178
- package/.opencode/oh-my-design/packages/mcp/src/index.ts +0 -58
- package/.opencode/oh-my-design/packages/mcp/src/prompts/design-from-ref.ts +0 -87
- package/.opencode/oh-my-design/packages/mcp/src/server.ts +0 -223
- package/.opencode/oh-my-design/packages/mcp/src/tools/get-design-md.ts +0 -44
- package/.opencode/oh-my-design/packages/mcp/src/tools/list-references.ts +0 -58
- package/.opencode/oh-my-design/packages/mcp/src/tools/search-by-vibe.ts +0 -114
- package/.opencode/oh-my-design/packages/mcp/tsconfig.json +0 -21
- package/.opencode/oh-my-design/packages/mcp/tsup.config.ts +0 -17
- package/.opencode/oh-my-design/packages/mcp/vitest.config.ts +0 -8
- package/.opencode/oh-my-design/scripts/bench/README.md +0 -72
- package/.opencode/oh-my-design/scripts/bench/score-init.mjs +0 -97
- package/.opencode/oh-my-design/scripts/bench/score-taste.mjs +0 -189
- package/.opencode/oh-my-design/scripts/check-release-hygiene.sh +0 -83
- package/.opencode/oh-my-design/scripts/context.cjs +0 -91
- package/.opencode/oh-my-design/scripts/ctx-prime.cjs +0 -266
- package/.opencode/oh-my-design/scripts/gen-llms-full.cjs +0 -143
- package/.opencode/oh-my-design/scripts/growth-snapshot.mjs +0 -59
- package/.opencode/oh-my-design/scripts/postinstall.cjs +0 -54
- package/.opencode/oh-my-design/scripts/smoke-md-twins.mjs +0 -98
- package/.opencode/oh-my-design/skills/claude-design/SKILL.md +0 -390
- package/.opencode/oh-my-design/skills/claude-design/references/claude-design-flow.md +0 -425
- package/.opencode/oh-my-design/skills/claude-design/references/codebase-analysis.md +0 -373
- package/.opencode/oh-my-design/skills/claude-design/scripts/analyze_codebase.py +0 -1369
- package/.opencode/oh-my-design/skills/claude-design/scripts/clickable_link.sh +0 -48
- package/.opencode/oh-my-design/skills/claude-design/scripts/collect_source.py +0 -178
- package/.opencode/oh-my-design/skills/claude-design/scripts/drive_claude_design.cjs +0 -378
- package/.opencode/oh-my-design/skills/claude-design/scripts/gather_references.py +0 -437
- package/.opencode/oh-my-design/skills/omd-apply/SKILL.md +0 -107
- package/.opencode/oh-my-design/skills/omd-asset-fetch/SKILL.md +0 -213
- package/.opencode/oh-my-design/skills/omd-codex-image/SKILL.md +0 -162
- package/.opencode/oh-my-design/skills/omd-designer-review/SKILL.md +0 -180
- package/.opencode/oh-my-design/skills/omd-experiment-gallery/SKILL.md +0 -164
- package/.opencode/oh-my-design/skills/omd-final-qa/SKILL.md +0 -182
- package/.opencode/oh-my-design/skills/omd-harness/SKILL.md +0 -726
- package/.opencode/oh-my-design/skills/omd-init/SKILL.md +0 -314
- package/.opencode/oh-my-design/skills/omd-kr-writer/SKILL.md +0 -299
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/SKILL.md +0 -129
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/playbooks/v1.md +0 -105
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/live-2026-04-27-water-app/feedback-log.md +0 -230
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/README.md +0 -46
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/founder/README.md +0 -7
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/junior-designer/src/components/Hero.tsx +0 -1
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/junior-designer/src/components/Project.tsx +0 -1
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Accordion.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Alert.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Avatar.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Badge.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Breadcrumb.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Button.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Card.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Combobox.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/DataTable.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Dialog.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Drawer.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Field.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Form.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Input.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Menu.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Modal.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Pagination.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Popover.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Select.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Sheet.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Spinner.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Tabs.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Toast.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/Tooltip.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/senior-dev/src/components/VirtualList.tsx +0 -4
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Alert.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Avatar.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Badge.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Button.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Card.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Input.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Modal.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Spinner.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Tabs.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/components/Toast.tsx +0 -3
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/src/styles/globals.css +0 -25
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/fixtures/vibe-coder/tailwind.config.ts +0 -28
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/iterations/i1-findings.md +0 -51
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/iterations/i2-audit-F.md +0 -133
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/iterations/i2-audit-J.md +0 -171
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/iterations/i2-audit-S.md +0 -232
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/iterations/i2-audit-V.md +0 -73
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/iterations/i2-consolidated.md +0 -69
- package/.opencode/oh-my-design/skills/omd-lab-02-design-harness/runs/v4-self-test/postmortem.md +0 -128
- package/.opencode/oh-my-design/skills/omd-learn/SKILL.md +0 -121
- package/.opencode/oh-my-design/skills/omd-locale-adapter/SKILL.md +0 -124
- package/.opencode/oh-my-design/skills/omd-orchestrator/SKILL.md +0 -124
- package/.opencode/oh-my-design/skills/omd-reference-capture/SKILL.md +0 -722
- package/.opencode/oh-my-design/skills/omd-remember/SKILL.md +0 -122
- package/.opencode/oh-my-design/skills/omd-sync/SKILL.md +0 -162
- package/.opencode/oh-my-design/skills/omd-taste/SKILL.md +0 -79
- package/.opencode/oh-my-design/skills-lock.json +0 -10
- package/.opencode/oh-my-design/spec/components-schema.md +0 -179
- package/.opencode/oh-my-design/spec/migration-checklist.md +0 -148
- package/.opencode/oh-my-design/spec/migration-plan.md +0 -124
- package/.opencode/oh-my-design/spec/omd-v0.1.md +0 -382
- package/.opencode/oh-my-design/spec/regional-sources.yaml +0 -77
- package/.opencode/oh-my-design/spec/verification-pipeline.md +0 -154
- package/.opencode/oh-my-design/src/cli/install-skills.ts +0 -1116
- package/.opencode/oh-my-design/src/core/agent-detect.ts +0 -49
- package/.opencode/oh-my-design/test/README.md +0 -89
- package/.opencode/oh-my-design/test/scripts/check-backgrounds.ts +0 -10
- package/.opencode/oh-my-design/test/scripts/generate-preview.ts +0 -42
- package/.opencode/oh-my-design/test/unit/cli/install-skills.test.ts +0 -227
- package/.opencode/oh-my-design/test/unit/core/agent-detect.test.ts +0 -97
- package/.opencode/oh-my-design/test/unit/core/catalog-resolution-order.test.ts +0 -73
- package/.opencode/oh-my-design/test/unit/hooks/hooks.test.ts +0 -499
- package/.opencode/oh-my-design/tsconfig.json +0 -20
- package/.opencode/oh-my-design/tsup.config.ts +0 -12
- package/.opencode/oh-my-design/vitest.config.ts +0 -13
- package/.opencode/oh-my-design/web/.env.example +0 -21
- package/.opencode/oh-my-design/web/AGENTS.md +0 -5
- package/.opencode/oh-my-design/web/CLAUDE.md +0 -1
- package/.opencode/oh-my-design/web/README.md +0 -45
- package/.opencode/oh-my-design/web/__tests__/catalog-integrity.test.ts +0 -333
- package/.opencode/oh-my-design/web/components.json +0 -25
- package/.opencode/oh-my-design/web/docs/font-playground-analytics.md +0 -110
- package/.opencode/oh-my-design/web/eslint.config.mjs +0 -18
- package/.opencode/oh-my-design/web/next.config.ts +0 -31
- package/.opencode/oh-my-design/web/postcss.config.mjs +0 -7
- package/.opencode/oh-my-design/web/public/file.svg +0 -1
- package/.opencode/oh-my-design/web/public/globe.svg +0 -1
- package/.opencode/oh-my-design/web/public/llms-full.txt +0 -3149
- package/.opencode/oh-my-design/web/public/llms.ko.txt +0 -130
- package/.opencode/oh-my-design/web/public/llms.txt +0 -377
- package/.opencode/oh-my-design/web/public/logo-white.png +0 -0
- package/.opencode/oh-my-design/web/public/logo.png +0 -0
- package/.opencode/oh-my-design/web/public/next.svg +0 -1
- package/.opencode/oh-my-design/web/public/og-image.png +0 -0
- package/.opencode/oh-my-design/web/public/twitter-image.png +0 -0
- package/.opencode/oh-my-design/web/public/vercel.svg +0 -1
- package/.opencode/oh-my-design/web/public/window.svg +0 -1
- package/.opencode/oh-my-design/web/references/11st/.verification.md +0 -37
- package/.opencode/oh-my-design/web/references/11st/DESIGN.md +0 -400
- package/.opencode/oh-my-design/web/references/17live/DESIGN.md +0 -467
- package/.opencode/oh-my-design/web/references/29cm/DESIGN.md +0 -495
- package/.opencode/oh-my-design/web/references/29cm/_promo.json +0 -23
- package/.opencode/oh-my-design/web/references/29cm/_research.md +0 -103
- package/.opencode/oh-my-design/web/references/3o3/.verification.md +0 -73
- package/.opencode/oh-my-design/web/references/3o3/DESIGN.md +0 -454
- package/.opencode/oh-my-design/web/references/91app/.verification.md +0 -25
- package/.opencode/oh-my-design/web/references/91app/DESIGN.md +0 -182
- package/.opencode/oh-my-design/web/references/abema/.verification.md +0 -64
- package/.opencode/oh-my-design/web/references/abema/DESIGN.md +0 -535
- package/.opencode/oh-my-design/web/references/ably/DESIGN.md +0 -646
- package/.opencode/oh-my-design/web/references/ably/_promo.json +0 -18
- package/.opencode/oh-my-design/web/references/ably/_research.md +0 -120
- package/.opencode/oh-my-design/web/references/accupass/.verification.md +0 -66
- package/.opencode/oh-my-design/web/references/accupass/DESIGN.md +0 -494
- package/.opencode/oh-my-design/web/references/adobe/.verification.md +0 -63
- package/.opencode/oh-my-design/web/references/adobe/DESIGN.md +0 -458
- package/.opencode/oh-my-design/web/references/airbnb/.verification.md +0 -143
- package/.opencode/oh-my-design/web/references/airbnb/DESIGN.md +0 -639
- package/.opencode/oh-my-design/web/references/airbnb/README.md +0 -23
- package/.opencode/oh-my-design/web/references/airbnb/preview-dark.html +0 -234
- package/.opencode/oh-my-design/web/references/airbnb/preview.html +0 -233
- package/.opencode/oh-my-design/web/references/airtable/.verification.md +0 -136
- package/.opencode/oh-my-design/web/references/airtable/DESIGN.md +0 -314
- package/.opencode/oh-my-design/web/references/airtable/README.md +0 -23
- package/.opencode/oh-my-design/web/references/airtable/preview-dark.html +0 -165
- package/.opencode/oh-my-design/web/references/airtable/preview.html +0 -164
- package/.opencode/oh-my-design/web/references/alipay/DESIGN.md +0 -506
- package/.opencode/oh-my-design/web/references/amazingtalker/.verification.md +0 -38
- package/.opencode/oh-my-design/web/references/amazingtalker/DESIGN.md +0 -434
- package/.opencode/oh-my-design/web/references/appier/DESIGN.md +0 -465
- package/.opencode/oh-my-design/web/references/apple/.verification.md +0 -162
- package/.opencode/oh-my-design/web/references/apple/DESIGN.md +0 -613
- package/.opencode/oh-my-design/web/references/apple/README.md +0 -24
- package/.opencode/oh-my-design/web/references/apple/preview-dark.html +0 -420
- package/.opencode/oh-my-design/web/references/apple/preview.html +0 -414
- package/.opencode/oh-my-design/web/references/baemin/.verification.md +0 -132
- package/.opencode/oh-my-design/web/references/baemin/DESIGN.md +0 -578
- package/.opencode/oh-my-design/web/references/baemin/README.md +0 -19
- package/.opencode/oh-my-design/web/references/baemin/_research.md +0 -84
- package/.opencode/oh-my-design/web/references/banksalad/DESIGN.md +0 -688
- package/.opencode/oh-my-design/web/references/banksalad/_promo.json +0 -29
- package/.opencode/oh-my-design/web/references/banksalad/_research.md +0 -190
- package/.opencode/oh-my-design/web/references/bilibili/DESIGN.md +0 -471
- package/.opencode/oh-my-design/web/references/bithumb/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/bithumb/DESIGN.md +0 -208
- package/.opencode/oh-my-design/web/references/bmw/.verification.md +0 -114
- package/.opencode/oh-my-design/web/references/bmw/DESIGN.md +0 -360
- package/.opencode/oh-my-design/web/references/bmw/README.md +0 -23
- package/.opencode/oh-my-design/web/references/bmw/preview-dark.html +0 -211
- package/.opencode/oh-my-design/web/references/bmw/preview.html +0 -210
- package/.opencode/oh-my-design/web/references/brandi/.verification.md +0 -29
- package/.opencode/oh-my-design/web/references/brandi/DESIGN.md +0 -414
- package/.opencode/oh-my-design/web/references/bunjang/DESIGN.md +0 -374
- package/.opencode/oh-my-design/web/references/bunjang/assets/_reference/.live-inspect-proof.json +0 -260
- package/.opencode/oh-my-design/web/references/bunjang/assets/_reference/fonts.json +0 -33
- package/.opencode/oh-my-design/web/references/bunjang/assets/_reference/logo-icon.svg +0 -10
- package/.opencode/oh-my-design/web/references/bunjang/assets/_reference/structure.json +0 -131
- package/.opencode/oh-my-design/web/references/bunjang/assets/_reference/tokens.json +0 -147
- package/.opencode/oh-my-design/web/references/cakeresume/.verification.md +0 -25
- package/.opencode/oh-my-design/web/references/cakeresume/DESIGN.md +0 -191
- package/.opencode/oh-my-design/web/references/cal/.verification.md +0 -145
- package/.opencode/oh-my-design/web/references/cal/DESIGN.md +0 -481
- package/.opencode/oh-my-design/web/references/cal/README.md +0 -23
- package/.opencode/oh-my-design/web/references/cal/preview-dark.html +0 -449
- package/.opencode/oh-my-design/web/references/cal/preview.html +0 -575
- package/.opencode/oh-my-design/web/references/catchtable/DESIGN.md +0 -341
- package/.opencode/oh-my-design/web/references/catchtable/_research.md +0 -54
- package/.opencode/oh-my-design/web/references/catchtable/assets/_reference/.live-inspect-proof.json +0 -204
- package/.opencode/oh-my-design/web/references/catchtable/assets/_reference/.live-inspect-raw.json +0 -22
- package/.opencode/oh-my-design/web/references/catchtable/assets/_reference/fonts.json +0 -21
- package/.opencode/oh-my-design/web/references/catchtable/assets/_reference/structure.json +0 -42
- package/.opencode/oh-my-design/web/references/catchtable/assets/_reference/tokens.json +0 -95
- package/.opencode/oh-my-design/web/references/cathay/.verification.md +0 -44
- package/.opencode/oh-my-design/web/references/cathay/DESIGN.md +0 -432
- package/.opencode/oh-my-design/web/references/channeltalk/DESIGN.md +0 -422
- package/.opencode/oh-my-design/web/references/channeltalk/assets/_reference/.live-inspect-proof.json +0 -320
- package/.opencode/oh-my-design/web/references/channeltalk/assets/_reference/fonts.json +0 -53
- package/.opencode/oh-my-design/web/references/channeltalk/assets/_reference/structure.json +0 -47
- package/.opencode/oh-my-design/web/references/channeltalk/assets/_reference/tokens.json +0 -78
- package/.opencode/oh-my-design/web/references/class101/DESIGN.md +0 -484
- package/.opencode/oh-my-design/web/references/classting/.verification.md +0 -32
- package/.opencode/oh-my-design/web/references/classting/DESIGN.md +0 -292
- package/.opencode/oh-my-design/web/references/classum/DESIGN.md +0 -279
- package/.opencode/oh-my-design/web/references/classum/assets/_reference/.live-inspect-proof.json +0 -72
- package/.opencode/oh-my-design/web/references/classum/assets/_reference/fonts.json +0 -20
- package/.opencode/oh-my-design/web/references/classum/assets/_reference/structure.json +0 -21
- package/.opencode/oh-my-design/web/references/classum/assets/_reference/tokens.json +0 -56
- package/.opencode/oh-my-design/web/references/claude/.verification.md +0 -106
- package/.opencode/oh-my-design/web/references/claude/DESIGN.md +0 -561
- package/.opencode/oh-my-design/web/references/claude/README.md +0 -24
- package/.opencode/oh-my-design/web/references/claude/preview-dark.html +0 -803
- package/.opencode/oh-my-design/web/references/claude/preview.html +0 -826
- package/.opencode/oh-my-design/web/references/clay/.verification.md +0 -129
- package/.opencode/oh-my-design/web/references/clay/DESIGN.md +0 -454
- package/.opencode/oh-my-design/web/references/clay/README.md +0 -23
- package/.opencode/oh-my-design/web/references/clay/preview-dark.html +0 -316
- package/.opencode/oh-my-design/web/references/clay/preview.html +0 -315
- package/.opencode/oh-my-design/web/references/clickhouse/.verification.md +0 -132
- package/.opencode/oh-my-design/web/references/clickhouse/DESIGN.md +0 -424
- package/.opencode/oh-my-design/web/references/clickhouse/README.md +0 -24
- package/.opencode/oh-my-design/web/references/clickhouse/preview-dark.html +0 -834
- package/.opencode/oh-my-design/web/references/clickhouse/preview.html +0 -786
- package/.opencode/oh-my-design/web/references/cloudflare/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/cloudflare/DESIGN.md +0 -637
- package/.opencode/oh-my-design/web/references/cohere/.verification.md +0 -136
- package/.opencode/oh-my-design/web/references/cohere/DESIGN.md +0 -409
- package/.opencode/oh-my-design/web/references/cohere/README.md +0 -24
- package/.opencode/oh-my-design/web/references/cohere/preview-dark.html +0 -803
- package/.opencode/oh-my-design/web/references/cohere/preview.html +0 -807
- package/.opencode/oh-my-design/web/references/coinbase/.verification.md +0 -116
- package/.opencode/oh-my-design/web/references/coinbase/DESIGN.md +0 -353
- package/.opencode/oh-my-design/web/references/coinbase/README.md +0 -23
- package/.opencode/oh-my-design/web/references/coinbase/preview-dark.html +0 -164
- package/.opencode/oh-my-design/web/references/coinbase/preview.html +0 -163
- package/.opencode/oh-my-design/web/references/coinone/.verification.md +0 -38
- package/.opencode/oh-my-design/web/references/coinone/DESIGN.md +0 -257
- package/.opencode/oh-my-design/web/references/composio/.verification.md +0 -143
- package/.opencode/oh-my-design/web/references/composio/DESIGN.md +0 -441
- package/.opencode/oh-my-design/web/references/composio/README.md +0 -24
- package/.opencode/oh-my-design/web/references/composio/preview-dark.html +0 -958
- package/.opencode/oh-my-design/web/references/composio/preview.html +0 -933
- package/.opencode/oh-my-design/web/references/cookpad/DESIGN.md +0 -394
- package/.opencode/oh-my-design/web/references/coupang/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/coupang/DESIGN.md +0 -557
- package/.opencode/oh-my-design/web/references/cursor/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/cursor/DESIGN.md +0 -460
- package/.opencode/oh-my-design/web/references/cursor/README.md +0 -24
- package/.opencode/oh-my-design/web/references/cursor/preview-dark.html +0 -393
- package/.opencode/oh-my-design/web/references/cursor/preview.html +0 -383
- package/.opencode/oh-my-design/web/references/dabang/DESIGN.md +0 -267
- package/.opencode/oh-my-design/web/references/dabang/assets/_reference/.live-inspect-proof.json +0 -145
- package/.opencode/oh-my-design/web/references/dabang/assets/_reference/fonts.json +0 -22
- package/.opencode/oh-my-design/web/references/dabang/assets/_reference/raw-capture-map.json +0 -718
- package/.opencode/oh-my-design/web/references/dabang/assets/_reference/raw-capture.json +0 -1125
- package/.opencode/oh-my-design/web/references/dabang/assets/_reference/structure.json +0 -53
- package/.opencode/oh-my-design/web/references/dabang/assets/_reference/tokens.json +0 -130
- package/.opencode/oh-my-design/web/references/danawa/.verification.md +0 -60
- package/.opencode/oh-my-design/web/references/danawa/DESIGN.md +0 -477
- package/.opencode/oh-my-design/web/references/dcard/.verification.md +0 -118
- package/.opencode/oh-my-design/web/references/dcard/DESIGN.md +0 -633
- package/.opencode/oh-my-design/web/references/dcard/README.md +0 -12
- package/.opencode/oh-my-design/web/references/dcard/_research/forum-1440px.png +0 -0
- package/.opencode/oh-my-design/web/references/dcard/_research.md +0 -133
- package/.opencode/oh-my-design/web/references/dell/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/dell/DESIGN.md +0 -636
- package/.opencode/oh-my-design/web/references/devsisters/.verification.md +0 -32
- package/.opencode/oh-my-design/web/references/devsisters/DESIGN.md +0 -282
- package/.opencode/oh-my-design/web/references/discord/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/discord/DESIGN.md +0 -604
- package/.opencode/oh-my-design/web/references/dji/DESIGN.md +0 -454
- package/.opencode/oh-my-design/web/references/drnow/.verification.md +0 -41
- package/.opencode/oh-my-design/web/references/drnow/DESIGN.md +0 -383
- package/.opencode/oh-my-design/web/references/dropbox/.verification.md +0 -61
- package/.opencode/oh-my-design/web/references/dropbox/DESIGN.md +0 -445
- package/.opencode/oh-my-design/web/references/duolingo/.verification.md +0 -20
- package/.opencode/oh-my-design/web/references/duolingo/DESIGN.md +0 -563
- package/.opencode/oh-my-design/web/references/elevenlabs/.verification.md +0 -128
- package/.opencode/oh-my-design/web/references/elevenlabs/DESIGN.md +0 -415
- package/.opencode/oh-my-design/web/references/elevenlabs/README.md +0 -23
- package/.opencode/oh-my-design/web/references/elevenlabs/preview-dark.html +0 -252
- package/.opencode/oh-my-design/web/references/elevenlabs/preview.html +0 -251
- package/.opencode/oh-my-design/web/references/expo/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/expo/DESIGN.md +0 -412
- package/.opencode/oh-my-design/web/references/expo/README.md +0 -24
- package/.opencode/oh-my-design/web/references/expo/preview-dark.html +0 -533
- package/.opencode/oh-my-design/web/references/expo/preview.html +0 -533
- package/.opencode/oh-my-design/web/references/fastcampus/DESIGN.md +0 -529
- package/.opencode/oh-my-design/web/references/fastcampus/assets/_reference/.live-inspect-proof.json +0 -950
- package/.opencode/oh-my-design/web/references/fastcampus/assets/_reference/fonts.json +0 -14
- package/.opencode/oh-my-design/web/references/fastcampus/assets/_reference/structure.json +0 -30
- package/.opencode/oh-my-design/web/references/fastcampus/assets/_reference/tokens.json +0 -109
- package/.opencode/oh-my-design/web/references/ferrari/.verification.md +0 -119
- package/.opencode/oh-my-design/web/references/ferrari/DESIGN.md +0 -447
- package/.opencode/oh-my-design/web/references/ferrari/README.md +0 -23
- package/.opencode/oh-my-design/web/references/ferrari/preview-dark.html +0 -1162
- package/.opencode/oh-my-design/web/references/ferrari/preview.html +0 -1122
- package/.opencode/oh-my-design/web/references/figma/.verification.md +0 -206
- package/.opencode/oh-my-design/web/references/figma/DESIGN.md +0 -534
- package/.opencode/oh-my-design/web/references/figma/README.md +0 -24
- package/.opencode/oh-my-design/web/references/figma/preview-dark.html +0 -822
- package/.opencode/oh-my-design/web/references/figma/preview.html +0 -832
- package/.opencode/oh-my-design/web/references/finda/.verification.md +0 -33
- package/.opencode/oh-my-design/web/references/finda/DESIGN.md +0 -413
- package/.opencode/oh-my-design/web/references/firstory/.verification.md +0 -70
- package/.opencode/oh-my-design/web/references/firstory/DESIGN.md +0 -487
- package/.opencode/oh-my-design/web/references/flex/DESIGN.md +0 -356
- package/.opencode/oh-my-design/web/references/flex/_research.md +0 -49
- package/.opencode/oh-my-design/web/references/flex/assets/_reference/.live-inspect-proof.json +0 -192
- package/.opencode/oh-my-design/web/references/flex/assets/_reference/.raw-inspect.json +0 -873
- package/.opencode/oh-my-design/web/references/flex/assets/_reference/fonts.json +0 -17
- package/.opencode/oh-my-design/web/references/flex/assets/_reference/structure.json +0 -58
- package/.opencode/oh-my-design/web/references/flex/assets/_reference/tokens.json +0 -75
- package/.opencode/oh-my-design/web/references/flo/.verification.md +0 -33
- package/.opencode/oh-my-design/web/references/flo/DESIGN.md +0 -349
- package/.opencode/oh-my-design/web/references/framer/.verification.md +0 -147
- package/.opencode/oh-my-design/web/references/framer/DESIGN.md +0 -431
- package/.opencode/oh-my-design/web/references/framer/README.md +0 -23
- package/.opencode/oh-my-design/web/references/framer/preview-dark.html +0 -902
- package/.opencode/oh-my-design/web/references/framer/preview.html +0 -883
- package/.opencode/oh-my-design/web/references/freee/.verification.md +0 -145
- package/.opencode/oh-my-design/web/references/freee/DESIGN.md +0 -620
- package/.opencode/oh-my-design/web/references/freee/README.md +0 -12
- package/.opencode/oh-my-design/web/references/freee/_research/vibes-storybook-1440px.png +0 -0
- package/.opencode/oh-my-design/web/references/freee/_research.md +0 -116
- package/.opencode/oh-my-design/web/references/fugle/.verification.md +0 -40
- package/.opencode/oh-my-design/web/references/fugle/DESIGN.md +0 -290
- package/.opencode/oh-my-design/web/references/funnow/.verification.md +0 -62
- package/.opencode/oh-my-design/web/references/funnow/DESIGN.md +0 -431
- package/.opencode/oh-my-design/web/references/gangnamunni/DESIGN.md +0 -677
- package/.opencode/oh-my-design/web/references/gangnamunni/_promo.json +0 -26
- package/.opencode/oh-my-design/web/references/gangnamunni/_research.md +0 -113
- package/.opencode/oh-my-design/web/references/genie/.verification.md +0 -29
- package/.opencode/oh-my-design/web/references/genie/DESIGN.md +0 -415
- package/.opencode/oh-my-design/web/references/github/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/github/DESIGN.md +0 -727
- package/.opencode/oh-my-design/web/references/gmarket/DESIGN.md +0 -534
- package/.opencode/oh-my-design/web/references/gmarket/assets/_reference/.live-inspect-proof.json +0 -217
- package/.opencode/oh-my-design/web/references/gmarket/assets/_reference/fonts.json +0 -41
- package/.opencode/oh-my-design/web/references/gmarket/assets/_reference/raw-capture-bestsellers.json +0 -1929
- package/.opencode/oh-my-design/web/references/gmarket/assets/_reference/raw-capture-home.json +0 -3675
- package/.opencode/oh-my-design/web/references/gmarket/assets/_reference/structure.json +0 -65
- package/.opencode/oh-my-design/web/references/gmarket/assets/_reference/tokens.json +0 -210
- package/.opencode/oh-my-design/web/references/gogolook/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/gogolook/DESIGN.md +0 -155
- package/.opencode/oh-my-design/web/references/gogoro/DESIGN.md +0 -441
- package/.opencode/oh-my-design/web/references/google/.verification.md +0 -61
- package/.opencode/oh-my-design/web/references/google/DESIGN.md +0 -499
- package/.opencode/oh-my-design/web/references/greenvines/.verification.md +0 -72
- package/.opencode/oh-my-design/web/references/greenvines/DESIGN.md +0 -454
- package/.opencode/oh-my-design/web/references/greeting/.verification.md +0 -64
- package/.opencode/oh-my-design/web/references/greeting/DESIGN.md +0 -462
- package/.opencode/oh-my-design/web/references/grip/.verification.md +0 -36
- package/.opencode/oh-my-design/web/references/grip/DESIGN.md +0 -289
- package/.opencode/oh-my-design/web/references/hahow/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/hahow/DESIGN.md +0 -184
- package/.opencode/oh-my-design/web/references/hashicorp/.verification.md +0 -142
- package/.opencode/oh-my-design/web/references/hashicorp/DESIGN.md +0 -411
- package/.opencode/oh-my-design/web/references/hashicorp/README.md +0 -24
- package/.opencode/oh-my-design/web/references/hashicorp/preview-dark.html +0 -1202
- package/.opencode/oh-my-design/web/references/hashicorp/preview.html +0 -1193
- package/.opencode/oh-my-design/web/references/hogangnono/.verification.md +0 -33
- package/.opencode/oh-my-design/web/references/hogangnono/DESIGN.md +0 -349
- package/.opencode/oh-my-design/web/references/hp/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/hp/DESIGN.md +0 -563
- package/.opencode/oh-my-design/web/references/hyperconnect/.verification.md +0 -40
- package/.opencode/oh-my-design/web/references/hyperconnect/DESIGN.md +0 -393
- package/.opencode/oh-my-design/web/references/hyundaicard/.verification.md +0 -25
- package/.opencode/oh-my-design/web/references/hyundaicard/DESIGN.md +0 -201
- package/.opencode/oh-my-design/web/references/ibm/.verification.md +0 -102
- package/.opencode/oh-my-design/web/references/ibm/DESIGN.md +0 -464
- package/.opencode/oh-my-design/web/references/ibm/README.md +0 -24
- package/.opencode/oh-my-design/web/references/ibm/preview-dark.html +0 -443
- package/.opencode/oh-my-design/web/references/ibm/preview.html +0 -428
- package/.opencode/oh-my-design/web/references/ichef/DESIGN.md +0 -455
- package/.opencode/oh-my-design/web/references/ikala/.verification.md +0 -35
- package/.opencode/oh-my-design/web/references/ikala/DESIGN.md +0 -400
- package/.opencode/oh-my-design/web/references/imweb/.verification.md +0 -61
- package/.opencode/oh-my-design/web/references/imweb/DESIGN.md +0 -460
- package/.opencode/oh-my-design/web/references/inflearn/DESIGN.md +0 -453
- package/.opencode/oh-my-design/web/references/inflearn/_promo.json +0 -29
- package/.opencode/oh-my-design/web/references/inflearn/_research.md +0 -85
- package/.opencode/oh-my-design/web/references/inflearn/assets/_reference/.live-inspect-proof-courses.json +0 -679
- package/.opencode/oh-my-design/web/references/inflearn/assets/_reference/.live-inspect-proof.json +0 -448
- package/.opencode/oh-my-design/web/references/inflearn/assets/_reference/fonts.json +0 -41
- package/.opencode/oh-my-design/web/references/inflearn/assets/_reference/structure.json +0 -110
- package/.opencode/oh-my-design/web/references/inflearn/assets/_reference/tokens.json +0 -54
- package/.opencode/oh-my-design/web/references/intercom/.verification.md +0 -144
- package/.opencode/oh-my-design/web/references/intercom/DESIGN.md +0 -271
- package/.opencode/oh-my-design/web/references/intercom/README.md +0 -23
- package/.opencode/oh-my-design/web/references/intercom/preview-dark.html +0 -185
- package/.opencode/oh-my-design/web/references/intercom/preview.html +0 -184
- package/.opencode/oh-my-design/web/references/jandi/.verification.md +0 -26
- package/.opencode/oh-my-design/web/references/jandi/DESIGN.md +0 -382
- package/.opencode/oh-my-design/web/references/jkopay/.verification.md +0 -32
- package/.opencode/oh-my-design/web/references/jkopay/DESIGN.md +0 -283
- package/.opencode/oh-my-design/web/references/jobkorea/.verification.md +0 -30
- package/.opencode/oh-my-design/web/references/jobkorea/DESIGN.md +0 -349
- package/.opencode/oh-my-design/web/references/jumpit/DESIGN.md +0 -403
- package/.opencode/oh-my-design/web/references/jumpit/_research.md +0 -119
- package/.opencode/oh-my-design/web/references/jumpit/assets/_reference/.live-inspect-proof.json +0 -182
- package/.opencode/oh-my-design/web/references/jumpit/assets/_reference/fonts.json +0 -20
- package/.opencode/oh-my-design/web/references/jumpit/assets/_reference/structure.json +0 -66
- package/.opencode/oh-my-design/web/references/jumpit/assets/_reference/tokens.json +0 -108
- package/.opencode/oh-my-design/web/references/kakao/.verification.md +0 -137
- package/.opencode/oh-my-design/web/references/kakao/DESIGN.md +0 -568
- package/.opencode/oh-my-design/web/references/kakao/README.md +0 -18
- package/.opencode/oh-my-design/web/references/kakao/_research.md +0 -98
- package/.opencode/oh-my-design/web/references/kakaobank/.verification.md +0 -133
- package/.opencode/oh-my-design/web/references/kakaobank/DESIGN.md +0 -602
- package/.opencode/oh-my-design/web/references/kakaopay/DESIGN.md +0 -603
- package/.opencode/oh-my-design/web/references/kakaopay/_promo.json +0 -22
- package/.opencode/oh-my-design/web/references/kakaopay/_research.md +0 -84
- package/.opencode/oh-my-design/web/references/kakaot/DESIGN.md +0 -507
- package/.opencode/oh-my-design/web/references/karrot/.verification.md +0 -143
- package/.opencode/oh-my-design/web/references/karrot/DESIGN.md +0 -494
- package/.opencode/oh-my-design/web/references/karrot/README.md +0 -18
- package/.opencode/oh-my-design/web/references/karrot/_research.md +0 -57
- package/.opencode/oh-my-design/web/references/kbank/DESIGN.md +0 -252
- package/.opencode/oh-my-design/web/references/kbank/assets/_reference/.live-inspect-proof.json +0 -215
- package/.opencode/oh-my-design/web/references/kbank/assets/_reference/.live-inspect-raw.json +0 -1
- package/.opencode/oh-my-design/web/references/kbank/assets/_reference/fonts.json +0 -20
- package/.opencode/oh-my-design/web/references/kbank/assets/_reference/structure.json +0 -151
- package/.opencode/oh-my-design/web/references/kbank/assets/_reference/tokens.json +0 -101
- package/.opencode/oh-my-design/web/references/kdan/.verification.md +0 -30
- package/.opencode/oh-my-design/web/references/kdan/DESIGN.md +0 -193
- package/.opencode/oh-my-design/web/references/kintone/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/kintone/DESIGN.md +0 -586
- package/.opencode/oh-my-design/web/references/kkbox/.verification.md +0 -27
- package/.opencode/oh-my-design/web/references/kkbox/DESIGN.md +0 -136
- package/.opencode/oh-my-design/web/references/kkday/DESIGN.md +0 -470
- package/.opencode/oh-my-design/web/references/kmong/.verification.md +0 -30
- package/.opencode/oh-my-design/web/references/kmong/DESIGN.md +0 -427
- package/.opencode/oh-my-design/web/references/krafton/.verification.md +0 -38
- package/.opencode/oh-my-design/web/references/krafton/DESIGN.md +0 -267
- package/.opencode/oh-my-design/web/references/kraken/.verification.md +0 -143
- package/.opencode/oh-my-design/web/references/kraken/DESIGN.md +0 -277
- package/.opencode/oh-my-design/web/references/kraken/README.md +0 -23
- package/.opencode/oh-my-design/web/references/kraken/preview-dark.html +0 -169
- package/.opencode/oh-my-design/web/references/kraken/preview.html +0 -168
- package/.opencode/oh-my-design/web/references/krds/.verification.md +0 -373
- package/.opencode/oh-my-design/web/references/krds/DESIGN.md +0 -1060
- package/.opencode/oh-my-design/web/references/kream/DESIGN.md +0 -432
- package/.opencode/oh-my-design/web/references/kream/assets/_reference/.live-inspect-proof.json +0 -289
- package/.opencode/oh-my-design/web/references/kream/assets/_reference/fonts.json +0 -26
- package/.opencode/oh-my-design/web/references/kream/assets/_reference/structure.json +0 -56
- package/.opencode/oh-my-design/web/references/kream/assets/_reference/tokens.json +0 -154
- package/.opencode/oh-my-design/web/references/kurly/.verification.md +0 -126
- package/.opencode/oh-my-design/web/references/kurly/DESIGN.md +0 -620
- package/.opencode/oh-my-design/web/references/laftel/.verification.md +0 -39
- package/.opencode/oh-my-design/web/references/laftel/DESIGN.md +0 -293
- package/.opencode/oh-my-design/web/references/lamborghini/.verification.md +0 -127
- package/.opencode/oh-my-design/web/references/lamborghini/DESIGN.md +0 -430
- package/.opencode/oh-my-design/web/references/lamborghini/README.md +0 -23
- package/.opencode/oh-my-design/web/references/lamborghini/preview-dark.html +0 -303
- package/.opencode/oh-my-design/web/references/lamborghini/preview.html +0 -381
- package/.opencode/oh-my-design/web/references/laundrygo/.verification.md +0 -60
- package/.opencode/oh-my-design/web/references/laundrygo/DESIGN.md +0 -434
- package/.opencode/oh-my-design/web/references/layerx/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/layerx/DESIGN.md +0 -615
- package/.opencode/oh-my-design/web/references/lezhin/.verification.md +0 -47
- package/.opencode/oh-my-design/web/references/lezhin/DESIGN.md +0 -348
- package/.opencode/oh-my-design/web/references/line/.verification.md +0 -137
- package/.opencode/oh-my-design/web/references/line/DESIGN.md +0 -467
- package/.opencode/oh-my-design/web/references/line/README.md +0 -12
- package/.opencode/oh-my-design/web/references/line/_research/home-1440px.png +0 -0
- package/.opencode/oh-my-design/web/references/line/_research.md +0 -65
- package/.opencode/oh-my-design/web/references/linear.app/.verification.md +0 -143
- package/.opencode/oh-my-design/web/references/linear.app/DESIGN.md +0 -642
- package/.opencode/oh-my-design/web/references/linear.app/README.md +0 -24
- package/.opencode/oh-my-design/web/references/linear.app/preview-dark.html +0 -383
- package/.opencode/oh-my-design/web/references/linear.app/preview.html +0 -373
- package/.opencode/oh-my-design/web/references/loom/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/loom/DESIGN.md +0 -396
- package/.opencode/oh-my-design/web/references/lovable/.verification.md +0 -154
- package/.opencode/oh-my-design/web/references/lovable/DESIGN.md +0 -423
- package/.opencode/oh-my-design/web/references/lovable/README.md +0 -24
- package/.opencode/oh-my-design/web/references/lovable/preview-dark.html +0 -349
- package/.opencode/oh-my-design/web/references/lovable/preview.html +0 -348
- package/.opencode/oh-my-design/web/references/lunit/DESIGN.md +0 -296
- package/.opencode/oh-my-design/web/references/lunit/assets/_reference/.live-inspect-proof.json +0 -249
- package/.opencode/oh-my-design/web/references/lunit/assets/_reference/fonts.json +0 -24
- package/.opencode/oh-my-design/web/references/lunit/assets/_reference/structure.json +0 -162
- package/.opencode/oh-my-design/web/references/lunit/assets/_reference/tokens.json +0 -115
- package/.opencode/oh-my-design/web/references/mastercard/.verification.md +0 -19
- package/.opencode/oh-my-design/web/references/mastercard/DESIGN.md +0 -587
- package/.opencode/oh-my-design/web/references/meituan/DESIGN.md +0 -466
- package/.opencode/oh-my-design/web/references/melon/.verification.md +0 -27
- package/.opencode/oh-my-design/web/references/melon/DESIGN.md +0 -179
- package/.opencode/oh-my-design/web/references/mercari/.verification.md +0 -155
- package/.opencode/oh-my-design/web/references/mercari/DESIGN.md +0 -514
- package/.opencode/oh-my-design/web/references/mercari/README.md +0 -12
- package/.opencode/oh-my-design/web/references/mercari/_research/home-1440px.png +0 -0
- package/.opencode/oh-my-design/web/references/mercari/_research.md +0 -137
- package/.opencode/oh-my-design/web/references/mercury/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/mercury/DESIGN.md +0 -589
- package/.opencode/oh-my-design/web/references/meta/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/meta/DESIGN.md +0 -615
- package/.opencode/oh-my-design/web/references/microsoft/.verification.md +0 -62
- package/.opencode/oh-my-design/web/references/microsoft/DESIGN.md +0 -508
- package/.opencode/oh-my-design/web/references/millie/DESIGN.md +0 -584
- package/.opencode/oh-my-design/web/references/minimax/.verification.md +0 -135
- package/.opencode/oh-my-design/web/references/minimax/DESIGN.md +0 -396
- package/.opencode/oh-my-design/web/references/minimax/README.md +0 -24
- package/.opencode/oh-my-design/web/references/minimax/preview-dark.html +0 -1262
- package/.opencode/oh-my-design/web/references/minimax/preview.html +0 -1248
- package/.opencode/oh-my-design/web/references/mintlify/.verification.md +0 -160
- package/.opencode/oh-my-design/web/references/mintlify/DESIGN.md +0 -472
- package/.opencode/oh-my-design/web/references/mintlify/README.md +0 -24
- package/.opencode/oh-my-design/web/references/mintlify/preview-dark.html +0 -409
- package/.opencode/oh-my-design/web/references/mintlify/preview.html +0 -398
- package/.opencode/oh-my-design/web/references/miricanvas/.verification.md +0 -61
- package/.opencode/oh-my-design/web/references/miricanvas/DESIGN.md +0 -464
- package/.opencode/oh-my-design/web/references/miro/.verification.md +0 -138
- package/.opencode/oh-my-design/web/references/miro/DESIGN.md +0 -319
- package/.opencode/oh-my-design/web/references/miro/README.md +0 -23
- package/.opencode/oh-my-design/web/references/miro/preview-dark.html +0 -174
- package/.opencode/oh-my-design/web/references/miro/preview.html +0 -173
- package/.opencode/oh-my-design/web/references/mistral.ai/.verification.md +0 -146
- package/.opencode/oh-my-design/web/references/mistral.ai/DESIGN.md +0 -390
- package/.opencode/oh-my-design/web/references/mistral.ai/README.md +0 -24
- package/.opencode/oh-my-design/web/references/mistral.ai/preview-dark.html +0 -806
- package/.opencode/oh-my-design/web/references/mistral.ai/preview.html +0 -805
- package/.opencode/oh-my-design/web/references/modusign/.verification.md +0 -58
- package/.opencode/oh-my-design/web/references/modusign/DESIGN.md +0 -524
- package/.opencode/oh-my-design/web/references/momoshop/.verification.md +0 -36
- package/.opencode/oh-my-design/web/references/momoshop/DESIGN.md +0 -322
- package/.opencode/oh-my-design/web/references/money-forward/DESIGN.md +0 -443
- package/.opencode/oh-my-design/web/references/mongodb/.verification.md +0 -145
- package/.opencode/oh-my-design/web/references/mongodb/DESIGN.md +0 -401
- package/.opencode/oh-my-design/web/references/mongodb/README.md +0 -23
- package/.opencode/oh-my-design/web/references/mongodb/preview-dark.html +0 -260
- package/.opencode/oh-my-design/web/references/mongodb/preview.html +0 -259
- package/.opencode/oh-my-design/web/references/muji/.verification.md +0 -20
- package/.opencode/oh-my-design/web/references/muji/DESIGN.md +0 -605
- package/.opencode/oh-my-design/web/references/musinsa/.verification.md +0 -59
- package/.opencode/oh-my-design/web/references/musinsa/DESIGN.md +0 -593
- package/.opencode/oh-my-design/web/references/mustit/.verification.md +0 -37
- package/.opencode/oh-my-design/web/references/mustit/DESIGN.md +0 -328
- package/.opencode/oh-my-design/web/references/myrealtrip/DESIGN.md +0 -494
- package/.opencode/oh-my-design/web/references/naver/.verification.md +0 -134
- package/.opencode/oh-my-design/web/references/naver/DESIGN.md +0 -582
- package/.opencode/oh-my-design/web/references/naverwebtoon/DESIGN.md +0 -477
- package/.opencode/oh-my-design/web/references/netflix/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/netflix/DESIGN.md +0 -572
- package/.opencode/oh-my-design/web/references/nexon/.verification.md +0 -27
- package/.opencode/oh-my-design/web/references/nexon/DESIGN.md +0 -389
- package/.opencode/oh-my-design/web/references/nhncloud/.verification.md +0 -23
- package/.opencode/oh-my-design/web/references/nhncloud/DESIGN.md +0 -207
- package/.opencode/oh-my-design/web/references/nike/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/nike/DESIGN.md +0 -588
- package/.opencode/oh-my-design/web/references/note/DESIGN.md +0 -346
- package/.opencode/oh-my-design/web/references/notion/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/notion/DESIGN.md +0 -557
- package/.opencode/oh-my-design/web/references/notion/README.md +0 -24
- package/.opencode/oh-my-design/web/references/notion/preview-dark.html +0 -372
- package/.opencode/oh-my-design/web/references/notion/preview.html +0 -364
- package/.opencode/oh-my-design/web/references/nvidia/.verification.md +0 -127
- package/.opencode/oh-my-design/web/references/nvidia/DESIGN.md +0 -550
- package/.opencode/oh-my-design/web/references/nvidia/README.md +0 -24
- package/.opencode/oh-my-design/web/references/nvidia/_research.md +0 -68
- package/.opencode/oh-my-design/web/references/nvidia/preview-dark.html +0 -374
- package/.opencode/oh-my-design/web/references/nvidia/preview.html +0 -366
- package/.opencode/oh-my-design/web/references/ohouse/.verification.md +0 -87
- package/.opencode/oh-my-design/web/references/ohouse/DESIGN.md +0 -635
- package/.opencode/oh-my-design/web/references/oliveyoung/DESIGN.md +0 -407
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/.live-inspect-proof.json +0 -158
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/_best_capture.json +0 -644
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/_detail_capture.json +0 -447
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/_main.html +0 -419
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/_main_capture.json +0 -1126
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/_search_capture.json +0 -912
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/fonts.json +0 -20
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/structure.json +0 -91
- package/.opencode/oh-my-design/web/references/oliveyoung/assets/_reference/tokens.json +0 -79
- package/.opencode/oh-my-design/web/references/ollama/.verification.md +0 -138
- package/.opencode/oh-my-design/web/references/ollama/DESIGN.md +0 -393
- package/.opencode/oh-my-design/web/references/ollama/README.md +0 -24
- package/.opencode/oh-my-design/web/references/ollama/preview-dark.html +0 -678
- package/.opencode/oh-my-design/web/references/ollama/preview.html +0 -678
- package/.opencode/oh-my-design/web/references/omnichat/.verification.md +0 -74
- package/.opencode/oh-my-design/web/references/omnichat/DESIGN.md +0 -499
- package/.opencode/oh-my-design/web/references/openai/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/openai/DESIGN.md +0 -641
- package/.opencode/oh-my-design/web/references/opencode.ai/.verification.md +0 -136
- package/.opencode/oh-my-design/web/references/opencode.ai/DESIGN.md +0 -425
- package/.opencode/oh-my-design/web/references/opencode.ai/README.md +0 -24
- package/.opencode/oh-my-design/web/references/opencode.ai/preview-dark.html +0 -366
- package/.opencode/oh-my-design/web/references/opencode.ai/preview.html +0 -357
- package/.opencode/oh-my-design/web/references/payco/.verification.md +0 -28
- package/.opencode/oh-my-design/web/references/payco/DESIGN.md +0 -267
- package/.opencode/oh-my-design/web/references/paypay/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/paypay/DESIGN.md +0 -656
- package/.opencode/oh-my-design/web/references/pchome/.verification.md +0 -38
- package/.opencode/oh-my-design/web/references/pchome/DESIGN.md +0 -439
- package/.opencode/oh-my-design/web/references/perplexity/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/perplexity/DESIGN.md +0 -546
- package/.opencode/oh-my-design/web/references/piccollage/.verification.md +0 -34
- package/.opencode/oh-my-design/web/references/piccollage/DESIGN.md +0 -320
- package/.opencode/oh-my-design/web/references/pinkoi/.verification.md +0 -147
- package/.opencode/oh-my-design/web/references/pinkoi/DESIGN.md +0 -639
- package/.opencode/oh-my-design/web/references/pinkoi/README.md +0 -12
- package/.opencode/oh-my-design/web/references/pinkoi/_research/browse-1440px.png +0 -0
- package/.opencode/oh-my-design/web/references/pinkoi/_research.md +0 -167
- package/.opencode/oh-my-design/web/references/pinterest/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/pinterest/DESIGN.md +0 -366
- package/.opencode/oh-my-design/web/references/pinterest/README.md +0 -23
- package/.opencode/oh-my-design/web/references/pinterest/preview-dark.html +0 -233
- package/.opencode/oh-my-design/web/references/pinterest/preview.html +0 -232
- package/.opencode/oh-my-design/web/references/pixiv/.verification.md +0 -20
- package/.opencode/oh-my-design/web/references/pixiv/DESIGN.md +0 -613
- package/.opencode/oh-my-design/web/references/pixnet/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/pixnet/DESIGN.md +0 -430
- package/.opencode/oh-my-design/web/references/posthog/.verification.md +0 -159
- package/.opencode/oh-my-design/web/references/posthog/DESIGN.md +0 -480
- package/.opencode/oh-my-design/web/references/posthog/README.md +0 -23
- package/.opencode/oh-my-design/web/references/posthog/preview-dark.html +0 -699
- package/.opencode/oh-my-design/web/references/posthog/preview.html +0 -749
- package/.opencode/oh-my-design/web/references/postype/.verification.md +0 -61
- package/.opencode/oh-my-design/web/references/postype/DESIGN.md +0 -431
- package/.opencode/oh-my-design/web/references/publy/DESIGN.md +0 -563
- package/.opencode/oh-my-design/web/references/qanda/.verification.md +0 -121
- package/.opencode/oh-my-design/web/references/qanda/DESIGN.md +0 -516
- package/.opencode/oh-my-design/web/references/ragic/.verification.md +0 -37
- package/.opencode/oh-my-design/web/references/ragic/DESIGN.md +0 -444
- package/.opencode/oh-my-design/web/references/rakuten/.verification.md +0 -60
- package/.opencode/oh-my-design/web/references/rakuten/DESIGN.md +0 -440
- package/.opencode/oh-my-design/web/references/ramp/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/ramp/DESIGN.md +0 -634
- package/.opencode/oh-my-design/web/references/rayark/.verification.md +0 -22
- package/.opencode/oh-my-design/web/references/rayark/DESIGN.md +0 -154
- package/.opencode/oh-my-design/web/references/raycast/.verification.md +0 -138
- package/.opencode/oh-my-design/web/references/raycast/DESIGN.md +0 -467
- package/.opencode/oh-my-design/web/references/raycast/README.md +0 -23
- package/.opencode/oh-my-design/web/references/raycast/preview-dark.html +0 -606
- package/.opencode/oh-my-design/web/references/raycast/preview.html +0 -688
- package/.opencode/oh-my-design/web/references/remember/.verification.md +0 -135
- package/.opencode/oh-my-design/web/references/remember/DESIGN.md +0 -504
- package/.opencode/oh-my-design/web/references/remember/_promo.json +0 -27
- package/.opencode/oh-my-design/web/references/remember/_research.md +0 -90
- package/.opencode/oh-my-design/web/references/renault/.verification.md +0 -139
- package/.opencode/oh-my-design/web/references/renault/DESIGN.md +0 -439
- package/.opencode/oh-my-design/web/references/renault/README.md +0 -23
- package/.opencode/oh-my-design/web/references/renault/preview-dark.html +0 -406
- package/.opencode/oh-my-design/web/references/renault/preview.html +0 -606
- package/.opencode/oh-my-design/web/references/replicate/.verification.md +0 -154
- package/.opencode/oh-my-design/web/references/replicate/DESIGN.md +0 -387
- package/.opencode/oh-my-design/web/references/replicate/README.md +0 -24
- package/.opencode/oh-my-design/web/references/replicate/preview-dark.html +0 -828
- package/.opencode/oh-my-design/web/references/replicate/preview.html +0 -831
- package/.opencode/oh-my-design/web/references/resend/.verification.md +0 -143
- package/.opencode/oh-my-design/web/references/resend/DESIGN.md +0 -440
- package/.opencode/oh-my-design/web/references/resend/README.md +0 -23
- package/.opencode/oh-my-design/web/references/resend/preview-dark.html +0 -355
- package/.opencode/oh-my-design/web/references/resend/preview.html +0 -354
- package/.opencode/oh-my-design/web/references/retool/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/retool/DESIGN.md +0 -645
- package/.opencode/oh-my-design/web/references/revolut/.verification.md +0 -140
- package/.opencode/oh-my-design/web/references/revolut/DESIGN.md +0 -319
- package/.opencode/oh-my-design/web/references/revolut/README.md +0 -23
- package/.opencode/oh-my-design/web/references/revolut/preview-dark.html +0 -234
- package/.opencode/oh-my-design/web/references/revolut/preview.html +0 -233
- package/.opencode/oh-my-design/web/references/richart/.verification.md +0 -41
- package/.opencode/oh-my-design/web/references/richart/DESIGN.md +0 -465
- package/.opencode/oh-my-design/web/references/ridi/.verification.md +0 -108
- package/.opencode/oh-my-design/web/references/ridi/DESIGN.md +0 -573
- package/.opencode/oh-my-design/web/references/riiid/.verification.md +0 -33
- package/.opencode/oh-my-design/web/references/riiid/DESIGN.md +0 -260
- package/.opencode/oh-my-design/web/references/ringle/.verification.md +0 -53
- package/.opencode/oh-my-design/web/references/ringle/DESIGN.md +0 -444
- package/.opencode/oh-my-design/web/references/robinhood/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/robinhood/DESIGN.md +0 -604
- package/.opencode/oh-my-design/web/references/runwayml/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/runwayml/DESIGN.md +0 -431
- package/.opencode/oh-my-design/web/references/runwayml/README.md +0 -24
- package/.opencode/oh-my-design/web/references/runwayml/preview-dark.html +0 -664
- package/.opencode/oh-my-design/web/references/runwayml/preview.html +0 -665
- package/.opencode/oh-my-design/web/references/salesforce/.verification.md +0 -66
- package/.opencode/oh-my-design/web/references/salesforce/DESIGN.md +0 -473
- package/.opencode/oh-my-design/web/references/sanity/.verification.md +0 -174
- package/.opencode/oh-my-design/web/references/sanity/DESIGN.md +0 -499
- package/.opencode/oh-my-design/web/references/sanity/README.md +0 -24
- package/.opencode/oh-my-design/web/references/sanity/preview-dark.html +0 -990
- package/.opencode/oh-my-design/web/references/sanity/preview.html +0 -1135
- package/.opencode/oh-my-design/web/references/sansan/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/sansan/DESIGN.md +0 -631
- package/.opencode/oh-my-design/web/references/sendbird/.verification.md +0 -67
- package/.opencode/oh-my-design/web/references/sendbird/DESIGN.md +0 -331
- package/.opencode/oh-my-design/web/references/sentry/.verification.md +0 -157
- package/.opencode/oh-my-design/web/references/sentry/DESIGN.md +0 -397
- package/.opencode/oh-my-design/web/references/sentry/README.md +0 -24
- package/.opencode/oh-my-design/web/references/sentry/preview-dark.html +0 -626
- package/.opencode/oh-my-design/web/references/sentry/preview.html +0 -951
- package/.opencode/oh-my-design/web/references/shinhancard/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/shinhancard/DESIGN.md +0 -421
- package/.opencode/oh-my-design/web/references/shopline/.verification.md +0 -34
- package/.opencode/oh-my-design/web/references/shopline/DESIGN.md +0 -431
- package/.opencode/oh-my-design/web/references/slack/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/slack/DESIGN.md +0 -635
- package/.opencode/oh-my-design/web/references/smarthr/DESIGN.md +0 -452
- package/.opencode/oh-my-design/web/references/smartnews/DESIGN.md +0 -360
- package/.opencode/oh-my-design/web/references/socar/DESIGN.md +0 -438
- package/.opencode/oh-my-design/web/references/socar/_promo.json +0 -28
- package/.opencode/oh-my-design/web/references/socar/_research.md +0 -55
- package/.opencode/oh-my-design/web/references/soomgo/.verification.md +0 -27
- package/.opencode/oh-my-design/web/references/soomgo/DESIGN.md +0 -326
- package/.opencode/oh-my-design/web/references/spacex/.verification.md +0 -132
- package/.opencode/oh-my-design/web/references/spacex/DESIGN.md +0 -415
- package/.opencode/oh-my-design/web/references/spacex/README.md +0 -23
- package/.opencode/oh-my-design/web/references/spacex/_research.md +0 -69
- package/.opencode/oh-my-design/web/references/spacex/preview-dark.html +0 -221
- package/.opencode/oh-my-design/web/references/spacex/preview.html +0 -220
- package/.opencode/oh-my-design/web/references/spoon/DESIGN.md +0 -492
- package/.opencode/oh-my-design/web/references/spotify/.verification.md +0 -128
- package/.opencode/oh-my-design/web/references/spotify/DESIGN.md +0 -489
- package/.opencode/oh-my-design/web/references/spotify/README.md +0 -23
- package/.opencode/oh-my-design/web/references/spotify/preview-dark.html +0 -231
- package/.opencode/oh-my-design/web/references/spotify/preview.html +0 -230
- package/.opencode/oh-my-design/web/references/starbucks/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/starbucks/DESIGN.md +0 -597
- package/.opencode/oh-my-design/web/references/stores/.verification.md +0 -61
- package/.opencode/oh-my-design/web/references/stores/DESIGN.md +0 -447
- package/.opencode/oh-my-design/web/references/stripe/.verification.md +0 -140
- package/.opencode/oh-my-design/web/references/stripe/DESIGN.md +0 -571
- package/.opencode/oh-my-design/web/references/stripe/README.md +0 -24
- package/.opencode/oh-my-design/web/references/stripe/preview-dark.html +0 -428
- package/.opencode/oh-my-design/web/references/stripe/preview.html +0 -419
- package/.opencode/oh-my-design/web/references/studio/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/studio/DESIGN.md +0 -602
- package/.opencode/oh-my-design/web/references/supabase/.verification.md +0 -145
- package/.opencode/oh-my-design/web/references/supabase/DESIGN.md +0 -389
- package/.opencode/oh-my-design/web/references/supabase/README.md +0 -24
- package/.opencode/oh-my-design/web/references/supabase/preview-dark.html +0 -977
- package/.opencode/oh-my-design/web/references/supabase/preview.html +0 -955
- package/.opencode/oh-my-design/web/references/superhuman/.verification.md +0 -184
- package/.opencode/oh-my-design/web/references/superhuman/DESIGN.md +0 -453
- package/.opencode/oh-my-design/web/references/superhuman/README.md +0 -23
- package/.opencode/oh-my-design/web/references/superhuman/preview-dark.html +0 -973
- package/.opencode/oh-my-design/web/references/superhuman/preview.html +0 -951
- package/.opencode/oh-my-design/web/references/surveycake/.verification.md +0 -31
- package/.opencode/oh-my-design/web/references/surveycake/DESIGN.md +0 -442
- package/.opencode/oh-my-design/web/references/tada/DESIGN.md +0 -579
- package/.opencode/oh-my-design/web/references/teamblind/.verification.md +0 -76
- package/.opencode/oh-my-design/web/references/teamblind/DESIGN.md +0 -497
- package/.opencode/oh-my-design/web/references/tesla/.verification.md +0 -149
- package/.opencode/oh-my-design/web/references/tesla/DESIGN.md +0 -501
- package/.opencode/oh-my-design/web/references/tesla/README.md +0 -23
- package/.opencode/oh-my-design/web/references/tesla/_research.md +0 -70
- package/.opencode/oh-my-design/web/references/tesla/preview-dark.html +0 -947
- package/.opencode/oh-my-design/web/references/tesla/preview.html +0 -925
- package/.opencode/oh-my-design/web/references/theverge/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/theverge/DESIGN.md +0 -500
- package/.opencode/oh-my-design/web/references/timee/.verification.md +0 -67
- package/.opencode/oh-my-design/web/references/timee/DESIGN.md +0 -444
- package/.opencode/oh-my-design/web/references/together.ai/.verification.md +0 -145
- package/.opencode/oh-my-design/web/references/together.ai/DESIGN.md +0 -389
- package/.opencode/oh-my-design/web/references/together.ai/README.md +0 -24
- package/.opencode/oh-my-design/web/references/together.ai/preview-dark.html +0 -892
- package/.opencode/oh-my-design/web/references/together.ai/preview.html +0 -897
- package/.opencode/oh-my-design/web/references/toss/.verification.md +0 -120
- package/.opencode/oh-my-design/web/references/toss/DESIGN.md +0 -698
- package/.opencode/oh-my-design/web/references/toss/README.md +0 -19
- package/.opencode/oh-my-design/web/references/toss-securities/DESIGN.md +0 -247
- package/.opencode/oh-my-design/web/references/toss-securities/assets/_reference/.live-inspect-proof.json +0 -126
- package/.opencode/oh-my-design/web/references/toss-securities/assets/_reference/.live-inspect-raw.json +0 -619
- package/.opencode/oh-my-design/web/references/toss-securities/assets/_reference/.live-inspect-stock.json +0 -525
- package/.opencode/oh-my-design/web/references/toss-securities/assets/_reference/fonts.json +0 -24
- package/.opencode/oh-my-design/web/references/toss-securities/assets/_reference/structure.json +0 -35
- package/.opencode/oh-my-design/web/references/toss-securities/assets/_reference/tokens.json +0 -87
- package/.opencode/oh-my-design/web/references/tossbank/DESIGN.md +0 -576
- package/.opencode/oh-my-design/web/references/trenbe/.verification.md +0 -32
- package/.opencode/oh-my-design/web/references/trenbe/DESIGN.md +0 -293
- package/.opencode/oh-my-design/web/references/triple/DESIGN.md +0 -481
- package/.opencode/oh-my-design/web/references/tumblbug/DESIGN.md +0 -578
- package/.opencode/oh-my-design/web/references/tving/DESIGN.md +0 -317
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/.live-inspect-proof.json +0 -131
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/LICENSE-NOTE.md +0 -37
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/attribution.md +0 -52
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/fonts.json +0 -31
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/screenshots/hero-desktop.png +0 -0
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/structure.json +0 -55
- package/.opencode/oh-my-design/web/references/tving/assets/_reference/tokens.json +0 -115
- package/.opencode/oh-my-design/web/references/uber/.verification.md +0 -128
- package/.opencode/oh-my-design/web/references/uber/DESIGN.md +0 -423
- package/.opencode/oh-my-design/web/references/uber/README.md +0 -24
- package/.opencode/oh-my-design/web/references/uber/preview-dark.html +0 -1120
- package/.opencode/oh-my-design/web/references/uber/preview.html +0 -1119
- package/.opencode/oh-my-design/web/references/ubie/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/ubie/DESIGN.md +0 -615
- package/.opencode/oh-my-design/web/references/uniqlo/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/uniqlo/DESIGN.md +0 -575
- package/.opencode/oh-my-design/web/references/upbit/DESIGN.md +0 -337
- package/.opencode/oh-my-design/web/references/upbit/_research.md +0 -83
- package/.opencode/oh-my-design/web/references/upbit/assets/_reference/.live-inspect-proof.json +0 -263
- package/.opencode/oh-my-design/web/references/upbit/assets/_reference/fonts.json +0 -18
- package/.opencode/oh-my-design/web/references/upbit/assets/_reference/raw-capture-exchange.json +0 -1901
- package/.opencode/oh-my-design/web/references/upbit/assets/_reference/raw-capture.json +0 -1121
- package/.opencode/oh-my-design/web/references/upbit/assets/_reference/structure.json +0 -52
- package/.opencode/oh-my-design/web/references/upbit/assets/_reference/tokens.json +0 -169
- package/.opencode/oh-my-design/web/references/upstage/DESIGN.md +0 -270
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/.live-inspect-proof.json +0 -157
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/_brand-resource-center.json +0 -44
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/_curated-samples.json +0 -310
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/_raw-capture.json +0 -1560
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/_root-vars.json +0 -76
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/_structure-raw.json +0 -298
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/fonts.json +0 -35
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/structure.json +0 -72
- package/.opencode/oh-my-design/web/references/upstage/assets/_reference/tokens.json +0 -183
- package/.opencode/oh-my-design/web/references/velog/.verification.md +0 -26
- package/.opencode/oh-my-design/web/references/velog/DESIGN.md +0 -196
- package/.opencode/oh-my-design/web/references/vercel/.verification.md +0 -134
- package/.opencode/oh-my-design/web/references/vercel/DESIGN.md +0 -523
- package/.opencode/oh-my-design/web/references/vercel/README.md +0 -24
- package/.opencode/oh-my-design/web/references/vercel/preview-dark.html +0 -368
- package/.opencode/oh-my-design/web/references/vercel/preview.html +0 -367
- package/.opencode/oh-my-design/web/references/voicetube/.verification.md +0 -34
- package/.opencode/oh-my-design/web/references/voicetube/DESIGN.md +0 -266
- package/.opencode/oh-my-design/web/references/voltagent/.verification.md +0 -159
- package/.opencode/oh-my-design/web/references/voltagent/DESIGN.md +0 -454
- package/.opencode/oh-my-design/web/references/voltagent/README.md +0 -24
- package/.opencode/oh-my-design/web/references/voltagent/preview-dark.html +0 -487
- package/.opencode/oh-my-design/web/references/voltagent/preview.html +0 -766
- package/.opencode/oh-my-design/web/references/wadiz/DESIGN.md +0 -415
- package/.opencode/oh-my-design/web/references/wadiz/assets/_reference/.live-inspect-proof.json +0 -137
- package/.opencode/oh-my-design/web/references/wadiz/assets/_reference/fonts.json +0 -17
- package/.opencode/oh-my-design/web/references/wadiz/assets/_reference/structure.json +0 -35
- package/.opencode/oh-my-design/web/references/wadiz/assets/_reference/tokens.json +0 -80
- package/.opencode/oh-my-design/web/references/wanted/DESIGN.md +0 -575
- package/.opencode/oh-my-design/web/references/wanted/_promo.json +0 -31
- package/.opencode/oh-my-design/web/references/wanted/_research.md +0 -119
- package/.opencode/oh-my-design/web/references/wantedly/.verification.md +0 -53
- package/.opencode/oh-my-design/web/references/wantedly/DESIGN.md +0 -437
- package/.opencode/oh-my-design/web/references/warp/.verification.md +0 -156
- package/.opencode/oh-my-design/web/references/warp/DESIGN.md +0 -431
- package/.opencode/oh-my-design/web/references/warp/README.md +0 -23
- package/.opencode/oh-my-design/web/references/warp/preview-dark.html +0 -500
- package/.opencode/oh-my-design/web/references/warp/preview.html +0 -533
- package/.opencode/oh-my-design/web/references/watcha/DESIGN.md +0 -465
- package/.opencode/oh-my-design/web/references/wavve/DESIGN.md +0 -480
- package/.opencode/oh-my-design/web/references/wconcept/DESIGN.md +0 -556
- package/.opencode/oh-my-design/web/references/webflow/.verification.md +0 -151
- package/.opencode/oh-my-design/web/references/webflow/DESIGN.md +0 -330
- package/.opencode/oh-my-design/web/references/webflow/README.md +0 -23
- package/.opencode/oh-my-design/web/references/webflow/preview-dark.html +0 -147
- package/.opencode/oh-my-design/web/references/webflow/preview.html +0 -146
- package/.opencode/oh-my-design/web/references/wired/.verification.md +0 -21
- package/.opencode/oh-my-design/web/references/wired/DESIGN.md +0 -572
- package/.opencode/oh-my-design/web/references/wise/.verification.md +0 -141
- package/.opencode/oh-my-design/web/references/wise/DESIGN.md +0 -317
- package/.opencode/oh-my-design/web/references/wise/README.md +0 -23
- package/.opencode/oh-my-design/web/references/wise/preview-dark.html +0 -230
- package/.opencode/oh-my-design/web/references/wise/preview.html +0 -229
- package/.opencode/oh-my-design/web/references/x.ai/.verification.md +0 -140
- package/.opencode/oh-my-design/web/references/x.ai/DESIGN.md +0 -397
- package/.opencode/oh-my-design/web/references/x.ai/README.md +0 -24
- package/.opencode/oh-my-design/web/references/x.ai/preview-dark.html +0 -356
- package/.opencode/oh-my-design/web/references/x.ai/preview.html +0 -407
- package/.opencode/oh-my-design/web/references/xiaohongshu/DESIGN.md +0 -462
- package/.opencode/oh-my-design/web/references/yanolja/.verification.md +0 -83
- package/.opencode/oh-my-design/web/references/yanolja/DESIGN.md +0 -508
- package/.opencode/oh-my-design/web/references/yeogiotte/.verification.md +0 -210
- package/.opencode/oh-my-design/web/references/yeogiotte/DESIGN.md +0 -500
- package/.opencode/oh-my-design/web/references/yogiyo/DESIGN.md +0 -515
- package/.opencode/oh-my-design/web/references/yourator/.verification.md +0 -39
- package/.opencode/oh-my-design/web/references/yourator/DESIGN.md +0 -453
- package/.opencode/oh-my-design/web/references/zapier/.verification.md +0 -156
- package/.opencode/oh-my-design/web/references/zapier/DESIGN.md +0 -474
- package/.opencode/oh-my-design/web/references/zapier/README.md +0 -24
- package/.opencode/oh-my-design/web/references/zapier/preview-dark.html +0 -380
- package/.opencode/oh-my-design/web/references/zapier/preview.html +0 -372
- package/.opencode/oh-my-design/web/references/zigbang/DESIGN.md +0 -500
- package/.opencode/oh-my-design/web/references/zigbang/_promo.json +0 -16
- package/.opencode/oh-my-design/web/references/zigbang/_research.md +0 -101
- package/.opencode/oh-my-design/web/references/zigzag/DESIGN.md +0 -695
- package/.opencode/oh-my-design/web/references/zigzag/_promo.json +0 -23
- package/.opencode/oh-my-design/web/references/zigzag/_research.md +0 -64
- package/.opencode/oh-my-design/web/references/zozotown/.verification.md +0 -20
- package/.opencode/oh-my-design/web/references/zozotown/DESIGN.md +0 -578
- package/.opencode/oh-my-design/web/scripts/build-registry.mjs +0 -257
- package/.opencode/oh-my-design/web/scripts/extract-tokens.mjs +0 -117
- package/.opencode/oh-my-design/web/scripts/fetch-og-images.mjs +0 -112
- package/.opencode/oh-my-design/web/scripts/gen-favicon.mjs +0 -58
- package/.opencode/oh-my-design/web/scripts/gen-og.mjs +0 -67
- package/.opencode/oh-my-design/web/scripts/migrate-frontmatters.mjs +0 -637
- package/.opencode/oh-my-design/web/scripts/sync-catalog.mjs +0 -140
- package/.opencode/oh-my-design/web/scripts/token-sheet.mjs +0 -72
- package/.opencode/oh-my-design/web/scripts/token-status.mjs +0 -94
- package/.opencode/oh-my-design/web/scripts/verify-reference.mjs +0 -185
- package/.opencode/oh-my-design/web/src/app/alternatives/[slug]/page.tsx +0 -399
- package/.opencode/oh-my-design/web/src/app/api/font-playground/match/route.ts +0 -205
- package/.opencode/oh-my-design/web/src/app/api/leaderboard/route.ts +0 -32
- package/.opencode/oh-my-design/web/src/app/api/og/playground/route.tsx +0 -179
- package/.opencode/oh-my-design/web/src/app/api/references/[id]/route.ts +0 -162
- package/.opencode/oh-my-design/web/src/app/api/references/route.ts +0 -142
- package/.opencode/oh-my-design/web/src/app/api/track/route.ts +0 -30
- package/.opencode/oh-my-design/web/src/app/apple-icon.png +0 -0
- package/.opencode/oh-my-design/web/src/app/builder/layout.tsx +0 -43
- package/.opencode/oh-my-design/web/src/app/builder/page.tsx +0 -434
- package/.opencode/oh-my-design/web/src/app/changelog/[version]/page.tsx +0 -160
- package/.opencode/oh-my-design/web/src/app/changelog/page.tsx +0 -142
- package/.opencode/oh-my-design/web/src/app/collections/[slug]/collection-grid.tsx +0 -27
- package/.opencode/oh-my-design/web/src/app/collections/[slug]/page.tsx +0 -171
- package/.opencode/oh-my-design/web/src/app/curation/layout.tsx +0 -43
- package/.opencode/oh-my-design/web/src/app/curation/page.tsx +0 -78
- package/.opencode/oh-my-design/web/src/app/design-systems/[id]/detail-view.tsx +0 -307
- package/.opencode/oh-my-design/web/src/app/design-systems/[id]/page.tsx +0 -184
- package/.opencode/oh-my-design/web/src/app/design-systems/layout.tsx +0 -24
- package/.opencode/oh-my-design/web/src/app/design-systems/page.tsx +0 -95
- package/.opencode/oh-my-design/web/src/app/docs/layout.tsx +0 -22
- package/.opencode/oh-my-design/web/src/app/docs/page.tsx +0 -1453
- package/.opencode/oh-my-design/web/src/app/faq/page.tsx +0 -324
- package/.opencode/oh-my-design/web/src/app/font-playground/font-playground-view.tsx +0 -424
- package/.opencode/oh-my-design/web/src/app/font-playground/page.tsx +0 -43
- package/.opencode/oh-my-design/web/src/app/globals.css +0 -328
- package/.opencode/oh-my-design/web/src/app/icon.png +0 -0
- package/.opencode/oh-my-design/web/src/app/layout.tsx +0 -229
- package/.opencode/oh-my-design/web/src/app/page.tsx +0 -50
- package/.opencode/oh-my-design/web/src/app/playground/page.tsx +0 -81
- package/.opencode/oh-my-design/web/src/app/playground/playground-view.tsx +0 -436
- package/.opencode/oh-my-design/web/src/app/qa-references/page.tsx +0 -233
- package/.opencode/oh-my-design/web/src/app/r/[id]/route.ts +0 -57
- package/.opencode/oh-my-design/web/src/app/reference/[id]/page.tsx +0 -152
- package/.opencode/oh-my-design/web/src/app/result/[typeCode]/layout.tsx +0 -70
- package/.opencode/oh-my-design/web/src/app/result/[typeCode]/page.tsx +0 -280
- package/.opencode/oh-my-design/web/src/app/robots.ts +0 -44
- package/.opencode/oh-my-design/web/src/app/sitemap.ts +0 -156
- package/.opencode/oh-my-design/web/src/app/what-is-design-md/page.tsx +0 -308
- package/.opencode/oh-my-design/web/src/components/ab-picker.tsx +0 -74
- package/.opencode/oh-my-design/web/src/components/analytics-init.tsx +0 -21
- package/.opencode/oh-my-design/web/src/components/brand-logo.tsx +0 -101
- package/.opencode/oh-my-design/web/src/components/browse-modal.tsx +0 -149
- package/.opencode/oh-my-design/web/src/components/component-modal.tsx +0 -108
- package/.opencode/oh-my-design/web/src/components/content-preview-modal.tsx +0 -213
- package/.opencode/oh-my-design/web/src/components/customizer.tsx +0 -641
- package/.opencode/oh-my-design/web/src/components/design-wizard.tsx +0 -691
- package/.opencode/oh-my-design/web/src/components/ds-card.tsx +0 -162
- package/.opencode/oh-my-design/web/src/components/export-panel.tsx +0 -162
- package/.opencode/oh-my-design/web/src/components/font-card.tsx +0 -121
- package/.opencode/oh-my-design/web/src/components/font-playground/color-palette.tsx +0 -86
- package/.opencode/oh-my-design/web/src/components/font-playground/detail-modal.tsx +0 -789
- package/.opencode/oh-my-design/web/src/components/font-playground/filter-bar.tsx +0 -192
- package/.opencode/oh-my-design/web/src/components/font-playground/font-tile.tsx +0 -92
- package/.opencode/oh-my-design/web/src/components/font-playground/gallery.tsx +0 -42
- package/.opencode/oh-my-design/web/src/components/font-playground/hero-entry.tsx +0 -150
- package/.opencode/oh-my-design/web/src/components/font-playground/labels.ts +0 -18
- package/.opencode/oh-my-design/web/src/components/font-playground/match-results.tsx +0 -486
- package/.opencode/oh-my-design/web/src/components/font-playground/my-fonts.tsx +0 -315
- package/.opencode/oh-my-design/web/src/components/font-playground/preview-templates.tsx +0 -395
- package/.opencode/oh-my-design/web/src/components/font-playground/sample-input.tsx +0 -30
- package/.opencode/oh-my-design/web/src/components/font-playground/script-toggle.tsx +0 -73
- package/.opencode/oh-my-design/web/src/components/font-playground/usage-guide.tsx +0 -172
- package/.opencode/oh-my-design/web/src/components/install-cta.tsx +0 -133
- package/.opencode/oh-my-design/web/src/components/landing-v2/hero.tsx +0 -459
- package/.opencode/oh-my-design/web/src/components/landing-v2/live-proof.tsx +0 -464
- package/.opencode/oh-my-design/web/src/components/landing-v2/nav.tsx +0 -126
- package/.opencode/oh-my-design/web/src/components/landing-v2/sections.tsx +0 -1166
- package/.opencode/oh-my-design/web/src/components/landing-v2/the-wall.tsx +0 -332
- package/.opencode/oh-my-design/web/src/components/landing-v2/tokens.ts +0 -33
- package/.opencode/oh-my-design/web/src/components/markdown.tsx +0 -168
- package/.opencode/oh-my-design/web/src/components/playground/actions-header.tsx +0 -28
- package/.opencode/oh-my-design/web/src/components/playground/contrast-badge.tsx +0 -112
- package/.opencode/oh-my-design/web/src/components/playground/controls/category-section.tsx +0 -50
- package/.opencode/oh-my-design/web/src/components/playground/controls/color-picker.tsx +0 -116
- package/.opencode/oh-my-design/web/src/components/playground/controls/density-picker.tsx +0 -56
- package/.opencode/oh-my-design/web/src/components/playground/controls/mood-picker.tsx +0 -53
- package/.opencode/oh-my-design/web/src/components/playground/controls/motion-picker.tsx +0 -62
- package/.opencode/oh-my-design/web/src/components/playground/controls/name-description.tsx +0 -55
- package/.opencode/oh-my-design/web/src/components/playground/controls/palette-grid.tsx +0 -111
- package/.opencode/oh-my-design/web/src/components/playground/controls/personas-picker.tsx +0 -85
- package/.opencode/oh-my-design/web/src/components/playground/controls/radius-picker.tsx +0 -48
- package/.opencode/oh-my-design/web/src/components/playground/controls/voice-picker.tsx +0 -120
- package/.opencode/oh-my-design/web/src/components/playground/controls/weight-picker.tsx +0 -48
- package/.opencode/oh-my-design/web/src/components/playground/export-box.tsx +0 -120
- package/.opencode/oh-my-design/web/src/components/playground/header.tsx +0 -71
- package/.opencode/oh-my-design/web/src/components/playground/layout.tsx +0 -50
- package/.opencode/oh-my-design/web/src/components/playground/mobile-drawer.tsx +0 -78
- package/.opencode/oh-my-design/web/src/components/playground/mood-override-badge.tsx +0 -40
- package/.opencode/oh-my-design/web/src/components/playground/preview-pane.tsx +0 -82
- package/.opencode/oh-my-design/web/src/components/playground/primitives-strip.tsx +0 -153
- package/.opencode/oh-my-design/web/src/components/playground/reference-picker-modal.tsx +0 -146
- package/.opencode/oh-my-design/web/src/components/playground/share-button.tsx +0 -42
- package/.opencode/oh-my-design/web/src/components/playground/start-from.tsx +0 -90
- package/.opencode/oh-my-design/web/src/components/preview-export-view.tsx +0 -205
- package/.opencode/oh-my-design/web/src/components/preview.tsx +0 -869
- package/.opencode/oh-my-design/web/src/components/reference-preview.tsx +0 -1187
- package/.opencode/oh-my-design/web/src/components/reference-selector.tsx +0 -671
- package/.opencode/oh-my-design/web/src/components/scroll-to-top.tsx +0 -41
- package/.opencode/oh-my-design/web/src/components/status-badge.tsx +0 -64
- package/.opencode/oh-my-design/web/src/components/survey/company-mini-ui.tsx +0 -669
- package/.opencode/oh-my-design/web/src/components/survey/install-cta.tsx +0 -80
- package/.opencode/oh-my-design/web/src/components/survey/mood-step.tsx +0 -260
- package/.opencode/oh-my-design/web/src/components/survey/quiz-wizard.tsx +0 -528
- package/.opencode/oh-my-design/web/src/components/survey/result-card.tsx +0 -242
- package/.opencode/oh-my-design/web/src/components/survey/share-buttons.tsx +0 -320
- package/.opencode/oh-my-design/web/src/components/survey/survey-wizard.tsx +0 -661
- package/.opencode/oh-my-design/web/src/components/survey/typography-step.tsx +0 -192
- package/.opencode/oh-my-design/web/src/components/theme-provider.tsx +0 -12
- package/.opencode/oh-my-design/web/src/components/ui/badge.tsx +0 -52
- package/.opencode/oh-my-design/web/src/components/ui/button.tsx +0 -58
- package/.opencode/oh-my-design/web/src/components/ui/card.tsx +0 -103
- package/.opencode/oh-my-design/web/src/components/ui/dialog.tsx +0 -160
- package/.opencode/oh-my-design/web/src/components/ui/input.tsx +0 -20
- package/.opencode/oh-my-design/web/src/components/ui/label.tsx +0 -20
- package/.opencode/oh-my-design/web/src/components/ui/radio-group.tsx +0 -38
- package/.opencode/oh-my-design/web/src/components/ui/scroll-area.tsx +0 -55
- package/.opencode/oh-my-design/web/src/components/ui/select.tsx +0 -201
- package/.opencode/oh-my-design/web/src/components/ui/separator.tsx +0 -25
- package/.opencode/oh-my-design/web/src/components/ui/sheet.tsx +0 -138
- package/.opencode/oh-my-design/web/src/components/ui/slider.tsx +0 -52
- package/.opencode/oh-my-design/web/src/components/ui/switch.tsx +0 -32
- package/.opencode/oh-my-design/web/src/components/ui/tabs.tsx +0 -82
- package/.opencode/oh-my-design/web/src/components/ui/tooltip.tsx +0 -66
- package/.opencode/oh-my-design/web/src/data/faq.ts +0 -81
- package/.opencode/oh-my-design/web/src/data/registry.generated.ts +0 -304
- package/.opencode/oh-my-design/web/src/data/version.generated.ts +0 -2
- package/.opencode/oh-my-design/web/src/lib/changelog.ts +0 -96
- package/.opencode/oh-my-design/web/src/lib/collections.ts +0 -252
- package/.opencode/oh-my-design/web/src/lib/contrast.ts +0 -40
- package/.opencode/oh-my-design/web/src/lib/core/builder-prompt.test.ts +0 -100
- package/.opencode/oh-my-design/web/src/lib/core/builder-prompt.ts +0 -102
- package/.opencode/oh-my-design/web/src/lib/core/color.ts +0 -122
- package/.opencode/oh-my-design/web/src/lib/core/config-hash.test.ts +0 -157
- package/.opencode/oh-my-design/web/src/lib/core/config-hash.ts +0 -133
- package/.opencode/oh-my-design/web/src/lib/core/generate-css.test.ts +0 -813
- package/.opencode/oh-my-design/web/src/lib/core/generate-css.ts +0 -586
- package/.opencode/oh-my-design/web/src/lib/core/survey-hash.test.ts +0 -51
- package/.opencode/oh-my-design/web/src/lib/core/survey-hash.ts +0 -56
- package/.opencode/oh-my-design/web/src/lib/core/types.ts +0 -37
- package/.opencode/oh-my-design/web/src/lib/design-systems.ts +0 -102
- package/.opencode/oh-my-design/web/src/lib/extract-components.test.ts +0 -116
- package/.opencode/oh-my-design/web/src/lib/extract-tokens.test.ts +0 -202
- package/.opencode/oh-my-design/web/src/lib/extract-tokens.ts +0 -1335
- package/.opencode/oh-my-design/web/src/lib/font-registry.ts +0 -376
- package/.opencode/oh-my-design/web/src/lib/fonts/analytics.test.ts +0 -194
- package/.opencode/oh-my-design/web/src/lib/fonts/analytics.ts +0 -234
- package/.opencode/oh-my-design/web/src/lib/fonts/catalog.ts +0 -1509
- package/.opencode/oh-my-design/web/src/lib/fonts/designmd-export.ts +0 -104
- package/.opencode/oh-my-design/web/src/lib/fonts/loaders.test.ts +0 -169
- package/.opencode/oh-my-design/web/src/lib/fonts/loaders.ts +0 -90
- package/.opencode/oh-my-design/web/src/lib/fonts/match-intent.test.ts +0 -93
- package/.opencode/oh-my-design/web/src/lib/fonts/match-intent.ts +0 -288
- package/.opencode/oh-my-design/web/src/lib/fonts/preview-contexts.ts +0 -124
- package/.opencode/oh-my-design/web/src/lib/fonts/rate-limit.ts +0 -43
- package/.opencode/oh-my-design/web/src/lib/fonts/saved-store.ts +0 -113
- package/.opencode/oh-my-design/web/src/lib/fonts/share-link.test.ts +0 -101
- package/.opencode/oh-my-design/web/src/lib/fonts/share-link.ts +0 -52
- package/.opencode/oh-my-design/web/src/lib/fonts/similarity.ts +0 -106
- package/.opencode/oh-my-design/web/src/lib/fonts/tweaks.test.ts +0 -213
- package/.opencode/oh-my-design/web/src/lib/fonts/tweaks.ts +0 -186
- package/.opencode/oh-my-design/web/src/lib/fonts/types.ts +0 -96
- package/.opencode/oh-my-design/web/src/lib/gtag.ts +0 -64
- package/.opencode/oh-my-design/web/src/lib/hot-refs.ts +0 -41
- package/.opencode/oh-my-design/web/src/lib/kv.ts +0 -30
- package/.opencode/oh-my-design/web/src/lib/logos.ts +0 -39
- package/.opencode/oh-my-design/web/src/lib/new-refs.ts +0 -30
- package/.opencode/oh-my-design/web/src/lib/playground/codec.ts +0 -34
- package/.opencode/oh-my-design/web/src/lib/playground/defaults.ts +0 -56
- package/.opencode/oh-my-design/web/src/lib/playground/generate.ts +0 -384
- package/.opencode/oh-my-design/web/src/lib/playground/palettes.ts +0 -259
- package/.opencode/oh-my-design/web/src/lib/playground/rules/density.ts +0 -59
- package/.opencode/oh-my-design/web/src/lib/playground/rules/mood.ts +0 -82
- package/.opencode/oh-my-design/web/src/lib/playground/rules/motion.ts +0 -71
- package/.opencode/oh-my-design/web/src/lib/playground/rules/personality.ts +0 -93
- package/.opencode/oh-my-design/web/src/lib/playground/rules/philosophy.ts +0 -270
- package/.opencode/oh-my-design/web/src/lib/playground/rules/radius.ts +0 -54
- package/.opencode/oh-my-design/web/src/lib/playground/rules/weight.ts +0 -41
- package/.opencode/oh-my-design/web/src/lib/playground/samples.ts +0 -280
- package/.opencode/oh-my-design/web/src/lib/playground/state.ts +0 -194
- package/.opencode/oh-my-design/web/src/lib/search-aliases.ts +0 -213
- package/.opencode/oh-my-design/web/src/lib/survey/profiles.generated.ts +0 -1143
- package/.opencode/oh-my-design/web/src/lib/survey/quiz-data.test.ts +0 -102
- package/.opencode/oh-my-design/web/src/lib/survey/quiz-data.ts +0 -571
- package/.opencode/oh-my-design/web/src/lib/survey/scoring.test.ts +0 -111
- package/.opencode/oh-my-design/web/src/lib/survey/scoring.ts +0 -146
- package/.opencode/oh-my-design/web/src/lib/survey/types.test.ts +0 -153
- package/.opencode/oh-my-design/web/src/lib/survey/types.ts +0 -604
- package/.opencode/oh-my-design/web/src/lib/utils.ts +0 -6
- package/.opencode/oh-my-design/web/src/styles/shadcn.css +0 -95
- package/.opencode/oh-my-design/web/src/styles/tw-animate.css +0 -1
- package/.opencode/oh-my-design/web/src/types/gtag.d.ts +0 -3
- package/.opencode/oh-my-design/web/tsconfig.json +0 -34
- package/.opencode/oh-my-design/web/vitest.config.ts +0 -14
- package/.utils/docs_opencode/acp.md +0 -165
- package/.utils/docs_opencode/acp.pdf +0 -0
- package/.utils/docs_opencode/agents.md +0 -803
- package/.utils/docs_opencode/agents.pdf +0 -0
- package/.utils/docs_opencode/commands.md +0 -354
- package/.utils/docs_opencode/commands.pdf +0 -0
- package/.utils/docs_opencode/custom-tools.md +0 -209
- package/.utils/docs_opencode/custom-tools.pdf +0 -0
- package/.utils/docs_opencode/ecosystem.md +0 -81
- package/.utils/docs_opencode/ecosystem.pdf +0 -0
- package/.utils/docs_opencode/formatters.md +0 -142
- package/.utils/docs_opencode/formatters.pdf +0 -0
- package/.utils/docs_opencode/keybinds.md +0 -205
- package/.utils/docs_opencode/keybinds.pdf +0 -0
- package/.utils/docs_opencode/lsp.md +0 -202
- package/.utils/docs_opencode/lsp.pdf +0 -0
- package/.utils/docs_opencode/mcp-servers.md +0 -565
- package/.utils/docs_opencode/mcp-servers.pdf +0 -0
- package/.utils/docs_opencode/models.md +0 -234
- package/.utils/docs_opencode/models.pdf +0 -0
- package/.utils/docs_opencode/permissions.md +0 -248
- package/.utils/docs_opencode/permissions.pdf +0 -0
- package/.utils/docs_opencode/plugins.md +0 -409
- package/.utils/docs_opencode/plugins.pdf +0 -0
- package/.utils/docs_opencode/rules.md +0 -189
- package/.utils/docs_opencode/rules.pdf +0 -0
- package/.utils/docs_opencode/sdk.md +0 -522
- package/.utils/docs_opencode/sdk.pdf +0 -0
- package/.utils/docs_opencode/server.md +0 -324
- package/.utils/docs_opencode/server.pdf +0 -0
- package/.utils/docs_opencode/skills.md +0 -235
- package/.utils/docs_opencode/skills.pdf +0 -0
- package/.utils/docs_opencode/themes.md +0 -378
- package/.utils/docs_opencode/themes.pdf +0 -0
- package/.utils/docs_opencode/tools.md +0 -364
- package/.utils/docs_opencode/tools.pdf +0 -0
- package/.utils/zugzweb/client/node_modules/.tmp/tsconfig.app.tsbuildinfo +0 -1
- package/.utils/zugzweb/client/node_modules/.tmp/tsconfig.node.tsbuildinfo +0 -1
- package/.utils/zugzweb/client/node_modules/nanoid/.claude/settings.local.json +0 -14
- package/.utils/zugzweb/client/package-lock.json +0 -3707
|
@@ -1,1335 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extract structured design tokens from a parsed RefDetail + raw DESIGN.md.
|
|
3
|
-
*
|
|
4
|
-
* Returns a normalized ParsedTokens object that the showcase ReferencePreview
|
|
5
|
-
* component renders. Falls back to sensible defaults when DESIGN.md prose
|
|
6
|
-
* doesn't expose explicit values.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export interface FontMention {
|
|
10
|
-
/** Raw name as it appeared in DESIGN.md (e.g., "Helvetica Neue"). */
|
|
11
|
-
raw: string;
|
|
12
|
-
/** Inferred role: "primary" | "mono" | "display" | "serif" | "fallback" | "icon" */
|
|
13
|
-
role: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface TypographyTier {
|
|
17
|
-
label: string; // "Display XXL", "Heading XL", etc.
|
|
18
|
-
role: string; // "Display", "Heading 1", "Heading 2", "Body", "Small", "Caption", "Smallest"
|
|
19
|
-
sampleText: string; // copy shown at this tier
|
|
20
|
-
fontSize: number; // px
|
|
21
|
-
fontWeight: number;
|
|
22
|
-
lineHeight: number;
|
|
23
|
-
letterSpacing: string;
|
|
24
|
-
muted?: boolean; // render in muted color (Small/Caption/Smallest)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type ColorCategory = "brand" | "accent" | "neutral" | "semantic";
|
|
28
|
-
|
|
29
|
-
export interface ColorRole {
|
|
30
|
-
hex: string;
|
|
31
|
-
name: string; // human-friendly auto-derived name (e.g., "Slate", "Crimson")
|
|
32
|
-
category: ColorCategory;
|
|
33
|
-
description?: string; // 1-line role/usage if extractable, else heuristic
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface RadiusScaleItem {
|
|
37
|
-
element: string; // "buttons", "cards", "badges", "inputs", "dialogs", "default", "pill"
|
|
38
|
-
value: string; // "8px", "9999px"
|
|
39
|
-
label?: string; // "Standard", "Comfortable" — tier label from prose
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface SpacingItem {
|
|
43
|
-
value: number; // px
|
|
44
|
-
purpose?: string; // "Base unit", "Section gap" — when extractable
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/** Functional spacing roles (refero-style): a small fixed lexicon that maps to
|
|
48
|
-
* the values most readers care about — denser than the raw scale, more honest
|
|
49
|
-
* than "Step 1, Step 2, Step 3". Filled by `deriveFunctionalSpacing()`. */
|
|
50
|
-
export interface FunctionalSpacing {
|
|
51
|
-
density: "compact" | "comfortable" | "spacious";
|
|
52
|
-
baseUnit: number; // px — typically 4 or 8
|
|
53
|
-
sectionGap: number; // px — large vertical separator
|
|
54
|
-
cardPadding: number; // px — inside-card padding
|
|
55
|
-
elementGap: number; // px — gap between sibling elements
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Parsed component spec from §4 Component Stylings. Each variant is a flat
|
|
59
|
-
* field bag; the renderer decides how to map fields to a live instance.
|
|
60
|
-
* Spec is the source of truth — extracted as-written, not normalized into
|
|
61
|
-
* a hex/px enforcement layer (so prose like "transparent", "pill", "1px
|
|
62
|
-
* solid #..." round-trip cleanly into the live instance via raw CSS). */
|
|
63
|
-
export type ComponentType =
|
|
64
|
-
| "button"
|
|
65
|
-
| "input"
|
|
66
|
-
| "card"
|
|
67
|
-
| "badge"
|
|
68
|
-
| "tab"
|
|
69
|
-
| "toggle"
|
|
70
|
-
| "toast"
|
|
71
|
-
| "dialog"
|
|
72
|
-
| "listItem"
|
|
73
|
-
| "avatar";
|
|
74
|
-
|
|
75
|
-
export interface ComponentVariant {
|
|
76
|
-
name: string; // exact `**Variant Name**` from §4
|
|
77
|
-
bg?: string;
|
|
78
|
-
fg?: string;
|
|
79
|
-
border?: string;
|
|
80
|
-
radius?: string;
|
|
81
|
-
padding?: string;
|
|
82
|
-
height?: string; // structured-token field; not all variants specify it
|
|
83
|
-
font?: string; // free-form, e.g. "16px / 600 / Toss Product Sans"
|
|
84
|
-
hover?: string;
|
|
85
|
-
focus?: string;
|
|
86
|
-
active?: string;
|
|
87
|
-
disabled?: string;
|
|
88
|
-
shadow?: string;
|
|
89
|
-
use?: string;
|
|
90
|
-
extras: Record<string, string>; // unknown `- Foo: bar` lines preserved
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export interface ComponentBlock {
|
|
94
|
-
type: ComponentType;
|
|
95
|
-
heading: string; // exact `### ...` heading from §4 (e.g., "Cards & Containers")
|
|
96
|
-
variants: ComponentVariant[];
|
|
97
|
-
notes?: string; // trailing prose paragraph (after the variants)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export interface BorderToken {
|
|
101
|
-
element: string; // "Card", "Input default", "Focus ring", …
|
|
102
|
-
width: string; // "1px", "2px", "1.5px"
|
|
103
|
-
color?: string; // "#e0e0e0" — when extractable
|
|
104
|
-
style?: string; // "solid" / "dashed" — when extractable
|
|
105
|
-
raw?: string; // original prose snippet for fallback display
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface Guideline {
|
|
109
|
-
type: "do" | "dont";
|
|
110
|
-
text: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface ParsedTokens {
|
|
114
|
-
identity: {
|
|
115
|
-
id?: string;
|
|
116
|
-
name: string;
|
|
117
|
-
primary: string;
|
|
118
|
-
background: string;
|
|
119
|
-
foreground: string;
|
|
120
|
-
accent?: string;
|
|
121
|
-
border?: string;
|
|
122
|
-
mood: string;
|
|
123
|
-
};
|
|
124
|
-
typography: {
|
|
125
|
-
family: string;
|
|
126
|
-
mono?: string;
|
|
127
|
-
headingWeight: string;
|
|
128
|
-
weights: number[]; // sorted unique font-weights observed in DESIGN.md
|
|
129
|
-
sizes: number[]; // sorted unique font-sizes (px) observed
|
|
130
|
-
hierarchy: TypographyTier[]; // canonical 7-tier hierarchy derived from extracted sizes/weights
|
|
131
|
-
fonts: FontMention[]; // ALL fonts mentioned in §3 with role inference
|
|
132
|
-
};
|
|
133
|
-
/** Per-component-type radius derived from the brand's full radius value.
|
|
134
|
-
* Buttons/inputs keep full radius (pill OK). Cards/dialogs cap at 16px.
|
|
135
|
-
* Badges cap at 8px. Kept for backward compat with legacy preview.tsx. */
|
|
136
|
-
radii: {
|
|
137
|
-
button: string;
|
|
138
|
-
input: string;
|
|
139
|
-
card: string;
|
|
140
|
-
dialog: string;
|
|
141
|
-
badge: string;
|
|
142
|
-
};
|
|
143
|
-
/** Per-element radius scale parsed from §5 `### Border Radius Scale`. Falls
|
|
144
|
-
* back to the 5-element shape derived from `radii` when prose is missing. */
|
|
145
|
-
radiusScale: RadiusScaleItem[];
|
|
146
|
-
/** Hex colors discovered in §2 of DESIGN.md, deduped and sorted by usage frequency. */
|
|
147
|
-
palette: string[];
|
|
148
|
-
/** Heuristic-categorized colors with auto-derived names — drives the refero-style
|
|
149
|
-
* Color Palette section in ReferencePreview. */
|
|
150
|
-
paletteRoles: ColorRole[];
|
|
151
|
-
/** Spacing scale values found in DESIGN.md (px or rem). Falls back to 4dp scale. */
|
|
152
|
-
spacing: number[];
|
|
153
|
-
/** Spacing scale paired with role/purpose labels when extractable. */
|
|
154
|
-
spacingScale: SpacingItem[];
|
|
155
|
-
/** Refero-style 5-row functional spacing summary (Density / Base unit /
|
|
156
|
-
* Section gap / Card padding / Element gap). Always populated — derived
|
|
157
|
-
* heuristically when DESIGN.md prose doesn't supply explicit labels. */
|
|
158
|
-
functionalSpacing: FunctionalSpacing;
|
|
159
|
-
/** Border tokens — line widths/colors/styles applied to surfaces, inputs,
|
|
160
|
-
* focus rings. Empty when DESIGN.md doesn't expose explicit border prose. */
|
|
161
|
-
borders: BorderToken[];
|
|
162
|
-
/** Per-component variant specs parsed from §4 Component Stylings.
|
|
163
|
-
* Empty when DESIGN.md hasn't been migrated yet — UI falls back to a
|
|
164
|
-
* "no spec" state instead of fabricating dashboard mock content. */
|
|
165
|
-
components: ComponentBlock[];
|
|
166
|
-
/** Shadow recipes found in §6. Falls back to 3-tier defaults. */
|
|
167
|
-
shadows: { name: string; value: string }[];
|
|
168
|
-
/** Do / Don't guidelines parsed from `### Do` / `### Don't` headers. */
|
|
169
|
-
guidelines: Guideline[];
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const DEFAULT_SPACING = [4, 8, 12, 16, 24, 32, 48, 64];
|
|
173
|
-
const DEFAULT_SHADOWS = [
|
|
174
|
-
{ name: "Subtle", value: "0 1px 2px 0 rgba(0,0,0,0.05)" },
|
|
175
|
-
{ name: "Default", value: "0 1px 3px 0 rgba(0,0,0,0.1), 0 1px 2px 0 rgba(0,0,0,0.06)" },
|
|
176
|
-
{ name: "Elevated", value: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06)" },
|
|
177
|
-
{ name: "Floating", value: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05)" },
|
|
178
|
-
{ name: "Modal", value: "0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04)" },
|
|
179
|
-
];
|
|
180
|
-
|
|
181
|
-
/** Extract every font name mentioned in §3 with role inference.
|
|
182
|
-
* Looks at: **Primary**: `...`, **Monospace**: `...`, **Display**: `...`,
|
|
183
|
-
* font-family declarations, and capitalized backticked tokens.
|
|
184
|
-
* Filters hex colors, CSS keywords, and weight-like strings. */
|
|
185
|
-
function extractFontMentions(md: string): FontMention[] {
|
|
186
|
-
const sec3m = md.match(/## 3\. Typography[\s\S]*?(?=## 4\.)/i);
|
|
187
|
-
if (!sec3m) return [];
|
|
188
|
-
const sec3 = sec3m[0];
|
|
189
|
-
const seen = new Set<string>();
|
|
190
|
-
const out: FontMention[] = [];
|
|
191
|
-
const push = (raw: string, role: string) => {
|
|
192
|
-
const cleaned = raw.replace(/['"]/g, "").replace(/[;].*/, "").trim();
|
|
193
|
-
if (!cleaned || cleaned.length > 50) return;
|
|
194
|
-
if (/^#[0-9a-f]{3,8}$/i.test(cleaned)) return;
|
|
195
|
-
if (/^(serif|sans-serif|monospace|var|inherit|var\(|none)$/i.test(cleaned)) return;
|
|
196
|
-
const key = cleaned.toLowerCase();
|
|
197
|
-
if (seen.has(key)) return;
|
|
198
|
-
seen.add(key);
|
|
199
|
-
out.push({ raw: cleaned, role });
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// 1. **Primary** / **Monospace** / **Display** / **Serif** etc.
|
|
203
|
-
for (const m of sec3.matchAll(/\*\*(Primary|Monospace|Display|Mono|Serif|Sans|Heading|Body)[^*]*\*\*:?\s*`([^`]+)`/gi)) {
|
|
204
|
-
const role = m[1].toLowerCase().includes("mono") ? "mono"
|
|
205
|
-
: m[1].toLowerCase().includes("display") ? "display"
|
|
206
|
-
: m[1].toLowerCase().includes("serif") ? "serif"
|
|
207
|
-
: "primary";
|
|
208
|
-
m[2].split(",").forEach((f) => push(f.trim(), role));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// 2. font-family declarations
|
|
212
|
-
for (const m of sec3.matchAll(/font-family:\s*([^;\n]+)/gi)) {
|
|
213
|
-
m[1].split(",").forEach((f) => push(f.trim(), "fallback"));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// 3. Backticked capitalized font names (heuristic)
|
|
217
|
-
for (const m of sec3.matchAll(/`([A-Z][A-Za-z][\w\s\-]{2,40})`/g)) {
|
|
218
|
-
const name = m[1].trim();
|
|
219
|
-
if (name.length > 35) continue;
|
|
220
|
-
if (/^(?:Display|Heading|Body|Caption|Small|Large|Medium|Regular|Bold|Light|Italic|Mono|Sans|Serif|Variable|Variable Font|Variable Light|Variable Medium|Variable Bold|Pro|Pro Medium|Pro SemiBold|Pro Italic|Bold Italic|Italic|XS|S|M|L|XL|XXL|UI|UI Variable|Inter Placeholder|Inter Fallback|Fallback|Subhead|Hero|Mobile|Roman|Light Italic|Medium Italic|SemiBold|ExtraBold|Black|Thin|Header|NORMAL|0|RegularXXS|XXS|Open Source|Open|Source)$/i.test(name)) continue;
|
|
221
|
-
if (/^[0-9]/.test(name)) continue;
|
|
222
|
-
push(name, "primary");
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return out.slice(0, 12); // cap to keep card grids reasonable
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function capRadius(radius: string, maxPx: number): string {
|
|
229
|
-
const m = radius.match(/^(\d+)/);
|
|
230
|
-
if (!m) return radius;
|
|
231
|
-
return parseInt(m[1], 10) > maxPx ? `${maxPx}px` : radius;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/** Apply user overrides (from builder customizer) on top of the parsed tokens. */
|
|
235
|
-
export interface PreviewOverrides {
|
|
236
|
-
primaryColor?: string;
|
|
237
|
-
fontFamily?: string;
|
|
238
|
-
headingWeight?: string;
|
|
239
|
-
borderRadius?: string;
|
|
240
|
-
/** Wizard style preferences — optional, surface-level hints that the
|
|
241
|
-
* preview applies on top of the parsed token set so builder step 3 reflects
|
|
242
|
-
* the user's A/B choices (button pill vs. sharp, elevated vs. bordered
|
|
243
|
-
* card, compact vs. spacious density, underline vs. bordered input). */
|
|
244
|
-
stylePreferences?: {
|
|
245
|
-
buttonStyle?: string;
|
|
246
|
-
inputStyle?: string;
|
|
247
|
-
cardStyle?: string;
|
|
248
|
-
density?: string;
|
|
249
|
-
[key: string]: string | undefined;
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export function applyOverrides(tokens: ParsedTokens, overrides?: PreviewOverrides): ParsedTokens {
|
|
254
|
-
if (!overrides) return tokens;
|
|
255
|
-
const o = overrides;
|
|
256
|
-
// Treat empty string the same as undefined — an empty override means "keep
|
|
257
|
-
// the reference default", not "apply the empty value". Required because
|
|
258
|
-
// BuilderPage holds Overrides as `{primaryColor: string, ...}` with `''` as
|
|
259
|
-
// the sentinel for "unset" (see use-as-is path), and `??` would leak that.
|
|
260
|
-
const pick = <T extends string | undefined>(v: T, fallback: string) => (v ? v : fallback);
|
|
261
|
-
const baseRadius = pick(o.borderRadius, tokens.radii.button);
|
|
262
|
-
const headingWeight = pick(o.headingWeight, tokens.typography.headingWeight);
|
|
263
|
-
const family = pick(o.fontFamily, tokens.typography.family);
|
|
264
|
-
const prefs = o.stylePreferences ?? {};
|
|
265
|
-
|
|
266
|
-
const sortedSizes = [...tokens.typography.sizes].sort((a, b) => b - a);
|
|
267
|
-
const hWeight = parseInt(headingWeight, 10) || 700;
|
|
268
|
-
const hierarchy = tokens.typography.hierarchy.map((tier) => {
|
|
269
|
-
const isHeading = tier.role === "Display" || tier.role === "Heading 1" || tier.role === "Heading 2";
|
|
270
|
-
return {
|
|
271
|
-
...tier,
|
|
272
|
-
fontWeight: isHeading ? hWeight : tier.fontWeight,
|
|
273
|
-
};
|
|
274
|
-
});
|
|
275
|
-
void sortedSizes; // keep variable for future size override
|
|
276
|
-
|
|
277
|
-
// buttonStyle:rounded forces pills; buttonStyle:sharp clamps to <=4px even if
|
|
278
|
-
// the user's borderRadius is larger. Input radius follows button when the
|
|
279
|
-
// input style is bordered; underline decouples input from the radius system.
|
|
280
|
-
const buttonRadius = prefs.buttonStyle === 'rounded'
|
|
281
|
-
? '9999px'
|
|
282
|
-
: prefs.buttonStyle === 'sharp'
|
|
283
|
-
? capRadius(baseRadius, 4)
|
|
284
|
-
: baseRadius;
|
|
285
|
-
const inputRadius = prefs.inputStyle === 'underline' ? '0px' : buttonRadius;
|
|
286
|
-
|
|
287
|
-
// cardStyle:elevated keeps the ref's shadow; cardStyle:bordered strips it to
|
|
288
|
-
// a flat "none" recipe so the preview visually demonstrates the user's pick.
|
|
289
|
-
const shadows = prefs.cardStyle === 'bordered'
|
|
290
|
-
? [{ name: 'Flat', value: 'none' }, ...tokens.shadows.slice(1)]
|
|
291
|
-
: tokens.shadows;
|
|
292
|
-
|
|
293
|
-
const newPrimary = pick(o.primaryColor, tokens.identity.primary);
|
|
294
|
-
// If the user changed the primary color in the customizer, update the brand
|
|
295
|
-
// entry of paletteRoles so the swatch reflects their pick. Re-categorize the
|
|
296
|
-
// old primary (it might shift from "brand" → "accent"). Other categories are
|
|
297
|
-
// left untouched — heuristic re-rolling on every keystroke would be jarring.
|
|
298
|
-
const paletteRoles: ColorRole[] = (() => {
|
|
299
|
-
if (!tokens.paletteRoles?.length) return tokens.paletteRoles;
|
|
300
|
-
if (newPrimary.toLowerCase() === tokens.identity.primary.toLowerCase()) return tokens.paletteRoles;
|
|
301
|
-
return tokens.paletteRoles.map((r) => {
|
|
302
|
-
if (r.category === "brand") {
|
|
303
|
-
const cat = categorizeColor(r.hex, false);
|
|
304
|
-
return { ...r, category: cat };
|
|
305
|
-
}
|
|
306
|
-
if (r.hex.toLowerCase() === newPrimary.toLowerCase()) {
|
|
307
|
-
return { ...r, category: "brand", description: heuristicColorDescription("brand", true) };
|
|
308
|
-
}
|
|
309
|
-
return r;
|
|
310
|
-
});
|
|
311
|
-
})();
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
...tokens,
|
|
315
|
-
identity: {
|
|
316
|
-
...tokens.identity,
|
|
317
|
-
primary: newPrimary,
|
|
318
|
-
},
|
|
319
|
-
typography: {
|
|
320
|
-
...tokens.typography,
|
|
321
|
-
family,
|
|
322
|
-
headingWeight,
|
|
323
|
-
hierarchy,
|
|
324
|
-
},
|
|
325
|
-
radii: {
|
|
326
|
-
button: buttonRadius,
|
|
327
|
-
input: inputRadius,
|
|
328
|
-
card: capRadius(buttonRadius, 16),
|
|
329
|
-
dialog: capRadius(buttonRadius, 16),
|
|
330
|
-
badge: capRadius(buttonRadius, 8),
|
|
331
|
-
},
|
|
332
|
-
radiusScale: tokens.radiusScale.map((r) => {
|
|
333
|
-
// Customizer override takes precedence ONLY when the user actively
|
|
334
|
-
// dialled borderRadius. Otherwise we keep the per-element scale parsed
|
|
335
|
-
// from DESIGN.md so e.g. "Buttons: 8px / Cards: 20px / Pill: 9999px"
|
|
336
|
-
// renders truthfully instead of stamping a single value across all rows.
|
|
337
|
-
if (!o.borderRadius) return r;
|
|
338
|
-
const isPill = r.element === "pill" || r.value === "9999px";
|
|
339
|
-
if (isPill) return r;
|
|
340
|
-
if (r.element === "cards" || r.element === "dialogs") return { ...r, value: capRadius(buttonRadius, 16) };
|
|
341
|
-
if (r.element === "badges") return { ...r, value: capRadius(buttonRadius, 8) };
|
|
342
|
-
if (r.element === "inputs") return { ...r, value: inputRadius };
|
|
343
|
-
if (r.element === "buttons") return { ...r, value: buttonRadius };
|
|
344
|
-
return r;
|
|
345
|
-
}),
|
|
346
|
-
functionalSpacing: (() => {
|
|
347
|
-
// density preference (compact/comfortable/spacious) wins over the
|
|
348
|
-
// heuristic bucket so the user's customizer choice is reflected in the
|
|
349
|
-
// refero-style summary the same way it's already reflected in cardPad.
|
|
350
|
-
const userDensity = (prefs.density as FunctionalSpacing["density"] | undefined);
|
|
351
|
-
if (!userDensity) return tokens.functionalSpacing;
|
|
352
|
-
const fs = tokens.functionalSpacing;
|
|
353
|
-
const adjusted: FunctionalSpacing = (() => {
|
|
354
|
-
if (userDensity === "compact") return { ...fs, cardPadding: Math.min(fs.cardPadding, 12), elementGap: Math.min(fs.elementGap, 8) };
|
|
355
|
-
if (userDensity === "spacious") return { ...fs, cardPadding: Math.max(fs.cardPadding, 24), elementGap: Math.max(fs.elementGap, 16) };
|
|
356
|
-
return fs;
|
|
357
|
-
})();
|
|
358
|
-
return { ...adjusted, density: userDensity };
|
|
359
|
-
})(),
|
|
360
|
-
paletteRoles,
|
|
361
|
-
shadows,
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
function extractWeights(md: string): number[] {
|
|
366
|
-
const matches = [...md.matchAll(/font-weight:?\s*(\d{3})/gi)];
|
|
367
|
-
const weights = new Set<number>();
|
|
368
|
-
for (const m of matches) {
|
|
369
|
-
const w = parseInt(m[1], 10);
|
|
370
|
-
if (w >= 100 && w <= 900) weights.add(w);
|
|
371
|
-
}
|
|
372
|
-
// Also pick up bare weight references like "weight 700"
|
|
373
|
-
const bareMatches = [...md.matchAll(/\bweight\s+(\d{3})\b/gi)];
|
|
374
|
-
for (const m of bareMatches) {
|
|
375
|
-
const w = parseInt(m[1], 10);
|
|
376
|
-
if (w >= 100 && w <= 900) weights.add(w);
|
|
377
|
-
}
|
|
378
|
-
if (weights.size === 0) return [400, 500, 700];
|
|
379
|
-
return [...weights].sort((a, b) => a - b);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
function extractFontSizes(md: string): number[] {
|
|
383
|
-
const matches = [...md.matchAll(/(\d{2})px/g)];
|
|
384
|
-
const sizes = new Set<number>();
|
|
385
|
-
for (const m of matches) {
|
|
386
|
-
const n = parseInt(m[1], 10);
|
|
387
|
-
// Plausible body/heading sizes
|
|
388
|
-
if (n >= 10 && n <= 72) sizes.add(n);
|
|
389
|
-
}
|
|
390
|
-
// Pick a sensible scale: capture small/body/large/display
|
|
391
|
-
const sorted = [...sizes].sort((a, b) => a - b);
|
|
392
|
-
if (sorted.length < 4) return [12, 14, 16, 20, 24, 32];
|
|
393
|
-
// Reduce to ~6 representative sizes
|
|
394
|
-
const picks: number[] = [];
|
|
395
|
-
const targets = [10, 12, 14, 16, 20, 24, 32, 48];
|
|
396
|
-
for (const t of targets) {
|
|
397
|
-
const closest = sorted.reduce((a, b) => (Math.abs(b - t) < Math.abs(a - t) ? b : a));
|
|
398
|
-
if (!picks.includes(closest) && Math.abs(closest - t) <= 6) picks.push(closest);
|
|
399
|
-
}
|
|
400
|
-
return picks.length >= 4 ? picks : [12, 14, 16, 20, 24, 32];
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
function extractPalette(md: string): string[] {
|
|
404
|
-
// Section 2 (Color Palette) extraction; fall back to whole doc if §2 not found
|
|
405
|
-
const sec2 = md.match(/## 2\. Color[\s\S]*?(?=## 3\.)/i)?.[0] ?? md;
|
|
406
|
-
const matches = [...sec2.matchAll(/#([0-9a-fA-F]{6})\b/g)];
|
|
407
|
-
const counts = new Map<string, number>();
|
|
408
|
-
for (const m of matches) {
|
|
409
|
-
const hex = `#${m[1].toLowerCase()}`;
|
|
410
|
-
counts.set(hex, (counts.get(hex) ?? 0) + 1);
|
|
411
|
-
}
|
|
412
|
-
return [...counts.entries()]
|
|
413
|
-
.sort((a, b) => b[1] - a[1])
|
|
414
|
-
.map(([hex]) => hex)
|
|
415
|
-
.slice(0, 24);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/** Narrow spacing extraction to the `### Spacing System` subsection so we do
|
|
419
|
-
* NOT pick up max-width (980/1080/1200), section-padding (80–120), card-padding
|
|
420
|
-
* ranges, or letter-spacing values that also live in §5. Prefer the explicit
|
|
421
|
-
* "Scale: ..." line; fall back to base unit + 4-power scale. */
|
|
422
|
-
function extractSpacing(md: string): number[] {
|
|
423
|
-
const sec5 = md.match(/## 5\. Layout[\s\S]*?(?=## 6\.)/i)?.[0] ?? "";
|
|
424
|
-
// Subsection: `### Spacing System` block until next ###/##
|
|
425
|
-
const spacingBlock = sec5.match(/###\s*Spacing[\s\S]*?(?=\n###|\n##|$)/i)?.[0] ?? "";
|
|
426
|
-
const values = new Set<number>();
|
|
427
|
-
|
|
428
|
-
// 1. Direct "Scale: 2px, 4px, 8px..." line
|
|
429
|
-
const scaleLine = spacingBlock.match(/Scale:?\s*([^\n]+)/i)?.[1] ?? "";
|
|
430
|
-
for (const m of scaleLine.matchAll(/\b(\d{1,3})(?:px|dp)\b/g)) {
|
|
431
|
-
const n = parseInt(m[1], 10);
|
|
432
|
-
if (n >= 2 && n <= 96) values.add(n);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// 2. If still sparse, harvest small-range bullets inside the spacing block
|
|
436
|
-
if (values.size < 4) {
|
|
437
|
-
for (const m of spacingBlock.matchAll(/\b(\d{1,3})(?:px|dp)\b/g)) {
|
|
438
|
-
const n = parseInt(m[1], 10);
|
|
439
|
-
// Cap at 64 here — anything bigger inside Spacing System tends to be a
|
|
440
|
-
// section-padding outlier (80, 96, 120) we don't want in the swatch list.
|
|
441
|
-
if (n >= 2 && n <= 64) values.add(n);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (values.size < 3) return DEFAULT_SPACING;
|
|
446
|
-
return [...values].sort((a, b) => a - b).slice(0, 10);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/** Pair spacing px values with purpose labels by grepping the spacing block for
|
|
450
|
-
* "<purpose>: Xpx" or "Base unit: 8px". Best-effort; missing labels just
|
|
451
|
-
* surface as bare values in the preview. */
|
|
452
|
-
function extractSpacingScale(md: string, values: number[]): SpacingItem[] {
|
|
453
|
-
const sec5 = md.match(/## 5\. Layout[\s\S]*?(?=## 6\.)/i)?.[0] ?? "";
|
|
454
|
-
const block = sec5.match(/###\s*Spacing[\s\S]*?(?=\n###|\n##|$)/i)?.[0] ?? "";
|
|
455
|
-
const purposes = new Map<number, string>();
|
|
456
|
-
// "- Base unit: 8px" or "- Section gap: 80px" or "**Base unit**: 8px"
|
|
457
|
-
for (const m of block.matchAll(/^[-*]?\s*\*{0,2}([A-Za-z][\w\s/-]{2,30}?)\*{0,2}\s*[::]\s*(?:approximately\s+)?(\d{1,3})\s*(?:px|dp)/gim)) {
|
|
458
|
-
const purpose = m[1].trim().replace(/\s+/g, " ");
|
|
459
|
-
const n = parseInt(m[2], 10);
|
|
460
|
-
if (purpose.toLowerCase() === "scale") continue;
|
|
461
|
-
if (!purposes.has(n)) purposes.set(n, purpose);
|
|
462
|
-
}
|
|
463
|
-
return values.map((v) => ({ value: v, purpose: purposes.get(v) }));
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/** Conservative radius scale derivation when there's no `### Border Radius`
|
|
467
|
-
* block. We trust ONLY two signals: (a) `Default radius: `Npx`` as the
|
|
468
|
-
* canonical universal value, applied to common elements with the standard
|
|
469
|
-
* caps; (b) explicit pill/circle prose. We deliberately do NOT scan
|
|
470
|
-
* per-element forward/reverse regex — multi-value border-radius prose like
|
|
471
|
-
* "border-radius: 0px 4px 4px 0px" or "Counter (...): 8px radius, 14px weight"
|
|
472
|
-
* generates noise (0px assigned to cards, 14px assigned to buttons).
|
|
473
|
-
* The structured `### Border Radius Scale` block is the place for per-element
|
|
474
|
-
* diversity; absence of that block means "default everywhere" is the truth. */
|
|
475
|
-
function extractRadiusFromProse(md: string): RadiusScaleItem[] {
|
|
476
|
-
const out: RadiusScaleItem[] = [];
|
|
477
|
-
const defaultM = md.match(/\*{0,2}Default radius\*{0,2}\s*[::]\s*`?(\d+px)`?/i);
|
|
478
|
-
if (defaultM) {
|
|
479
|
-
const v = normalizeRadiusValue(defaultM[1]) ?? defaultM[1];
|
|
480
|
-
const cardCap = capRadius(v, 16);
|
|
481
|
-
const dialogCap = capRadius(v, 16);
|
|
482
|
-
const badgeCap = capRadius(v, 8);
|
|
483
|
-
out.push(
|
|
484
|
-
{ element: "buttons", value: v, label: "Default" },
|
|
485
|
-
{ element: "inputs", value: v, label: "Default" },
|
|
486
|
-
{ element: "cards", value: cardCap, label: "Default" },
|
|
487
|
-
{ element: "dialogs", value: dialogCap, label: "Default" },
|
|
488
|
-
{ element: "badges", value: badgeCap, label: "Default" },
|
|
489
|
-
);
|
|
490
|
-
}
|
|
491
|
-
if (/\b(?:full[- ]pill|pill[- ]shaped|pill\s+button)\b/i.test(md) && !out.some((r) => r.value === "9999px")) {
|
|
492
|
-
out.push({ element: "pill", value: "9999px", label: "Pill" });
|
|
493
|
-
}
|
|
494
|
-
if (/\bcircle\b|50%\s*radius/i.test(md) && !out.some((r) => r.value === "50%")) {
|
|
495
|
-
out.push({ element: "circle", value: "50%", label: "Circle" });
|
|
496
|
-
}
|
|
497
|
-
return out;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/** Parse `### Border Radius Scale` block in §5 into per-element entries.
|
|
501
|
-
* Recognised patterns:
|
|
502
|
-
* - "Standard (8px): Buttons, cards, badges"
|
|
503
|
-
* - "**Standard**: 8px — buttons, cards"
|
|
504
|
-
* - "Card (20px): Feature cards, large buttons"
|
|
505
|
-
* Returns one item per (label/element) pair. */
|
|
506
|
-
function extractRadiusScale(md: string): RadiusScaleItem[] {
|
|
507
|
-
const sec5 = md.match(/## 5\. Layout[\s\S]*?(?=## 6\.)/i)?.[0] ?? "";
|
|
508
|
-
const block = sec5.match(/###\s*Border\s*Radius[\s\S]*?(?=\n###|\n##|$)/i)?.[0] ?? "";
|
|
509
|
-
const out: RadiusScaleItem[] = [];
|
|
510
|
-
// Pattern 1: "- Standard (8px): Buttons, inputs"
|
|
511
|
-
for (const m of block.matchAll(/^[-*]\s*\*{0,2}([A-Za-z][\w\s-]{0,24}?)\*{0,2}\s*\(\s*([^)]+?)\s*\)\s*[::]\s*([^\n]+)/gm)) {
|
|
512
|
-
const label = m[1].trim();
|
|
513
|
-
const value = normalizeRadiusValue(m[2]);
|
|
514
|
-
const elementsRaw = m[3].trim();
|
|
515
|
-
if (!value) continue;
|
|
516
|
-
const elements = elementsRaw
|
|
517
|
-
.split(/[,,·]/)
|
|
518
|
-
.map((s) => s.replace(/[—–-].*/, "").replace(/\(.*?\)/g, "").trim().toLowerCase())
|
|
519
|
-
.filter((s) => s && s.length < 32);
|
|
520
|
-
if (elements.length === 0) {
|
|
521
|
-
out.push({ element: label.toLowerCase(), value, label });
|
|
522
|
-
} else {
|
|
523
|
-
for (const el of elements) out.push({ element: simplifyElementWord(el), value, label });
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
// De-dup by element keeping the first occurrence (which tends to be the
|
|
527
|
-
// canonical / smaller-tier mention in DESIGN.md prose).
|
|
528
|
-
const seen = new Set<string>();
|
|
529
|
-
return out.filter((r) => {
|
|
530
|
-
const k = `${r.element}|${r.value}`;
|
|
531
|
-
if (seen.has(k)) return false;
|
|
532
|
-
seen.add(k);
|
|
533
|
-
return true;
|
|
534
|
-
}).slice(0, 12);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
function normalizeRadiusValue(raw: string): string | null {
|
|
538
|
-
const s = raw.trim();
|
|
539
|
-
if (/^(full\s+pill|pill|circle)$/i.test(s)) return "9999px";
|
|
540
|
-
if (/^50%$/i.test(s)) return "50%";
|
|
541
|
-
// Multi-digit huge values ("33.5M px", "9999px", "1280px") → pill.
|
|
542
|
-
// Anything ≥ 64 is effectively a pill for a 32–48px button anyway, so
|
|
543
|
-
// collapse it to the canonical 9999 instead of confusing readers with
|
|
544
|
-
// "1280px" or "980px" — those values are accurate prose but useless tokens.
|
|
545
|
-
const numMatch = s.match(/(\d+(?:\.\d+)?)/);
|
|
546
|
-
if (!numMatch) return null;
|
|
547
|
-
const n = parseFloat(numMatch[1]);
|
|
548
|
-
if (n >= 64) return "9999px";
|
|
549
|
-
return `${Math.round(n)}px`;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/** Same threshold as normalizeRadiusValue — anything ≥64px collapses to pill.
|
|
553
|
-
* Used in fallback paths where we receive a single string value (detail.radius)
|
|
554
|
-
* that the source pipeline didn't sanitize. Keeps the preview honest: a
|
|
555
|
-
* literal "1280px" radius doesn't mean "1280px corner" — it means pill. */
|
|
556
|
-
function sanitizeRadiusString(value: string): string {
|
|
557
|
-
const m = value.match(/(\d+(?:\.\d+)?)/);
|
|
558
|
-
if (!m) return value;
|
|
559
|
-
const n = parseFloat(m[1]);
|
|
560
|
-
if (n >= 64) return "9999px";
|
|
561
|
-
return value;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const RADIUS_ELEMENT_CANON: Record<string, string> = {
|
|
565
|
-
cta: "buttons", "ctas": "buttons", button: "buttons", buttons: "buttons",
|
|
566
|
-
input: "inputs", inputs: "inputs", field: "inputs", fields: "inputs",
|
|
567
|
-
card: "cards", cards: "cards",
|
|
568
|
-
badge: "badges", badges: "badges", tag: "badges", tags: "badges", chip: "badges", chips: "badges",
|
|
569
|
-
dialog: "dialogs", dialogs: "dialogs", modal: "dialogs", modals: "dialogs",
|
|
570
|
-
pill: "pill", "full pill": "pill",
|
|
571
|
-
};
|
|
572
|
-
function simplifyElementWord(s: string): string {
|
|
573
|
-
const head = s.split(/\s+/)[0].replace(/[^a-z]/g, "");
|
|
574
|
-
return RADIUS_ELEMENT_CANON[head] ?? RADIUS_ELEMENT_CANON[s.trim()] ?? head ?? "default";
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
/** Map a list of spacing px values to refero's 5-row functional summary.
|
|
578
|
-
* Strategy:
|
|
579
|
-
* 1. Honour explicit purpose labels from spacingScale when present (DCard
|
|
580
|
-
* writes "- Header padding: 20px"; we still don't equate that with
|
|
581
|
-
* "Card padding" — only the canonical purpose names match).
|
|
582
|
-
* 2. Fill remaining slots heuristically: smallest non-trivial value → base,
|
|
583
|
-
* largest reasonable value → section gap, mid-low → card padding,
|
|
584
|
-
* mid-low → element gap.
|
|
585
|
-
* 3. Density bucket follows base unit (4 → compact, 8 → comfortable, ≥10 →
|
|
586
|
-
* spacious). User's `density` preference (if any) wins via overrides. */
|
|
587
|
-
function deriveFunctionalSpacing(
|
|
588
|
-
md: string,
|
|
589
|
-
values: number[],
|
|
590
|
-
scale: SpacingItem[],
|
|
591
|
-
): FunctionalSpacing {
|
|
592
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
593
|
-
const findPurpose = (substr: RegExp): number | undefined =>
|
|
594
|
-
scale.find((s) => s.purpose && substr.test(s.purpose))?.value;
|
|
595
|
-
|
|
596
|
-
// Explicit-label hits
|
|
597
|
-
const baseLabel = findPurpose(/^base unit$|^step$|baseline/i);
|
|
598
|
-
const sectionLabel = findPurpose(/section\s*gap|section\s*padding|gutter/i);
|
|
599
|
-
const cardLabel = findPurpose(/card\s*padding|post\s*entry|content\s*padding|panel\s*padding/i);
|
|
600
|
-
const elementLabel = findPurpose(/element\s*gap|item\s*gap|component\s*gap|inline\s*gap|forum.*sections.*gap/i);
|
|
601
|
-
|
|
602
|
-
// Pull "Base unit: 8px" if §5 spacing prose mentions it directly. The
|
|
603
|
-
// existing extractSpacingScale() already captures it as a labelled value;
|
|
604
|
-
// we just give "Base unit" tighter precedence here than the heuristic min.
|
|
605
|
-
const baseProse = md.match(/\*{0,2}Base unit\*{0,2}\s*[::]\s*`?(\d+)\s*(?:px|dp)/i);
|
|
606
|
-
const baseFromProse = baseProse ? parseInt(baseProse[1], 10) : undefined;
|
|
607
|
-
|
|
608
|
-
const minPos = sorted.find((v) => v >= 4) ?? sorted[0] ?? 8;
|
|
609
|
-
const baseUnit = baseLabel ?? baseFromProse ?? minPos;
|
|
610
|
-
const big = sortedAtPercentile(sorted, 0.85);
|
|
611
|
-
const sectionGap = sectionLabel ?? Math.max(big, 16);
|
|
612
|
-
const midLow = sortedAtPercentile(sorted, 0.45);
|
|
613
|
-
const cardPadding = cardLabel ?? clampClosest(midLow, [12, 16, 20, 24]);
|
|
614
|
-
const elementGap = elementLabel ?? Math.max(baseUnit, clampClosest(sortedAtPercentile(sorted, 0.30), [8, 12]));
|
|
615
|
-
|
|
616
|
-
// Density: prose-stated label wins over heuristic. DCard says
|
|
617
|
-
// "**medium-density**" explicitly; we'd rather repeat that verbatim than
|
|
618
|
-
// bucket it from baseUnit alone (DCard uses 20px CSS-var spacing without
|
|
619
|
-
// exposing a smaller "base unit", which would otherwise read "spacious").
|
|
620
|
-
const proseDensity = (() => {
|
|
621
|
-
const m = md.match(/\b(low|medium|high|compact|comfortable|spacious|dense)[- ]?density\b/i);
|
|
622
|
-
if (!m) return null;
|
|
623
|
-
const word = m[1].toLowerCase();
|
|
624
|
-
if (word === "low" || word === "spacious") return "spacious";
|
|
625
|
-
if (word === "high" || word === "dense" || word === "compact") return "compact";
|
|
626
|
-
return "comfortable";
|
|
627
|
-
})();
|
|
628
|
-
const density: FunctionalSpacing["density"] = proseDensity ??
|
|
629
|
-
(baseUnit <= 4 ? "compact" : baseUnit >= 16 ? "spacious" : "comfortable");
|
|
630
|
-
|
|
631
|
-
return { density, baseUnit, sectionGap, cardPadding, elementGap };
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
function sortedAtPercentile(sorted: number[], p: number): number {
|
|
635
|
-
if (sorted.length === 0) return 0;
|
|
636
|
-
const idx = Math.min(sorted.length - 1, Math.max(0, Math.floor(p * (sorted.length - 1))));
|
|
637
|
-
return sorted[idx];
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
function clampClosest(n: number, candidates: number[]): number {
|
|
641
|
-
if (n === 0) return candidates[0];
|
|
642
|
-
return candidates.reduce((a, b) => (Math.abs(b - n) < Math.abs(a - n) ? b : a));
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
/** Extract border tokens — width × color × style — from DESIGN.md.
|
|
646
|
-
* Recognised patterns:
|
|
647
|
-
* - "Border default (1px solid #e0e0e0): cards, dividers"
|
|
648
|
-
* - "Card border: `1px solid #e0e0e0`"
|
|
649
|
-
* - "Focus ring: `2px solid #428bff`"
|
|
650
|
-
* Falls back empty when prose lacks explicit border statements. */
|
|
651
|
-
function extractBorders(md: string): BorderToken[] {
|
|
652
|
-
const out: BorderToken[] = [];
|
|
653
|
-
const seen = new Set<string>();
|
|
654
|
-
const push = (tok: BorderToken) => {
|
|
655
|
-
const k = `${tok.element}|${tok.width}|${tok.color ?? ""}`;
|
|
656
|
-
if (seen.has(k)) return;
|
|
657
|
-
seen.add(k);
|
|
658
|
-
out.push(tok);
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
// Pattern 1: "**Card border**: `1px solid #e0e0e0` — used on…"
|
|
662
|
-
for (const m of md.matchAll(/\*{0,2}([A-Za-z][A-Za-z0-9 \/\-]{2,30}?)\s*border\*{0,2}\s*[::]\s*`?(\d+(?:\.\d+)?px)\s+(solid|dashed|dotted|double)\s+(#[0-9a-fA-F]{3,8})/gi)) {
|
|
663
|
-
push({
|
|
664
|
-
element: titleCase(m[1].trim()),
|
|
665
|
-
width: m[2],
|
|
666
|
-
style: m[3].toLowerCase(),
|
|
667
|
-
color: m[4].toLowerCase(),
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
// Pattern 2: "Border <variant>: `1px solid #...`" / "Outline: `2px solid …`"
|
|
672
|
-
for (const m of md.matchAll(/\*{0,2}(Border|Outline|Stroke|Divider|Focus(?:\s+ring)?)\s+([A-Za-z][\w\s/-]{0,24}?)\*{0,2}\s*[::]\s*`?(\d+(?:\.\d+)?px)\s+(solid|dashed|dotted|double)\s+(#[0-9a-fA-F]{3,8})/gi)) {
|
|
673
|
-
push({
|
|
674
|
-
element: `${titleCase(m[1])} ${titleCase(m[2].trim())}`.trim(),
|
|
675
|
-
width: m[3],
|
|
676
|
-
style: m[4].toLowerCase(),
|
|
677
|
-
color: m[5].toLowerCase(),
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// Pattern 3: Compact form "1px solid #color" preceded by element name in
|
|
682
|
-
// a bulleted line, e.g. "- Card: `1px solid #e0e0e0`"
|
|
683
|
-
for (const m of md.matchAll(/^[-*]\s+\*{0,2}([A-Za-z][\w\s/-]{1,28}?)\*{0,2}\s*[::]\s*`(\d+(?:\.\d+)?px)\s+(solid|dashed|dotted|double)\s+(#[0-9a-fA-F]{3,8})`/gim)) {
|
|
684
|
-
const el = m[1].trim();
|
|
685
|
-
if (!/border|outline|stroke|divider|focus|ring/i.test(el)) continue;
|
|
686
|
-
push({
|
|
687
|
-
element: titleCase(el),
|
|
688
|
-
width: m[2],
|
|
689
|
-
style: m[3].toLowerCase(),
|
|
690
|
-
color: m[4].toLowerCase(),
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
return out.slice(0, 8);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
function titleCase(s: string): string {
|
|
698
|
-
return s.replace(/\b([a-z])/g, (m) => m.toUpperCase()).replace(/\s+/g, " ");
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
/* ─────────── §4 Component Stylings parser ─────────── */
|
|
702
|
-
|
|
703
|
-
/** Map a `### {heading}` to one of our canonical ComponentType buckets, or
|
|
704
|
-
* `null` if the heading is descriptive prose (Navigation, Image Treatment,
|
|
705
|
-
* Animation, etc.) we don't extract. See spec/components-schema.md for the
|
|
706
|
-
* full vocabulary. */
|
|
707
|
-
function classifyComponentHeading(heading: string): ComponentType | null {
|
|
708
|
-
const h = heading.toLowerCase().trim();
|
|
709
|
-
// Order matters: more-specific synonyms first. All single-word alternatives
|
|
710
|
-
// get a `s?` so `Input` and `Inputs` both match — `\bword\b` won't match a
|
|
711
|
-
// plural otherwise (the `s` blocks the trailing word boundary).
|
|
712
|
-
if (/\b(buttons?|ctas?)\b/.test(h)) return "button";
|
|
713
|
-
if (/\b(inputs?|forms?|fields?|textfields?|inputs? & forms?|forms? & inputs?)\b/.test(h)) return "input";
|
|
714
|
-
if (/\b(cards?|containers?|surfaces?|panels?)\b/.test(h)) return "card";
|
|
715
|
-
if (/\b(badges?|tags?|chips?|pills?)\b/.test(h)) return "badge";
|
|
716
|
-
if (/\btabs?\b/.test(h)) return "tab";
|
|
717
|
-
if (/\b(toggles?|switches?)\b/.test(h)) return "toggle";
|
|
718
|
-
if (/\b(toasts?|snackbars?)\b/.test(h)) return "toast";
|
|
719
|
-
if (/\b(dialogs?|modals?|bottom sheets?|sheets?)\b/.test(h)) return "dialog";
|
|
720
|
-
if (/\b(list items?|list-items?|row items?|friend lists?)\b/.test(h)) return "listItem";
|
|
721
|
-
if (/\bavatars?\b/.test(h)) return "avatar";
|
|
722
|
-
return null;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
const FIELD_ALIASES: Record<string, keyof ComponentVariant | "_extras"> = {
|
|
726
|
-
// bg
|
|
727
|
-
background: "bg", bg: "bg", fill: "bg",
|
|
728
|
-
// fg
|
|
729
|
-
text: "fg", color: "fg", foreground: "fg",
|
|
730
|
-
// border
|
|
731
|
-
border: "border", outline: "border", stroke: "border",
|
|
732
|
-
// radius
|
|
733
|
-
radius: "radius", "border-radius": "radius", "border radius": "radius",
|
|
734
|
-
// padding
|
|
735
|
-
padding: "padding",
|
|
736
|
-
// font
|
|
737
|
-
font: "font", typography: "font", type: "font",
|
|
738
|
-
// states
|
|
739
|
-
hover: "hover",
|
|
740
|
-
focus: "focus",
|
|
741
|
-
active: "active", pressed: "active",
|
|
742
|
-
disabled: "disabled",
|
|
743
|
-
shadow: "shadow",
|
|
744
|
-
// use
|
|
745
|
-
use: "use", usage: "use", when: "use",
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
function parseVariantField(line: string): { key: keyof ComponentVariant | null; rawKey: string; value: string } | null {
|
|
749
|
-
const m = line.match(/^[-*]\s+\*{0,2}([A-Za-z][\w\s/-]{0,28}?)\*{0,2}\s*[::]\s*(.+?)\s*$/);
|
|
750
|
-
if (!m) return null;
|
|
751
|
-
const rawKey = m[1].trim();
|
|
752
|
-
const value = m[2].trim();
|
|
753
|
-
const lookup = FIELD_ALIASES[rawKey.toLowerCase()];
|
|
754
|
-
if (!lookup || lookup === "_extras") return { key: null, rawKey, value };
|
|
755
|
-
return { key: lookup, rawKey, value };
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
/** The set of §4 field keys the parser recognizes (e.g. "background", "text",
|
|
759
|
-
* "border"). Exposed so the catalog-integrity lint can detect the
|
|
760
|
-
* slash-multi-field anti-pattern (`- Background: #x / Text: #y`) — where a
|
|
761
|
-
* second known field hides inside the first field's value and is silently
|
|
762
|
-
* swallowed (the KRDS 35/36-variants-lost bug). The lint flags any field
|
|
763
|
-
* bullet whose value contains ` / <knownField>:`. */
|
|
764
|
-
export const KNOWN_FIELD_KEYS: readonly string[] = Object.keys(FIELD_ALIASES);
|
|
765
|
-
|
|
766
|
-
/** The 10 component types the preview can render. Structured `tokens.components`
|
|
767
|
-
* entries whose `type` falls outside this set are rendered as a generic card. */
|
|
768
|
-
const RENDER_TYPES: readonly ComponentType[] = [
|
|
769
|
-
"button", "input", "card", "badge", "tab", "toggle", "toast", "dialog", "listItem", "avatar",
|
|
770
|
-
];
|
|
771
|
-
/** Structured-component field → ComponentVariant key. Unmapped keys go to extras. */
|
|
772
|
-
const TOKEN_FIELD_MAP: Record<string, keyof ComponentVariant> = {
|
|
773
|
-
bg: "bg", background: "bg", fg: "fg", text: "fg", color: "fg",
|
|
774
|
-
border: "border", radius: "radius", padding: "padding", height: "height",
|
|
775
|
-
font: "font", shadow: "shadow", hover: "hover", focus: "focus",
|
|
776
|
-
active: "active", disabled: "disabled", use: "use",
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
/** Split a flow-mapping body on top-level commas (ignoring commas inside quotes
|
|
780
|
-
* or nested brackets). `a: 1, b: "x, y", c: [1,2]` → ["a: 1", ' b: "x, y"', " c: [1,2]"]. */
|
|
781
|
-
function splitTopLevel(s: string): string[] {
|
|
782
|
-
const out: string[] = [];
|
|
783
|
-
let depth = 0, quote = "", cur = "";
|
|
784
|
-
for (const ch of s) {
|
|
785
|
-
if (quote) { cur += ch; if (ch === quote) quote = ""; continue; }
|
|
786
|
-
if (ch === '"' || ch === "'") { quote = ch; cur += ch; continue; }
|
|
787
|
-
if (ch === "{" || ch === "[") depth++;
|
|
788
|
-
else if (ch === "}" || ch === "]") depth--;
|
|
789
|
-
else if (ch === "," && depth === 0) { out.push(cur); cur = ""; continue; }
|
|
790
|
-
cur += ch;
|
|
791
|
-
}
|
|
792
|
-
if (cur.trim()) out.push(cur);
|
|
793
|
-
return out;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
function parseFlowObject(body: string): Record<string, string> {
|
|
797
|
-
const obj: Record<string, string> = {};
|
|
798
|
-
for (const pair of splitTopLevel(body)) {
|
|
799
|
-
const i = pair.indexOf(":");
|
|
800
|
-
if (i === -1) continue;
|
|
801
|
-
const k = pair.slice(0, i).trim();
|
|
802
|
-
const v = pair.slice(i + 1).trim().replace(/^["']|["']$/g, "");
|
|
803
|
-
if (k) obj[k] = v;
|
|
804
|
-
}
|
|
805
|
-
return obj;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/** Build ComponentBlocks from a STRUCTURED `tokens.components` frontmatter block
|
|
809
|
-
* (getdesign-aligned: components as first-class structured tokens). Preferred
|
|
810
|
-
* over prose §4 parsing because (a) it carries an explicit render `type` per
|
|
811
|
-
* component, so group headings like "Actions"/"Overlays" — which don't classify
|
|
812
|
-
* to a render type — no longer drop components, and (b) it's immune to whether
|
|
813
|
-
* the prose section lives in §4 or §8. Hand-parses the flow-style block (one
|
|
814
|
-
* `name: { ... }` per line) to avoid bundling a YAML parser into the client.
|
|
815
|
-
* Returns null when the ref has no structured component tokens → callers fall
|
|
816
|
-
* back to extractComponentSpecs(md). */
|
|
817
|
-
export function componentsFromTokens(md: string): ComponentBlock[] | null {
|
|
818
|
-
if (!md.startsWith("---")) return null;
|
|
819
|
-
const fmEnd = md.indexOf("\n---", 4);
|
|
820
|
-
if (fmEnd === -1) return null;
|
|
821
|
-
const lines = md.slice(4, fmEnd).split("\n");
|
|
822
|
-
// Locate `components:` inside the tokens block + capture its indent.
|
|
823
|
-
let ci = -1, cIndent = 0;
|
|
824
|
-
for (let i = 0; i < lines.length; i++) {
|
|
825
|
-
const m = lines[i].match(/^(\s*)components:\s*$/);
|
|
826
|
-
if (m) { ci = i; cIndent = m[1].length; break; }
|
|
827
|
-
}
|
|
828
|
-
if (ci === -1) return null;
|
|
829
|
-
const entries: { name: string; obj: Record<string, string> }[] = [];
|
|
830
|
-
let sawObject = false;
|
|
831
|
-
for (let i = ci + 1; i < lines.length; i++) {
|
|
832
|
-
const line = lines[i];
|
|
833
|
-
if (!line.trim()) continue;
|
|
834
|
-
const indent = (line.match(/^(\s*)/)?.[1] ?? "").length;
|
|
835
|
-
if (indent <= cIndent) break; // dedent → end of the components block
|
|
836
|
-
const m = line.match(/^\s*([\w.-]+):\s*(.*)$/);
|
|
837
|
-
if (!m) continue;
|
|
838
|
-
const name = m[1].trim();
|
|
839
|
-
const val = m[2].trim();
|
|
840
|
-
const om = val.match(/^\{(.*)\}$/);
|
|
841
|
-
if (om) { sawObject = true; entries.push({ name, obj: parseFlowObject(om[1]) }); }
|
|
842
|
-
else entries.push({ name, obj: { use: val.replace(/^["']|["']$/g, "") } });
|
|
843
|
-
}
|
|
844
|
-
if (!sawObject || entries.length === 0) return null; // flat-string block → use prose
|
|
845
|
-
|
|
846
|
-
const byType = new Map<ComponentType, ComponentVariant[]>();
|
|
847
|
-
for (const { name, obj } of entries) {
|
|
848
|
-
let type = (obj.type as ComponentType) || classifyComponentHeading(name) || "card";
|
|
849
|
-
if (!RENDER_TYPES.includes(type)) type = "card";
|
|
850
|
-
const variant: ComponentVariant = { name, extras: {} };
|
|
851
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
852
|
-
if (k === "type" || k === "group" || !v) continue;
|
|
853
|
-
const key = TOKEN_FIELD_MAP[k.toLowerCase()];
|
|
854
|
-
if (key) (variant as unknown as Record<string, string>)[key] = v;
|
|
855
|
-
else variant.extras[k] = v;
|
|
856
|
-
}
|
|
857
|
-
if (!byType.has(type)) byType.set(type, []);
|
|
858
|
-
byType.get(type)!.push(variant);
|
|
859
|
-
}
|
|
860
|
-
return [...byType.entries()].map(([type, variants]) => ({ type, heading: "", variants }));
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
/** Parse §4 into a list of ComponentBlock. Rules (see spec/components-schema.md):
|
|
864
|
-
* - `## 4. Component Stylings` opens the section.
|
|
865
|
-
* - Each `### Heading` starts a subsection. We map heading → ComponentType.
|
|
866
|
-
* - Inside each subsection, `**Variant Name**` lines start a variant block.
|
|
867
|
-
* - Subsequent `- Field: value` lines populate that variant.
|
|
868
|
-
* - Trailing prose paragraph (no `**` or `-` prefix) is captured as `notes`. */
|
|
869
|
-
export function extractComponentSpecs(md: string): ComponentBlock[] {
|
|
870
|
-
const sec4 = md.match(/## 4\. Component[\s\S]*?(?=## 5\.)/i)?.[0] ?? "";
|
|
871
|
-
if (!sec4) return [];
|
|
872
|
-
const blocks: ComponentBlock[] = [];
|
|
873
|
-
|
|
874
|
-
// Split into ### subsections (excluding the leading h2 itself).
|
|
875
|
-
const subsections = [...sec4.matchAll(/###\s+([^\n]+)\n([\s\S]*?)(?=\n###|\n##|$)/g)];
|
|
876
|
-
for (const sub of subsections) {
|
|
877
|
-
const heading = sub[1].trim();
|
|
878
|
-
const body = sub[2];
|
|
879
|
-
const type = classifyComponentHeading(heading);
|
|
880
|
-
if (!type) continue;
|
|
881
|
-
|
|
882
|
-
const variants: ComponentVariant[] = [];
|
|
883
|
-
let current: ComponentVariant | null = null;
|
|
884
|
-
let trailingNotes = "";
|
|
885
|
-
|
|
886
|
-
for (const line of body.split("\n")) {
|
|
887
|
-
// Variant header: a standalone bolded line `**Name**` (optionally with
|
|
888
|
-
// bracketed qualifier "**Primary (Fill)**"). Tolerates leading whitespace.
|
|
889
|
-
const variantMatch = line.match(/^\s*\*\*([^*][^*]*?)\*\*\s*$/);
|
|
890
|
-
if (variantMatch) {
|
|
891
|
-
if (current) variants.push(current);
|
|
892
|
-
current = { name: variantMatch[1].trim(), extras: {} };
|
|
893
|
-
continue;
|
|
894
|
-
}
|
|
895
|
-
// Field bullet under the current variant
|
|
896
|
-
if (current) {
|
|
897
|
-
const field = parseVariantField(line);
|
|
898
|
-
if (field) {
|
|
899
|
-
if (field.key === null) {
|
|
900
|
-
current.extras[field.rawKey] = field.value;
|
|
901
|
-
} else {
|
|
902
|
-
(current as unknown as Record<string, string>)[field.key] = field.value;
|
|
903
|
-
}
|
|
904
|
-
continue;
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
// Otherwise: trailing prose / note. Accumulate (skipping blank/heading
|
|
908
|
-
// lines and bullets that didn't match a variant or field — those are
|
|
909
|
-
// legacy free-list bullets we tolerate but don't parse).
|
|
910
|
-
const trimmed = line.trim();
|
|
911
|
-
if (!trimmed) continue;
|
|
912
|
-
if (trimmed.startsWith("**") || trimmed.startsWith("-") || trimmed.startsWith("*")) continue;
|
|
913
|
-
if (current) continue; // mid-variant prose ignored — keep it focused
|
|
914
|
-
trailingNotes += (trailingNotes ? "\n" : "") + trimmed;
|
|
915
|
-
}
|
|
916
|
-
if (current) variants.push(current);
|
|
917
|
-
|
|
918
|
-
if (variants.length === 0) continue;
|
|
919
|
-
blocks.push({ type, heading, variants, notes: trailingNotes || undefined });
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
return blocks;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
/** Parse Do/Don't guidelines from DESIGN.md. Recognises THREE shapes:
|
|
926
|
-
* A. `### Do` / `### Don't` headers with bulleted bodies (apple, airbnb).
|
|
927
|
-
* B. `### Do's and Don'ts` combined block split on inline DO / DONT markers.
|
|
928
|
-
* C. Inline `- DO ...` / `- DON'T ...` bullets without a separate header.
|
|
929
|
-
* (DCard, Cursor, and a long tail of refs use this — we scan anywhere
|
|
930
|
-
* in the doc since they sometimes live under §10 Voice.) */
|
|
931
|
-
function extractGuidelines(md: string): Guideline[] {
|
|
932
|
-
const out: Guideline[] = [];
|
|
933
|
-
const blocks: { type: "do" | "dont"; body: string }[] = [];
|
|
934
|
-
|
|
935
|
-
// Shape A & B
|
|
936
|
-
for (const m of md.matchAll(/###\s+(Do(?:'s)?|Don['']?t(?:'s)?|Do['']?s and Don['']?ts)\s*\n([\s\S]*?)(?=\n###|\n##|$)/gi)) {
|
|
937
|
-
const head = m[1].toLowerCase();
|
|
938
|
-
const body = m[2];
|
|
939
|
-
if (head.startsWith("do") && !head.includes("don")) blocks.push({ type: "do", body });
|
|
940
|
-
else if (head.startsWith("don")) blocks.push({ type: "dont", body });
|
|
941
|
-
else {
|
|
942
|
-
let cur: "do" | "dont" = "do";
|
|
943
|
-
for (const line of body.split("\n")) {
|
|
944
|
-
if (/\*\*DO\*\*|\bDO\b\s/i.test(line) && !/\*\*DON.?T\*\*/i.test(line)) cur = "do";
|
|
945
|
-
if (/\*\*DON.?T\*\*|\bDON.?T\b\s|\bAvoid\b/i.test(line)) cur = "dont";
|
|
946
|
-
const text = parseGuidelineLine(line);
|
|
947
|
-
if (text) out.push({ type: cur, text });
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
for (const b of blocks) {
|
|
952
|
-
for (const line of b.body.split("\n")) {
|
|
953
|
-
const text = parseGuidelineLine(line);
|
|
954
|
-
if (text) out.push({ type: b.type, text });
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
// Shape C: standalone `- **DO** ...` / `- **DON'T** ...` bullets anywhere
|
|
959
|
-
for (const m of md.matchAll(/^[-*]\s+\*\*(DO|DON['']?T)\*\*\s*[::]?\s*([^\n]+)/gim)) {
|
|
960
|
-
const type = /^DO$/i.test(m[1]) ? "do" : "dont";
|
|
961
|
-
let text = m[2].replace(/\*\*/g, "").trim();
|
|
962
|
-
if (text.length < 8 || text.length > 240) continue;
|
|
963
|
-
text = text.replace(/^use\s+/i, "Use ").replace(/^avoid\s+/i, "Avoid ");
|
|
964
|
-
out.push({ type, text });
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
// De-dup by lowercased text
|
|
968
|
-
const seen = new Set<string>();
|
|
969
|
-
return out.filter((g) => {
|
|
970
|
-
const k = `${g.type}|${g.text.toLowerCase()}`;
|
|
971
|
-
if (seen.has(k)) return false;
|
|
972
|
-
seen.add(k);
|
|
973
|
-
return true;
|
|
974
|
-
}).slice(0, 16);
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
function parseGuidelineLine(line: string): string | null {
|
|
978
|
-
const m = line.match(/^\s*[-*]\s+(.+)$/);
|
|
979
|
-
if (!m) return null;
|
|
980
|
-
let text = m[1]
|
|
981
|
-
.replace(/^\*{0,2}(?:DO|DON.?T)\*{0,2}\s*[::—-]?\s*/i, "")
|
|
982
|
-
.replace(/\*\*/g, "")
|
|
983
|
-
.trim();
|
|
984
|
-
// Strip leading "Don't" — we already group by type
|
|
985
|
-
text = text.replace(/^Don['']?t\s+/i, "").replace(/^Avoid\s+/i, "Avoid ").trim();
|
|
986
|
-
if (text.length < 8 || text.length > 240) return null;
|
|
987
|
-
return text;
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
/* ─────────── Color heuristics ─────────── */
|
|
991
|
-
|
|
992
|
-
function hexToRgb(hex: string): [number, number, number] | null {
|
|
993
|
-
const m = hex.replace("#", "").match(/^([0-9a-f]{6})$/i);
|
|
994
|
-
if (!m) return null;
|
|
995
|
-
const v = parseInt(m[1], 16);
|
|
996
|
-
return [(v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
/** Convert hex → HSL, h in [0, 360), s/l in [0, 1]. */
|
|
1000
|
-
function hexToHsl(hex: string): { h: number; s: number; l: number } | null {
|
|
1001
|
-
const rgb = hexToRgb(hex);
|
|
1002
|
-
if (!rgb) return null;
|
|
1003
|
-
const [r, g, b] = rgb.map((c) => c / 255) as [number, number, number];
|
|
1004
|
-
const max = Math.max(r, g, b);
|
|
1005
|
-
const min = Math.min(r, g, b);
|
|
1006
|
-
const l = (max + min) / 2;
|
|
1007
|
-
let h = 0;
|
|
1008
|
-
let s = 0;
|
|
1009
|
-
if (max !== min) {
|
|
1010
|
-
const d = max - min;
|
|
1011
|
-
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
1012
|
-
switch (max) {
|
|
1013
|
-
case r: h = ((g - b) / d + (g < b ? 6 : 0)); break;
|
|
1014
|
-
case g: h = ((b - r) / d + 2); break;
|
|
1015
|
-
case b: h = ((r - g) / d + 4); break;
|
|
1016
|
-
}
|
|
1017
|
-
h *= 60;
|
|
1018
|
-
}
|
|
1019
|
-
return { h, s, l };
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
const HUE_NAMES: { range: [number, number]; name: string }[] = [
|
|
1023
|
-
{ range: [0, 12], name: "Red" },
|
|
1024
|
-
{ range: [12, 32], name: "Orange" },
|
|
1025
|
-
{ range: [32, 52], name: "Amber" },
|
|
1026
|
-
{ range: [52, 70], name: "Yellow" },
|
|
1027
|
-
{ range: [70, 95], name: "Lime" },
|
|
1028
|
-
{ range: [95, 145], name: "Green" },
|
|
1029
|
-
{ range: [145, 170], name: "Mint" },
|
|
1030
|
-
{ range: [170, 195], name: "Teal" },
|
|
1031
|
-
{ range: [195, 215], name: "Cyan" },
|
|
1032
|
-
{ range: [215, 245], name: "Blue" },
|
|
1033
|
-
{ range: [245, 270], name: "Indigo" },
|
|
1034
|
-
{ range: [270, 290], name: "Violet" },
|
|
1035
|
-
{ range: [290, 320], name: "Purple" },
|
|
1036
|
-
{ range: [320, 345], name: "Magenta" },
|
|
1037
|
-
{ range: [345, 360], name: "Rose" },
|
|
1038
|
-
];
|
|
1039
|
-
|
|
1040
|
-
function nameColor(hex: string): string {
|
|
1041
|
-
const hsl = hexToHsl(hex);
|
|
1042
|
-
if (!hsl) return hex.toUpperCase();
|
|
1043
|
-
const { h, s, l } = hsl;
|
|
1044
|
-
// Achromatic — name purely from lightness
|
|
1045
|
-
if (s < 0.08) {
|
|
1046
|
-
if (l < 0.06) return "Pitch Black";
|
|
1047
|
-
if (l < 0.18) return "Charcoal";
|
|
1048
|
-
if (l < 0.32) return "Graphite";
|
|
1049
|
-
if (l < 0.5) return "Slate";
|
|
1050
|
-
if (l < 0.68) return "Ash";
|
|
1051
|
-
if (l < 0.84) return "Silver";
|
|
1052
|
-
if (l < 0.96) return "Mist";
|
|
1053
|
-
return "Porcelain";
|
|
1054
|
-
}
|
|
1055
|
-
const hue = HUE_NAMES.find((b) => h >= b.range[0] && h < b.range[1])?.name ?? "Hue";
|
|
1056
|
-
const tint =
|
|
1057
|
-
l < 0.18 ? "Deep" :
|
|
1058
|
-
l < 0.34 ? "Dark" :
|
|
1059
|
-
l < 0.48 ? "" :
|
|
1060
|
-
l < 0.62 ? "" :
|
|
1061
|
-
l < 0.76 ? "Light" :
|
|
1062
|
-
l < 0.88 ? "Pale" : "Mist";
|
|
1063
|
-
const sat = s < 0.30 ? "Muted" : s > 0.75 ? "Vivid" : "";
|
|
1064
|
-
return [tint, sat, hue].filter(Boolean).join(" ");
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
function categorizeColor(hex: string, isPrimary: boolean): ColorCategory {
|
|
1068
|
-
if (isPrimary) return "brand";
|
|
1069
|
-
const hsl = hexToHsl(hex);
|
|
1070
|
-
if (!hsl) return "accent";
|
|
1071
|
-
const { h, s, l } = hsl;
|
|
1072
|
-
// Pure neutral — low saturation OR extreme lightness
|
|
1073
|
-
if (s < 0.10) return "neutral";
|
|
1074
|
-
if (l < 0.05 || l > 0.97) return "neutral";
|
|
1075
|
-
// Saturated red/orange (warning/danger) or saturated green (success)
|
|
1076
|
-
const isRed = (h <= 18 || h >= 345) && s > 0.45;
|
|
1077
|
-
const isGreen = h >= 95 && h <= 155 && s > 0.40;
|
|
1078
|
-
if (isRed || isGreen) return "semantic";
|
|
1079
|
-
return "accent";
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
/** Parse §2 prose for `- **Name** (`#hex`): description` patterns. Returns a
|
|
1083
|
-
* hex→{name, description} lookup table used to enrich heuristic naming. */
|
|
1084
|
-
function extractColorMeta(md: string): Map<string, { name: string; description: string }> {
|
|
1085
|
-
const sec2 = md.match(/## 2\. Color[\s\S]*?(?=## 3\.)/i)?.[0] ?? "";
|
|
1086
|
-
const map = new Map<string, { name: string; description: string }>();
|
|
1087
|
-
// - **Name** (`#hex`): description... OR - **Name** (#hex): ...
|
|
1088
|
-
for (const m of sec2.matchAll(/^[-*]\s+\*\*([^*]+?)\*\*\s*\(\s*`?(#[0-9a-fA-F]{6})`?\s*\)\s*[::]\s*([^\n]+)/gm)) {
|
|
1089
|
-
const name = m[1].trim();
|
|
1090
|
-
const hex = m[2].toLowerCase();
|
|
1091
|
-
let description = m[3].trim();
|
|
1092
|
-
// Trim leading css-token noise. The token can be followed by ANY of
|
|
1093
|
-
// `,` `.` `:` `;` ` --` ` —` before the human description starts —
|
|
1094
|
-
// DCard/Toss write "`blue500`. Primary interactive color", airbnb writes
|
|
1095
|
-
// "`--palette-bg-primary-core`, primary CTA". Both should drop the token.
|
|
1096
|
-
description = description
|
|
1097
|
-
.replace(/^`[^`]+`\s*[.,:;]\s*/, "")
|
|
1098
|
-
.replace(/^`[^`]+`\s*[—–-]+\s*/, "")
|
|
1099
|
-
.replace(/\.$/, "");
|
|
1100
|
-
if (description.length > 180) description = description.slice(0, 177) + "…";
|
|
1101
|
-
if (!map.has(hex)) map.set(hex, { name, description });
|
|
1102
|
-
}
|
|
1103
|
-
return map;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
function extractColorRoles(palette: string[], primary: string, md: string): ColorRole[] {
|
|
1107
|
-
// No-fallback policy: only render swatches for hex values that actually appear
|
|
1108
|
-
// in §2 of DESIGN.md. Don't force-inject the API's fallback primary (#6366f1)
|
|
1109
|
-
// or any value not present in source. Empty Brand category → hidden by renderer.
|
|
1110
|
-
// (primary param still used to mark the brand swatch when it IS in palette.)
|
|
1111
|
-
const all = palette;
|
|
1112
|
-
const meta = extractColorMeta(md);
|
|
1113
|
-
const seen = new Set<string>();
|
|
1114
|
-
const roles: ColorRole[] = [];
|
|
1115
|
-
for (const raw of all) {
|
|
1116
|
-
const hex = raw.toLowerCase();
|
|
1117
|
-
if (seen.has(hex)) continue;
|
|
1118
|
-
seen.add(hex);
|
|
1119
|
-
if (!/^#[0-9a-f]{6}$/.test(hex)) continue;
|
|
1120
|
-
const isPrimary = hex === primary.toLowerCase();
|
|
1121
|
-
const category = categorizeColor(hex, isPrimary);
|
|
1122
|
-
const m = meta.get(hex);
|
|
1123
|
-
roles.push({
|
|
1124
|
-
hex,
|
|
1125
|
-
name: m?.name ?? nameColor(hex),
|
|
1126
|
-
category,
|
|
1127
|
-
description: m?.description ?? heuristicColorDescription(category, isPrimary),
|
|
1128
|
-
});
|
|
1129
|
-
}
|
|
1130
|
-
// Sort: brand → accent → semantic → neutral; within each, by lightness desc for accents/semantic,
|
|
1131
|
-
// by lightness asc for neutrals (dark → light), brand stays single.
|
|
1132
|
-
const order: Record<ColorCategory, number> = { brand: 0, accent: 1, semantic: 2, neutral: 3 };
|
|
1133
|
-
return roles.sort((a, b) => {
|
|
1134
|
-
if (order[a.category] !== order[b.category]) return order[a.category] - order[b.category];
|
|
1135
|
-
const la = hexToHsl(a.hex)?.l ?? 0;
|
|
1136
|
-
const lb = hexToHsl(b.hex)?.l ?? 0;
|
|
1137
|
-
return a.category === "neutral" ? la - lb : lb - la;
|
|
1138
|
-
});
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
function heuristicColorDescription(cat: ColorCategory, isPrimary: boolean): string {
|
|
1142
|
-
if (isPrimary) return "Primary brand color — used for emphasis, calls to action, and focal moments.";
|
|
1143
|
-
if (cat === "accent") return "Accent for highlights, secondary surfaces, and decorative emphasis.";
|
|
1144
|
-
if (cat === "semantic") return "Semantic indicator — status, success, warning, or alert states.";
|
|
1145
|
-
return "Neutral surface — backgrounds, borders, dividers, or text tiers.";
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
function extractShadows(md: string): { name: string; value: string }[] {
|
|
1149
|
-
const sec6 = md.match(/## 6\. Depth[\s\S]*?(?=## 7\.)/i)?.[0] ?? "";
|
|
1150
|
-
// Try to find shadow recipes — look for "0 Xpx Ypx ..." patterns
|
|
1151
|
-
const lines = sec6.split("\n");
|
|
1152
|
-
const shadows: { name: string; value: string }[] = [];
|
|
1153
|
-
for (const line of lines) {
|
|
1154
|
-
const m = line.match(/`?(0(?:px|\s)\s*[\w(),. \-/]+rgba?\([^)]+\)[^`\n]*)/i);
|
|
1155
|
-
if (m && shadows.length < 5) {
|
|
1156
|
-
// Try to extract a name from the line (e.g., "Card lift —" or "Modal:")
|
|
1157
|
-
const nameMatch = line.match(/^\s*[-•*]?\s*\*?\*?([A-Z][\w\s/-]+?)\*?\*?\s*[—:–]/);
|
|
1158
|
-
const name = nameMatch ? nameMatch[1].trim() : `Shadow ${shadows.length + 1}`;
|
|
1159
|
-
shadows.push({ name, value: m[1].trim() });
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
return shadows.length > 0 ? shadows : DEFAULT_SHADOWS;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
/**
|
|
1166
|
-
* Build the canonical 7-tier typography hierarchy.
|
|
1167
|
-
* Maps the brand's actual extracted sizes onto a normalized scale:
|
|
1168
|
-
* Display XXL · Heading XL · Heading L · Body M · Small S · Caption XS · Smallest XXS
|
|
1169
|
-
* Heading tiers use the brand's headingWeight; body and below use 400 unless detected.
|
|
1170
|
-
* Line-height defaults to 1.25 for headlines, 1.5 for body+ (CJK-friendly).
|
|
1171
|
-
*/
|
|
1172
|
-
function buildHierarchy(sizes: number[], headingWeight: string, hasCJK: boolean): TypographyTier[] {
|
|
1173
|
-
const sorted = [...sizes].sort((a, b) => b - a);
|
|
1174
|
-
const hWeight = parseInt(headingWeight, 10) || 700;
|
|
1175
|
-
const bodyWeight = 400;
|
|
1176
|
-
|
|
1177
|
-
// Pick concrete sizes per tier — fall back to web-typography defaults when extracted scale is sparse.
|
|
1178
|
-
const pick = (idx: number, fallback: number) => sorted[idx] ?? fallback;
|
|
1179
|
-
const display = Math.max(pick(0, 32), 28);
|
|
1180
|
-
const headingXL = Math.max(pick(1, 24), 20);
|
|
1181
|
-
const headingL = Math.max(pick(2, 19), 16);
|
|
1182
|
-
const body = sorted.find((s) => s >= 14 && s <= 18) ?? 16;
|
|
1183
|
-
const small = sorted.find((s) => s >= 12 && s <= 13) ?? 14;
|
|
1184
|
-
const caption = sorted.find((s) => s >= 10 && s <= 12) ?? 12;
|
|
1185
|
-
const smallest = sorted.find((s) => s >= 9 && s <= 10) ?? 10;
|
|
1186
|
-
|
|
1187
|
-
// English-only samples — the hierarchy is rendered in system-ui purely to show
|
|
1188
|
-
// scale & weight ratios. The brand's own fonts get full treatment in the
|
|
1189
|
-
// cards below; mixing CJK in a system-ui preview just muddles the ratio comparison.
|
|
1190
|
-
void hasCJK;
|
|
1191
|
-
const sample = {
|
|
1192
|
-
display: "Design at scale",
|
|
1193
|
-
headingXL: "Section heading",
|
|
1194
|
-
headingL: "Subheading",
|
|
1195
|
-
body: "Body text. The quick brown fox jumps over the lazy dog. Designed for readable line-height in long-form content.",
|
|
1196
|
-
small: "Supporting text",
|
|
1197
|
-
caption: "Caption · timestamp · 2026",
|
|
1198
|
-
smallest: "BADGE / LABEL",
|
|
1199
|
-
};
|
|
1200
|
-
|
|
1201
|
-
return [
|
|
1202
|
-
{ role: "Display", label: `Display XXL`, sampleText: sample.display, fontSize: display, fontWeight: hWeight, lineHeight: 1.25, letterSpacing: "-0.01em" },
|
|
1203
|
-
{ role: "Heading 1", label: `Heading XL`, sampleText: sample.headingXL, fontSize: headingXL, fontWeight: hWeight, lineHeight: 1.25, letterSpacing: "0" },
|
|
1204
|
-
{ role: "Heading 2", label: `Heading L`, sampleText: sample.headingL, fontSize: headingL, fontWeight: hWeight, lineHeight: 1.4, letterSpacing: "0" },
|
|
1205
|
-
{ role: "Body", label: `Body M`, sampleText: sample.body, fontSize: body, fontWeight: bodyWeight, lineHeight: 1.5, letterSpacing: "0" },
|
|
1206
|
-
{ role: "Small", label: `Small S`, sampleText: sample.small, fontSize: small, fontWeight: bodyWeight, lineHeight: 1.5, letterSpacing: "0", muted: true },
|
|
1207
|
-
{ role: "Caption", label: `Caption XS`, sampleText: sample.caption, fontSize: caption, fontWeight: bodyWeight, lineHeight: 1.5, letterSpacing: "0", muted: true },
|
|
1208
|
-
{ role: "Smallest", label: `Smallest XXS`, sampleText: sample.smallest, fontSize: smallest, fontWeight: 500, lineHeight: 1.5, letterSpacing: "0.06em", muted: true },
|
|
1209
|
-
];
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
export function extractTokens(detail: {
|
|
1213
|
-
id: string;
|
|
1214
|
-
designMd: string;
|
|
1215
|
-
primary: string;
|
|
1216
|
-
background: string;
|
|
1217
|
-
foreground: string;
|
|
1218
|
-
fontFamily: string;
|
|
1219
|
-
mono?: string;
|
|
1220
|
-
headingWeight: string;
|
|
1221
|
-
radius: string;
|
|
1222
|
-
mood: string;
|
|
1223
|
-
accent?: string;
|
|
1224
|
-
border?: string;
|
|
1225
|
-
}): ParsedTokens {
|
|
1226
|
-
const md = detail.designMd;
|
|
1227
|
-
const SPECIAL_NAMES: Record<string, string> = {
|
|
1228
|
-
krds: "KRDS", ibm: "IBM", bmw: "BMW", nvidia: "NVIDIA", ridi: "RIDI",
|
|
1229
|
-
qanda: "QANDA", kakaobank: "KakaoBank", spacex: "SpaceX", "x.ai": "xAI",
|
|
1230
|
-
"linear.app": "Linear", cal: "Cal.com", "mistral.ai": "Mistral AI",
|
|
1231
|
-
"opencode.ai": "OpenCode AI", "together.ai": "Together AI",
|
|
1232
|
-
posthog: "PostHog", supabase: "Supabase", voltagent: "VoltAgent",
|
|
1233
|
-
elevenlabs: "ElevenLabs", runwayml: "RunwayML", coinbase: "Coinbase",
|
|
1234
|
-
airbnb: "Airbnb", clickhouse: "ClickHouse", karrot: "Karrot",
|
|
1235
|
-
toss: "Toss", baemin: "Baemin", kakao: "Kakao", pinkoi: "Pinkoi",
|
|
1236
|
-
dcard: "Dcard", line: "LINE", mercari: "Mercari", freee: "freee",
|
|
1237
|
-
yeogiotte: "여기어때", musinsa: "Musinsa", kurly: "Kurly", ohouse: "Ohouse",
|
|
1238
|
-
naver: "Naver", yanolja: "Yanolja", coupang: "Coupang",
|
|
1239
|
-
};
|
|
1240
|
-
return {
|
|
1241
|
-
identity: {
|
|
1242
|
-
id: detail.id,
|
|
1243
|
-
name: SPECIAL_NAMES[detail.id] ?? detail.id.replace(".app", "").replace(/^./, (c) => c.toUpperCase()),
|
|
1244
|
-
primary: detail.primary,
|
|
1245
|
-
background: detail.background,
|
|
1246
|
-
foreground: detail.foreground,
|
|
1247
|
-
accent: detail.accent,
|
|
1248
|
-
border: detail.border,
|
|
1249
|
-
mood: detail.mood,
|
|
1250
|
-
} as ParsedTokens["identity"],
|
|
1251
|
-
typography: (() => {
|
|
1252
|
-
const sizes = extractFontSizes(md);
|
|
1253
|
-
const hasCJK = /Hiragino|Meiryo|PingFang|Noto Sans (?:JP|KR|TC|SC)|MS Gothic|Heiti|微軟|黑體|ヒラギノ/i.test(detail.fontFamily) || /[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uac00-\ud7af]/.test(md);
|
|
1254
|
-
const fonts = extractFontMentions(md);
|
|
1255
|
-
// If parser missed the API-provided primary font, prepend it
|
|
1256
|
-
if (detail.fontFamily) {
|
|
1257
|
-
const apiPrimary = detail.fontFamily.split(",")[0].replace(/['"]/g, "").trim();
|
|
1258
|
-
if (apiPrimary && !fonts.some((f) => f.raw.toLowerCase() === apiPrimary.toLowerCase())) {
|
|
1259
|
-
fonts.unshift({ raw: apiPrimary, role: "primary" });
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
if (detail.mono && !fonts.some((f) => f.raw.toLowerCase() === detail.mono!.toLowerCase())) {
|
|
1263
|
-
fonts.push({ raw: detail.mono, role: "mono" });
|
|
1264
|
-
}
|
|
1265
|
-
return {
|
|
1266
|
-
family: detail.fontFamily,
|
|
1267
|
-
mono: detail.mono,
|
|
1268
|
-
headingWeight: detail.headingWeight,
|
|
1269
|
-
weights: extractWeights(md),
|
|
1270
|
-
sizes,
|
|
1271
|
-
hierarchy: buildHierarchy(sizes, detail.headingWeight, hasCJK),
|
|
1272
|
-
fonts,
|
|
1273
|
-
};
|
|
1274
|
-
})(),
|
|
1275
|
-
radii: (() => {
|
|
1276
|
-
// Normalize: some refs express radius as a range ("4px-8px") rather
|
|
1277
|
-
// than a single CSS value. Strip anything after the first "-"/"–" so
|
|
1278
|
-
// the radii tokens always produce valid CSS. Sanitize huge values
|
|
1279
|
-
// (≥64px) to canonical pill so a stray "1280px" from upstream doesn't
|
|
1280
|
-
// leak into the preview as a giant button radius.
|
|
1281
|
-
const normalized = sanitizeRadiusString(detail.radius.replace(/[-–].*/, "").trim());
|
|
1282
|
-
return {
|
|
1283
|
-
button: normalized, // full — pill OK
|
|
1284
|
-
input: normalized, // matches button
|
|
1285
|
-
card: capRadius(normalized, 16), // cap large surfaces
|
|
1286
|
-
dialog: capRadius(normalized, 16),
|
|
1287
|
-
badge: capRadius(normalized, 8), // tighter for inline pills
|
|
1288
|
-
};
|
|
1289
|
-
})(),
|
|
1290
|
-
radiusScale: (() => {
|
|
1291
|
-
const parsed = extractRadiusScale(md);
|
|
1292
|
-
if (parsed.length >= 3) return parsed;
|
|
1293
|
-
// Mid-fallback: scan the whole DESIGN.md for "Default radius" and
|
|
1294
|
-
// per-element prose ("buttons … 8px") before falling back to the
|
|
1295
|
-
// single-value detail.radius synthesis. Often recovers ≥3 useful rows.
|
|
1296
|
-
const prose = extractRadiusFromProse(md);
|
|
1297
|
-
if (prose.length >= 3) return prose;
|
|
1298
|
-
// Last-ditch: synthesize 5 entries from the legacy single radius value.
|
|
1299
|
-
const normalized = sanitizeRadiusString(detail.radius.replace(/[-–].*/, "").trim());
|
|
1300
|
-
const seeded = [
|
|
1301
|
-
{ element: "buttons", value: normalized },
|
|
1302
|
-
{ element: "inputs", value: normalized },
|
|
1303
|
-
{ element: "cards", value: capRadius(normalized, 16) },
|
|
1304
|
-
{ element: "dialogs", value: capRadius(normalized, 16) },
|
|
1305
|
-
{ element: "badges", value: capRadius(normalized, 8) },
|
|
1306
|
-
];
|
|
1307
|
-
// Merge any prose hits we found (e.g., a single "Default radius" line)
|
|
1308
|
-
// on top of the seed so the canonical value wins for duplicated keys.
|
|
1309
|
-
const map = new Map(seeded.map((r) => [r.element, r]));
|
|
1310
|
-
for (const r of prose) map.set(r.element, r);
|
|
1311
|
-
return [...map.values()];
|
|
1312
|
-
})(),
|
|
1313
|
-
palette: extractPalette(md),
|
|
1314
|
-
paletteRoles: (() => {
|
|
1315
|
-
const palette = extractPalette(md);
|
|
1316
|
-
return extractColorRoles(palette, detail.primary, md);
|
|
1317
|
-
})(),
|
|
1318
|
-
spacing: extractSpacing(md),
|
|
1319
|
-
spacingScale: (() => {
|
|
1320
|
-
const values = extractSpacing(md);
|
|
1321
|
-
return extractSpacingScale(md, values);
|
|
1322
|
-
})(),
|
|
1323
|
-
functionalSpacing: (() => {
|
|
1324
|
-
const values = extractSpacing(md);
|
|
1325
|
-
const scale = extractSpacingScale(md, values);
|
|
1326
|
-
return deriveFunctionalSpacing(md, values, scale);
|
|
1327
|
-
})(),
|
|
1328
|
-
borders: extractBorders(md),
|
|
1329
|
-
// Prefer structured `tokens.components` (getdesign-aligned, explicit per-
|
|
1330
|
-
// component type). Falls back to prose §4 parsing for un-migrated refs.
|
|
1331
|
-
components: componentsFromTokens(md) ?? extractComponentSpecs(md),
|
|
1332
|
-
shadows: extractShadows(md),
|
|
1333
|
-
guidelines: extractGuidelines(md),
|
|
1334
|
-
};
|
|
1335
|
-
}
|