css-is-awesome 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +343 -0
- package/CHANGELOG.md +1036 -0
- package/CLAUDE.md +9 -0
- package/CONTRACT.md +580 -0
- package/GEMINI.md +9 -0
- package/LICENSE +21 -0
- package/LICENSE-third-party +88 -0
- package/MIGRATION.md +312 -0
- package/README.md +380 -0
- package/ROADMAP.md +714 -0
- package/THEMING.md +290 -0
- package/THREE-TIERS.md +158 -0
- package/VERSIONING.md +200 -0
- package/_index.scss +34 -0
- package/api.scss +16 -0
- package/bin/README.md +57 -0
- package/bin/cia.cjs +114 -0
- package/bin/migrate-bootstrap.cjs +427 -0
- package/bin/migrate-tailwind.cjs +832 -0
- package/css-is-awesome.instructions.md +533 -0
- package/dist/css-is-awesome.core.css +598 -0
- package/dist/css-is-awesome.core.min.css +1 -0
- package/dist/css-is-awesome.css +3733 -0
- package/dist/css-is-awesome.min.css +1 -0
- package/dist/css-is-awesome.utilities.css +2445 -0
- package/dist/css-is-awesome.utilities.min.css +1 -0
- package/dist/tokens.css +508 -0
- package/dist/tokens.d.ts +266 -0
- package/dist/tokens.min.css +1 -0
- package/figma-tokens/README.md +57 -0
- package/figma-tokens/primitives-brand.scss +121 -0
- package/figma-tokens/semantic-dark.scss +61 -0
- package/figma-tokens/semantic-light.scss +61 -0
- package/figma-tokens/tokens.json +144 -0
- package/llm.txt +183 -0
- package/mcp/server.cjs +1495 -0
- package/package.json +199 -0
- package/public/icons/README.md +278 -0
- package/public/icons/arrow-right.svg +4 -0
- package/public/icons/check.svg +4 -0
- package/public/icons/chevron-down.svg +4 -0
- package/public/icons/close.svg +4 -0
- package/public/icons/core/arrow-down.svg +13 -0
- package/public/icons/core/arrow-left.svg +13 -0
- package/public/icons/core/arrow-right.svg +13 -0
- package/public/icons/core/arrow-up.svg +13 -0
- package/public/icons/core/bell.svg +13 -0
- package/public/icons/core/calendar.svg +15 -0
- package/public/icons/core/check.svg +12 -0
- package/public/icons/core/chevron-down.svg +12 -0
- package/public/icons/core/chevron-left.svg +12 -0
- package/public/icons/core/chevron-right.svg +12 -0
- package/public/icons/core/chevron-up.svg +12 -0
- package/public/icons/core/clock.svg +13 -0
- package/public/icons/core/close.svg +13 -0
- package/public/icons/core/copy.svg +13 -0
- package/public/icons/core/download.svg +14 -0
- package/public/icons/core/edit.svg +13 -0
- package/public/icons/core/error.svg +14 -0
- package/public/icons/core/external-link.svg +14 -0
- package/public/icons/core/eye-off.svg +15 -0
- package/public/icons/core/eye.svg +13 -0
- package/public/icons/core/filter.svg +12 -0
- package/public/icons/core/heart.svg +12 -0
- package/public/icons/core/help.svg +14 -0
- package/public/icons/core/home.svg +13 -0
- package/public/icons/core/info.svg +14 -0
- package/public/icons/core/loading.svg +12 -0
- package/public/icons/core/lock.svg +13 -0
- package/public/icons/core/mail.svg +13 -0
- package/public/icons/core/menu.svg +14 -0
- package/public/icons/core/message.svg +12 -0
- package/public/icons/core/minus.svg +12 -0
- package/public/icons/core/more-horizontal.svg +14 -0
- package/public/icons/core/pause.svg +13 -0
- package/public/icons/core/play.svg +12 -0
- package/public/icons/core/plus.svg +13 -0
- package/public/icons/core/refresh.svg +15 -0
- package/public/icons/core/save.svg +14 -0
- package/public/icons/core/search.svg +13 -0
- package/public/icons/core/settings.svg +13 -0
- package/public/icons/core/share.svg +14 -0
- package/public/icons/core/sort.svg +15 -0
- package/public/icons/core/star.svg +12 -0
- package/public/icons/core/success.svg +13 -0
- package/public/icons/core/trash.svg +16 -0
- package/public/icons/core/unlock.svg +13 -0
- package/public/icons/core/upload.svg +14 -0
- package/public/icons/core/user.svg +13 -0
- package/public/icons/core/users.svg +15 -0
- package/public/icons/core/warning.svg +14 -0
- package/public/icons/download.svg +4 -0
- package/public/icons/edit.svg +4 -0
- package/public/icons/menu.svg +4 -0
- package/public/icons/search.svg +4 -0
- package/public/theme.css +4179 -0
- package/public/themes/README.md +102 -0
- package/public/themes/boilerplate/theme.css +154 -0
- package/public/themes/boilerplate-dark/theme.css +171 -0
- package/public/themes/boilerplate-light/theme.css +171 -0
- package/public/themes/cupertino/theme.css +165 -0
- package/public/themes/cupertino-dark/theme.css +200 -0
- package/public/themes/cupertino-light/theme.css +227 -0
- package/public/themes/glass/theme.css +190 -0
- package/public/themes/glass-dark/theme.css +201 -0
- package/public/themes/glass-light/theme.css +229 -0
- package/public/themes/graphite/theme.css +155 -0
- package/public/themes/graphite-dark/theme.css +223 -0
- package/public/themes/graphite-light/theme.css +191 -0
- package/public/themes/press/theme.css +189 -0
- package/public/themes/press-dark/theme.css +199 -0
- package/public/themes/press-light/theme.css +235 -0
- package/public/themes/prism/theme.css +159 -0
- package/public/themes/prism-dark/theme.css +185 -0
- package/public/themes/prism-light/theme.css +188 -0
- package/public/themes/sketchbook/theme.css +152 -0
- package/public/themes/sketchbook-dark/theme.css +194 -0
- package/public/themes/sketchbook-light/theme.css +188 -0
- package/public/themes/terminal/theme.css +159 -0
- package/public/themes/terminal-dark/theme.css +229 -0
- package/public/themes/terminal-light/theme.css +152 -0
- package/scripts/README.md +70 -0
- package/scripts/icon-contract.json +67 -0
- package/scripts/icon-validator.js +205 -0
- package/scripts/prepare-dist.mjs +65 -0
- package/scripts/theme-a11y.js +415 -0
- package/scripts/theme-contract.json +171 -0
- package/scripts/theme-validator.js +674 -0
- package/scss/README.md +55 -0
- package/scss/_animations-utilities.scss +107 -0
- package/scss/_animations.scss +248 -0
- package/scss/_app-styles.scss +15 -0
- package/scss/_generator.scss +174 -0
- package/scss/_icons.scss +475 -0
- package/scss/_index.scss +17 -0
- package/scss/_layout.scss +597 -0
- package/scss/_mixins.scss +1036 -0
- package/scss/_system.scss +291 -0
- package/scss/_utilities.scss +377 -0
- package/scss/api.scss +61 -0
- package/scss/components/_accordion.scss +72 -0
- package/scss/components/_buttons.scss +171 -0
- package/scss/components/_copy-button.scss +69 -0
- package/scss/components/_data.scss +190 -0
- package/scss/components/_feedback.scss +197 -0
- package/scss/components/_forms.scss +272 -0
- package/scss/components/_index.scss +17 -0
- package/scss/components/_navigation.scss +186 -0
- package/scss/components/_overlay.scss +259 -0
- package/scss/components/_stepper.scss +159 -0
- package/scss/components/_tabs.scss +72 -0
- package/scss/core.scss +54 -0
- package/scss/examples/_theming.scss +107 -0
- package/scss/examples/_usage.scss +317 -0
- package/scss/main.scss +64 -0
- package/scss/recipes/README.md +110 -0
- package/scss/recipes/_bare-tags.scss +232 -0
- package/scss/recipes/_recipe-template.md +119 -0
- package/scss/recipes/combobox.md +509 -0
- package/scss/recipes/dialog.md +265 -0
- package/scss/recipes/print-to-pdf.md +263 -0
- package/scss/theme/README.md +67 -0
- package/scss/theme/_brand.scss +18 -0
- package/scss/theme/_colors-dark.scss +68 -0
- package/scss/theme/_colors-light.scss +70 -0
- package/scss/theme/_components.scss +94 -0
- package/scss/theme/_icons.scss +104 -0
- package/scss/theme/_index.scss +62 -0
- package/scss/theme/_shadows.scss +65 -0
- package/scss/theme/_shape.scss +13 -0
- package/scss/theme/_typography.scss +9 -0
- package/scss/theme/registry.json +447 -0
- package/scss/themes/boilerplate-dark.scss +212 -0
- package/scss/themes/boilerplate-light.scss +209 -0
- package/scss/themes/boilerplate.scss +181 -0
- package/scss/themes/cupertino-dark.scss +238 -0
- package/scss/themes/cupertino-light.scss +266 -0
- package/scss/themes/cupertino.scss +194 -0
- package/scss/themes/glass-dark.scss +238 -0
- package/scss/themes/glass-light.scss +266 -0
- package/scss/themes/glass.scss +220 -0
- package/scss/themes/graphite-dark.scss +260 -0
- package/scss/themes/graphite-light.scss +228 -0
- package/scss/themes/graphite.scss +182 -0
- package/scss/themes/press-dark.scss +237 -0
- package/scss/themes/press-light.scss +273 -0
- package/scss/themes/press.scss +241 -0
- package/scss/themes/prism-dark.scss +217 -0
- package/scss/themes/prism-light.scss +220 -0
- package/scss/themes/prism.scss +190 -0
- package/scss/themes/sketchbook-dark.scss +231 -0
- package/scss/themes/sketchbook-light.scss +231 -0
- package/scss/themes/sketchbook.scss +178 -0
- package/scss/themes/terminal-dark.scss +267 -0
- package/scss/themes/terminal-light.scss +175 -0
- package/scss/themes/terminal.scss +185 -0
- package/scss/tokens.scss +23 -0
- package/scss/utilities-only.scss +4 -0
package/package.json
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "css-is-awesome",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "A token-driven SCSS design system with light/dark theming, semantic color tokens, and a 800+ LOC mixin API.",
|
|
5
|
+
"homepage": "https://github.com/Jerry2d3d/css-is-awesome#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/Jerry2d3d/css-is-awesome/issues"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/css-is-awesome.css",
|
|
10
|
+
"style": "dist/css-is-awesome.css",
|
|
11
|
+
"sass": "scss/main.scss",
|
|
12
|
+
"bin": {
|
|
13
|
+
"css-is-awesome-mcp": "mcp/server.cjs",
|
|
14
|
+
"cia": "bin/cia.cjs"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": [
|
|
17
|
+
"**/*.css",
|
|
18
|
+
"**/*.scss"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"sass": "./scss/main.scss",
|
|
23
|
+
"style": "./dist/css-is-awesome.css",
|
|
24
|
+
"default": "./dist/css-is-awesome.css"
|
|
25
|
+
},
|
|
26
|
+
"./api": {
|
|
27
|
+
"sass": "./scss/api.scss"
|
|
28
|
+
},
|
|
29
|
+
"./api.scss": "./scss/api.scss",
|
|
30
|
+
"./core": "./dist/css-is-awesome.core.css",
|
|
31
|
+
"./core.css": "./dist/css-is-awesome.core.css",
|
|
32
|
+
"./tokens": "./dist/tokens.css",
|
|
33
|
+
"./tokens.css": "./dist/tokens.css",
|
|
34
|
+
"./tokens.d.ts": "./dist/tokens.d.ts",
|
|
35
|
+
"./utilities": "./dist/css-is-awesome.utilities.css",
|
|
36
|
+
"./utilities.css": "./dist/css-is-awesome.utilities.css",
|
|
37
|
+
"./min": "./dist/css-is-awesome.min.css",
|
|
38
|
+
"./min.css": "./dist/css-is-awesome.min.css",
|
|
39
|
+
"./css": "./dist/css-is-awesome.css",
|
|
40
|
+
"./css.css": "./dist/css-is-awesome.css",
|
|
41
|
+
"./scss": "./scss/main.scss",
|
|
42
|
+
"./scss/main": "./scss/main.scss",
|
|
43
|
+
"./scss/tokens": "./scss/tokens.scss",
|
|
44
|
+
"./scss/mixins": "./scss/_mixins.scss",
|
|
45
|
+
"./scss/generator": "./scss/_generator.scss",
|
|
46
|
+
"./scss/utilities": "./scss/_utilities.scss",
|
|
47
|
+
"./scss/animations": "./scss/_animations.scss",
|
|
48
|
+
"./scss/icons": "./scss/_icons.scss",
|
|
49
|
+
"./scss/layout": "./scss/_layout.scss",
|
|
50
|
+
"./scss/system": "./scss/_system.scss",
|
|
51
|
+
"./scss/theme": "./scss/theme/_index.scss",
|
|
52
|
+
"./scss/theme/*": "./scss/theme/_*.scss",
|
|
53
|
+
"./scss/components": "./scss/components/_index.scss",
|
|
54
|
+
"./scss/components/*": "./scss/components/_*.scss",
|
|
55
|
+
"./scss/recipes/*": "./scss/recipes/_*.scss",
|
|
56
|
+
"./scss/*": "./scss/*.scss",
|
|
57
|
+
"./theme": "./public/theme.css",
|
|
58
|
+
"./theme.css": "./public/theme.css",
|
|
59
|
+
"./themes/*": "./public/themes/*/theme.css",
|
|
60
|
+
"./figma-tokens": "./figma-tokens/tokens.json",
|
|
61
|
+
"./figma-tokens/*": "./figma-tokens/*",
|
|
62
|
+
"./package.json": "./package.json"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"scss",
|
|
66
|
+
"api.scss",
|
|
67
|
+
"_index.scss",
|
|
68
|
+
"dist",
|
|
69
|
+
"figma-tokens",
|
|
70
|
+
"mcp",
|
|
71
|
+
"scripts/theme-contract.json",
|
|
72
|
+
"scripts/theme-validator.js",
|
|
73
|
+
"scripts/theme-a11y.js",
|
|
74
|
+
"scripts/icon-validator.js",
|
|
75
|
+
"scripts/icon-contract.json",
|
|
76
|
+
"bin",
|
|
77
|
+
"public/theme.css",
|
|
78
|
+
"public/themes",
|
|
79
|
+
"public/icons",
|
|
80
|
+
"README.md",
|
|
81
|
+
"CHANGELOG.md",
|
|
82
|
+
"LICENSE",
|
|
83
|
+
"LICENSE-third-party",
|
|
84
|
+
"css-is-awesome.instructions.md",
|
|
85
|
+
"AGENTS.md",
|
|
86
|
+
"CLAUDE.md",
|
|
87
|
+
"GEMINI.md",
|
|
88
|
+
"llm.txt",
|
|
89
|
+
"THREE-TIERS.md",
|
|
90
|
+
"THEMING.md",
|
|
91
|
+
"MIGRATION.md",
|
|
92
|
+
"CONTRACT.md",
|
|
93
|
+
"ROADMAP.md",
|
|
94
|
+
"VERSIONING.md",
|
|
95
|
+
"scripts/prepare-dist.mjs"
|
|
96
|
+
],
|
|
97
|
+
"scripts": {
|
|
98
|
+
"dev": "next dev -p 5173",
|
|
99
|
+
"build": "next build",
|
|
100
|
+
"start": "next start -p 5173",
|
|
101
|
+
"lint": "next lint",
|
|
102
|
+
"lint:fix": "next lint --fix",
|
|
103
|
+
"lint:scss": "stylelint \"scss/**/*.scss\"",
|
|
104
|
+
"lint:scss:fix": "stylelint \"scss/**/*.scss\" --fix",
|
|
105
|
+
"build:css": "sass scss/main.scss dist/css-is-awesome.css --no-source-map",
|
|
106
|
+
"build:css:core": "sass scss/core.scss dist/css-is-awesome.core.css --no-source-map",
|
|
107
|
+
"build:css:tokens": "sass scss/tokens.scss dist/tokens.css --no-source-map",
|
|
108
|
+
"build:css:themes": "node scripts/build-themes.mjs && node scripts/build-theme-bundle.mjs",
|
|
109
|
+
"build:css:utilities": "sass scss/utilities-only.scss dist/css-is-awesome.utilities.css --no-source-map",
|
|
110
|
+
"build:css:min": "sass scss/main.scss dist/css-is-awesome.min.css --style=compressed --no-source-map && sass scss/core.scss dist/css-is-awesome.core.min.css --style=compressed --no-source-map && sass scss/tokens.scss dist/tokens.min.css --style=compressed --no-source-map && sass scss/utilities-only.scss dist/css-is-awesome.utilities.min.css --style=compressed --no-source-map",
|
|
111
|
+
"build:token-types": "node scripts/generate-token-types.mjs",
|
|
112
|
+
"dtcg-to-scss": "node scripts/dtcg-to-scss.mjs",
|
|
113
|
+
"build:css:all": "npm run build:css && npm run build:css:core && npm run build:css:tokens && npm run build:css:utilities && npm run build:css:themes && npm run build:css:min && npm run build:token-types",
|
|
114
|
+
"watch:css": "sass scss/main.scss dist/css-is-awesome.css --watch",
|
|
115
|
+
"validate-themes": "node scripts/theme-validator.js --all",
|
|
116
|
+
"validate-icons": "node scripts/icon-validator.js",
|
|
117
|
+
"validate-api": "node scripts/validate-api.mjs",
|
|
118
|
+
"validate-package": "node scripts/validate-package.mjs",
|
|
119
|
+
"validate-recipes": "node scripts/validate-recipes.mjs",
|
|
120
|
+
"size-budget": "node scripts/size-budget.mjs",
|
|
121
|
+
"size-report": "node scripts/size-budget.mjs --report",
|
|
122
|
+
"coverage:api": "node scripts/api-coverage.mjs",
|
|
123
|
+
"coverage:mcp": "node scripts/mcp-coverage.mjs",
|
|
124
|
+
"coverage": "npm run coverage:api && npm run coverage:mcp",
|
|
125
|
+
"pack:consumer": "node scripts/pack-to-consumer.mjs",
|
|
126
|
+
"test": "playwright test",
|
|
127
|
+
"test:update-snapshots": "playwright test --update-snapshots",
|
|
128
|
+
"playwright:install": "playwright install --with-deps",
|
|
129
|
+
"prepare": "node scripts/prepare-dist.mjs",
|
|
130
|
+
"prepublishOnly": "npm run build:css:all",
|
|
131
|
+
"check:theme-drift": "node scripts/check-theme-drift.mjs"
|
|
132
|
+
},
|
|
133
|
+
"keywords": [
|
|
134
|
+
"css",
|
|
135
|
+
"scss",
|
|
136
|
+
"sass",
|
|
137
|
+
"design-system",
|
|
138
|
+
"design-tokens",
|
|
139
|
+
"theming",
|
|
140
|
+
"dark-mode"
|
|
141
|
+
],
|
|
142
|
+
"author": "Jerry2d3d",
|
|
143
|
+
"license": "MIT",
|
|
144
|
+
"repository": {
|
|
145
|
+
"type": "git",
|
|
146
|
+
"url": "git+https://github.com/Jerry2d3d/css-is-awesome.git"
|
|
147
|
+
},
|
|
148
|
+
"publishConfig": {
|
|
149
|
+
"access": "public"
|
|
150
|
+
},
|
|
151
|
+
"engines": {
|
|
152
|
+
"node": ">=20"
|
|
153
|
+
},
|
|
154
|
+
"peerDependencies": {
|
|
155
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
156
|
+
"sass": "^1.77.0",
|
|
157
|
+
"zod": "^3.25.0 || ^4.0.0"
|
|
158
|
+
},
|
|
159
|
+
"peerDependenciesMeta": {
|
|
160
|
+
"sass": {
|
|
161
|
+
"optional": true
|
|
162
|
+
},
|
|
163
|
+
"@modelcontextprotocol/sdk": {
|
|
164
|
+
"optional": true
|
|
165
|
+
},
|
|
166
|
+
"zod": {
|
|
167
|
+
"optional": true
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"devDependencies": {
|
|
171
|
+
"@axe-core/playwright": "^4.11.2",
|
|
172
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
173
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
174
|
+
"@playwright/test": "^1.59.1",
|
|
175
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
176
|
+
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
177
|
+
"@semantic-release/git": "^10.0.1",
|
|
178
|
+
"@semantic-release/github": "^11.0.0",
|
|
179
|
+
"@semantic-release/npm": "^12.0.1",
|
|
180
|
+
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
181
|
+
"@types/node": "^22.0.0",
|
|
182
|
+
"@types/react": "^19.0.0",
|
|
183
|
+
"@types/react-dom": "^19.0.0",
|
|
184
|
+
"eslint": "^9.17.0",
|
|
185
|
+
"eslint-config-next": "^15.0.0",
|
|
186
|
+
"jiti": "^2.7.0",
|
|
187
|
+
"marked": "^15.0.12",
|
|
188
|
+
"next": "^15.0.0",
|
|
189
|
+
"react": "^19.0.0",
|
|
190
|
+
"react-dom": "^19.0.0",
|
|
191
|
+
"sass": "^1.97.1",
|
|
192
|
+
"semantic-release": "^24.2.0",
|
|
193
|
+
"serve": "^14.2.6",
|
|
194
|
+
"stylelint": "^17.8.0",
|
|
195
|
+
"stylelint-config-standard-scss": "^17.0.0",
|
|
196
|
+
"typescript": "^5.7.0",
|
|
197
|
+
"zod": "^3.25.0"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# Icons
|
|
2
|
+
|
|
3
|
+
The css-is-awesome icon system is mixin-first and pack-based. The
|
|
4
|
+
default `core` pack ships at `public/icons/core/` (49 Lucide-vendored
|
|
5
|
+
glyphs — see `LICENSE-third-party` for attribution).
|
|
6
|
+
|
|
7
|
+
## The 30-second version
|
|
8
|
+
|
|
9
|
+
1. Drop an SVG file into a pack folder (`public/icons/core/foo.svg`).
|
|
10
|
+
2. Reference it anywhere: `@include m.svg(foo);`
|
|
11
|
+
3. Style it with CSS. `currentColor` means it reskins automatically with `color:`.
|
|
12
|
+
|
|
13
|
+
That's the whole system. No registry file, no build step, no import list.
|
|
14
|
+
|
|
15
|
+
The full contract (resolution order, naming rules, override mechanism)
|
|
16
|
+
lives in [`CONTRACT.md` → Icons contract](../../CONTRACT.md#icons-contract).
|
|
17
|
+
|
|
18
|
+
## Mixins
|
|
19
|
+
|
|
20
|
+
All mixins live in `scss/_icons.scss`. Bring them in via the `m.` namespace
|
|
21
|
+
(`@use 'mixins' as m;`) that the rest of the system uses.
|
|
22
|
+
|
|
23
|
+
### `m.svg($name, $size: t.$theme-icon-size, $color: currentColor)`
|
|
24
|
+
|
|
25
|
+
Inline single-color icon. Renders via CSS `mask` + `background: currentColor`,
|
|
26
|
+
so the icon inherits the parent's `color`. Use for UI glyphs that should
|
|
27
|
+
tint with text.
|
|
28
|
+
|
|
29
|
+
```scss
|
|
30
|
+
.btn-close {
|
|
31
|
+
@include m.svg(close);
|
|
32
|
+
color: var(--color-danger);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Compiled CSS:
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
.btn-close {
|
|
40
|
+
display: inline-flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
width: 24px;
|
|
44
|
+
height: 24px;
|
|
45
|
+
color: var(--color-danger);
|
|
46
|
+
}
|
|
47
|
+
.btn-close::before {
|
|
48
|
+
content: '';
|
|
49
|
+
display: block;
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: 100%;
|
|
52
|
+
background: currentColor;
|
|
53
|
+
mask: var(--cia-icon-x, url('/icons/core/x.svg')) center / contain no-repeat;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `m.svg-bg($name, $size: t.$icon-size)`
|
|
58
|
+
|
|
59
|
+
SVG rendered as a plain `background-image`. No mask, no tint — the source
|
|
60
|
+
SVG's colors are preserved. Use for multi-color illustrations and brand
|
|
61
|
+
marks that should NOT become monochrome.
|
|
62
|
+
|
|
63
|
+
```scss
|
|
64
|
+
.logo {
|
|
65
|
+
@include m.svg-bg(brand-mark, 48px);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `m.svg-text($name, $size: 1em, $gap: 0.5em, $position: before)`
|
|
70
|
+
|
|
71
|
+
Icon + label in one flex row. The icon goes in `::before` (default) or
|
|
72
|
+
`::after`, with `gap` between them. `$size: 1em` means the icon scales
|
|
73
|
+
with the element's `font-size`.
|
|
74
|
+
|
|
75
|
+
```scss
|
|
76
|
+
.btn-save {
|
|
77
|
+
@include m.svg-text(check); // icon-then-text, 0.5em gap
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.btn-next {
|
|
81
|
+
@include m.svg-text(arrow-right, 1em, 0.5em, after);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Config
|
|
86
|
+
|
|
87
|
+
All config lives in `scss/theme/_icons.scss` and is re-exported from
|
|
88
|
+
`scss/theme/_index.scss` as `t.$theme-*`.
|
|
89
|
+
|
|
90
|
+
### Icon folder path
|
|
91
|
+
|
|
92
|
+
`$theme-icon-path` defaults to `/icons` and `$theme-icon-pack` defaults
|
|
93
|
+
to `core`, so `m.svg(foo)` resolves to `/icons/core/foo.svg` by default.
|
|
94
|
+
Each theme can override individual glyphs via `--cia-icon-<name>` custom
|
|
95
|
+
properties (preferred) or swap the entire pack folder by changing
|
|
96
|
+
`$theme-icon-path` / `$theme-icon-pack` — see "Per-theme icon packs"
|
|
97
|
+
below and `CONTRACT.md → Icons contract`.
|
|
98
|
+
|
|
99
|
+
### Default icon size
|
|
100
|
+
|
|
101
|
+
`$theme-icon-size` defaults to `24px`. Used by `svg` and `fa-icon` when
|
|
102
|
+
you don't pass an explicit `$size`.
|
|
103
|
+
|
|
104
|
+
### Alias map
|
|
105
|
+
|
|
106
|
+
`$theme-icon-svg-alias` remaps semantic names to real filenames. Ships
|
|
107
|
+
with a small default set:
|
|
108
|
+
|
|
109
|
+
```scss
|
|
110
|
+
$icon-svg-alias: (
|
|
111
|
+
delete: 'trash',
|
|
112
|
+
close: 'x',
|
|
113
|
+
);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
With that map in place, `@include m.svg(delete);` resolves to
|
|
117
|
+
`/icons/trash.svg`. Add your own entries to keep call sites semantic
|
|
118
|
+
without renaming files.
|
|
119
|
+
|
|
120
|
+
## Sizing
|
|
121
|
+
|
|
122
|
+
Two ways to size an icon:
|
|
123
|
+
|
|
124
|
+
1. **Implicit (recommended for text-paired icons).** `svg-text` defaults
|
|
125
|
+
`$size` to `1em`, so the icon scales with `font-size`.
|
|
126
|
+
|
|
127
|
+
```scss
|
|
128
|
+
.btn { font-size: 1.125rem; @include m.svg-text(check); } // icon is 18px
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
2. **Explicit.** Pass a `$size`:
|
|
132
|
+
|
|
133
|
+
```scss
|
|
134
|
+
.nav-toggle { @include m.svg(menu, 32px); }
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Coloring
|
|
138
|
+
|
|
139
|
+
Set `color:` on the element (or any ancestor) and the icon follows. This
|
|
140
|
+
works because `svg` / `svg-text` render the glyph as a mask over
|
|
141
|
+
`background: currentColor`.
|
|
142
|
+
|
|
143
|
+
```scss
|
|
144
|
+
.btn-danger { color: #e11; @include m.svg(delete); } // red trash icon
|
|
145
|
+
.btn-danger:hover { color: #a00; } // hover darkens
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
If an icon isn't picking up the color, see Troubleshooting.
|
|
149
|
+
|
|
150
|
+
## Mask vs background (svg vs svg-bg)
|
|
151
|
+
|
|
152
|
+
| Use case | Mixin |
|
|
153
|
+
|------------------------------------------|-------------|
|
|
154
|
+
| Single-color UI glyph that tints | `svg` |
|
|
155
|
+
| Multi-color illustration / brand mark | `svg-bg` |
|
|
156
|
+
| Icon paired with a text label | `svg-text` |
|
|
157
|
+
|
|
158
|
+
The `svg` path requires the source SVG to have no hardcoded `fill=` (or
|
|
159
|
+
have `fill="currentColor"`). If the SVG has baked-in colors, `svg` will
|
|
160
|
+
discard them (mask only cares about shape). Use `svg-bg` to keep them.
|
|
161
|
+
|
|
162
|
+
## Aliases
|
|
163
|
+
|
|
164
|
+
`$theme-icon-svg-alias` is a `name → filename` map. It lets call sites
|
|
165
|
+
use semantic names while the file on disk stays neutral:
|
|
166
|
+
|
|
167
|
+
```scss
|
|
168
|
+
// scss/theme/_icons.scss
|
|
169
|
+
$icon-svg-alias: (
|
|
170
|
+
delete: 'trash',
|
|
171
|
+
close: 'x',
|
|
172
|
+
primary-action: 'star-filled',
|
|
173
|
+
);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
```scss
|
|
177
|
+
.btn-remove { @include m.svg(delete); } // loads /icons/trash.svg
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Per-theme icon packs
|
|
181
|
+
|
|
182
|
+
There are two ways a theme overrides icons. Pick whichever matches the
|
|
183
|
+
scope of the change.
|
|
184
|
+
|
|
185
|
+
### Per-glyph (preferred — runtime CSS, no SCSS rebuild)
|
|
186
|
+
|
|
187
|
+
Drop replacement SVGs at `public/themes/<theme>/icons/<pack>/<name>.svg`
|
|
188
|
+
and declare a custom property in that theme's `:root` (or
|
|
189
|
+
`[data-theme="<theme>"]`) block:
|
|
190
|
+
|
|
191
|
+
```css
|
|
192
|
+
[data-theme="sketchbook-light"] {
|
|
193
|
+
--cia-icon-search: url('/themes/sketchbook-light/icons/core/search.svg');
|
|
194
|
+
--cia-icon-x: url('/themes/sketchbook-light/icons/core/x.svg');
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Glyphs you don't override fall back to the bundled `core` pack
|
|
199
|
+
automatically. The mixin emits `var(--cia-icon-<name>, url(<core>))` —
|
|
200
|
+
the second argument is the fallback.
|
|
201
|
+
|
|
202
|
+
### Pack-wide (compile-time SCSS swap)
|
|
203
|
+
|
|
204
|
+
If a theme replaces every glyph, override `$theme-icon-path` once and
|
|
205
|
+
ship the full set in the new folder:
|
|
206
|
+
|
|
207
|
+
```scss
|
|
208
|
+
// themes/corporate/_icons.scss
|
|
209
|
+
$icon-path: '/themes/corporate/icons';
|
|
210
|
+
$icon-pack: 'core'; // keep the contract pack name
|
|
211
|
+
$icon-svg-alias: (
|
|
212
|
+
delete: 'bin',
|
|
213
|
+
close: 'dismiss',
|
|
214
|
+
);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Drop the SVGs at `public/themes/corporate/icons/core/` and every
|
|
218
|
+
`@include m.svg(...)` in that theme's bundle resolves against the
|
|
219
|
+
corporate pack.
|
|
220
|
+
|
|
221
|
+
## Font Awesome integration
|
|
222
|
+
|
|
223
|
+
Use the FA mixins when your project is already on Font Awesome (you have
|
|
224
|
+
a Pro license, a brand kit, or need thousands of glyphs you don't want to
|
|
225
|
+
curate by hand). Configure `$theme-fa-path`, `$theme-fa-style`, and
|
|
226
|
+
`$theme-icon-fa-map` in `scss/theme/_icons.scss`.
|
|
227
|
+
|
|
228
|
+
### Self-hosted
|
|
229
|
+
|
|
230
|
+
Drop `fa-solid-900.woff2`, `fa-regular-400.woff2`, and
|
|
231
|
+
`fa-brands-400.woff2` into your `$theme-fa-path` folder (default
|
|
232
|
+
`/webfonts`), then call `fa-load` once:
|
|
233
|
+
|
|
234
|
+
```scss
|
|
235
|
+
// main.scss
|
|
236
|
+
@include m.fa-load;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### CDN / kit
|
|
240
|
+
|
|
241
|
+
Skip `fa-load` entirely. Include FA's stylesheet in your HTML as normal;
|
|
242
|
+
the mixins below will pick up the already-registered font families.
|
|
243
|
+
|
|
244
|
+
### FA mixins at a glance
|
|
245
|
+
|
|
246
|
+
```scss
|
|
247
|
+
.icon-search { @include m.fa-icon(search); }
|
|
248
|
+
.btn-download { @include m.fa-text(download); }
|
|
249
|
+
.loader { @include m.fa-spin(spinner); }
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Authoring tips
|
|
253
|
+
|
|
254
|
+
- **Single-color glyph.** Export with `fill="currentColor"` (or no `fill`
|
|
255
|
+
at all). Use `m.svg` / `m.svg-text`. Drive the color from the parent's
|
|
256
|
+
`color:`.
|
|
257
|
+
- **Multi-color illustration.** Export with fills baked in. Use `m.svg-bg`.
|
|
258
|
+
`color:` has no effect.
|
|
259
|
+
- **Adding a new icon.** Save the file as `public/icons/<name>.svg` and
|
|
260
|
+
reference it with `@include m.svg(<name>);`. No manifest update needed.
|
|
261
|
+
|
|
262
|
+
## Troubleshooting
|
|
263
|
+
|
|
264
|
+
- **Icon doesn't render.** Check `$theme-icon-path` resolves to a real URL
|
|
265
|
+
and the file exists (e.g. open `/icons/foo.svg` in the browser).
|
|
266
|
+
- **Icon renders black and won't pick up `color`.** The SVG has a hardcoded
|
|
267
|
+
`fill` attribute. Either remove the `fill` from the source, change it to
|
|
268
|
+
`currentColor`, or switch to `m.svg-bg`.
|
|
269
|
+
- **Icon is stretched or cropped.** `svg` / `svg-text` set `width` and
|
|
270
|
+
`height` to the same value. If your source SVG isn't square, wrap it in
|
|
271
|
+
a `<svg viewBox="...">` with matching width/height, or size it via
|
|
272
|
+
`svg-bg` with an explicit `background-size`.
|
|
273
|
+
- **Icon looks fuzzy on high-DPI.** Bump `$size`, or confirm the source is
|
|
274
|
+
a real SVG (not a rasterized PNG exported as `.svg`).
|
|
275
|
+
- **FA icon shows a box / wrong glyph.** `$theme-icon-fa-map` doesn't have
|
|
276
|
+
that name, or the FA font file for that style (solid/regular/brands)
|
|
277
|
+
isn't loaded. Check `fa-load` was called, or that your CDN include is
|
|
278
|
+
present.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="M12 5v14" />
|
|
12
|
+
<path d="m19 12-7 7-7-7" />
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="m12 19-7-7 7-7" />
|
|
12
|
+
<path d="M19 12H5" />
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="M5 12h14" />
|
|
12
|
+
<path d="m12 5 7 7-7 7" />
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="m5 12 7-7 7 7" />
|
|
12
|
+
<path d="M12 19V5" />
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="M10.268 21a2 2 0 0 0 3.464 0" />
|
|
12
|
+
<path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" />
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="M8 2v4" />
|
|
12
|
+
<path d="M16 2v4" />
|
|
13
|
+
<rect width="18" height="18" x="3" y="4" rx="2" />
|
|
14
|
+
<path d="M3 10h18" />
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="M20 6 9 17l-5-5" />
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="m15 18-6-6 6-6" />
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="m9 18 6-6-6-6" />
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<path d="m18 15-6-6-6 6" />
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-width="2"
|
|
8
|
+
stroke-linecap="round"
|
|
9
|
+
stroke-linejoin="round"
|
|
10
|
+
>
|
|
11
|
+
<circle cx="12" cy="12" r="10" />
|
|
12
|
+
<path d="M12 6v6l4 2" />
|
|
13
|
+
</svg>
|