nk_jtb 0.27.3 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,9 +4,9 @@ Page loaders and spinners to communicate in-progress and waiting states.
4
4
 
5
5
  ## Spinners
6
6
 
7
- ### SVG Arc
7
+ ### SVG Border
8
8
 
9
- Apply `animate-spin` to an SVG with a dashed stroke to create a spinner.
9
+ A static arc on a faint circular track. Apply `animate-spin` to the SVG.
10
10
 
11
11
  Use `wh-*` utilities to control size.
12
12
 
@@ -28,21 +28,82 @@ Use `wh-*` utilities to control size.
28
28
  Use `txt-*` utilities to control colour.
29
29
 
30
30
  ```html +demo-folded class="bx example-utils" preview-class="flex-centered gap"
31
- <svg class="animate-spin wh-2 txt-blue" viewBox="0 0 36 36">
31
+ <svg class="animate-spin wh-3 txt-blue" viewBox="0 0 36 36">
32
32
  <circle cx="18" cy="18" r="14" fill="none" stroke="currentColor" stroke-width="3" stroke-opacity="0.25" />
33
33
  <circle cx="18" cy="18" r="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="butt" stroke-dasharray="22 66" />
34
34
  </svg>
35
- <svg class="animate-spin wh-2 txt-blue-900" viewBox="0 0 36 36">
35
+ <svg class="animate-spin wh-3 txt-blue-900" viewBox="0 0 36 36">
36
36
  <circle cx="18" cy="18" r="14" fill="none" stroke="currentColor" stroke-width="3" stroke-opacity="0.25" />
37
37
  <circle cx="18" cy="18" r="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="butt" stroke-dasharray="22 66" />
38
38
  </svg>
39
- <svg class="animate-spin wh-2 txt-orange-400" viewBox="0 0 36 36">
39
+ <svg class="animate-spin wh-3 txt-orange-400" viewBox="0 0 36 36">
40
40
  <circle cx="18" cy="18" r="14" fill="none" stroke="currentColor" stroke-width="3" stroke-opacity="0.25" />
41
41
  <circle cx="18" cy="18" r="14" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="butt" stroke-dasharray="22 66" />
42
42
  </svg>
43
43
  ```
44
44
 
45
- ## Loader Container (review)
45
+ ### SVG Arc
46
+
47
+ Apply `animate-dash` to an SVG element. A single class handles both rotation and
48
+ stroke morphing. Use `wh-*` to control size and `txt-*` to control colour.
49
+
50
+ ```html +demo-folded class="bx example-utils" preview-class="flex-centered vac gap-2"
51
+ <svg class="animate-dash wh-2 txt-primary" viewBox="0 0 44 44">
52
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
53
+ </svg>
54
+ <svg class="animate-dash wh-3 txt-primary" viewBox="0 0 44 44">
55
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
56
+ </svg>
57
+ <svg class="animate-dash wh-4 txt-primary" viewBox="0 0 44 44">
58
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
59
+ </svg>
60
+ ```
61
+
62
+ Use `txt-*` utilities to control colour.
63
+
64
+ ```html +demo-folded class="bx example-utils" preview-class="flex-centered gap"
65
+ <svg class="animate-dash wh-3 txt-blue" viewBox="0 0 44 44">
66
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
67
+ </svg>
68
+ <svg class="animate-dash wh-3 txt-blue-900" viewBox="0 0 44 44">
69
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
70
+ </svg>
71
+ <svg class="animate-dash wh-3 txt-orange-400" viewBox="0 0 44 44">
72
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
73
+ </svg>
74
+ ```
75
+
76
+ ### Dots (review)
46
77
 
