@adnap/krysalicss 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/dist/base/global.css +141 -0
- package/dist/base/global.min.css +1 -0
- package/dist/base/reset.css +170 -0
- package/dist/base/reset.min.css +1 -0
- package/dist/element/badge.css +167 -0
- package/dist/element/badge.min.css +1 -0
- package/dist/element/button.css +250 -0
- package/dist/element/button.min.css +1 -0
- package/dist/element/checkbox.css +149 -0
- package/dist/element/checkbox.min.css +1 -0
- package/dist/element/file.css +148 -0
- package/dist/element/file.min.css +1 -0
- package/dist/element/progress.css +183 -0
- package/dist/element/progress.min.css +1 -0
- package/dist/element/radio.css +144 -0
- package/dist/element/radio.min.css +1 -0
- package/dist/element/range.css +183 -0
- package/dist/element/range.min.css +1 -0
- package/dist/element/select.css +156 -0
- package/dist/element/select.min.css +1 -0
- package/dist/element/switch.css +186 -0
- package/dist/element/switch.min.css +1 -0
- package/dist/element/text-input.css +143 -0
- package/dist/element/text-input.min.css +1 -0
- package/dist/element/textarea.css +145 -0
- package/dist/element/textarea.min.css +1 -0
- package/dist/helper/breakpoints.css +113 -0
- package/dist/helper/breakpoints.min.css +1 -0
- package/dist/helper/state.css +126 -0
- package/dist/helper/state.min.css +1 -0
- package/dist/krysalicss.css +1420 -0
- package/dist/krysalicss.css.map +1 -0
- package/dist/krysalicss.min.css +1 -0
- package/dist/layout/container.css +145 -0
- package/dist/layout/container.min.css +1 -0
- package/dist/layout/flex.css +135 -0
- package/dist/layout/flex.min.css +1 -0
- package/dist/layout/grid.css +188 -0
- package/dist/layout/grid.min.css +1 -0
- package/dist/module/alert.css +166 -0
- package/dist/module/alert.min.css +1 -0
- package/dist/module/card.css +157 -0
- package/dist/module/card.min.css +1 -0
- package/dist/module/field.css +138 -0
- package/dist/module/field.min.css +1 -0
- package/dist/module/modal.css +187 -0
- package/dist/module/modal.min.css +1 -0
- package/dist/module/navbar.css +256 -0
- package/dist/module/navbar.min.css +1 -0
- package/dist/module/tabs.css +167 -0
- package/dist/module/tabs.min.css +1 -0
- package/dist/tokens/dark.json +85 -0
- package/dist/tokens/default.json +85 -0
- package/dist/tokens/high-contrast.json +85 -0
- package/dist/typography/base.css +131 -0
- package/dist/typography/base.min.css +1 -0
- package/dist/typography/content.css +137 -0
- package/dist/typography/content.min.css +1 -0
- package/dist/typography/link.css +132 -0
- package/dist/typography/link.min.css +1 -0
- package/dist/typography/table.css +121 -0
- package/dist/typography/table.min.css +1 -0
- package/dist/typography/title.css +122 -0
- package/dist/typography/title.min.css +1 -0
- package/package.json +111 -0
- package/src/_index.scss +18 -0
- package/src/base/_index.scss +2 -0
- package/src/base/global/_index.scss +2 -0
- package/src/base/global/_plugin.scss +34 -0
- package/src/base/global/_variables.scss +11 -0
- package/src/base/reset/_index.scss +2 -0
- package/src/base/reset/_plugin.scss +70 -0
- package/src/base/reset/_variables.scss +5 -0
- package/src/element/_index.scss +11 -0
- package/src/element/badge/_index.scss +2 -0
- package/src/element/badge/_plugin.scss +44 -0
- package/src/element/badge/_variables.scss +19 -0
- package/src/element/button/_index.scss +2 -0
- package/src/element/button/_plugin.scss +173 -0
- package/src/element/button/_variables.scss +36 -0
- package/src/element/checkbox/_index.scss +2 -0
- package/src/element/checkbox/_plugin.scss +48 -0
- package/src/element/checkbox/_variables.scss +24 -0
- package/src/element/file/_index.scss +2 -0
- package/src/element/file/_plugin.scss +45 -0
- package/src/element/file/_variables.scss +27 -0
- package/src/element/progress/_index.scss +2 -0
- package/src/element/progress/_plugin.scss +96 -0
- package/src/element/progress/_variables.scss +19 -0
- package/src/element/radio/_index.scss +2 -0
- package/src/element/radio/_plugin.scss +47 -0
- package/src/element/radio/_variables.scss +16 -0
- package/src/element/range/_index.scss +2 -0
- package/src/element/range/_plugin.scss +101 -0
- package/src/element/range/_variables.scss +19 -0
- package/src/element/select/_index.scss +2 -0
- package/src/element/select/_plugin.scss +58 -0
- package/src/element/select/_variables.scss +26 -0
- package/src/element/switch/_index.scss +2 -0
- package/src/element/switch/_plugin.scss +105 -0
- package/src/element/switch/_variables.scss +28 -0
- package/src/element/text-input/_index.scss +2 -0
- package/src/element/text-input/_plugin.scss +37 -0
- package/src/element/text-input/_variables.scss +22 -0
- package/src/element/textarea/_index.scss +2 -0
- package/src/element/textarea/_plugin.scss +39 -0
- package/src/element/textarea/_variables.scss +22 -0
- package/src/helper/_breakpoints.scss +45 -0
- package/src/helper/_controls.scss +82 -0
- package/src/helper/_index.scss +3 -0
- package/src/helper/_state.scss +35 -0
- package/src/krysalicss.scss +17 -0
- package/src/layout/_index.scss +3 -0
- package/src/layout/container/_index.scss +2 -0
- package/src/layout/container/_plugin.scss +26 -0
- package/src/layout/container/_variables.scss +5 -0
- package/src/layout/flex/_index.scss +2 -0
- package/src/layout/flex/_plugin.scss +32 -0
- package/src/layout/flex/_variables.scss +9 -0
- package/src/layout/grid/_index.scss +2 -0
- package/src/layout/grid/_plugin.scss +37 -0
- package/src/layout/grid/_variables.scss +37 -0
- package/src/module/_index.scss +6 -0
- package/src/module/alert/_index.scss +2 -0
- package/src/module/alert/_plugin.scss +51 -0
- package/src/module/alert/_variables.scss +24 -0
- package/src/module/card/_index.scss +2 -0
- package/src/module/card/_plugin.scss +31 -0
- package/src/module/card/_variables.scss +13 -0
- package/src/module/field/_index.scss +2 -0
- package/src/module/field/_plugin.scss +49 -0
- package/src/module/field/_variables.scss +26 -0
- package/src/module/modal/_index.scss +2 -0
- package/src/module/modal/_plugin.scss +137 -0
- package/src/module/modal/_variables.scss +39 -0
- package/src/module/navbar/_index.scss +2 -0
- package/src/module/navbar/_plugin.scss +186 -0
- package/src/module/navbar/_variables.scss +49 -0
- package/src/module/tabs/_index.scss +2 -0
- package/src/module/tabs/_plugin.scss +106 -0
- package/src/module/tabs/_variables.scss +16 -0
- package/src/theme/_create.scss +74 -0
- package/src/theme/dark.scss +51 -0
- package/src/theme/default.scss +45 -0
- package/src/theme/high-contrast.scss +53 -0
- package/src/typography/_index.scss +5 -0
- package/src/typography/base/_index.scss +2 -0
- package/src/typography/base/_plugin.scss +21 -0
- package/src/typography/base/_variables.scss +15 -0
- package/src/typography/content/_index.scss +2 -0
- package/src/typography/content/_plugin.scss +39 -0
- package/src/typography/content/_variables.scss +1 -0
- package/src/typography/link/_index.scss +2 -0
- package/src/typography/link/_mixins.scss +29 -0
- package/src/typography/link/_plugin.scss +15 -0
- package/src/typography/link/_variables.scss +15 -0
- package/src/typography/table/_index.scss +2 -0
- package/src/typography/table/_plugin.scss +13 -0
- package/src/typography/table/_variables.scss +6 -0
- package/src/typography/title/_index.scss +2 -0
- package/src/typography/title/_plugin.scss +36 -0
- package/src/typography/title/_variables.scss +7 -0
- package/src/variables/_color.scss +66 -0
- package/src/variables/_default.scss +52 -0
- package/src/variables/_feature.scss +39 -0
- package/src/variables/_global.scss +93 -0
- package/src/variables/_index.scss +7 -0
- package/src/variables/_responsive.scss +10 -0
- package/src/variables/_selector.scss +1 -0
- package/src/variables/_size.scss +5 -0
package/package.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adnap/krysalicss",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A modern, extremely modular, multi-theme CSS framework with first-class theming via CSS custom properties.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "adnap",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://gitlab.com/adnap/krysalicss.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://gitlab.com/adnap/krysalicss/-/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://krysalicss.eu",
|
|
16
|
+
"main": "dist/krysalicss.css",
|
|
17
|
+
"style": "dist/krysalicss.min.css",
|
|
18
|
+
"sass": "src/krysalicss.scss",
|
|
19
|
+
"unpkg": "dist/krysalicss.min.css",
|
|
20
|
+
"sideEffects": [
|
|
21
|
+
"*.css",
|
|
22
|
+
"*.scss"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"sass": "./src/krysalicss.scss",
|
|
27
|
+
"style": "./dist/krysalicss.min.css",
|
|
28
|
+
"default": "./dist/krysalicss.css"
|
|
29
|
+
},
|
|
30
|
+
"./min": {
|
|
31
|
+
"style": "./dist/krysalicss.min.css",
|
|
32
|
+
"default": "./dist/krysalicss.min.css"
|
|
33
|
+
},
|
|
34
|
+
"./helper/*": {
|
|
35
|
+
"sass": "./src/helper/_*.scss",
|
|
36
|
+
"style": "./dist/helper/*.min.css",
|
|
37
|
+
"default": "./dist/helper/*.css"
|
|
38
|
+
},
|
|
39
|
+
"./*": {
|
|
40
|
+
"sass": "./src/*/_index.scss",
|
|
41
|
+
"style": "./dist/*.min.css",
|
|
42
|
+
"default": "./dist/*.css"
|
|
43
|
+
},
|
|
44
|
+
"./package.json": "./package.json"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"src",
|
|
48
|
+
"dist",
|
|
49
|
+
"README.md",
|
|
50
|
+
"LICENSE"
|
|
51
|
+
],
|
|
52
|
+
"keywords": [
|
|
53
|
+
"css",
|
|
54
|
+
"scss",
|
|
55
|
+
"sass",
|
|
56
|
+
"css-framework",
|
|
57
|
+
"framework",
|
|
58
|
+
"modular",
|
|
59
|
+
"responsive",
|
|
60
|
+
"flexbox",
|
|
61
|
+
"themes",
|
|
62
|
+
"dark-mode",
|
|
63
|
+
"css-variables"
|
|
64
|
+
],
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@axe-core/playwright": "^4.11.3",
|
|
67
|
+
"@playwright/test": "^1.59.1",
|
|
68
|
+
"@types/node": "^24.12.2",
|
|
69
|
+
"autoprefixer": "^10.5.0",
|
|
70
|
+
"cssnano": "^8.0.0",
|
|
71
|
+
"postcss": "^8.5.14",
|
|
72
|
+
"sass-embedded": "^1.99.0",
|
|
73
|
+
"tsx": "^4.21.0",
|
|
74
|
+
"typescript": "^6.0.3"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=24"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "pnpm build:prod && pnpm build:dev",
|
|
81
|
+
"build:prod": "tsx tools/build.ts prod",
|
|
82
|
+
"build:dev": "tsx tools/build.ts dev",
|
|
83
|
+
"watch": "tsx tools/watch.ts",
|
|
84
|
+
"test": "pnpm test:snapshots",
|
|
85
|
+
"test:snapshots": "tsx tools/test-snapshots.ts",
|
|
86
|
+
"test:visual": "pnpm --filter @adnap/krysalicss-docs build && playwright test tests/visual/",
|
|
87
|
+
"test:visual:wipe": "rm -rf tests/visual/__screenshots__",
|
|
88
|
+
"test:visual:update": "pnpm --filter @adnap/krysalicss-docs build && playwright test tests/visual/ --update-snapshots",
|
|
89
|
+
"test:visual:podman": "tsx tools/test-visual-podman.ts",
|
|
90
|
+
"test:visual:podman:update": "tsx tools/test-visual-podman.ts --update",
|
|
91
|
+
"test:a11y": "pnpm --filter @adnap/krysalicss-docs build && playwright test tests/a11y/ --project=a11y",
|
|
92
|
+
"bundle:check": "tsx tools/bundle-size.ts",
|
|
93
|
+
"lint": "deno lint",
|
|
94
|
+
"lint:flags": "tsx tools/lint-feature-flags.ts",
|
|
95
|
+
"lint:motion": "tsx tools/lint-reduced-motion.ts",
|
|
96
|
+
"smoke:imports": "tsx tools/smoke-imports.ts",
|
|
97
|
+
"tokens:build": "tsx tools/export-tokens.ts",
|
|
98
|
+
"format": "deno fmt",
|
|
99
|
+
"format:check": "deno fmt --check",
|
|
100
|
+
"typecheck": "tsc --noEmit",
|
|
101
|
+
"check": "pnpm format:check && pnpm lint && pnpm typecheck",
|
|
102
|
+
"docs:dev": "pnpm --filter @adnap/krysalicss-docs dev",
|
|
103
|
+
"docs:build": "pnpm --filter @adnap/krysalicss-docs build",
|
|
104
|
+
"docs:preview": "pnpm --filter @adnap/krysalicss-docs preview",
|
|
105
|
+
"docs:check": "pnpm --filter @adnap/krysalicss-docs check",
|
|
106
|
+
"build:vue": "pnpm --filter @adnap/krysalicss-vue build",
|
|
107
|
+
"test:vue": "pnpm --filter @adnap/krysalicss-vue test",
|
|
108
|
+
"build:react": "pnpm --filter @adnap/krysalicss-react build",
|
|
109
|
+
"test:react": "pnpm --filter @adnap/krysalicss-react test"
|
|
110
|
+
}
|
|
111
|
+
}
|
package/src/_index.scss
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Forwards-only entry. Use this when you want to bring your own theme:
|
|
2
|
+
// @use 'krysalicss/src/index' with ($features: (button, card));
|
|
3
|
+
// @use 'krysalicss/src/theme/dark';
|
|
4
|
+
//
|
|
5
|
+
// Order matters: variables → base → helper → layout → typography → module → element.
|
|
6
|
+
// Themes are NOT included here: consumers pull a theme explicitly.
|
|
7
|
+
//
|
|
8
|
+
// Each category is forwarded with a `<category>-*` prefix so siblings that share
|
|
9
|
+
// generic token names (`$selector`, `$gap`, `$border-radius`) don't collide at
|
|
10
|
+
// this layer. Reach for symbols as `$layout-selector`, `$module-selector`, etc.
|
|
11
|
+
@forward "variables";
|
|
12
|
+
@forward "base" as base-*;
|
|
13
|
+
@forward "helper" as helper-*;
|
|
14
|
+
@forward "layout" as layout-*;
|
|
15
|
+
@forward "typography" as typography-*;
|
|
16
|
+
@forward "module" as module-*;
|
|
17
|
+
@forward "element" as element-*;
|
|
18
|
+
@forward "theme/create" as theme-create-*;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
|
|
4
|
+
@if variables.$feature-base-global {
|
|
5
|
+
html {
|
|
6
|
+
@include variables.backgroundColor(bg, $background-fallback);
|
|
7
|
+
@include variables.textColor(fg, $foreground-fallback);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Forced-colors (Windows High Contrast). Authoring tokens remap to OS
|
|
11
|
+
// system colour keywords so user agent contrast wins over brand palette.
|
|
12
|
+
@if $forced-colors-fallback {
|
|
13
|
+
@media (forced-colors: active) {
|
|
14
|
+
:root {
|
|
15
|
+
--kc-bg: Canvas;
|
|
16
|
+
--kc-fg: CanvasText;
|
|
17
|
+
--kc-link: LinkText;
|
|
18
|
+
--kc-link-hover: LinkText;
|
|
19
|
+
--kc-card-bg: Canvas;
|
|
20
|
+
--kc-card-fg: CanvasText;
|
|
21
|
+
--kc-default-bg: Canvas;
|
|
22
|
+
--kc-default-fg: CanvasText;
|
|
23
|
+
--kc-primary-bg: Highlight;
|
|
24
|
+
--kc-primary-fg: HighlightText;
|
|
25
|
+
--kc-warning-bg: Canvas;
|
|
26
|
+
--kc-warning-fg: CanvasText;
|
|
27
|
+
--kc-danger-bg: Canvas;
|
|
28
|
+
--kc-danger-fg: CanvasText;
|
|
29
|
+
--kc-success-bg: Canvas;
|
|
30
|
+
--kc-success-fg: CanvasText;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Fallback values used when the corresponding theme custom property is unset.
|
|
2
|
+
// Match the `white` / `black` palette entries so consumers re-tinting the
|
|
3
|
+
// palette still get coherent fallbacks.
|
|
4
|
+
$background-fallback: #ffffff !default;
|
|
5
|
+
$foreground-fallback: #27282b !default;
|
|
6
|
+
|
|
7
|
+
// Windows High Contrast Mode: opt-in by default. When active, the
|
|
8
|
+
// emitted block remaps theme tokens to `Canvas` / `CanvasText` /
|
|
9
|
+
// `LinkText` / `Highlight` so the OS palette wins. Set to `false` if
|
|
10
|
+
// the consumer would rather author their own forced-colors handling.
|
|
11
|
+
$forced-colors-fallback: true !default;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
|
|
4
|
+
@if variables.$feature-base-reset {
|
|
5
|
+
/*! krysalicss-reset
|
|
6
|
+
derived from minireset.css v0.0.6
|
|
7
|
+
MIT
|
|
8
|
+
github.com/jgthms/minireset.css)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#{$selector-list} {
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#{$heading-selector} {
|
|
17
|
+
font-size: 100%;
|
|
18
|
+
font-weight: normal;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
ul {
|
|
22
|
+
list-style: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#{$form-selector} {
|
|
26
|
+
margin: 0;
|
|
27
|
+
// UA stylesheets apply `font: -webkit-small-control` (or similar) to
|
|
28
|
+
// form controls, which renders ~13px instead of inheriting the page
|
|
29
|
+
// font. Inherit explicitly so `<button class="button">` matches
|
|
30
|
+
// `<a class="button">` and form fields match surrounding prose.
|
|
31
|
+
font-family: inherit;
|
|
32
|
+
font-size: 1em;
|
|
33
|
+
line-height: inherit;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
html {
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
* {
|
|
41
|
+
&,
|
|
42
|
+
&::before,
|
|
43
|
+
&::after {
|
|
44
|
+
box-sizing: inherit;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#{$media-selector} {
|
|
49
|
+
height: auto;
|
|
50
|
+
max-width: 100%;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
iframe {
|
|
54
|
+
border: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
table {
|
|
58
|
+
border-collapse: collapse;
|
|
59
|
+
border-spacing: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
td,
|
|
63
|
+
th {
|
|
64
|
+
padding: 0;
|
|
65
|
+
|
|
66
|
+
&:not([align]) {
|
|
67
|
+
text-align: start;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
$selector-list: "html, body, p, ol, ul, li, dl, dt, dd, blockquote, figure, fieldset, legend, textarea, pre, iframe, hr, h1, h2, h3, h4, h5, h6"
|
|
2
|
+
!default;
|
|
3
|
+
$heading-selector: "h1, h2, h3, h4, h5, h6" !default;
|
|
4
|
+
$form-selector: "button, input, select, textarea" !default;
|
|
5
|
+
$media-selector: "img, video" !default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@forward "button" as button-*;
|
|
2
|
+
@forward "badge" as badge-*;
|
|
3
|
+
@forward "progress" as progress-*;
|
|
4
|
+
@forward "text-input" as text-input-*;
|
|
5
|
+
@forward "textarea" as textarea-*;
|
|
6
|
+
@forward "select" as select-*;
|
|
7
|
+
@forward "checkbox" as checkbox-*;
|
|
8
|
+
@forward "radio" as radio-*;
|
|
9
|
+
@forward "switch" as switch-*;
|
|
10
|
+
@forward "file" as file-*;
|
|
11
|
+
@forward "range" as range-*;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
@use "sass:list";
|
|
2
|
+
@use "variables" as *;
|
|
3
|
+
@use "../../variables";
|
|
4
|
+
|
|
5
|
+
@if variables.$feature-element-badge {
|
|
6
|
+
#{$selector} {
|
|
7
|
+
@include variables.backgroundColor(
|
|
8
|
+
default-bg,
|
|
9
|
+
list.nth($default-combination, 1),
|
|
10
|
+
);
|
|
11
|
+
@include variables.textColor(default-fg, list.nth($default-combination, 2));
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
padding: 0 $padding-x;
|
|
16
|
+
line-height: $line-height;
|
|
17
|
+
font-size: $font-size;
|
|
18
|
+
border-radius: $border-radius;
|
|
19
|
+
// Subtle outline disambiguates pill shape from page bg when the variant
|
|
20
|
+
// bg ≈ page bg (e.g. .is-default on white, .is-light on dark). Matches
|
|
21
|
+
// the page-foreground axis at low alpha so it reads regardless of
|
|
22
|
+
// variant colour. WCAG 1.4.11 graphical-object contrast.
|
|
23
|
+
outline: 1px solid
|
|
24
|
+
color-mix(in srgb, var(--kc-fg, currentColor) 50%, transparent);
|
|
25
|
+
outline-offset: -1px;
|
|
26
|
+
|
|
27
|
+
&#{$square-selector} {
|
|
28
|
+
border-radius: $square-border-radius;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@include variables.combinations using ($label, $tuple) {
|
|
32
|
+
@include variables.backgroundColor(#{$label}-bg, list.nth($tuple, 1));
|
|
33
|
+
@include variables.textColor(#{$label}-fg, list.nth($tuple, 2));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Forced-colors: the 35%-mixed outline collapses to a near-transparent
|
|
37
|
+
// system colour and the pill shape disappears against Canvas. Force a
|
|
38
|
+
// solid CanvasText outline so the boundary stays visible; the variant
|
|
39
|
+
// distinction flattens
|
|
40
|
+
@media (forced-colors: active) {
|
|
41
|
+
outline-color: CanvasText;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
$selector: ".badge" !default;
|
|
4
|
+
$square-selector: "#{variables.$selector-prefix-is}square" !default;
|
|
5
|
+
|
|
6
|
+
// Inline indicator sizing. Fixed line-height keeps the pill height
|
|
7
|
+
// independent of the surrounding text's line-height (which would otherwise
|
|
8
|
+
// stretch a numeric badge inside prose). All three derive from the size
|
|
9
|
+
// scale so the badge sits in the framework's dimensional rhythm.
|
|
10
|
+
$padding-x: variables.$size-extra-small !default;
|
|
11
|
+
$line-height: variables.$size-medium !default;
|
|
12
|
+
$font-size: variables.$size-small !default;
|
|
13
|
+
|
|
14
|
+
// Pill default. The `.is-square` modifier overrides this with the global
|
|
15
|
+
// border radius so badges can match the corner radius of adjacent buttons.
|
|
16
|
+
$border-radius: variables.$global-max-border-radius !default;
|
|
17
|
+
$square-border-radius: variables.$global-border-radius !default;
|
|
18
|
+
|
|
19
|
+
$default-combination: variables.$color-combination-default !default;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
@use "sass:list";
|
|
2
|
+
@use "variables" as *;
|
|
3
|
+
@use "../../variables";
|
|
4
|
+
@use "../../helper/controls" as controls;
|
|
5
|
+
@use "../../typography/link/mixins" as link;
|
|
6
|
+
|
|
7
|
+
@if variables.$feature-element-button {
|
|
8
|
+
#{$selector} {
|
|
9
|
+
@include variables.backgroundColor(
|
|
10
|
+
default-bg,
|
|
11
|
+
list.nth($default-combination, 1),
|
|
12
|
+
);
|
|
13
|
+
@include variables.textColor(default-fg, list.nth($default-combination, 2));
|
|
14
|
+
// Transparent border by default so the box stays the same size in
|
|
15
|
+
// every modifier; `.is-outlined` (and its per-combination override
|
|
16
|
+
// below) reach back in and set a visible `border-color`. Without
|
|
17
|
+
// this, toggling outlined would shift the layout by 2px.
|
|
18
|
+
border: 1px solid transparent;
|
|
19
|
+
padding: $padding-y $padding-x;
|
|
20
|
+
min-width: $min-width;
|
|
21
|
+
border-radius: $border-radius;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
// `<a class="button">` would otherwise inherit the bare-link underline.
|
|
24
|
+
// `.is-link` re-asserts underline via `linkSurface` below.
|
|
25
|
+
text-decoration: none;
|
|
26
|
+
|
|
27
|
+
&:focus-visible {
|
|
28
|
+
@include controls.focus-ring(
|
|
29
|
+
$focus-outline-width,
|
|
30
|
+
$focus-outline-style,
|
|
31
|
+
$focus-outline-offset,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// `filter: brightness()` is preferred over swapping `(bg, fg)` on hover:
|
|
36
|
+
// brightness scales every channel uniformly so the rest-state contrast
|
|
37
|
+
// ratio is preserved, which means every shipped combination AND any
|
|
38
|
+
// consumer-supplied palette stay WCAG AA at hover. A bg/fg swap, by
|
|
39
|
+
// contrast, lands at whatever ratio the inverted pair happens to have.
|
|
40
|
+
// Mid-luminance combinations like `.is-primary` and `.is-success` would
|
|
41
|
+
// drop below 4.5:1.
|
|
42
|
+
&:hover {
|
|
43
|
+
filter: brightness($hover-brightness);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Matches the framework convention used by every other interactive
|
|
47
|
+
// element (text-input, select, switch, …): faded glyph + `cursor:
|
|
48
|
+
// not-allowed`, and the brightness hover is unset so the button
|
|
49
|
+
// doesn't visually react under a disabled-pointer.
|
|
50
|
+
&:disabled {
|
|
51
|
+
cursor: not-allowed;
|
|
52
|
+
opacity: $disabled-opacity;
|
|
53
|
+
|
|
54
|
+
&:hover {
|
|
55
|
+
filter: none;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@include variables.combinations using ($label, $tuple) {
|
|
60
|
+
@include variables.backgroundColor(#{$label}-bg, list.nth($tuple, 1));
|
|
61
|
+
@include variables.textColor(#{$label}-fg, list.nth($tuple, 2));
|
|
62
|
+
|
|
63
|
+
// `.is-inverted` flips the combination onto the page surface:
|
|
64
|
+
// page bg as the fill, the combination's bg (its "main" colour)
|
|
65
|
+
// as text. Theme-aware via `--kc-bg` / `--kc-<label>-bg` so light
|
|
66
|
+
// theme shows e.g. white-bg + green-text on `is-primary`, dark
|
|
67
|
+
// theme shows dark-bg + themed-green-text. Skipped for `default`
|
|
68
|
+
// because its bg matches the page bg (the result would be
|
|
69
|
+
// invisible); the modifier-less branch below handles that case
|
|
70
|
+
// with a true `(bg, fg)` swap. Border stays at the base rule's
|
|
71
|
+
// transparent placeholder so the surface is borderless.
|
|
72
|
+
@if $label != default {
|
|
73
|
+
&#{$inverted-selector} {
|
|
74
|
+
@include variables.backgroundColor(
|
|
75
|
+
bg,
|
|
76
|
+
list.nth($default-combination, 1),
|
|
77
|
+
);
|
|
78
|
+
@include variables.textColor(#{$label}-bg, list.nth($tuple, 1));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// `.is-outlined` keeps the combination's bg as the visible
|
|
83
|
+
// signature: transparent fill, bg-as-text, bg-as-border. Raw
|
|
84
|
+
// literals (not the var-aware mixin) match `.is-inverted`'s
|
|
85
|
+
// legacy-palette stance so contrast stays predictable across
|
|
86
|
+
// consumer-supplied themes. Skipped for `default` because its bg
|
|
87
|
+
// is the page bg in light theme — `.button.is-default.is-outlined`
|
|
88
|
+
// falls through to the modifier-less `&#{$outlined-selector}`
|
|
89
|
+
// rule below + `.button.is-default`'s themed fg.
|
|
90
|
+
@if $label != default {
|
|
91
|
+
&#{$outlined-selector} {
|
|
92
|
+
background: transparent;
|
|
93
|
+
color: list.nth($tuple, 1);
|
|
94
|
+
border: 1px solid list.nth($tuple, 1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Modifier-less inverted/outlined rules sit AFTER the combinations
|
|
100
|
+
// loop so they out-cascade the `.is-default` combination at equal
|
|
101
|
+
// specificity (both are two-class selectors). Higher-specificity
|
|
102
|
+
// `.is-<combo>.is-<modifier>` rules in the loop above still win for
|
|
103
|
+
// explicit combinations.
|
|
104
|
+
//
|
|
105
|
+
// `.button.is-inverted` (and `.is-default.is-inverted`) is a true
|
|
106
|
+
// `(bg, fg)` swap of the default combination's theme tokens —
|
|
107
|
+
// `--kc-default-fg` becomes the fill, `--kc-default-bg` becomes
|
|
108
|
+
// the text. The non-default combinations follow a different rule
|
|
109
|
+
// (page-bg fill + combo's bg as text); default needs the explicit
|
|
110
|
+
// swap because its bg matches the page bg, so a page-bg-fill
|
|
111
|
+
// inversion would render invisible. Border stays transparent
|
|
112
|
+
// (inherited from the base rule).
|
|
113
|
+
&#{$inverted-selector} {
|
|
114
|
+
@include variables.backgroundColor(
|
|
115
|
+
default-fg,
|
|
116
|
+
list.nth($default-combination, 2),
|
|
117
|
+
);
|
|
118
|
+
@include variables.textColor(
|
|
119
|
+
default-bg,
|
|
120
|
+
list.nth($default-combination, 1),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// `.button.is-outlined` strips the fill and re-asserts a visible
|
|
125
|
+
// themed border. The default button's visible signature is its
|
|
126
|
+
// themed fg, so the border tracks `--kc-default-fg` here; using
|
|
127
|
+
// `--kc-default-bg` for the outline would render invisible against
|
|
128
|
+
// the page in light theme. Per-combination outlined rules above
|
|
129
|
+
// override `border-color` with the combo's bg.
|
|
130
|
+
&#{$outlined-selector} {
|
|
131
|
+
background: transparent;
|
|
132
|
+
@include variables.defaultProperty(
|
|
133
|
+
border-color,
|
|
134
|
+
default-fg,
|
|
135
|
+
list.nth($default-combination, 2),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// `.button.is-link` styles the button as a link: no fill, no
|
|
140
|
+
// visible border (kept transparent so layout is preserved when
|
|
141
|
+
// toggling), themed `--kc-link` text, and `--kc-link-hover` on
|
|
142
|
+
// hover. The brightness filter is unset so hover transitions
|
|
143
|
+
// through the link-hover token rather than darkening the
|
|
144
|
+
// surrounding chrome. Sits after the combinations loop so it
|
|
145
|
+
// wins over the combination's bg/fg/border at equal specificity
|
|
146
|
+
// when authors compose `.is-<combo>.is-link` (the link surface
|
|
147
|
+
// takes priority — combinations have no link-styled variant).
|
|
148
|
+
&#{$link-selector} {
|
|
149
|
+
background: transparent;
|
|
150
|
+
border: 1px solid transparent;
|
|
151
|
+
@include link.linkSurface(
|
|
152
|
+
$fallback: list.nth($default-combination, 2),
|
|
153
|
+
$hover-fallback: list.nth($default-combination, 2),
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
&:hover {
|
|
157
|
+
filter: none;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Forced-colors (Windows High Contrast). The `filter: brightness()` hover
|
|
162
|
+
// is a no-op once colours are system-forced, so press feedback would
|
|
163
|
+
// disappear. Replace with an explicit Highlight outline on hover; the
|
|
164
|
+
// focus-visible ring already handles keyboard focus via system colours
|
|
165
|
+
// (UA forces outline-color to CanvasText). WCAG 1.4.11 / 2.4.7.
|
|
166
|
+
@media (forced-colors: active) {
|
|
167
|
+
&:hover {
|
|
168
|
+
outline: 2px solid Highlight;
|
|
169
|
+
outline-offset: 2px;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
|
|
4
|
+
$selector: "button, .button" !default;
|
|
5
|
+
$inverted-selector: "#{variables.$selector-prefix-is}inverted" !default;
|
|
6
|
+
$outlined-selector: "#{variables.$selector-prefix-is}outlined" !default;
|
|
7
|
+
$link-selector: "#{variables.$selector-prefix-is}link" !default;
|
|
8
|
+
|
|
9
|
+
@function _touch-target-padding($target, $line-height-rem) {
|
|
10
|
+
@return math.max(0rem, math.div($target - $line-height-rem, 2));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Vertical padding is derived so the AAA touch-target invariant is enforced
|
|
14
|
+
// in code, not just a comment. The button has no explicit `font-size`, so it
|
|
15
|
+
// inherits the body size (`1rem` once `$global-base-size` is applied at the
|
|
16
|
+
// root). Effective height = padding-y × 2 + line-height × font-size; setting
|
|
17
|
+
// padding-y to half the slack between the touch-target floor and the
|
|
18
|
+
// rendered line height gives exactly the AAA minimum at default settings:
|
|
19
|
+
// (2.75rem − 1rem × 1.5) / 2 = 0.625rem. Override `$global-min-touch-target`
|
|
20
|
+
// or `$global-body-line-height` and the padding follows.
|
|
21
|
+
$padding-y: _touch-target-padding(
|
|
22
|
+
variables.$global-min-touch-target,
|
|
23
|
+
1rem * variables.$global-body-line-height
|
|
24
|
+
) !default;
|
|
25
|
+
$padding-x: variables.$size-normal !default;
|
|
26
|
+
|
|
27
|
+
$min-width: variables.$global-min-touch-target !default;
|
|
28
|
+
$border-radius: variables.$global-border-radius !default;
|
|
29
|
+
$default-combination: variables.$color-combination-default !default;
|
|
30
|
+
|
|
31
|
+
$focus-outline-width: variables.$global-focus-outline-width !default;
|
|
32
|
+
$focus-outline-style: variables.$global-focus-outline-style !default;
|
|
33
|
+
$focus-outline-offset: variables.$global-focus-outline-offset !default;
|
|
34
|
+
|
|
35
|
+
$hover-brightness: variables.$global-hover-brightness !default;
|
|
36
|
+
$disabled-opacity: variables.$global-disabled-opacity !default;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
@use "../../helper/controls" as controls;
|
|
4
|
+
|
|
5
|
+
@if variables.$feature-element-checkbox {
|
|
6
|
+
#{$selector} {
|
|
7
|
+
appearance: none;
|
|
8
|
+
-webkit-appearance: none;
|
|
9
|
+
-moz-appearance: none;
|
|
10
|
+
display: inline-block;
|
|
11
|
+
width: $size;
|
|
12
|
+
height: $size;
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
@include controls.borderWithMix($border-width, $border-mix);
|
|
16
|
+
border-radius: $border-radius;
|
|
17
|
+
background-color: transparent;
|
|
18
|
+
vertical-align: middle;
|
|
19
|
+
flex-shrink: 0;
|
|
20
|
+
|
|
21
|
+
&:checked {
|
|
22
|
+
background-color: var(--kc-primary-bg, currentColor);
|
|
23
|
+
border-color: var(--kc-primary-bg, currentColor);
|
|
24
|
+
// The SVG strokes with `currentColor`; pinning `color` to the
|
|
25
|
+
// primary foreground token guarantees the tick contrasts the fill
|
|
26
|
+
// whatever the theme's primary palette is.
|
|
27
|
+
color: var(--kc-primary-fg, currentColor);
|
|
28
|
+
background-image: $check-image;
|
|
29
|
+
background-repeat: no-repeat;
|
|
30
|
+
background-position: center;
|
|
31
|
+
background-size: 80% auto;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&:focus-visible {
|
|
35
|
+
@include controls.focus-ring(
|
|
36
|
+
$focus-outline-width,
|
|
37
|
+
$focus-outline-style,
|
|
38
|
+
$focus-outline-offset,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@include controls.invalidControl();
|
|
43
|
+
|
|
44
|
+
&:disabled {
|
|
45
|
+
@include controls.disabledControl($disabled-opacity);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
// Excludes `.switch`-classed inputs so the switch plugin can fully restyle
|
|
4
|
+
// them. Keep this exclusion in sync if you add another checkbox variant.
|
|
5
|
+
$selector: 'input[type="checkbox"]:not(.switch)' !default;
|
|
6
|
+
|
|
7
|
+
$size: 1rem !default;
|
|
8
|
+
$border-radius: 3px !default;
|
|
9
|
+
$border-width: variables.$global-border-width !default;
|
|
10
|
+
|
|
11
|
+
$focus-outline-width: variables.$global-focus-outline-width !default;
|
|
12
|
+
$focus-outline-style: variables.$global-focus-outline-style !default;
|
|
13
|
+
$focus-outline-offset: variables.$global-focus-outline-offset !default;
|
|
14
|
+
|
|
15
|
+
$disabled-opacity: variables.$global-disabled-opacity !default;
|
|
16
|
+
$border-mix: variables.$global-border-mix !default;
|
|
17
|
+
|
|
18
|
+
// Inline tick mark using `stroke="currentColor"`: the SVG inherits the
|
|
19
|
+
// element's `color`, which the plugin pins to `--kc-primary-fg` on
|
|
20
|
+
// `:checked`. That keeps the tick AAA-readable against any primary-bg
|
|
21
|
+
// the theme picks (deep sage, mid-tone teal, a high-contrast cyan):
|
|
22
|
+
// the fg token is always the contrast pair of the bg token.
|
|
23
|
+
$check-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none"><path d="M2.5 6.5l2.5 2.5 4.5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>')
|
|
24
|
+
!default;
|