@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
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
// Covers every text-flavoured native input. Listed individually rather than via
|
|
4
|
+
// `input:not([type])` because the latter also matches non-text types (number is
|
|
5
|
+
// a text-like control, but checkbox/radio/etc. need different rules and are
|
|
6
|
+
// handled by their own plugins). Order is alphabetical for deterministic
|
|
7
|
+
// selector list output.
|
|
8
|
+
$selector: 'input[type="email"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="url"]'
|
|
9
|
+
!default;
|
|
10
|
+
|
|
11
|
+
$padding-y: variables.$size-extra-small !default;
|
|
12
|
+
$padding-x: variables.$size-small !default;
|
|
13
|
+
|
|
14
|
+
$border-radius: variables.$global-border-radius !default;
|
|
15
|
+
$border-width: variables.$global-border-width !default;
|
|
16
|
+
|
|
17
|
+
$focus-outline-width: variables.$global-focus-outline-width !default;
|
|
18
|
+
$focus-outline-style: variables.$global-focus-outline-style !default;
|
|
19
|
+
$focus-outline-offset: variables.$global-focus-outline-offset !default;
|
|
20
|
+
|
|
21
|
+
$disabled-opacity: variables.$global-disabled-opacity !default;
|
|
22
|
+
$border-mix: variables.$global-border-mix !default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
@use "../../helper/controls" as controls;
|
|
4
|
+
|
|
5
|
+
@if variables.$feature-element-textarea {
|
|
6
|
+
#{$selector} {
|
|
7
|
+
@include variables.backgroundColor(input-bg, transparent);
|
|
8
|
+
@include variables.textColor(input-fg, currentColor);
|
|
9
|
+
display: block;
|
|
10
|
+
width: 100%;
|
|
11
|
+
min-height: $min-height;
|
|
12
|
+
padding: $padding-y $padding-x;
|
|
13
|
+
@include controls.borderWithMix($border-width, $border-mix);
|
|
14
|
+
border-radius: $border-radius;
|
|
15
|
+
font: inherit;
|
|
16
|
+
line-height: 1.4;
|
|
17
|
+
resize: $resize;
|
|
18
|
+
|
|
19
|
+
&:focus-visible {
|
|
20
|
+
@include controls.focus-ring(
|
|
21
|
+
$focus-outline-width,
|
|
22
|
+
$focus-outline-style,
|
|
23
|
+
$focus-outline-offset,
|
|
24
|
+
);
|
|
25
|
+
border-color: var(--kc-fg, currentColor);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@include controls.invalidControl();
|
|
29
|
+
|
|
30
|
+
&:disabled {
|
|
31
|
+
@include controls.disabledControl($disabled-opacity);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&::placeholder {
|
|
35
|
+
color: color-mix(in srgb, currentColor 65%, transparent);
|
|
36
|
+
opacity: 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
$selector: "textarea" !default;
|
|
4
|
+
|
|
5
|
+
$padding-y: variables.$size-extra-small !default;
|
|
6
|
+
$padding-x: variables.$size-small !default;
|
|
7
|
+
|
|
8
|
+
$border-radius: variables.$global-border-radius !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
|
+
$min-height: 4rem !default;
|
|
19
|
+
|
|
20
|
+
// Vertical-only resize is the safer default: horizontal resize on a fluid
|
|
21
|
+
// container can break responsive layouts. Consumers can override to `both`.
|
|
22
|
+
$resize: vertical !default;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@use "sass:map";
|
|
2
|
+
@use "../variables";
|
|
3
|
+
|
|
4
|
+
// Viewport-query mixins. `$device` is a key from `$responsive-breakpoints`
|
|
5
|
+
// (`tablet`, `desktop`, `widescreen`, `fullhd`); `mobile` is `null` and
|
|
6
|
+
// not valid here.
|
|
7
|
+
@mixin from($device) {
|
|
8
|
+
@media screen and (min-width: map.get(
|
|
9
|
+
variables.$responsive-breakpoints,
|
|
10
|
+
$device
|
|
11
|
+
)) {
|
|
12
|
+
@content;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@mixin until($device) {
|
|
17
|
+
@media screen and (max-width: map.get(
|
|
18
|
+
variables.$responsive-breakpoints,
|
|
19
|
+
$device
|
|
20
|
+
)
|
|
21
|
+
- 1px) {
|
|
22
|
+
@content;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Container-query counterparts. Same `$responsive-breakpoints` keyspace;
|
|
27
|
+
// resolves against the nearest containment context rather than the
|
|
28
|
+
// viewport. Caller is responsible for declaring `container-type` (and
|
|
29
|
+
// optionally `container-name`) on the host element. Most module
|
|
30
|
+
// variables expose a `$container-name` opt-in for that.
|
|
31
|
+
@mixin containerFrom($device) {
|
|
32
|
+
@container (min-width: #{map.get(
|
|
33
|
+
variables.$responsive-breakpoints,
|
|
34
|
+
$device
|
|
35
|
+
)}) {
|
|
36
|
+
@content;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@mixin containerUntil($device) {
|
|
41
|
+
@container (max-width: #{map.get(variables.$responsive-breakpoints, $device)
|
|
42
|
+
- 1px}) {
|
|
43
|
+
@content;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
@use "sass:list";
|
|
2
|
+
@use "../variables";
|
|
3
|
+
|
|
4
|
+
// Shared affordances for interactive controls (form inputs, buttons, tabs,
|
|
5
|
+
// links, navbar items). Each form-control plugin used to inline these four
|
|
6
|
+
// blocks verbatim; centralising them here keeps the focus / disabled /
|
|
7
|
+
// invalid / border-mix contracts in one place and lets the framework
|
|
8
|
+
// version focus behaviour globally (fall-back chains, double rings, etc.)
|
|
9
|
+
// without touching every component.
|
|
10
|
+
|
|
11
|
+
// `$token` defaults to the global `focus-ring` token; the fallback chain
|
|
12
|
+
// keeps the outline visible in themes that haven't shipped a focus-ring
|
|
13
|
+
// override (falls through to `--kc-fg` and then `currentColor`). Plugins
|
|
14
|
+
// that want a different focus token (rare) pass `$token: <name>`.
|
|
15
|
+
@mixin focus-ring(
|
|
16
|
+
$width: variables.$global-focus-outline-width,
|
|
17
|
+
$style: variables.$global-focus-outline-style,
|
|
18
|
+
$offset: variables.$global-focus-outline-offset,
|
|
19
|
+
$token: focus-ring,
|
|
20
|
+
) {
|
|
21
|
+
outline: $width $style var(--kc-#{$token}, var(--kc-fg, currentColor));
|
|
22
|
+
outline-offset: $offset;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@mixin disabledControl($opacity: variables.$global-disabled-opacity) {
|
|
26
|
+
cursor: not-allowed;
|
|
27
|
+
opacity: $opacity;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Form-control border tint. The control inherits `color` from the surface
|
|
31
|
+
// so mixing `currentColor` with transparent keeps the border tuned against
|
|
32
|
+
// the foreground regardless of theme. WCAG 1.4.11 (3:1 non-text contrast)
|
|
33
|
+
// is held by `$global-border-mix` (50%).
|
|
34
|
+
@mixin borderWithMix(
|
|
35
|
+
$width: variables.$global-border-width,
|
|
36
|
+
$mix: variables.$global-border-mix,
|
|
37
|
+
$color: currentColor,
|
|
38
|
+
) {
|
|
39
|
+
border: $width solid color-mix(in srgb, $color #{$mix}, transparent);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// `:user-invalid` (not `:invalid`): only flags after interaction or submit
|
|
43
|
+
// attempt, avoiding the false-positive red ring on untouched `required`
|
|
44
|
+
// fields. `[aria-invalid="true"]` remains the manual hook for JS-validated
|
|
45
|
+
// forms. `$color-token` lets a caller redirect the cue (rare).
|
|
46
|
+
@mixin invalidControl($color-token: danger-bg) {
|
|
47
|
+
&:user-invalid,
|
|
48
|
+
&[aria-invalid="true"] {
|
|
49
|
+
border-color: var(--kc-#{$color-token}, currentColor);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Nested-link affordance for surface modules (alert, card). The page-level
|
|
54
|
+
// `--kc-link` is calibrated against the page bg, not the module surface bg;
|
|
55
|
+
// pinning links to `currentColor` keeps them paired with the surface fg
|
|
56
|
+
// (contrast-safe by construction on themed `.is-*` variants). Underline
|
|
57
|
+
// preserves the link cue now that colour alone can't (WCAG 1.4.1).
|
|
58
|
+
@mixin nestedLinks {
|
|
59
|
+
a {
|
|
60
|
+
color: currentColor;
|
|
61
|
+
text-decoration: underline;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Iterate over the framework's colour combinations and emit a per-label
|
|
66
|
+
// child selector that assigns `--kc-<prefix><label>-bg` / `-fg` tokens.
|
|
67
|
+
// Components whose `using ($label, $tuple)` body is JUST these two calls
|
|
68
|
+
// (alert, card) replace the inline block with a single
|
|
69
|
+
// `@include controls.combinations-apply()`. Components with additional
|
|
70
|
+
// per-combination rules (button) keep the inline block.
|
|
71
|
+
@mixin combinations-apply($bg-token-prefix: "", $fg-token-prefix: "") {
|
|
72
|
+
@include variables.combinations using ($label, $tuple) {
|
|
73
|
+
@include variables.backgroundColor(
|
|
74
|
+
"#{$bg-token-prefix}#{$label}-bg",
|
|
75
|
+
list.nth($tuple, 1),
|
|
76
|
+
);
|
|
77
|
+
@include variables.textColor(
|
|
78
|
+
"#{$fg-token-prefix}#{$label}-fg",
|
|
79
|
+
list.nth($tuple, 2),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@use "sass:map";
|
|
2
|
+
@use "../variables";
|
|
3
|
+
|
|
4
|
+
// `[data-state]` icon hook. Pairs with the `.is-<label>` colour combinations
|
|
5
|
+
// to satisfy WCAG 1.4.1 (Use of Colour): a non-colour cue precedes the label
|
|
6
|
+
// so colour-blind users, monochrome displays, and forced-colours mode all
|
|
7
|
+
// read the state. Consumers opt their markup in:
|
|
8
|
+
//
|
|
9
|
+
// <span data-state="success">Saved</span>
|
|
10
|
+
//
|
|
11
|
+
// Defaults are baked in as the `var()` fallback per label; consumers who set
|
|
12
|
+
// `--kc-state-icon-<label>` at any scope override the glyph (or `''` to drop
|
|
13
|
+
// it).
|
|
14
|
+
//
|
|
15
|
+
// Only labels with a non-empty glyph emit a rule: the `default`, `light`,
|
|
16
|
+
// and `primary` combinations have no inherent state semantic, so emitting an
|
|
17
|
+
// empty `::before` for them is pure dead weight. Consumers who want to opt
|
|
18
|
+
// those in can add `$icons` keys via `@use 'helper/state' with (...)`.
|
|
19
|
+
$selector-attr: "data-state" !default;
|
|
20
|
+
|
|
21
|
+
// Trailing space is U+0020 so the icon visually separates from the label
|
|
22
|
+
// without an extra wrapping element.
|
|
23
|
+
$icons: (
|
|
24
|
+
success: "✓ ",
|
|
25
|
+
warning: "⚠ ",
|
|
26
|
+
danger: "✕ ",
|
|
27
|
+
) !default;
|
|
28
|
+
|
|
29
|
+
@if variables.$feature-helper-state {
|
|
30
|
+
@each $label, $glyph in $icons {
|
|
31
|
+
[#{$selector-attr}="#{$label}"]::before {
|
|
32
|
+
content: var(--kc-state-icon-#{$label}, "#{$glyph}");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Batteries-included entry. Pulls every category, the default
|
|
2
|
+
// light theme, and the dark theme (auto-switching via prefers-color-scheme +
|
|
3
|
+
// opt-in `.theme-dark` override). Consumers wanting only one theme should
|
|
4
|
+
// use `_index.scss` and import their chosen theme(s) themselves.
|
|
5
|
+
//
|
|
6
|
+
// Re-export the feature-flag list under `$feature-list` so consumers can
|
|
7
|
+
// tree-shake from the root entry:
|
|
8
|
+
// @use '@adnap/krysalicss' with ($feature-list: ('base-reset', 'element-button'));
|
|
9
|
+
// `_feature.scss` already declares `$list: true !default;`, so a bare
|
|
10
|
+
// @forward keeps the variable configurable downstream without locking the
|
|
11
|
+
// value via a redundant `with` clause (which would error if the module had
|
|
12
|
+
// been loaded transitively first via a per-component `_variables.scss`).
|
|
13
|
+
@forward "variables/feature" as feature-*;
|
|
14
|
+
|
|
15
|
+
@use "theme/default";
|
|
16
|
+
@use "theme/dark";
|
|
17
|
+
@use "index";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
@use "../../helper/breakpoints" as breakpoints;
|
|
4
|
+
|
|
5
|
+
@if variables.$feature-layout-container {
|
|
6
|
+
#{$selector} {
|
|
7
|
+
flex-grow: 1;
|
|
8
|
+
margin: 0 auto;
|
|
9
|
+
position: relative;
|
|
10
|
+
width: auto;
|
|
11
|
+
padding-inline-start: $gutter;
|
|
12
|
+
padding-inline-end: $gutter;
|
|
13
|
+
|
|
14
|
+
@if $fluid-modifier {
|
|
15
|
+
@each $device, $size in variables.$responsive-breakpoints {
|
|
16
|
+
@include breakpoints.from($device) {
|
|
17
|
+
max-width: $size;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&#{variables.$selector-prefix-is}#{$fluid-modifier} {
|
|
22
|
+
max-width: none;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
|
|
4
|
+
@if variables.$feature-layout-flex {
|
|
5
|
+
#{$flex-selector} {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-wrap: wrap;
|
|
8
|
+
gap: $gap;
|
|
9
|
+
|
|
10
|
+
&.no-wrap {
|
|
11
|
+
flex-wrap: nowrap;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&#{variables.$selector-prefix-is}centered {
|
|
15
|
+
justify-content: center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&#{variables.$selector-prefix-is}vertical {
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
> #{$column-selector} {
|
|
23
|
+
flex: 1 1 0;
|
|
24
|
+
min-width: 0;
|
|
25
|
+
|
|
26
|
+
// Sizes to its content instead of growing to share row width.
|
|
27
|
+
&#{$narrow-selector} {
|
|
28
|
+
flex: none;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
$flex-selector: ".flex" !default;
|
|
4
|
+
$column-selector: ".col" !default;
|
|
5
|
+
$narrow-selector: "#{variables.$selector-prefix-is}narrow" !default;
|
|
6
|
+
|
|
7
|
+
// Inter-item gap, applied via native CSS `gap` (Baseline since 2021).
|
|
8
|
+
// Defaults to the global token so flex and grid share spacing rhythm.
|
|
9
|
+
$gap: variables.$global-gap !default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@use "sass:map";
|
|
2
|
+
@use "variables" as *;
|
|
3
|
+
@use "../../variables";
|
|
4
|
+
|
|
5
|
+
@if variables.$feature-layout-grid {
|
|
6
|
+
#{$selector} {
|
|
7
|
+
display: grid;
|
|
8
|
+
gap: $gap;
|
|
9
|
+
// Default behaviour: responsive auto-fit. Cells stretch to fill the row
|
|
10
|
+
// and reflow into more / fewer columns as the viewport changes. No media
|
|
11
|
+
// queries required: the CSS Grid algorithm handles it.
|
|
12
|
+
grid-template-columns: repeat(auto-fit, minmax($auto-min, 1fr));
|
|
13
|
+
|
|
14
|
+
// Explicit column-count variants: `.grid.is-cols-3` etc.
|
|
15
|
+
@each $n in $column-modifiers {
|
|
16
|
+
&#{variables.$selector-prefix-is}cols-#{$n} {
|
|
17
|
+
grid-template-columns: repeat($n, minmax(0, 1fr));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Cell spans. Apply to direct children with `.cell.is-span-N` or
|
|
22
|
+
// `.cell.is-half` etc. Cells with no span class fill one column.
|
|
23
|
+
> #{$cell-selector} {
|
|
24
|
+
@for $i from 1 through $columns {
|
|
25
|
+
&#{variables.$selector-prefix-is}span-#{$i} {
|
|
26
|
+
grid-column: span $i;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@each $label, $span in $named-spans {
|
|
31
|
+
&#{variables.$selector-prefix-is}#{$label} {
|
|
32
|
+
grid-column: span $span;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
// Container + cell selectors. Both configurable so consumers can rescope to a
|
|
4
|
+
// class prefix or web-component shadow root without forking the source.
|
|
5
|
+
$selector: ".grid" !default;
|
|
6
|
+
$cell-selector: ".cell" !default;
|
|
7
|
+
|
|
8
|
+
// `gap` between rows + columns. Uses CSS `gap` natively (unlike flex which
|
|
9
|
+
// pads columns then negative-margins the row), so no half-step math needed.
|
|
10
|
+
$gap: variables.$global-gap !default;
|
|
11
|
+
|
|
12
|
+
// Auto-fit min cell width. The default `.grid` container is responsive:
|
|
13
|
+
// `repeat(auto-fit, minmax($auto-min, 1fr))`. Cells flow into as many columns
|
|
14
|
+
// as fit at the current viewport width. Override via:
|
|
15
|
+
// @use '@adnap/krysalicss' with ($layout-grid-auto-min: 14rem);
|
|
16
|
+
$auto-min: 16rem !default;
|
|
17
|
+
|
|
18
|
+
// Total columns for the explicit-grid variant (`.grid.is-cols-N` and
|
|
19
|
+
// `.cell.is-span-N`). 12 mirrors the flex grid's division count so consumers
|
|
20
|
+
// can reuse the same mental model.
|
|
21
|
+
$columns: 12 !default;
|
|
22
|
+
|
|
23
|
+
// Explicit column-count modifiers emitted as `.grid.is-cols-<N>`. Listed
|
|
24
|
+
// values get `repeat(<N>, minmax(0, 1fr))`. Trim the list to ship a smaller
|
|
25
|
+
// CSS surface; the default covers the common-case grid widths.
|
|
26
|
+
$column-modifiers: (2, 3, 4, 6, 12) !default;
|
|
27
|
+
|
|
28
|
+
// Named cell spans: match the flex grid's `.col.is-half`, `.is-one-third`,
|
|
29
|
+
// etc. naming so the API feels consistent across both layouts.
|
|
30
|
+
$named-spans: (
|
|
31
|
+
full: 12,
|
|
32
|
+
half: 6,
|
|
33
|
+
one-third: 4,
|
|
34
|
+
two-thirds: 8,
|
|
35
|
+
one-quarter: 3,
|
|
36
|
+
three-quarters: 9,
|
|
37
|
+
) !default;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
@use "sass:list";
|
|
2
|
+
@use "variables" as *;
|
|
3
|
+
@use "../../variables";
|
|
4
|
+
@use "../../helper/controls" as controls;
|
|
5
|
+
|
|
6
|
+
@if variables.$feature-module-alert {
|
|
7
|
+
#{$selector} {
|
|
8
|
+
@include variables.backgroundColor(
|
|
9
|
+
alert-bg,
|
|
10
|
+
list.nth($default-combination, 1),
|
|
11
|
+
);
|
|
12
|
+
@include variables.textColor(alert-fg, list.nth($default-combination, 2));
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: flex-start;
|
|
15
|
+
gap: $icon-gap;
|
|
16
|
+
padding: $padding-y $padding-x;
|
|
17
|
+
border-radius: $border-radius;
|
|
18
|
+
border-inline-start-width: $accent-width;
|
|
19
|
+
border-inline-start-style: solid;
|
|
20
|
+
border-inline-start-color: var(
|
|
21
|
+
--kc-fg,
|
|
22
|
+
#{list.nth($default-combination, 2)}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
@if $container-name {
|
|
26
|
+
container-type: inline-size;
|
|
27
|
+
container-name: #{$container-name};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
> #{$icon-selector} {
|
|
31
|
+
flex: 0 0 auto;
|
|
32
|
+
// Inherit the body line-height so the icon's first-line box matches
|
|
33
|
+
// the prose first-line box height. With `align-items: flex-start`
|
|
34
|
+
// above this means the glyph centres line up with the first line of
|
|
35
|
+
// text instead of floating above it. Pre-fix the icon used
|
|
36
|
+
// `line-height: 1` (~1em box) against ~1.5em text boxes, so the
|
|
37
|
+
// glyph rendered visibly higher than the text baseline.
|
|
38
|
+
line-height: inherit;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Nested links inherit the surface fg + carry an underline. The
|
|
42
|
+
// page-level --kc-link is calibrated against page bg, not against
|
|
43
|
+
// alert surface bg; pairing the link with the alert's own fg colour
|
|
44
|
+
// is contrast-safe by construction (it's the same colour that the
|
|
45
|
+
// body text reads at). The underline preserves the link affordance
|
|
46
|
+
// now that colour alone can't (WCAG 1.4.1).
|
|
47
|
+
@include controls.nestedLinks;
|
|
48
|
+
|
|
49
|
+
@include controls.combinations-apply();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
$selector: ".alert" !default;
|
|
4
|
+
$icon-selector: ".alert__icon" !default;
|
|
5
|
+
|
|
6
|
+
$padding-y: variables.$size-small !default;
|
|
7
|
+
$padding-x: variables.$size-normal !default;
|
|
8
|
+
|
|
9
|
+
$border-radius: variables.$global-border-radius !default;
|
|
10
|
+
|
|
11
|
+
// Left-edge accent: 3px solid stripe in the page foreground (`--kc-fg`).
|
|
12
|
+
// Stays constant across combinations — only the background changes per
|
|
13
|
+
// combination, so the stripe reads as a fixed identity marker.
|
|
14
|
+
// Width chosen to read as a stripe rather than a border at default sizes.
|
|
15
|
+
$accent-width: 3px !default;
|
|
16
|
+
|
|
17
|
+
// Gap between an optional `.alert__icon` slot and the prose body. Consumers
|
|
18
|
+
// supply their own icon glyph; the framework only standardises spacing.
|
|
19
|
+
$icon-gap: variables.$size-extra-small !default;
|
|
20
|
+
|
|
21
|
+
$default-combination: variables.$color-combination-default !default;
|
|
22
|
+
|
|
23
|
+
// Opt-in container-query host. See `module/card/_variables.scss` for rationale.
|
|
24
|
+
$container-name: null !default;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@use "sass:list";
|
|
2
|
+
@use "variables" as *;
|
|
3
|
+
@use "../../variables";
|
|
4
|
+
@use "../../helper/controls" as controls;
|
|
5
|
+
|
|
6
|
+
@if variables.$feature-module-card {
|
|
7
|
+
#{$selector} {
|
|
8
|
+
@include variables.backgroundColor(
|
|
9
|
+
card-bg,
|
|
10
|
+
list.nth($default-combination, 1),
|
|
11
|
+
);
|
|
12
|
+
@include variables.textColor(card-fg, list.nth($default-combination, 2));
|
|
13
|
+
padding: $gap;
|
|
14
|
+
border-radius: $border-radius;
|
|
15
|
+
border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
|
|
16
|
+
|
|
17
|
+
@if $container-name {
|
|
18
|
+
container-type: inline-size;
|
|
19
|
+
container-name: #{$container-name};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Nested links inherit the surface fg + carry an underline. Same
|
|
23
|
+
// rationale as alert: page-level --kc-link is calibrated against page
|
|
24
|
+
// bg, not card surface bg; pairing with the card's own fg avoids
|
|
25
|
+
// contrast failures on themed `.is-*` variants and on default cards
|
|
26
|
+
// in dark themes. Underline preserves the link cue (WCAG 1.4.1).
|
|
27
|
+
@include controls.nestedLinks;
|
|
28
|
+
|
|
29
|
+
@include controls.combinations-apply();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@use "../../variables";
|
|
2
|
+
|
|
3
|
+
$selector: ".card" !default;
|
|
4
|
+
$gap: variables.$global-gap !default;
|
|
5
|
+
$border-radius: variables.$global-border-radius !default;
|
|
6
|
+
$default-combination: variables.$color-combination-default !default;
|
|
7
|
+
|
|
8
|
+
// Opt-in container-query host. When non-null, the plugin emits
|
|
9
|
+
// `container-type: inline-size; container-name: <value>;` on the card so
|
|
10
|
+
// consumers can scope their own `containerFrom(...)` rules to card width
|
|
11
|
+
// instead of the viewport. The framework itself emits no container-query
|
|
12
|
+
// rules for card today; this is a hook for downstream code.
|
|
13
|
+
$container-name: null !default;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
@use "variables" as *;
|
|
2
|
+
@use "../../variables";
|
|
3
|
+
|
|
4
|
+
@if variables.$feature-module-field {
|
|
5
|
+
#{$selector} {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
gap: $gap;
|
|
9
|
+
margin-block-end: $margin-bottom;
|
|
10
|
+
|
|
11
|
+
> #{$label-selector} {
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
> #{$help-selector} {
|
|
16
|
+
font-size: $help-font-size;
|
|
17
|
+
color: color-mix(in srgb, currentColor #{$help-mix}, transparent);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// `.field.is-invalid` lets consumers flag the whole field (label + help
|
|
21
|
+
// tinted danger) without reaching into individual control selectors.
|
|
22
|
+
// Uses `:where()`-style scoping via direct child to keep specificity low
|
|
23
|
+
// and avoid leaking into nested fields.
|
|
24
|
+
&#{$invalid-selector} > #{$help-selector} {
|
|
25
|
+
color: var(--kc-danger-bg, currentColor);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Non-colour cue for invalid state. Triggered by the explicit
|
|
29
|
+
// `.is-invalid` modifier OR `:has(:user-invalid, [aria-invalid="true"])`.
|
|
30
|
+
// `:user-invalid` (not `:invalid`) avoids painting the glyph on every
|
|
31
|
+
// untouched `required` control: the user must have interacted (or
|
|
32
|
+
// attempted submit) before the danger cue fires. `:has()` and
|
|
33
|
+
// `:user-invalid` are both in our evergreen baseline. WCAG 1.4.1 + 1.4.11.
|
|
34
|
+
&#{$invalid-selector} > #{$label-selector}::before,
|
|
35
|
+
&:has(:user-invalid) > #{$label-selector}::before,
|
|
36
|
+
&:has([aria-invalid="true"]) > #{$label-selector}::before {
|
|
37
|
+
content: var(--kc-state-icon-danger, "#{$invalid-icon}");
|
|
38
|
+
color: var(--kc-danger-bg, currentColor);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Disabled-field hint dims the label + help so the visual state matches
|
|
42
|
+
// the underlying control. The control itself dims via its own `:disabled`
|
|
43
|
+
// rule; this just keeps surrounding text in sync.
|
|
44
|
+
&#{$disabled-selector} > #{$label-selector},
|
|
45
|
+
&#{$disabled-selector} > #{$help-selector} {
|
|
46
|
+
opacity: 0.6;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|