47
- `.loader-container` centers a spinner and loading text as a column. For a
48
- composed example see [UI Examples](/docs/jtb/examples/showcase-ui).
78
+ Eight dots arranged in a circle, fading in sequence. Use `wh-*` to control size
79
+ and `txt-*` to control colour.
80
+
81
+ ```html +demo-folded class="bx example-jtb" preview-class="flex-centered vac gap-2"
82
+ <div class="spinner-dots wh-2 txt-primary">
83
+ <div></div><div></div><div></div><div></div>
84
+ <div></div><div></div><div></div><div></div>
85
+ </div>
86
+ <div class="spinner-dots wh-3 txt-primary">
87
+ <div></div><div></div><div></div><div></div>
88
+ <div></div><div></div><div></div><div></div>
89
+ </div>
90
+ <div class="spinner-dots wh-4 txt-primary">
91
+ <div></div><div></div><div></div><div></div>
92
+ <div></div><div></div><div></div><div></div>
93
+ </div>
94
+ ```
95
+
96
+ ## Page Loader
97
+
98
+ Compose a page loader with utilities. Use `flex flex-col flex-centered` to
99
+ centre the spinner and text as a column. Add `animate-dots` for an animated
100
+ ellipsis alongside the loading label.
101
+
102
+ ```html +demo-folded class="bx example-utils" preview-class="flex-centered"
103
+ <div class="flex flex-col flex-centered gap-1">
104
+ <svg class="animate-dash wh-4 txt-primary" viewBox="0 0 44 44">
105
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
106
+ </svg>
107
+ <span>Loading<span class="animate-dots"></span></span>
108
+ </div>
109
+ ```
@@ -52,7 +52,7 @@ a doc is confirmed accurate or a utility is completed.
52
52
 
53
53
  | Utility | Framework | Docs | Notes |
54
54
  | ----------- | --------- | ------ | --------------------- |
55
- | `animation` | review | Review | `animate-*` utilities |
55
+ | `animation` | | | `animate-*` utilities |
56
56
 
57
57
  ### Backgrounds (review)
58
58
 
@@ -295,7 +295,7 @@ Files parked in `docs/review/` — purpose or audience unclear.
295
295
  | `components/menu.md` | review | |
296
296
  | `components/navbar.md` | review | |
297
297
  | `components/table.md` | review | |
298
- | `components/loaders-and-spinners.md` | partial | Spinners section confirmed (SVG Arc utility approach). Loader Container still pending. |
298
+ | `components/loaders-and-spinners.md` | partial | SVG Border, SVG Arc, Page Loader confirmed. Dots section still under review. |
299
299
  | `components/example-navigations.md` | stub | Bare HTML, no explanation |
300
300
 
301
301
  ### Utilities
@@ -304,7 +304,7 @@ Files parked in `docs/review/` — purpose or audience unclear.
304
304
  | ------------------------------------- | ------ | --------------------------------------------------- |
305
305
  | `utilities/border.md` | review | Border, outline, and divider utilities |
306
306
  | `utilities/typography.md` | review | New — needs review pass |
307
- | `utilities/animation.md` | review | Rewritten — loader/spinner content moved to components/loaders-and-spinners.md |
307
+ | `utilities/animation.md` | | |
308
308
  | `utilities/display-and-visibility.md` | review | |
309
309
  | `utilities/effects.md` | review | |
310
310
  | `utilities/position.md` | review | |
@@ -2,26 +2,28 @@
2
2
 
3
3
  Utility classes for applying CSS animations.
4
4
 
