@agorapulse/ui-theme 20.1.19 → 20.1.21

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.
Files changed (72) hide show
  1. package/agorapulse-ui-theme-20.1.21.tgz +0 -0
  2. package/assets/desktop_variables.css +10 -0
  3. package/assets/mobile_variables.css +10 -0
  4. package/assets/style/_tooltip.scss +6 -1
  5. package/assets/style/css-ui/_accordion.scss +54 -0
  6. package/assets/style/css-ui/_action-dropdown.scss +163 -0
  7. package/assets/style/css-ui/_avatar-group.scss +61 -0
  8. package/assets/style/css-ui/_avatar.scss +183 -0
  9. package/assets/style/css-ui/{badge.css → _badge.scss} +10 -12
  10. package/assets/style/css-ui/_button.scss +258 -0
  11. package/assets/style/css-ui/_card.scss +17 -0
  12. package/assets/style/css-ui/_checkbox.scss +164 -0
  13. package/assets/style/css-ui/_counter.scss +76 -0
  14. package/assets/style/css-ui/_datepicker.scss +307 -0
  15. package/assets/style/css-ui/_dialog.scss +74 -0
  16. package/assets/style/css-ui/_dot-stepper.scss +68 -0
  17. package/assets/style/{_helpers.scss → css-ui/_helpers.scss} +14 -13
  18. package/assets/style/css-ui/_icon-button.scss +162 -0
  19. package/assets/style/css-ui/_infobox.scss +154 -0
  20. package/assets/style/css-ui/_input.scss +129 -0
  21. package/assets/style/css-ui/_label.scss +95 -0
  22. package/assets/style/css-ui/_link.scss +86 -0
  23. package/assets/style/css-ui/_list-panel.scss +73 -0
  24. package/assets/style/css-ui/_loader.scss +173 -0
  25. package/assets/style/css-ui/_mixins.scss +50 -0
  26. package/assets/style/css-ui/_pagination.scss +177 -0
  27. package/assets/style/css-ui/_radio-card.scss +200 -0
  28. package/assets/style/css-ui/_radio.scss +107 -0
  29. package/assets/style/css-ui/{select.css → _select.scss} +290 -298
  30. package/assets/style/css-ui/_selection-dropdown.scss +183 -0
  31. package/assets/style/css-ui/_snackbar.scss +161 -0
  32. package/assets/style/css-ui/_split-button.scss +74 -0
  33. package/assets/style/css-ui/_status.scss +71 -0
  34. package/assets/style/css-ui/_stepper.scss +113 -0
  35. package/assets/style/css-ui/_table.scss +325 -0
  36. package/assets/style/css-ui/_tabs.scss +182 -0
  37. package/assets/style/css-ui/_tag.scss +169 -0
  38. package/assets/style/css-ui/_textarea.scss +121 -0
  39. package/assets/style/css-ui/_toggle.scss +132 -0
  40. package/assets/style/css-ui/_tooltip.scss +122 -0
  41. package/assets/style/{_mat-typography.scss → css-ui/_typography.scss} +34 -26
  42. package/assets/style/css-ui/font-face.css +43 -0
  43. package/assets/style/css-ui/index.css +4907 -27
  44. package/assets/style/css-ui/index.css.map +1 -0
  45. package/assets/style/css-ui/index.scss +39 -0
  46. package/assets/style/theme.scss +9 -2
  47. package/package.json +17 -2
  48. package/src/tokens/system/icon.json +33 -0
  49. package/agorapulse-ui-theme-20.1.19.tgz +0 -0
  50. package/assets/style/css-ui/action-dropdown.css +0 -172
  51. package/assets/style/css-ui/avatar.css +0 -199
  52. package/assets/style/css-ui/button.css +0 -446
  53. package/assets/style/css-ui/checkbox.css +0 -170
  54. package/assets/style/css-ui/counter.css +0 -73
  55. package/assets/style/css-ui/datepicker.css +0 -294
  56. package/assets/style/css-ui/dot-stepper.css +0 -67
  57. package/assets/style/css-ui/infobox.css +0 -163
  58. package/assets/style/css-ui/input.css +0 -119
  59. package/assets/style/css-ui/label.css +0 -67
  60. package/assets/style/css-ui/link.css +0 -92
  61. package/assets/style/css-ui/loader.css +0 -247
  62. package/assets/style/css-ui/pagination.css +0 -161
  63. package/assets/style/css-ui/radio.css +0 -109
  64. package/assets/style/css-ui/snackbar.css +0 -166
  65. package/assets/style/css-ui/status.css +0 -87
  66. package/assets/style/css-ui/stepper.css +0 -123
  67. package/assets/style/css-ui/table.css +0 -305
  68. package/assets/style/css-ui/tabs.css +0 -188
  69. package/assets/style/css-ui/tag.css +0 -171
  70. package/assets/style/css-ui/textarea.css +0 -158
  71. package/assets/style/css-ui/toggle.css +0 -161
  72. package/assets/style/css-ui/tooltip.css +0 -228
