tiny-essentials 1.29.1 → 1.29.2
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/changelog/1/29/2.md +82 -0
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyFetchLoader.min.js +1 -0
- package/dist/v1/TinyImageLoader.min.js +1 -0
- package/dist/v1/TinyMediaCache.min.js +1 -0
- package/dist/v1/TinyMediaLoader.min.js +1 -0
- package/dist/v1/basics/index.cjs +5 -0
- package/dist/v1/basics/index.d.mts +2 -1
- package/dist/v1/basics/index.d.mts.map +1 -1
- package/dist/v1/basics/index.mjs +2 -1
- package/dist/v1/basics/media/youtube.cjs +275 -0
- package/dist/v1/basics/media/youtube.d.mts +107 -0
- package/dist/v1/basics/media/youtube.d.mts.map +1 -0
- package/dist/v1/basics/media/youtube.mjs +214 -0
- package/dist/v1/index.cjs +13 -0
- package/dist/v1/index.d.mts +6 -1
- package/dist/v1/index.d.mts.map +1 -1
- package/dist/v1/index.mjs +7 -2
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.cjs +0 -1
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts +0 -1
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts.map +1 -1
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.mjs +0 -1
- package/dist/v1/libs/fs/plugins/OPFS/index.cjs +0 -8
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts +0 -8
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts.map +1 -1
- package/dist/v1/libs/fs/plugins/OPFS/index.mjs +0 -8
- package/dist/v1/libs/html/TinyHtml.cjs +1 -1
- package/dist/v1/libs/html/TinyHtml.d.mts +2 -2
- package/dist/v1/libs/html/TinyHtml.d.mts.map +1 -1
- package/dist/v1/libs/html/TinyHtml.mjs +1 -1
- package/dist/v1/libs/html/loader/TinyMediaLoader.cjs +1999 -0
- package/dist/v1/libs/html/loader/TinyMediaLoader.d.mts +999 -0
- package/dist/v1/libs/html/loader/TinyMediaLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/TinyMediaLoader.mjs +1852 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.cjs +77 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.d.mts +103 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyAudioLoader.mjs +67 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.cjs +630 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.d.mts +138 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyContentLoader.mjs +576 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.cjs +70 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.d.mts +100 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/formats/TinyVideoLoader.mjs +60 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.cjs +946 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.d.mts +67 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/beta/probe/TinyMediaProbe.mjs +896 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.cjs +225 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.d.mts +149 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/formats/TinyFetchLoader.mjs +197 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.cjs +1454 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.d.mts +200 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/formats/TinyImageLoader.mjs +1317 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.cjs +668 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.d.mts +83 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/probe/TinyImageProbe.mjs +626 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.cjs +277 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.d.mts +118 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyBufferReader.mjs +247 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.cjs +128 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.d.mts +49 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyIsoBox.mjs +116 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.cjs +796 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.d.mts +354 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaCache.mjs +734 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.cjs +302 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.d.mts +256 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaMirror.mjs +280 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.cjs +194 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.d.mts +138 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.d.mts.map +1 -0
- package/dist/v1/libs/html/loader/utils/TinyMediaProgress.mjs +175 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.cjs +359 -55
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts +64 -6
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts.map +1 -1
- package/dist/v1/libs/tools/TinyPkgExportValidator.mjs +320 -57
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.cjs +0 -1
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts +0 -1
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts.map +1 -1
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.mjs +0 -1
- package/dist/v1/webTemplates/bootstrap/5.3/scss/background/_background-grid.scss +15 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/buttons/_buttons-contrast.scss +208 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/buttons/_buttons-ghost.scss +89 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/icon/_cube-icon.scss +65 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/components/icon/_sphere-pulse.scss +39 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_badges.scss +90 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_bootstrap-overrides.scss +495 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_buttons.scss +390 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_colors.scss +213 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_effects.scss +153 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_forms-tones.scss +69 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_forms.scss +323 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_global.scss +31 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_links.scss +47 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_tables.scss +25 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_theme.scss +21 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_tokens.scss +161 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_utilities.scss +81 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/_variables.scss +63 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_form-tone-mixins.scss +236 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_sizing.scss +68 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_tone-mixins.scss +392 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/_typography.scss +112 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/background/_tiny_gradient_1.scss +131 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/themes/deepstrap/plugins/colors/_pink.scss +47 -0
- package/docs/v1/Exports.md +33 -2
- package/docs/v1/README.md +9 -0
- package/docs/v1/basics/youtube.md +204 -0
- package/docs/v1/libs/html/loader/TinyFetchLoader.md +114 -0
- package/docs/v1/libs/html/loader/TinyImageLoader.md +141 -0
- package/docs/v1/libs/html/loader/TinyMediaCache.md +166 -0
- package/docs/v1/libs/html/loader/TinyMediaLoader.md +300 -0
- package/docs/v1/libs/tools/TinyPkgExportValidator.md +55 -0
- package/docs/v1/webTemplates/bootstrap/5.3/DeepStrap.md +177 -0
- package/package.json +244 -8
- /package/dist/v1/webTemplates/bootstrap/5.3/scss/input/{Placeholder-Colors-Fix.scss → _placeholder-colors-fix.scss} +0 -0
- /package/dist/v1/webTemplates/bootstrap/5.3/scss/spacing/{Spacing-Plus.scss → _spacing-plus.scss} +0 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
@use 'sass:list';
|
|
2
|
+
@use 'sass:map';
|
|
3
|
+
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// 1. Configuration
|
|
6
|
+
// =============================================================================
|
|
7
|
+
|
|
8
|
+
/// Defaults merged into every `$button-families` entry.
|
|
9
|
+
///
|
|
10
|
+
/// @type Map
|
|
11
|
+
/// @prop {String|null} mix - Overrides `--btn-mix`.
|
|
12
|
+
/// @prop {String|null} hover - Overrides `--btn-hover-amount`.
|
|
13
|
+
/// @prop {String|null} press - Overrides `--btn-press-amount`.
|
|
14
|
+
/// @prop {Boolean} seam - Draws a stronger outline edge.
|
|
15
|
+
/// @prop {List} variants - Which variants to emit.
|
|
16
|
+
$button-defaults: (
|
|
17
|
+
'mix': null,
|
|
18
|
+
'hover': null,
|
|
19
|
+
'press': null,
|
|
20
|
+
'seam': false,
|
|
21
|
+
'variants': (
|
|
22
|
+
'solid',
|
|
23
|
+
'outline',
|
|
24
|
+
'subtle',
|
|
25
|
+
),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
/// Every button family. One entry generates up to three classes:
|
|
29
|
+
///
|
|
30
|
+
/// .btn-<name> solid
|
|
31
|
+
/// .btn-outline-<name> outline
|
|
32
|
+
/// .btn-subtle-<name> subtle
|
|
33
|
+
///
|
|
34
|
+
/// @type Map
|
|
35
|
+
$button-families: (
|
|
36
|
+
'primary': (
|
|
37
|
+
tone: 'accent',
|
|
38
|
+
),
|
|
39
|
+
'secondary': (
|
|
40
|
+
tone: 'text-muted',
|
|
41
|
+
),
|
|
42
|
+
'success': (
|
|
43
|
+
tone: 'success',
|
|
44
|
+
),
|
|
45
|
+
'danger': (
|
|
46
|
+
tone: 'error',
|
|
47
|
+
),
|
|
48
|
+
'warning': (
|
|
49
|
+
tone: 'warn',
|
|
50
|
+
),
|
|
51
|
+
'info': (
|
|
52
|
+
tone: 'info',
|
|
53
|
+
),
|
|
54
|
+
'light': (
|
|
55
|
+
tone: 'neutral-light',
|
|
56
|
+
mix: 'rgb(var(--ui-shade-rgb))',
|
|
57
|
+
hover: '92%',
|
|
58
|
+
press: '82%',
|
|
59
|
+
seam: true,
|
|
60
|
+
),
|
|
61
|
+
'dark': (
|
|
62
|
+
tone: 'neutral-dark',
|
|
63
|
+
mix: 'var(--ui-neutral-light)',
|
|
64
|
+
hover: '82%',
|
|
65
|
+
press: '72%',
|
|
66
|
+
seam: true,
|
|
67
|
+
),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/// Ghost module configuration. Must mirror `$button-families`.
|
|
71
|
+
$ghost-tones: (
|
|
72
|
+
'primary': var(--ui-accent),
|
|
73
|
+
'secondary': var(--ui-text-muted),
|
|
74
|
+
'success': var(--ui-success),
|
|
75
|
+
'danger': var(--ui-error),
|
|
76
|
+
'warning': var(--ui-warn),
|
|
77
|
+
'info': var(--ui-info),
|
|
78
|
+
'light': var(--ui-neutral-light),
|
|
79
|
+
'dark': var(--ui-neutral-dark),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
@use '../../components/buttons/_buttons-ghost.scss' with (
|
|
83
|
+
$tones: $ghost-tones
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// Fail loud during development if a family is missing from the ghost map.
|
|
87
|
+
@each $name, $config in $button-families {
|
|
88
|
+
@if not map.has-key($ghost-tones, $name) {
|
|
89
|
+
@warn 'Button family `#{$name}` is missing from `$ghost-tones`.';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// 2. Primitives
|
|
95
|
+
// =============================================================================
|
|
96
|
+
|
|
97
|
+
/// Blends a theme tone into an opaque surface colour.
|
|
98
|
+
/// @param {String} $tone - Token suffix, without the `--ui-` prefix.
|
|
99
|
+
/// @param {Number} $amount - Share of the tone in the mix.
|
|
100
|
+
/// @param {String} $base - CSS colour the tone is blended into.
|
|
101
|
+
/// @return {String} An opaque `color-mix()` value.
|
|
102
|
+
@function solid-tint($tone, $amount: 40%, $base: var(--ui-canvas)) {
|
|
103
|
+
@return color-mix(in srgb, var(--ui-#{$tone}) #{$amount}, #{$base});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// =============================================================================
|
|
107
|
+
// 3. Variant mixins
|
|
108
|
+
// =============================================================================
|
|
109
|
+
|
|
110
|
+
/// @param {String} $tone - Token suffix, without the `--ui-` prefix.
|
|
111
|
+
@mixin subtle-variant($tone) {
|
|
112
|
+
--btn-tone: var(--ui-#{$tone});
|
|
113
|
+
--btn-tone-rgb: var(--ui-#{$tone}-rgb);
|
|
114
|
+
--bs-btn-color: var(--ui-#{$tone});
|
|
115
|
+
--bs-btn-hover-color: var(--ui-#{$tone});
|
|
116
|
+
--bs-btn-active-color: var(--ui-#{$tone});
|
|
117
|
+
--bs-btn-disabled-color: var(--ui-#{$tone});
|
|
118
|
+
|
|
119
|
+
--btn-border: transparent;
|
|
120
|
+
|
|
121
|
+
--btn-group-border: color-mix(in srgb, var(--ui-#{$tone}) 40%, var(--btn-group-bg));
|
|
122
|
+
|
|
123
|
+
color: var(--ui-#{$tone});
|
|
124
|
+
background-color: rgb(var(--ui-#{$tone}-rgb) / 0.12);
|
|
125
|
+
|
|
126
|
+
border: 1px solid var(--btn-border);
|
|
127
|
+
|
|
128
|
+
&.hover-border {
|
|
129
|
+
--btn-border: #{solid-tint($tone, 40%, var(--btn-group-bg, var(--ui-canvas)))};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&:hover:not(:disabled):not(.disabled),
|
|
133
|
+
&:active:not(:disabled):not(.disabled),
|
|
134
|
+
&.active {
|
|
135
|
+
border-color: var(--btn-border);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&:hover:not(:disabled):not(.disabled) {
|
|
139
|
+
--btn-glow:
|
|
140
|
+
0 0 0 1px rgb(var(--ui-#{$tone}-rgb) / 0.25), 0 0 20px -6px rgb(var(--ui-#{$tone}-rgb) / 0.45);
|
|
141
|
+
|
|
142
|
+
background-color: rgb(var(--ui-#{$tone}-rgb) / 0.2);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
&:active:not(:disabled):not(.disabled) {
|
|
146
|
+
background-color: rgb(var(--ui-#{$tone}-rgb) / 0.28);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/// Emits a solid variant.
|
|
151
|
+
///
|
|
152
|
+
/// @param {String} $tone - Token suffix, without the `--ui-` prefix.
|
|
153
|
+
@mixin solid-variant($tone) {
|
|
154
|
+
--btn-tone: var(--ui-#{$tone});
|
|
155
|
+
--btn-tone-rgb: var(--ui-#{$tone}-rgb);
|
|
156
|
+
--bs-btn-color: var(--ui-on-#{$tone});
|
|
157
|
+
--bs-btn-hover-color: var(--ui-on-#{$tone});
|
|
158
|
+
--bs-btn-active-color: var(--ui-on-#{$tone});
|
|
159
|
+
--bs-btn-disabled-color: var(--ui-on-#{$tone});
|
|
160
|
+
|
|
161
|
+
--bs-btn-bg: var(--ui-#{$tone});
|
|
162
|
+
--bs-btn-border-color: var(--ui-#{$tone});
|
|
163
|
+
--bs-btn-hover-bg: color-mix(in srgb, var(--ui-#{$tone}) var(--btn-hover-amount), var(--btn-mix));
|
|
164
|
+
--bs-btn-hover-border-color: var(--bs-btn-hover-bg);
|
|
165
|
+
--bs-btn-active-bg: color-mix(
|
|
166
|
+
in srgb,
|
|
167
|
+
var(--ui-#{$tone}) var(--btn-press-amount),
|
|
168
|
+
var(--btn-mix)
|
|
169
|
+
);
|
|
170
|
+
--bs-btn-active-border-color: var(--bs-btn-active-bg);
|
|
171
|
+
--bs-btn-disabled-bg: var(--ui-#{$tone});
|
|
172
|
+
--bs-btn-disabled-border-color: var(--ui-#{$tone});
|
|
173
|
+
--bs-btn-focus-shadow-rgb: var(--ui-#{$tone}-rgb);
|
|
174
|
+
|
|
175
|
+
--btn-group-border: color-mix(in srgb, var(--ui-on-#{$tone}) 40%, var(--ui-#{$tone}));
|
|
176
|
+
|
|
177
|
+
--btn-fill: var(--ui-#{$tone});
|
|
178
|
+
|
|
179
|
+
color: var(--ui-on-#{$tone});
|
|
180
|
+
background-color: var(--btn-fill);
|
|
181
|
+
border-color: transparent !important;
|
|
182
|
+
|
|
183
|
+
&:hover:not(:disabled):not(.disabled) {
|
|
184
|
+
--btn-glow:
|
|
185
|
+
0 0 20px -4px rgb(var(--ui-#{$tone}-rgb) / 0.55),
|
|
186
|
+
0 0 40px -8px rgb(var(--ui-#{$tone}-rgb) / 0.35);
|
|
187
|
+
|
|
188
|
+
--btn-fill: color-mix(in srgb, var(--ui-#{$tone}) var(--btn-hover-amount), var(--btn-mix));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
&:active:not(:disabled):not(.disabled),
|
|
192
|
+
&.active {
|
|
193
|
+
--btn-fill: color-mix(in srgb, var(--ui-#{$tone}) var(--btn-press-amount), var(--btn-mix));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/// Emits an outline variant.
|
|
198
|
+
///
|
|
199
|
+
/// @param {String} $tone - Token suffix, without the `--ui-` prefix.
|
|
200
|
+
/// @param {Boolean} $seam - Draws a hairline ring so the button stays visible
|
|
201
|
+
/// when the tone matches the page background.
|
|
202
|
+
@mixin outline-variant($tone, $seam: false) {
|
|
203
|
+
--btn-tone: var(--ui-#{$tone});
|
|
204
|
+
--btn-tone-rgb: var(--ui-#{$tone}-rgb);
|
|
205
|
+
--bs-btn-color: var(--ui-#{$tone});
|
|
206
|
+
--bs-btn-hover-color: var(--ui-on-#{$tone});
|
|
207
|
+
--bs-btn-active-color: var(--ui-on-#{$tone});
|
|
208
|
+
--bs-btn-disabled-color: var(--ui-#{$tone});
|
|
209
|
+
|
|
210
|
+
--bs-btn-bg: transparent;
|
|
211
|
+
--bs-btn-border-color: var(--ui-#{$tone});
|
|
212
|
+
--bs-btn-hover-bg: var(--ui-#{$tone});
|
|
213
|
+
--bs-btn-hover-border-color: var(--ui-#{$tone});
|
|
214
|
+
--bs-btn-active-bg: color-mix(
|
|
215
|
+
in srgb,
|
|
216
|
+
var(--ui-#{$tone}) var(--btn-press-amount),
|
|
217
|
+
var(--btn-mix)
|
|
218
|
+
);
|
|
219
|
+
--bs-btn-active-border-color: var(--bs-btn-active-bg);
|
|
220
|
+
--bs-btn-disabled-bg: transparent;
|
|
221
|
+
--bs-btn-disabled-border-color: var(--ui-#{$tone});
|
|
222
|
+
--bs-btn-focus-shadow-rgb: var(--ui-#{$tone}-rgb);
|
|
223
|
+
|
|
224
|
+
--btn-group-border: color-mix(in srgb, var(--ui-#{$tone}) 40%, var(--btn-group-bg));
|
|
225
|
+
|
|
226
|
+
color: var(--ui-#{$tone});
|
|
227
|
+
background-color: transparent;
|
|
228
|
+
border-color: solid-tint($tone, 40%, var(--btn-group-bg, var(--ui-canvas)));
|
|
229
|
+
|
|
230
|
+
@if $seam {
|
|
231
|
+
border-color: solid-tint($tone, 70%, var(--btn-group-bg, var(--ui-canvas)));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
&:hover:not(:disabled):not(.disabled) {
|
|
235
|
+
--btn-glow:
|
|
236
|
+
0 0 0 1px rgb(var(--ui-#{$tone}-rgb) / 0.35), 0 0 20px -4px rgb(var(--ui-#{$tone}-rgb) / 0.55);
|
|
237
|
+
|
|
238
|
+
color: var(--ui-on-#{$tone});
|
|
239
|
+
background-color: var(--ui-#{$tone});
|
|
240
|
+
border-color: var(--ui-#{$tone});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
&:active:not(:disabled):not(.disabled),
|
|
244
|
+
&.active {
|
|
245
|
+
color: var(--ui-on-#{$tone});
|
|
246
|
+
background-color: color-mix(
|
|
247
|
+
in srgb,
|
|
248
|
+
var(--ui-#{$tone}) var(--btn-press-amount),
|
|
249
|
+
var(--btn-mix)
|
|
250
|
+
);
|
|
251
|
+
border-color: transparent;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// =============================================================================
|
|
256
|
+
// 4. Base
|
|
257
|
+
// =============================================================================
|
|
258
|
+
|
|
259
|
+
.btn {
|
|
260
|
+
--bs-btn-border-radius: var(--bs-border-radius-sm);
|
|
261
|
+
--bs-btn-disabled-opacity: 0.4;
|
|
262
|
+
--btn-tone: var(--ui-accent);
|
|
263
|
+
--btn-tone-rgb: var(--ui-accent-rgb);
|
|
264
|
+
--btn-glow: none;
|
|
265
|
+
|
|
266
|
+
--btn-mix: var(--ui-btn-mix);
|
|
267
|
+
--btn-hover-amount: 76%;
|
|
268
|
+
--btn-press-amount: 68%;
|
|
269
|
+
|
|
270
|
+
border: 1px solid var(--bs-btn-border-color, transparent);
|
|
271
|
+
transition:
|
|
272
|
+
background-color var(--ui-duration) var(--ui-ease),
|
|
273
|
+
border-color var(--ui-duration) var(--ui-ease),
|
|
274
|
+
color var(--ui-duration) var(--ui-ease),
|
|
275
|
+
box-shadow var(--ui-duration) var(--ui-ease);
|
|
276
|
+
|
|
277
|
+
.badge {
|
|
278
|
+
transition:
|
|
279
|
+
color var(--ui-duration) var(--ui-ease),
|
|
280
|
+
background-color var(--ui-duration) var(--ui-ease),
|
|
281
|
+
border-color var(--ui-duration) var(--ui-ease);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
&:active:not(:disabled):not(.disabled) {
|
|
285
|
+
transition-duration: 60ms;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
&:focus-visible {
|
|
289
|
+
outline: 2px solid var(--btn-tone);
|
|
290
|
+
outline-offset: 2px;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
&:disabled,
|
|
294
|
+
&.disabled {
|
|
295
|
+
pointer-events: none;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// =============================================================================
|
|
300
|
+
// 5. Generator
|
|
301
|
+
// =============================================================================
|
|
302
|
+
|
|
303
|
+
/// Emits the `--btn-*` overrides for a single family.
|
|
304
|
+
///
|
|
305
|
+
/// @param {Map} $config - Merged `$button-families` entry.
|
|
306
|
+
@mixin button-overrides($config) {
|
|
307
|
+
$mix: map.get($config, 'mix');
|
|
308
|
+
$hover: map.get($config, 'hover');
|
|
309
|
+
$press: map.get($config, 'press');
|
|
310
|
+
|
|
311
|
+
@if $mix != null {
|
|
312
|
+
--btn-mix: #{$mix};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@if $hover != null {
|
|
316
|
+
--btn-hover-amount: #{$hover};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
@if $press != null {
|
|
320
|
+
--btn-press-amount: #{$press};
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/// Emits the variants for a single family.
|
|
325
|
+
///
|
|
326
|
+
/// @param {String} $name - Class suffix, e.g. `primary`.
|
|
327
|
+
/// @param {Map} $config - Entry from `$button-families`.
|
|
328
|
+
@mixin button-family($name, $config) {
|
|
329
|
+
$config: map.merge($button-defaults, $config);
|
|
330
|
+
$tone: map.get($config, 'tone');
|
|
331
|
+
$seam: map.get($config, 'seam');
|
|
332
|
+
$variants: map.get($config, 'variants');
|
|
333
|
+
|
|
334
|
+
@if list.index($variants, 'solid') {
|
|
335
|
+
.btn-#{$name} {
|
|
336
|
+
@include solid-variant($tone);
|
|
337
|
+
@include button-overrides($config);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
@if list.index($variants, 'outline') {
|
|
342
|
+
.btn-outline-#{$name} {
|
|
343
|
+
@include outline-variant($tone, $seam: $seam);
|
|
344
|
+
@include button-overrides($config);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
@if list.index($variants, 'subtle') {
|
|
349
|
+
.btn-subtle-#{$name} {
|
|
350
|
+
@include subtle-variant($tone);
|
|
351
|
+
@include button-overrides($config);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
@each $name, $config in $button-families {
|
|
357
|
+
@include button-family($name, $config);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// =============================================================================
|
|
361
|
+
// 6. Utilities
|
|
362
|
+
// =============================================================================
|
|
363
|
+
|
|
364
|
+
.btn-lighting {
|
|
365
|
+
&:hover:not(:disabled):not(.disabled) {
|
|
366
|
+
box-shadow: var(--btn-glow);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.btn-group,
|
|
371
|
+
.btn-group-vertical {
|
|
372
|
+
--btn-group-bg: var(--ui-canvas);
|
|
373
|
+
|
|
374
|
+
> .btn {
|
|
375
|
+
position: relative;
|
|
376
|
+
border-width: 1px;
|
|
377
|
+
border-style: solid;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
> .btn:hover:not(:disabled):not(.disabled),
|
|
381
|
+
> .btn:focus-visible:not(:disabled):not(.disabled) {
|
|
382
|
+
z-index: 1;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
> .btn.active,
|
|
386
|
+
> .btn:active:not(:disabled):not(.disabled),
|
|
387
|
+
> .btn-check:checked + .btn {
|
|
388
|
+
z-index: 2;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use 'sass:string';
|
|
3
|
+
|
|
4
|
+
// ---------------------------------------------------------------- 1. palette --
|
|
5
|
+
/// Raw colours. Keys describe the hue, never the role.
|
|
6
|
+
$palette: (
|
|
7
|
+
// Neutral ramp, dark end.
|
|
8
|
+
'slate-950': #0b0e14,
|
|
9
|
+
'slate-900': #10141d,
|
|
10
|
+
'slate-850': #151a25,
|
|
11
|
+
'slate-800': #1c2230,
|
|
12
|
+
'slate-700': #2a3243,
|
|
13
|
+
'slate-600': #3b4557,
|
|
14
|
+
'slate-400': #6b7688,
|
|
15
|
+
'slate-200': #b6bfce,
|
|
16
|
+
'slate-050': #e8ecf3,
|
|
17
|
+
|
|
18
|
+
// Neutral ramp, light end.
|
|
19
|
+
'paper-000': #ffffff,
|
|
20
|
+
'paper-050': #f7f9fd,
|
|
21
|
+
'paper-100': #f4f6fb,
|
|
22
|
+
'paper-200': #dde3ee,
|
|
23
|
+
'paper-300': #c3ccdd,
|
|
24
|
+
'ink-000': #000000,
|
|
25
|
+
'ink-900': #0d1220,
|
|
26
|
+
'ink-700': #3a4459,
|
|
27
|
+
|
|
28
|
+
// Accents.
|
|
29
|
+
'indigo-700': #3f5fe0,
|
|
30
|
+
'indigo-600': #5c7bf5,
|
|
31
|
+
'indigo-500': #6c8cff,
|
|
32
|
+
'indigo-400': #8aa2ff,
|
|
33
|
+
'green-500': #3ddc97,
|
|
34
|
+
'green-700': #0f8f5f,
|
|
35
|
+
'red-500': #ff6b81,
|
|
36
|
+
'red-700': #cf2445,
|
|
37
|
+
'amber-500': #ffc46b,
|
|
38
|
+
'amber-700': #a56200,
|
|
39
|
+
'cyan-500': #5fd3f3,
|
|
40
|
+
'cyan-700': #0a7fa5,
|
|
41
|
+
|
|
42
|
+
// Foreground inks. Sit on top of a filled tone; never used as a background.
|
|
43
|
+
'on-accent': #080b11,
|
|
44
|
+
'on-success': #04140d,
|
|
45
|
+
'on-error': #1a0308,
|
|
46
|
+
'on-warn': #1a1200,
|
|
47
|
+
'on-info': #04141a,
|
|
48
|
+
|
|
49
|
+
// Cool dark used by the light theme so shadows do not read as grey.
|
|
50
|
+
'shadow-slate': #1e293b
|
|
51
|
+
) !default;
|
|
52
|
+
|
|
53
|
+
/// Returns a raw colour from the palette.
|
|
54
|
+
///
|
|
55
|
+
/// @param {String} $key - Palette key, e.g. `slate-900`.
|
|
56
|
+
/// @returns {Color} The raw colour value.
|
|
57
|
+
@function palette($key) {
|
|
58
|
+
@if not map.has-key($palette, $key) {
|
|
59
|
+
@error 'Unknown palette key: #{$key}';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@return map.get($palette, $key);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------- 2. themes --
|
|
66
|
+
$theme-dark: (
|
|
67
|
+
'canvas': palette('slate-950'),
|
|
68
|
+
'surface': palette('slate-900'),
|
|
69
|
+
'surface-raised': palette('slate-850'),
|
|
70
|
+
'input': palette('slate-800'),
|
|
71
|
+
'border': palette('slate-700'),
|
|
72
|
+
'border-strong': palette('slate-600'),
|
|
73
|
+
'text': palette('slate-200'),
|
|
74
|
+
'text-muted': palette('slate-400'),
|
|
75
|
+
'heading': palette('slate-050'),
|
|
76
|
+
'accent': palette('indigo-500'),
|
|
77
|
+
'accent-soft': palette('indigo-400'),
|
|
78
|
+
'success': palette('green-500'),
|
|
79
|
+
'error': palette('red-500'),
|
|
80
|
+
'warn': palette('amber-500'),
|
|
81
|
+
'info': palette('cyan-500'),
|
|
82
|
+
) !default;
|
|
83
|
+
|
|
84
|
+
$theme-light: (
|
|
85
|
+
'canvas': palette('paper-100'),
|
|
86
|
+
'surface': palette('paper-000'),
|
|
87
|
+
'surface-raised': palette('paper-050'),
|
|
88
|
+
'input': palette('paper-000'),
|
|
89
|
+
'border': palette('paper-200'),
|
|
90
|
+
'border-strong': palette('paper-300'),
|
|
91
|
+
'text': palette('ink-700'),
|
|
92
|
+
'text-muted': palette('slate-400'),
|
|
93
|
+
'heading': palette('ink-900'),
|
|
94
|
+
'accent': palette('indigo-700'),
|
|
95
|
+
'accent-soft': palette('indigo-600'),
|
|
96
|
+
'success': palette('green-700'),
|
|
97
|
+
'error': palette('red-700'),
|
|
98
|
+
'warn': palette('amber-700'),
|
|
99
|
+
'info': palette('cyan-700'),
|
|
100
|
+
) !default;
|
|
101
|
+
|
|
102
|
+
// ------------------------------------------------------------ 3. foreground --
|
|
103
|
+
$on-dark: (
|
|
104
|
+
'accent': palette('on-accent'),
|
|
105
|
+
'success': palette('on-success'),
|
|
106
|
+
'error': palette('on-error'),
|
|
107
|
+
'warn': palette('on-warn'),
|
|
108
|
+
'info': palette('on-info'),
|
|
109
|
+
'text-muted': palette('paper-000'),
|
|
110
|
+
) !default;
|
|
111
|
+
|
|
112
|
+
$on-light: (
|
|
113
|
+
'accent': palette('paper-000'),
|
|
114
|
+
'success': palette('paper-000'),
|
|
115
|
+
'error': palette('paper-000'),
|
|
116
|
+
'warn': palette('paper-000'),
|
|
117
|
+
'info': palette('paper-000'),
|
|
118
|
+
'text-muted': palette('paper-000'),
|
|
119
|
+
) !default;
|
|
120
|
+
|
|
121
|
+
$subtle-tokens: (
|
|
122
|
+
'primary': 'accent',
|
|
123
|
+
'secondary': 'text-muted',
|
|
124
|
+
'success': 'success',
|
|
125
|
+
'danger': 'error',
|
|
126
|
+
'warning': 'warn',
|
|
127
|
+
'info': 'info',
|
|
128
|
+
) !default;
|
|
129
|
+
|
|
130
|
+
// ------------------------------------------------------------- 4. constants --
|
|
131
|
+
$constants: (
|
|
132
|
+
// Backdrop behind modals.
|
|
133
|
+
'scrim': #05070b,
|
|
134
|
+
// Chevron inside `.form-select` and `.accordion-button`.
|
|
135
|
+
'control-icon': palette('slate-400'),
|
|
136
|
+
'control-icon-active': palette('indigo-500'),
|
|
137
|
+
// Active carousel indicator.
|
|
138
|
+
'carousel-indicator': palette('indigo-500')
|
|
139
|
+
) !default;
|
|
140
|
+
|
|
141
|
+
$shadow: (
|
|
142
|
+
'dark': palette('ink-000'),
|
|
143
|
+
'light': palette('shadow-slate'),
|
|
144
|
+
) !default;
|
|
145
|
+
|
|
146
|
+
$scrims: (
|
|
147
|
+
'dark': (
|
|
148
|
+
'base': palette('ink-000'),
|
|
149
|
+
'caption': palette('paper-000'),
|
|
150
|
+
'indicator': palette('paper-000'),
|
|
151
|
+
'ink': palette('paper-000'),
|
|
152
|
+
),
|
|
153
|
+
'light': (
|
|
154
|
+
'base': palette('paper-000'),
|
|
155
|
+
'caption': theme-color('text', 'light'),
|
|
156
|
+
'indicator': palette('slate-950'),
|
|
157
|
+
'ink': palette('ink-000'),
|
|
158
|
+
),
|
|
159
|
+
) !default;
|
|
160
|
+
|
|
161
|
+
/// @param {String} $theme - `dark` or `light`.
|
|
162
|
+
/// @param {String} $role - `base`, `caption`, `indicator` or `ink`.
|
|
163
|
+
/// @returns {Color} The scrim colour.
|
|
164
|
+
@function scrim($theme, $role) {
|
|
165
|
+
$map: map.get($scrims, $theme);
|
|
166
|
+
|
|
167
|
+
@if not map.has-key($map, $role) {
|
|
168
|
+
@error 'Unknown scrim role: #{$role}';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@return map.get($map, $role);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// --------------------------------------------------------------- accessors --
|
|
175
|
+
/// @param {String} $name - Key in `$constants`.
|
|
176
|
+
/// @returns {Color} The constant value.
|
|
177
|
+
@function ui-color($name) {
|
|
178
|
+
@if not map.has-key($constants, $name) {
|
|
179
|
+
@error 'Unknown colour constant: #{$name}';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@return map.get($constants, $name);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
$_themes: (
|
|
186
|
+
'dark': $theme-dark,
|
|
187
|
+
'light': $theme-light,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
/// @param {String} $role - Semantic role, e.g. `canvas`.
|
|
191
|
+
/// @param {String} $theme - `dark` or `light`.
|
|
192
|
+
/// @returns {Color} The role colour for the given theme.
|
|
193
|
+
@function theme-color($role, $theme: 'dark') {
|
|
194
|
+
@if not map.has-key($_themes, $theme) {
|
|
195
|
+
@error 'Unknown theme: #{$theme}';
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
$map: map.get($_themes, $theme);
|
|
199
|
+
|
|
200
|
+
@if not map.has-key($map, $role) {
|
|
201
|
+
@error 'Unknown colour role: #{$role}';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@return map.get($map, $role);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/// URL-encoded hex, for inline SVG data URIs.
|
|
208
|
+
///
|
|
209
|
+
/// @param {String} $name - Key in `$constants`.
|
|
210
|
+
/// @returns {String} `%23rrggbb`.
|
|
211
|
+
@function svg-color($name) {
|
|
212
|
+
@return '%23' + string.slice('#{ui-color($name)}', 2);
|
|
213
|
+
}
|