5
- | Class | Animation |
6
- | --------------------- | ------------------- |
7
- | `animate-spin` | Continuous rotation |
8
- | `animate-bounce` | Vertical bounce |
9
- | `animate-pulse` | Opacity fade |
10
- | `animate-pulse-ring` | Expanding ring |
11
- | `animate-ping` | Scale and fade out |
12
- | `animate-checkmark` | SVG stroke draw-in |
13
- | `animate-circle` | SVG stroke draw-in |
14
- | `animate-none` | Removes animation |
15
-
16
- ## Spin (review)
17
-
18
- Rotates an element continuously. Commonly used for loading indicators.
19
-
20
- ```html +demo-folded class="bx"
21
- <div class="animate-spin wh-3 bdr-4 bdr-gray-200 bdr-t-blue-500 rounded-full"></div>
5
+ | Class | Animation |
6
+ | -------------------- | ----------------------- |
7
+ | `animate-spin` | Continuous rotation |
8
+ | `animate-bounce` | Vertical bounce |
9
+ | `animate-pulse` | Opacity fade |
10
+ | `animate-pulse-ring` | Expanding ring |
11
+ | `animate-ping` | Scale and fade out |
12
+ | `animate-dash` | SVG stroke arc morphing |
13
+ | `animate-dots` | Animated ellipsis |
14
+ | `animate-checkmark` | SVG stroke draw-in |
15
+ | `animate-circle` | SVG stroke draw-in |
16
+ | `animate-none` | Removes animation |
17
+
18
+ ## Spin
19
+
20
+ Rotates an element continuously.
21
+
22
+ ```html +demo-folded class="bx" preview-class="flex-centered"
23
+ <div class="animate-spin wh-3 bdr-4 bdr-blue-500 rounded-full"></div>
22
24
  ```
23
25
 
24
- ## Bounce (review)
26
+ ## Bounce
25
27
 
26
28
  Applies a vertical bounce. Stagger `animation-delay` across sibling elements for
27
29
  a sequential effect.
@@ -32,16 +34,15 @@ a sequential effect.
32
34
  <div class="wh-1 bg-blue-600 rounded-full animate-bounce" style="animation-delay: 0.2s;"></div>
33
35
  ```
34
36
 
35
- ## Pulse (review)
37
+ ## Pulse
36
38
 
37
- Fades an element's opacity in and out. Use for skeleton loaders or ambient
38
- status indicators.
39
+ Fades an element's opacity in and out.
39
40
 
40
41
  ```html +demo-folded class="bx"
41
42
  <div class="wh-4 bg-teal-500 rounded-full animate-pulse"></div>
42
43
  ```
43
44
 
44
- ## Pulse Ring (review)
45
+ ## Pulse Ring
45
46
 
46
47
  Scales and fades an element outward to create an expanding ring effect. Use
47
48
  `relative` positioning with overlapping siblings for layered rings.
@@ -54,7 +55,7 @@ Scales and fades an element outward to create an expanding ring effect. Use
54
55
  </div>
55
56
  ```
56
57
 
57
- ## Ping (review)
58
+ ## Ping
58
59
 
59
60
  Scales an element to twice its size while fading it out — a one-shot burst
60
61
  effect. Commonly used as a notification indicator layered over a badge or dot.
@@ -66,14 +67,35 @@ effect. Commonly used as a notification indicator layered over a badge or dot.
66
67
  </div>
67
68
  ```
68
69
 
69
- ## SVG Animations (review)
70
+ ## Dots
71
+
72
+ Animates a `::after` pseudo-element to cycle through an ellipsis sequence.
73
+
74
+ ```html +demo-folded class="bx" preview-class="flex-centered"
75
+ <span>Loading<span class="animate-dots"></span></span>
76
+ ```
77
+
78
+ ## SVG Animations
79
+
80
+ ### Dash
81
+
82
+ Rotates an SVG while morphing its child circle's `stroke-dasharray`. A single
83
+ class handles both the rotation and the stroke animation.
84
+
85
+ ```html +demo-folded class="bx" preview-class="flex-centered"
86
+ <svg class="animate-dash wh-4 txt-blue-500" viewBox="0 0 44 44">
87
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
88
+ </svg>
89
+ ```
90
+
91
+ ### Draw-in
70
92
 
71
93
  `animate-circle` draws a circular stroke in from nothing to full.
72
- `animate-checkmark` does the same for a path. Both classes set `stroke-dasharray`
94
+ `animate-checkmark` does the same for a path. Both set `stroke-dasharray`
73
95
  and animate `stroke-dashoffset`. The SVG path or circle length must be no greater