@@ -0,0 +1,154 @@
1
+ // Agorapulse Infobox Styles
2
+ @use 'mixins' as m;
3
+
4
+ .ap-infobox {
5
+ container: infobox / inline-size;
6
+ display: flex;
7
+ width: 100%;
8
+ max-width: 100%;
9
+ font-size: var(--ref-font-size-sm);
10
+ line-height: var(--ref-font-line-height-sm);
11
+ align-items: flex-start;
12
+ color: var(--ref-color-grey-100);
13
+ padding: var(--comp-infobox-padding-top) var(--comp-infobox-padding-right) var(--comp-infobox-padding-bottom) var(--comp-infobox-padding-left);
14
+ border-radius: var(--comp-infobox-border-radius);
15
+ overflow: hidden;
16
+ font-family: var(--comp-infobox-text-title-font-family);
17
+ box-sizing: border-box;
18
+ position: relative;
19
+ gap: var(--ref-spacing-xs);
20
+
21
+ // Left banner via pseudo-element (no HTML needed)
22
+ &::before {
23
+ content: '';
24
+ position: absolute;
25
+ left: 0;
26
+ top: 0;
27
+ width: var(--comp-infobox-border-width, 4px);
28
+ height: 100%;
29
+ }
30
+
31
+ // Icon — direct <i> child, size defaulted to sm (no wrapper, no size class needed)
32
+ > i {
33
+ font-size: var(--sys-icon-css-sm);
34
+ flex-shrink: 0;
35
+ margin-top: 1px;
36
+ }
37
+
38
+ // With title — center icon vertically with the title+message block
39
+ &.has-title {
40
+ align-items: center;
41
+
42
+ > i {
43
+ margin-top: 0;
44
+ }
45
+ }
46
+
47
+ // Variants
48
+ &.info {
49
+ background-color: var(--comp-infobox-info-background-color);
50
+ > i { color: var(--comp-infobox-info-icon-color); }
51
+ &::before { background-color: var(--comp-infobox-info-border-left-color); }
52
+ }
53
+
54
+ &.warning {
55
+ background-color: var(--comp-infobox-warning-background-color);
56
+ > i { color: var(--comp-infobox-warning-icon-color); }
57
+ &::before { background-color: var(--comp-infobox-warning-border-left-color); }
58
+ }
59
+
60
+ &.error {
61
+ background-color: var(--comp-infobox-error-background-color);
62
+ > i { color: var(--comp-infobox-error-icon-color); }
63
+ &::before { background-color: var(--comp-infobox-error-border-left-color); }
64
+ }
65
+
66
+ &.success {
67
+ background-color: var(--comp-infobox-success-background-color);
68
+ > i { color: var(--comp-infobox-success-icon-color); }
69
+ &::before { background-color: var(--comp-infobox-success-border-left-color); }
70
+ }
71
+ }
72
+
73
+ // Content wrapper
74
+ .ap-infobox-content {
75
+ display: flex;
76
+ flex-direction: column;
77
+ align-items: flex-start;
78
+ flex: 1;
79
+ justify-content: space-between;
80
+ gap: var(--ref-spacing-xxs);
81
+ min-width: 0;
82
+
83
+ > .ap-button {
84
+ width: unset;
85
+ }
86
+ }
87
+
88
+ // Text content
89
+ .ap-infobox-texts {
90
+ display: flex;
91
+ flex-direction: column;
92
+ overflow-wrap: anywhere;
93
+ width: 100%;
94
+ }
95
+
96
+ // Title
97
+ .ap-infobox-title {
98
+ font-weight: var(--comp-infobox-text-title-weight);
99
+ font-family: var(--comp-infobox-text-title-font-family);
100
+ font-size: var(--comp-infobox-text-title-size);
101
+ line-height: var(--comp-infobox-text-title-line-height);
102
+ }
103
+
104
+ // Message/Body text
105
+ .ap-infobox-message {
106
+ font-weight: var(--comp-infobox-text-content-weight);
107
+ font-family: var(--comp-infobox-text-content-font-family);
108
+ font-size: var(--comp-infobox-text-content-size);
109
+ line-height: var(--comp-infobox-text-content-line-height);
110
+ }
111
+
112
+ // Close button
113
+ .ap-infobox-close {
114
+ display: flex;
115
+ justify-content: center;
116
+ align-items: center;
117
+ @include m.fixed-size(var(--comp-close-button-size));
118
+ border-radius: 50%;
119
+ background: transparent;
120
+ border: none;
121
+ padding: var(--comp-close-button-padding);
122
+ cursor: pointer;
123
+ flex-shrink: 0;
124
+ transition: background 0.25s;
125
+
126
+ @media (hover: hover) {
127
+ &:focus:not(:active) {
128
+ @include m.focus-ring;
129
+ }
130
+ }
131
+
132
+ &:hover {
133
+ background: var(--comp-close-button-hover-background);
134
+ }
135
+
136
+ &:active {
137
+ background: var(--comp-close-button-active-background);
138
+ }
139
+
140
+ // Close icon (implicit > i)
141
+ > i {
142
+ color: var(--ref-color-grey-80);
143
+ }
144
+ }
145
+
146
+ // Wide layout via container query
147
+ // Threshold adjusted from 588px to 560px to compensate for infobox padding (28px)
148
+ // so the breakpoint triggers at the same visual width as the Angular component.
149
+ @container infobox (min-width: 560px) {
150
+ .ap-infobox-content {
151
+ flex-direction: row;
152
+ align-items: center;
153
+ }
154
+ }
@@ -0,0 +1,129 @@
1
+ // Agorapulse Input Styles
2
+ @use 'mixins' as m;
3
+ @use 'ui-symbol/icons/build/ap-icons-data' as icons;
4
+
5
+ // Form field container
6
+ .ap-form-field {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: var(--ref-spacing-xxs);
10
+
11
+ // Label — implicit > label
12
+ > label {
13
+ @include m.text-style('body');
14
+ color: var(--ref-color-grey-100);
15
+ }
16
+ }
17
+
18
+ // Input group container
19
+ .ap-input-group {
20
+ width: 100%;
21
+ display: inline-flex;
22
+ align-items: center;
23
+ height: var(--comp-input-height);
24
+ border: 1px solid var(--comp-input-border-default-color);
25
+ box-sizing: border-box;
26
+ border-radius: var(--comp-input-border-radius);
27
+ overflow: hidden;
28
+ background-color: var(--comp-input-fill-color);
29
+ gap: var(--ref-spacing-xxs);
30
+ padding: 0 var(--ref-spacing-xs);
31
+
32
+ // Disabled input
33
+ &:has(input:disabled) {
34
+ background-color: var(--comp-input-fill-disabled-color);
35
+ color: var(--comp-input-text-disabled-color);
36
+ }
37
+
38
+ // Hover state
39
+ &:hover:not(:has(input:disabled)) {
40
+ border-color: var(--comp-input-border-hover-color);
41
+ }
42
+
43
+ // Focus state
44
+ &:focus-within:not(:has(input:disabled)) {
45
+ border-color: var(--comp-input-border-focused-color);
46
+ }
47
+
48
+ // Invalid state
49
+ &.invalid,
50
+ &:has(input.invalid) {
51
+ border-color: var(--comp-input-border-error-color);
52
+ }
53
+
54
+ // Valid state
55
+ &.valid,
56
+ &:has(input.valid) {
57
+ border-color: var(--comp-input-border-success-color);
58
+ }
59
+
60
+
61
+ // Input — implicit > input
62
+ > input {
63
+ flex: 1;
64
+ border: none;
65
+ outline: none;
66
+ background: transparent;
67
+ color: var(--comp-input-text-default-color);
68
+ font-family: var(--comp-input-text-font-family);
69
+ font-size: var(--comp-input-text-size);
70
+ font-weight: var(--comp-input-text-font-weight);
71
+ padding: 0;
72
+ min-width: 0;
73
+
74
+ &::placeholder {
75
+ color: var(--comp-input-text-placeholder-color);
76
+ }
77
+
78
+ &:disabled {
79
+ color: var(--comp-input-text-disabled-color);
80
+ }
81
+ }
82
+
83
+ // Icon — implicit > i
84
+ > i {
85
+ flex-shrink: 0;
86
+ width: var(--comp-input-icon-size);
87
+ height: var(--comp-input-icon-size);
88
+ color: var(--comp-input-icon-color);
89
+ pointer-events: none;
90
+ }
91
+ }
92
+
93
+ // Form message (error/success)
94
+ .ap-form-message {
95
+ font-size: var(--comp-forms-status-text-size);
96
+ font-weight: var(--comp-forms-status-text-font-weight);
97
+ line-height: var(--comp-forms-status-text-line-height);
98
+ font-family: var(--comp-forms-status-text-font-family);
99
+ margin: 0;
100
+ display: flex;
101
+ align-items: center;
102
+ gap: var(--ref-spacing-xxxs);
103
+
104
+ // Icon injected via ::before (no <i> needed in HTML)
105
+ &::before {
106
+ @include icons.icon-base;
107
+ width: var(--comp-forms-status-icon-size);
108
+ height: var(--comp-forms-status-icon-size);
109
+ flex-shrink: 0;
110
+ }
111
+
112
+ &.error {
113
+ color: var(--comp-forms-status-text-error-color);
114
+
115
+ &::before {
116
+ @include icons.icon('error_fill');
117
+ color: var(--comp-forms-status-icon-error-color);
118
+ }
119
+ }
120
+
121
+ &.success {
122
+ color: var(--comp-forms-status-text-success-color);
123
+
124
+ &::before {
125
+ @include icons.icon('rounded-check_fill');
126
+ color: var(--comp-forms-status-icon-success-color);
127
+ }
128
+ }
129
+ }
@@ -0,0 +1,95 @@
1
+ // Agorapulse Label Styles
2
+ @use 'mixins' as m;
3
+
4
+ .ap-label {
5
+ display: inline-flex;
6
+ align-items: center;
7
+ max-width: 100%;
8
+ background: var(--comp-label-background-color);
9
+ border-radius: var(--comp-label-border-radius);
10
+ padding: 0 var(--comp-label-padding-right) 0 var(--comp-label-padding-left);
11
+ height: var(--comp-label-height);
12
+ box-sizing: border-box;
13
+ border: none;
14
+
15
+ // Text styles on container (span optional)
16
+ color: var(--comp-label-text-color);
17
+ font-family: var(--comp-label-text-style-font-family);
18
+ font-size: var(--comp-label-text-style-size);
19
+ font-weight: var(--comp-label-text-style-font-weight);
20
+ line-height: var(--comp-label-text-style-line-height);
21
+ white-space: nowrap;
22
+ text-decoration: none;
23
+
24
+ // Auto-detect icon — add gap
25
+ &:has(> i) {
26
+ gap: var(--comp-label-closable-spacing);
27
+ }
28
+
29
+ // Auto-detect close button — tighter padding + gap
30
+ &:has(> button) {
31
+ gap: var(--comp-label-closable-spacing);
32
+ padding: 0 var(--comp-label-closable-padding-right) 0 var(--ref-spacing-xxs);
33
+ }
34
+
35
+ // Text truncation — use > span when combined with a close button
36
+ > span {
37
+ @include m.truncate;
38
+ max-width: 180px;
39
+ }
40
+
41
+ // Icon slot — implicit > i
42
+ > i {
43
+ width: 12px;
44
+ height: 12px;
45
+ }
46
+
47
+ // Close button with <i class="ap-icon-close"> inside
48
+ > button {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ flex-shrink: 0;
53
+ width: calc(var(--comp-label-height) - 4px);
54
+ height: calc(var(--comp-label-height) - 4px);
55
+ min-width: calc(var(--comp-label-height) - 4px);
56
+ border: none;
57
+ background: transparent;
58
+ border-radius: 50%;
59
+ cursor: pointer;
60
+ padding: 0;
61
+ color: var(--comp-label-text-color);
62
+ transition: background-color 0.15s;
63
+
64
+ &:hover {
65
+ background: var(--ref-color-electric-blue-40);
66
+ }
67
+
68
+ &:active {
69
+ background: var(--ref-color-electric-blue-60);
70
+ }
71
+
72
+ > i {
73
+ width: 12px;
74
+ height: 12px;
75
+ }
76
+ }
77
+
78
+ // button.ap-label — focus ring for clickable labels
79
+ &:is(button) {
80
+ cursor: pointer;
81
+
82
+ @media (hover: hover) {
83
+ &:focus:not(:disabled):not(:active) {
84
+ @include m.focus-ring;
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ // Label list container
91
+ .ap-label-list {
92
+ display: flex;
93
+ flex-wrap: wrap;
94
+ gap: var(--ref-spacing-xxs);
95
+ }
@@ -0,0 +1,86 @@
1
+ // Agorapulse Link Styles
2
+ @use 'mixins' as m;
3
+
4
+ // Base link styling
5
+ .ap-link {
6
+ display: inline-flex;
7
+ gap: var(--comp-link-spacing);
8
+ font-family: var(--comp-link-text-font-family);
9
+ font-weight: var(--comp-link-text-font-weight);
10
+ line-height: var(--comp-link-text-line-height);
11
+ font-size: var(--comp-link-text-size);
12
+ align-items: center;
13
+ text-decoration: underline;
14
+ -webkit-tap-highlight-color: transparent;
15
+ cursor: pointer;
16
+ color: var(--comp-link-default-color);
17
+
18
+ // Size variants
19
+ &.small {
20
+ font-family: var(--comp-link-small-text-style-font-family);
21
+ font-weight: var(--comp-link-small-text-style-font-weight);
22
+ line-height: var(--comp-link-small-text-style-line-height);
23
+ font-size: var(--comp-link-small-text-style-size);
24
+ }
25
+
26
+ &.big {
27
+ font-family: var(--comp-link-big-text-style-font-family);
28
+ font-weight: var(--comp-link-big-text-style-font-weight);
29
+ line-height: var(--comp-link-big-text-style-line-height);
30
+ font-size: var(--comp-link-big-text-style-size);
31
+ }
32
+
33
+ // Standalone variant (no underline)
34
+ &.standalone {
35
+ text-decoration: none;
36
+ font-family: var(--comp-link-standalone-default-text-style-font-family);
37
+ font-weight: var(--comp-link-standalone-default-text-style-font-weight);
38
+ line-height: var(--comp-link-standalone-default-text-style-line-height);
39
+ font-size: var(--comp-link-standalone-default-text-style-size);
40
+ color: var(--comp-link-default-color);
41
+
42
+ &.small {
43
+ font-family: var(--comp-link-standalone-small-text-style-font-family);
44
+ font-weight: var(--comp-link-standalone-small-text-style-font-weight);
45
+ line-height: var(--comp-link-standalone-small-text-style-line-height);
46
+ font-size: var(--comp-link-standalone-small-text-style-size);
47
+ }
48
+ }
49
+
50
+ // States
51
+ &:hover {
52
+ color: var(--comp-link-hover-color);
53
+ }
54
+
55
+ &:active:not(:visited):not(.disabled) {
56
+ color: var(--comp-link-clicked-color);
57
+ }
58
+
59
+ &:visited:not(.standalone) {
60
+ color: var(--comp-link-visited-color);
61
+ }
62
+
63
+ // Disabled state
64
+ &.disabled,
65
+ &[aria-disabled='true'] {
66
+ color: var(--comp-link-disabled-color);
67
+ pointer-events: none;
68
+ cursor: default;
69
+ }
70
+
71
+ // Focus state for accessibility
72
+ &:focus-visible {
73
+ @include m.focus-ring;
74
+ outline-offset: 2px;
75
+ border-radius: 2px;
76
+ }
77
+
78
+ // Icon sizing — implicit > i
79
+ > i {
80
+ min-width: var(--comp-link-icon-size);
81
+ min-height: var(--comp-link-icon-size);
82
+ max-width: var(--comp-link-icon-size);
83
+ max-height: var(--comp-link-icon-size);
84
+ flex-shrink: 0;
85
+ }
86
+ }
@@ -0,0 +1,73 @@
1
+ .ap-list-panel {
2
+ background-color: var(--ref-color-white);
3
+ border-right: 1px solid var(--ref-color-grey-10);
4
+ display: flex;
5
+ flex-direction: column;
6
+ height: 100%;
7
+ }
8
+
9
+ .ap-list-panel-header {
10
+ border-bottom: 1px solid var(--ref-color-grey-10);
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: var(--ref-spacing-sm);
14
+ padding: var(--ref-spacing-sm);
15
+ }
16
+
17
+ .ap-list-panel-items {
18
+ display: flex;
19
+ flex-direction: column;
20
+ flex: 1 0 0;
21
+ overflow-y: auto;
22
+ padding: var(--ref-spacing-sm) 0;
23
+ }
24
+
25
+ .ap-list-panel-item {
26
+ display: flex;
27
+ align-items: center;
28
+ min-height: 40px;
29
+ padding: var(--ref-spacing-xxs) var(--ref-spacing-sm);
30
+ gap: var(--ref-spacing-xxs);
31
+ font-size: var(--ref-font-size-sm);
32
+ line-height: var(--ref-font-line-height-sm);
33
+ color: var(--ref-color-grey-100);
34
+ cursor: pointer;
35
+ transition: background-color var(--ref-animation-short);
36
+
37
+ &:hover {
38
+ background-color: var(--ref-color-electric-blue-10);
39
+ }
40
+
41
+ &.selected {
42
+ background-color: var(--ref-color-electric-blue-20);
43
+
44
+ .ap-list-panel-item-name {
45
+ color: var(--ref-color-electric-blue-150);
46
+ font-weight: var(--ref-font-weight-bold);
47
+ }
48
+ }
49
+ }
50
+
51
+ .ap-list-panel-item-text {
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: 2px;
55
+ flex: 1;
56
+ min-width: 0;
57
+ }
58
+
59
+ .ap-list-panel-item-name {
60
+ overflow: hidden;
61
+ text-overflow: ellipsis;
62
+ white-space: nowrap;
63
+
64
+ &:has(+ .ap-list-panel-item-subtitle) {
65
+ font-weight: var(--ref-font-weight-bold);
66
+ }
67
+ }
68
+
69
+ .ap-list-panel-item-subtitle {
70
+ font-size: var(--ref-font-size-xs);
71
+ line-height: var(--ref-font-line-height-xs);
72
+ color: var(--ref-color-grey-80);
73
+ }
@@ -0,0 +1,173 @@
1
+ // Agorapulse Loader Styles
2
+ // SVG-based loader with CSS-driven geometry and animation
3
+ // Usage: <div class="ap-loader orange size-48"><svg><circle/><circle/></svg></div>
4
+ //
5
+ // Zero attributes on SVG elements — all geometry, stroke, and animation in CSS.
6
+ // Reproduces the Angular loader exactly: round caps, per-size dasharray, dual easing.
7
+
8
+ .ap-loader {
9
+ --_track: var(--ref-color-orange-40);
10
+ --_color: var(--ref-color-orange-100);
11
+
12
+ display: inline-block;
13
+ position: relative;
14
+ line-height: 0;
15
+
16
+ svg {
17
+ width: 100%;
18
+ height: 100%;
19
+ }
20
+
21
+ circle {
22
+ cx: 50%;
23
+ cy: 50%;
24
+ fill: transparent;
25
+ stroke-linecap: round;
26
+ transform: rotate(-90deg);
27
+ transform-origin: center;
28
+ }
29
+
30
+ circle:first-child {
31
+ stroke: var(--_track);
32
+ }
33
+
34
+ circle:last-child {
35
+ stroke: var(--_color);
36
+ }
37
+
38
+ // Color variants
39
+ &.blue {
40
+ --_track: var(--ref-color-electric-blue-10);
41
+ --_color: var(--ref-color-electric-blue-100);
42
+ }
43
+
44
+ &.orange {
45
+ --_track: var(--ref-color-orange-40);
46
+ --_color: var(--ref-color-orange-100);
47
+ }
48
+
49
+ &.grey {
50
+ --_track: var(--ref-color-grey-20);
51
+ --_color: var(--ref-color-grey-80);
52
+ }
53
+
54
+ // Size variants — r, stroke-width, dasharray from Angular source
55
+ &.size-16 {
56
+ width: 16px;
57
+ height: 16px;
58
+ circle {
59
+ r: 6.5px;
60
+ stroke-width: 3;
61
+ stroke-dasharray: 40;
62
+ stroke-dashoffset: 47;
63
+ }
64
+ circle:first-child { animation: ap-loader-16 1.5s cubic-bezier(0.42, 0, 0.78, 1) infinite; }
65
+ circle:last-child { animation: ap-loader-16 1.5s cubic-bezier(0.42, 0, 0.58, 1) infinite; }
66
+ }
67
+
68
+ &.size-24 {
69
+ width: 24px;
70
+ height: 24px;
71
+ circle {
72
+ r: 10px;
73
+ stroke-width: 4;
74
+ stroke-dasharray: 62;
75
+ stroke-dashoffset: 69;
76
+ }
77
+ circle:first-child { animation: ap-loader-24 1.5s cubic-bezier(0.42, 0, 0.78, 1) infinite; }
78
+ circle:last-child { animation: ap-loader-24 1.5s cubic-bezier(0.42, 0, 0.58, 1) infinite; }
79
+ }
80
+
81
+ &.size-30 {
82
+ width: 30px;
83
+ height: 30px;
84
+ circle {
85
+ r: 12.5px;
86
+ stroke-width: 5;
87
+ stroke-dasharray: 78;
88
+ stroke-dashoffset: 84;
89
+ }
90
+ circle:first-child { animation: ap-loader-30 1.5s cubic-bezier(0.42, 0, 0.78, 1) infinite; }
91
+ circle:last-child { animation: ap-loader-30 1.5s cubic-bezier(0.42, 0, 0.58, 1) infinite; }
92
+ }
93
+
94
+ &.size-48 {
95
+ width: 48px;
96
+ height: 48px;
97
+ circle {
98
+ r: 20.5px;
99
+ stroke-width: 7;
100
+ stroke-dasharray: 128;
101
+ stroke-dashoffset: 131;
102
+ }
103
+ circle:first-child { animation: ap-loader-48 1.5s cubic-bezier(0.42, 0, 0.78, 1) infinite; }
104
+ circle:last-child { animation: ap-loader-48 1.5s cubic-bezier(0.42, 0, 0.58, 1) infinite; }
105
+ }
106
+
107
+ &.size-60 {
108
+ width: 60px;
109
+ height: 60px;
110
+ circle {
111
+ r: 26px;
112
+ stroke-width: 8;
113
+ stroke-dasharray: 163;
114
+ stroke-dashoffset: 166;
115
+ }
116
+ circle:first-child { animation: ap-loader-60 1.5s cubic-bezier(0.42, 0, 0.78, 1) infinite; }
117
+ circle:last-child { animation: ap-loader-60 1.5s cubic-bezier(0.42, 0, 0.58, 1) infinite; }
118
+ }
119
+ }
120
+
121
+ // Keyframes per size — exact Angular stroke-dashoffset values
122
+ // 0%: full dashoffset (invisible) → 50%: ~55% mark (arc visible) → 100%: back to full + 630deg rotation
123
+
124
+ @keyframes ap-loader-16 {
125
+ 0% { stroke-dashoffset: 47; }
126
+ 50% { stroke-dashoffset: 25; }
127
+ 100% { stroke-dashoffset: 47; transform: rotate(630deg); }
128
+ }
129
+
130
+ @keyframes ap-loader-24 {
131
+ 0% { stroke-dashoffset: 69; }
132
+ 50% { stroke-dashoffset: 37; }
133
+ 100% { stroke-dashoffset: 69; transform: rotate(630deg); }
134
+ }
135
+
136
+ @keyframes ap-loader-30 {
137
+ 0% { stroke-dashoffset: 84; }
138
+ 50% { stroke-dashoffset: 46; }
139
+ 100% { stroke-dashoffset: 84; transform: rotate(630deg); }
140
+ }
141
+
142
+ @keyframes ap-loader-48 {
143
+ 0% { stroke-dashoffset: 131; }
144
+ 50% { stroke-dashoffset: 72; }
145
+ 100% { stroke-dashoffset: 131; transform: rotate(630deg); }
146
+ }
147
+
148
+ @keyframes ap-loader-60 {
149
+ 0% { stroke-dashoffset: 166; }
150
+ 50% { stroke-dashoffset: 91; }
151
+ 100% { stroke-dashoffset: 166; transform: rotate(630deg); }
152
+ }
153
+
154
+ // Loader container for centered display
155
+ .ap-loader-container {
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ }
160
+
161
+ // Full page loader overlay
162
+ .ap-loader-overlay {
163
+ position: fixed;
164
+ top: 0;
165
+ left: 0;
166
+ right: 0;
167
+ bottom: 0;
168
+ display: flex;
169
+ align-items: center;
170
+ justify-content: center;
171
+ background: rgba(255, 255, 255, 0.8);
172
+ z-index: 9999;
173
+ }