74
96
  than the class's `stroke-dasharray` value (166 for circle, 100 for checkmark).
75
97
 
76
- ```html +demo-folded class="bx"
98
+ ```html +demo-folded class="bx" preview-class="flex-centered"
77
99
  <svg viewBox="0 0 52 52" class="wh-4 txt-green-600" fill="none">
78
100
  <circle cx="26" cy="26" r="25" stroke="currentColor" stroke-width="2" class="animate-circle" />
79
101
  <path d="M14 27l8 8 16-16" stroke="currentColor" stroke-width="2" class="animate-checkmark" />
package/index.html CHANGED
@@ -10,6 +10,18 @@
10
10
 
11
11
  <body>
12
12
 
13
+
14
+
15
+ <div class="mb-2.5">
16
+ <h2>Page loader</h2>
17
+ <div class="bx flex-col flex-centered gap-1">
18
+ <svg class="animate-dash wh-3 txt-blue-500" viewBox="0 0 44 44">
19
+ <circle cx="22" cy="22" r="16" stroke="currentColor" />
20
+ </svg>
21
+ <p class="txt-sm txt-muted">Loading your workspace…</p>
22
+ </div>
23
+ </div>
24
+
13
25
  <style>
14
26
  /* ============================================================
15
27
  Local helpers — JTB gaps documented in jtb-conversion-notes.md
@@ -171,52 +183,6 @@
171
183
  </style>
172
184
 
173
185
  <div class="py-1.5 container-md">
174
- <style>
175
-
176
- /*SVG arc — @keyframes dash not in JTB animation utilities*/
177
- @keyframes dash {
178
- 0% {
179
- stroke-dasharray: 1, 150;
180
- stroke-dashoffset: 0;
181
- }
182
-
183
- 50% {
184
- stroke-dasharray: 90, 150;
185
- stroke-dashoffset: -35;
186
- }
187
-
188
- 100% {
189
- stroke-dasharray: 90, 150;
190
- stroke-dashoffset: -124;
191
- }
192
- }
193
-
194
- .arc circle {
195
- fill: none;
196
- stroke-width: 3;
197
- stroke-linecap: round;
198
- animation: dash 1.4s ease-in-out infinite;
199
- }
200
- </style>
201
-
202
- <div class="mb-2.5">
203
- <h2>SVG arc spinner</h2>
204
- <div class="bx flex-vac flex-wrap gap-1.5">
205
- <div class="flex-col flex-vac gap-05">
206
- <svg class="animate-spin arc wh-2.5 txt-blue-500" viewBox="0 0 36 36">
207
- <circle cx="18" cy="18" r="14" stroke="currentColor" />
208
- </svg>
209
- <span class="txt-xs txt-muted">smooth arc</span>
210
- </div>
211
- <div class="flex-col flex-vac gap-05">
212
- <svg class="animate-spin arc wh-3 txt-emerald-500" viewBox="0 0 48 48">
213
- <circle cx="24" cy="24" r="18" stroke="currentColor" />
214
- </svg>
215
- <span class="txt-xs txt-muted">teal / lg</span>
216
- </div>
217
- </div>
218
- </div>
219
-
220
186
  <div class="mb-2.5">
221
187
  <h2>Dot indicators</h2>
222
188
  <div class="bx flex-vac flex-wrap gap-1.5">
@@ -338,15 +304,7 @@
338
304
  </div>
339
305
  </div>
340
306
 
341
- <div class="mb-2.5">
342
- <h2>Page loader</h2>
343
- <div class="bx flex-col flex-centered gap-1">
344
- <svg class="animate-spin arc wh-3 txt-blue-500" viewBox="0 0 44 44">
345
- <circle cx="22" cy="22" r="16" stroke="currentColor" />
346
- </svg>
347
- <p class="txt-sm txt-muted">Loading your workspace…</p>
348
- </div>
349
- </div>
307
+
350
308
 
351
309
  </div>
352
310
 
@@ -1,28 +1,28 @@
1
- # JTB Conversion Notes
2
-
3
- Actionable gaps found during conversion of `loaders_and_spinners.html`.
4
-
5
- ## Missing Keyframes / Animation Utilities
6
-
7
- | Gap | Detail |
8
- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
9
- | `@keyframes dash` | SVG arc morphing — stroke-dasharray animates between values. No JTB equivalent. Candidate for `_animation.scss`. |
10
- | `@keyframes grow` | Vertical scale pulse for bar equalizer. No JTB equivalent. |
11
- | `@keyframes skeleton` | Gradient sweep shimmer. Very commonly needed. Strong candidate for `_animation.scss`. |
12
- | `@keyframes progress-indeterminate` | Horizontal bar sweep for indeterminate progress. No JTB equivalent. |
13
- | `@keyframes ripple` | Scale from 0 → 2.5 with fade. `animate-ping` starts from scale 1 — not a match. |
14
-
15
- ## Missing Utilities
16
-
17
- | Gap | Detail |
18
- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
19
- | Positional border-color | `bdr-t-{color}` not generated — `border-color` config has no `positions` key. Needed for spinner accent colour and the spin demo example. |
20
- | `flex-shrink: 0` | No `fs-0` or equivalent confirmed. Used on skeleton avatar. |
21
- | Percentage widths | `55%`, `65%`, `80%` width values not in JTB sizing scale. Needed for skeleton text blocks. |
22
-
23
- ## Component Gaps
24
-
25
- | Gap | Detail |
26
- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
27
- | Spinner colour theming | `.spinner` hardcodes `#f3f3f3` and `#3498db` no CSS custom properties for colour. Accent and button-context spinners require local overrides. |
28
- | Icon-only button | `.btn` has no square/icon variant. A `btn-icon` or `btn xs` pattern would cover `width = height, padding: 0`. |
1
+ # JTB Conversion Notes
2
+
3
+ Actionable gaps found during conversion of `loaders_and_spinners.html`.
4
+
5
+ ## Missing Keyframes / Animation Utilities
6
+
7
+ | Gap | Detail |
8
+ | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
9
+ | `@keyframes dash` | Added as `animate-dash` in `_animation.scss`. |
10
+ | `@keyframes grow` | Vertical scale pulse for bar equalizer. No JTB equivalent. |
11
+ | `@keyframes skeleton` | Gradient sweep shimmer. Very commonly needed. Strong candidate for `_animation.scss`. |
12
+ | `@keyframes progress-indeterminate` | Horizontal bar sweep for indeterminate progress. No JTB equivalent. |
13
+ | `@keyframes ripple` | Scale from 0 → 2.5 with fade. `animate-ping` starts from scale 1 — not a match. |
14
+
15
+ ## Missing Utilities
16
+
17
+ | Gap | Detail |
18
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | Positional border-color | `bdr-t-{color}` not generated — `border-color` config has no `positions` key. Needed for spinner accent colour and the spin demo example. |
20
+ | `flex-shrink: 0` | No `fs-0` or equivalent confirmed. Used on skeleton avatar. |
21
+ | Percentage widths | `55%`, `65%`, `80%` width values not in JTB sizing scale. Needed for skeleton text blocks. |
22
+
23
+ ## Component Gaps
24
+
25
+ | Gap | Detail |
26
+ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | Spinner colour theming | `.spinner` component removedspinner is now utility-based, colour via `txt-*`. |
28
+ | Icon-only button | `.btn` has no square/icon variant. A `btn-icon` or `btn xs` pattern would cover `width = height, padding: 0`. |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nk_jtb",
3
3
  "description": "Yet another utility based framework.",
4
- "version": "0.27.3",
4
+ "version": "0.28.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/naykel76/nk_jtb.git"
@@ -49,7 +49,7 @@
49
49
  "Utilities": {
50
50
  "links": [
51
51
  {
52
- "name": "Animation (wip)",
52
+ "name": "Animation",
53
53
  "route_name": "docs.jtb.utilities.animation"
54
54
  },
55
55
  {
package/skills-lock.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "source": "naykel76/skills-and-guidelines",
24
24
  "sourceType": "github",
25
25
  "skillPath": "nk-documentation-best-practices/SKILL.md",
26
- "computedHash": "ad8bdd5e8b52cd29d50caf9a1be1615fd107e37b1b00114e4447f3656b22f956"
26
+ "computedHash": "64d145c8e7e332c70805a8faddf1fc2afe276aa6f3300c6c924c8a9f0fba7d85"
27
27
  },
28
28
  "skill-creation": {
29
29
  "source": "naykel76/skills-and-guidelines",
@@ -2,6 +2,16 @@
2
2
  @use '../maps_and_variables/colors' as *;
3
3
  @use '../maps_and_variables/components' as *;
4
4
  @use '../maps_and_variables/typography' as *;
5
+ @use '../functions/color-functions' as *;
6
+ @use 'sass:map';
7
+
8
+ @mixin define-runtime-theme-vars($theme-name, $theme-color) {
9
+ --#{$theme-name}: #{$theme-color};
10
+ --#{$theme-name}-hover: color-mix(in srgb, var(--#{$theme-name}), white 5%);
11
+ --#{$theme-name}-active: color-mix(in srgb, var(--#{$theme-name}), black 5%);
12
+ --#{$theme-name}-border: #{border-contrast($theme-color)};
13
+ --on-#{$theme-name}: #{text-color($theme-color)};
14
+ }
5
15
 
6
16
  :root {
7
17
  // create css variables including brand colors
@@ -37,10 +47,10 @@
37
47
  --bg-toggle-on: var(--primary);
38
48
  --bg-toggle-ball: var(--white);
39
49
 
40
- // -- Brand Colors --
41
- --primary: #{$primary};
42
- --secondary: #{$secondary};
43
- --accent: #{$accent};
50
+ // -- Runtime Semantic Theme Colors --
51
+ @each $theme-name in $runtime-theme-colors {
52
+ @include define-runtime-theme-vars($theme-name, map.get($base-colors, $theme-name));
53
+ }
44
54
 
45
55
  // -- Text Colors --
46
56
  --text-color: #{$text-color};
@@ -109,3 +109,19 @@
109
109
  @include active($color);
110
110
  }
111
111
  }
112
+
113
+ @each $theme-name in $runtime-theme-colors {
114
+ .#{$button-prefix}.#{$theme-name} {
115
+ &:hover {
116
+ background-color: var(--#{$theme-name}-hover);
117
+ border-color: var(--#{$theme-name}-border);
118
+ color: var(--on-#{$theme-name});
119
+ }
120
+
121
+ &:active {
122
+ background-color: var(--#{$theme-name}-active);
123
+ border-color: var(--#{$theme-name}-border);
124
+ color: var(--on-#{$theme-name});
125
+ }
126
+ }
127
+ }
@@ -1,24 +1,24 @@
1
- .loader-container {
2
- align-items: center;
3
- display: flex;
4
- flex-direction: column;
5
- justify-content: center;
6
-
7
- .loading-text {
8
- color: #fff;
9
- font-size: 18px;
10
- font-weight: 500;
11
- letter-spacing: 0.5px;
12
- }
13
-
14
- .dots {
15
- display: inline-block;
16
- text-align: left;
17
- width: 20px;
18
-
19
- &::after {
20
- animation: dots 1.5s steps(4, end) infinite;
21
- content: '';
22
- }
23
- }
24
- }
1
+ .spinner-dots {
2
+ position: relative;
3
+
4
+ > div {
5
+ animation: ball-spin 1s ease-in-out infinite;
6
+ background-color: currentColor;
7
+ border-radius: 50%;
8
+ height: 25%;
9
+ margin-left: -12.5%;
10
+ margin-top: -12.5%;
11
+ position: absolute;
12
+ width: 25%;
13
+ }
14
+
15
+ // prettier-ignore
16
+ > div:nth-child(1) { top: 5%; left: 50%; animation-delay: -1.125s; }
17
+ > div:nth-child(2) { top: 18.18%; left: 81.82%; animation-delay: -1.25s; }
18
+ > div:nth-child(3) { top: 50%; left: 95%; animation-delay: -1.375s; }
19
+ > div:nth-child(4) { top: 81.82%; left: 81.82%; animation-delay: -1.5s; }
20
+ > div:nth-child(5) { top: 95%; left: 50%; animation-delay: -1.625s; }
21
+ > div:nth-child(6) { top: 81.82%; left: 18.18%; animation-delay: -1.75s; }
22
+ > div:nth-child(7) { top: 50%; left: 5%; animation-delay: -1.875s; }
23
+ > div:nth-child(8) { top: 18.18%; left: 18.18%; animation-delay: -2s; }
24
+ }
@@ -51,6 +51,10 @@ $theme-colors: (
51
51
  'warning': #ffdd57
52
52
  ) !default;
53
53
 
54
+ // Semantic theme names that should remain runtime-swappable via CSS custom
55
+ // properties. Hue and scale colors stay compile-time tokens.
56
+ $runtime-theme-colors: ('primary', 'secondary', 'accent') !default;
57
+
54
58
  // based on Tailwind 500 series colors
55
59
  $base-colors: (
56
60
  'primary': base.$primary,
@@ -73,11 +73,47 @@
73
73
  75% { content: '...'; }
74
74
  }
75
75
 
76
+ @keyframes ball-spin {
77
+ 0%,
78
+ 100% {
79
+ opacity: 1;
80
+ transform: scale(1);
81
+ }
82
+
83
+ 20% {
84
+ opacity: 1;
85
+ }
86
+
87
+ 80% {
88
+ opacity: 0;
89
+ transform: scale(0);
90
+ }
91
+ }
92
+
93
+ @keyframes dash {
94
+ 0% {
95
+ stroke-dasharray: 1, 150;
96
+ stroke-dashoffset: 0;
97
+ }
98
+
99
+ 50% {
100
+ stroke-dasharray: 90, 150;
101
+ stroke-dashoffset: -35;
102
+ }
103
+
104
+ 100% {
105
+ stroke-dasharray: 90, 150;
106
+ stroke-dashoffset: -124;
107
+ }
108
+ }
109
+
76
110
  // ============================================================================
77
111
  // -- Animations --
78
112
  // ============================================================================
79
113
  :root {
80
114
  --animate-bounce: bounce 1s infinite;
115
+ --animate-dash: dash 1.4s ease-in-out infinite;
116
+ --animate-dots: dots 1.5s steps(4, end) infinite;
81
117
  --animate-ping: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
82
118
  --animate-pulse-ring: pulse-ring 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
83
119
  --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
@@ -108,6 +144,28 @@
108
144
  animation: var(--animate-spin);
109
145
  }
110
146
 
147
+ .animate-dash {
148
+ animation: var(--animate-spin);
149
+
150
+ > circle {
151
+ animation: var(--animate-dash);
152
+ fill: none;
153
+ stroke-linecap: round;
154
+ stroke-width: 3;
155
+ }
156
+ }
157
+
158
+ .animate-dots {
159
+ display: inline-block;
160
+ text-align: left;
161
+ width: 20px;
162
+
163
+ &::after {
164
+ animation: var(--animate-dots);
165
+ content: '';
166
+ }
167
+ }
168
+
111
169
  .animate-checkmark {
112
170
  animation: checkmark 0.6s ease-in-out forwards;
113
171
  stroke-dasharray: 100;
@@ -22,4 +22,18 @@ $background-color-properties: (
22
22
  )
23
23
  );
24
24
 
25
+ $runtime-background-colors: ();
26
+
27
+ @each $theme-name in $runtime-theme-colors {
28
+ $runtime-background-colors: map.set($runtime-background-colors, $theme-name, var(--#{$theme-name}));
29
+ }
30
+
31
+ $runtime-background-color-properties: (
32
+ background-color: (
33
+ prefix: 'bg-',
34
+ values: $runtime-background-colors
35
+ )
36
+ );
37
+
25
38
  @include build-classes($background-color-properties, $responsive: false, $with-state: true);
39
+ @include build-classes($runtime-background-color-properties, $responsive: false, $with-state: true);
@@ -51,6 +51,23 @@ $divider-properties-map: (
51
51
  )
52
52
  ) !default;
53
53
 
54
+ $runtime-border-colors: ();
55
+
56
+ @each $theme-name in $runtime-theme-colors {
57
+ $runtime-border-colors: map.set($runtime-border-colors, $theme-name, var(--#{$theme-name}));
58
+ }
59
+
60
+ $runtime-border-properties-map: (
61
+ border-color: (
62
+ prefix: #{$border-prefix},
63
+ values: $runtime-border-colors
64
+ ),
65
+ outline-color: (
66
+ prefix: 'outline-',
67
+ values: $runtime-border-colors
68
+ )
69
+ );
70
+
54
71
  .divide-y-gradient > :not(:last-child) {
55
72
  border-block-end-width: 3px;
56
73
  border-image-slice: 1;
@@ -68,4 +85,5 @@ $divider-properties-map: (
68
85
  // Builds
69
86
  // ============================================================================
70
87
  @include build-classes($border-properties-map, $responsive: true);
88
+ @include build-classes($runtime-border-properties-map, $responsive: true);
71
89
  @include build-composite-classes($divider-properties-map, $responsive: true);
@@ -50,3 +50,22 @@ $themes-map: ();
50
50
  @each $color, $value in map.merge($base-colors, $theme-colors) {
51
51
  @include build-outline-theme('#{$color}-outline', $value);
52
52
  }
53
+
54
+ @each $theme-name in $runtime-theme-colors {
55
+ .#{$theme-name} {
56
+ background-color: var(--#{$theme-name});
57
+ border: 1px solid var(--#{$theme-name}-border);
58
+ color: var(--on-#{$theme-name});
59
+ }
60
+
61
+ .#{$theme-name}-outline {
62
+ background-color: transparent;
63
+ border: 1px solid var(--#{$theme-name});
64
+ color: var(--#{$theme-name});
65
+
66
+ &:hover:not(:disabled, .disabled) {
67
+ background-color: var(--#{$theme-name});
68
+ color: var(--on-#{$theme-name});
69
+ }
70
+ }
71
+ }
@@ -124,8 +124,23 @@ $text-classes-map: (
124
124
  )
125
125
  );
126
126
 
127
+ $runtime-text-colors: ();
128
+
129
+ @each $theme-name in $runtime-theme-colors {
130
+ $runtime-text-colors: map.set($runtime-text-colors, $theme-name, var(--#{$theme-name}));
131
+ }
132
+
133
+ $runtime-typography-properties-map: (
134
+ color: (
135
+ prefix: '#{$text-prefix}',
136
+ values: $runtime-text-colors,
137
+ states: ('hover', 'focus')
138
+ )
139
+ );
140
+
127
141
  // ============================================================================
128
142
  // BUILDS
129
143
  // ============================================================================
130
144
  @include build-classes($typography-properties-map, $responsive: true);
145
+ @include build-classes($runtime-typography-properties-map, $responsive: true);
131
146
  @include build-composite-classes($text-classes-map, $responsive: true);