astralkit 0.3.0 → 0.3.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.
@@ -1,410 +1,410 @@
1
-
2
-
3
- /* Avatar primitives -- base, sizes, colors, shapes, groups, progress, rings, faces */
4
-
5
-
6
-
7
- /* Avatar base */
8
- .ak-avatar {
9
- display: inline-flex;
10
- align-items: center;
11
- justify-content: center;
12
- border-radius: var(--radius-ak-full);
13
- overflow: hidden;
14
- position: relative;
15
- flex-shrink: 0;
16
- background: var(--color-ak-surface-2);
17
- color: var(--color-ak-text-secondary);
18
- font-weight: 600;
19
- line-height: 1;
20
- letter-spacing: 0.01em;
21
- user-select: none;
22
- -webkit-font-smoothing: antialiased;
23
- border: none;
24
- /* Fix jagged circle edge from overflow:hidden + border-radius.
25
- Inset shadow acts as an AA layer at the clip boundary. */
26
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.04);
27
- }
28
- .ak-avatar img {
29
- width: 100%;
30
- height: 100%;
31
- object-fit: cover;
32
- display: block;
33
- filter: grayscale(100%);
34
- }
35
-
36
- /* Size modifiers */
37
- .ak-avatar--md { width: var(--size-ak-avatar-md); height: var(--size-ak-avatar-md); font-size: var(--text-ak-avatar-md); font-weight: 600; }
38
- .ak-avatar--md i { font-size: var(--size-ak-icon-md); }
39
- .ak-avatar--lg { width: var(--size-ak-avatar-lg); height: var(--size-ak-avatar-lg); font-size: var(--text-ak-avatar-lg); font-weight: 600; }
40
- .ak-avatar--lg i { font-size: var(--size-ak-icon-lg); }
41
- .ak-avatar--xl { width: var(--size-ak-avatar-xl); height: var(--size-ak-avatar-xl); font-size: var(--text-ak-avatar-xl); font-weight: 500; }
42
- .ak-avatar--xl i { font-size: var(--size-ak-icon-xl); }
43
- .ak-avatar--2xl { width: var(--size-ak-avatar-2xl); height: var(--size-ak-avatar-2xl); font-size: var(--text-ak-avatar-2xl); font-weight: 500; }
44
- .ak-avatar--2xl i { font-size: var(--size-ak-icon-2xl); }
45
- .ak-avatar--3xl { width: var(--size-ak-avatar-3xl); height: var(--size-ak-avatar-3xl); font-size: var(--text-ak-avatar-3xl); font-weight: 500; }
46
- .ak-avatar--3xl i { font-size: var(--size-ak-icon-3xl); }
47
-
48
- /* Color variants */
49
- .ak-avatar--primary { background: var(--color-ak-primary); color: var(--color-ak-on-primary); }
50
- .ak-avatar--success { background: var(--color-ak-success-subtle); color: var(--color-ak-success-text); }
51
- .ak-avatar--warning { background: var(--color-ak-warning-subtle); color: var(--color-ak-warning-text); }
52
- .ak-avatar--danger { background: var(--color-ak-danger-subtle); color: var(--color-ak-danger-text); }
53
- .ak-avatar--info { background: var(--color-ak-info-subtle); color: var(--color-ak-info-text); }
54
- .ak-avatar--surface { background: var(--color-ak-surface-2); color: var(--color-ak-text-secondary); }
55
-
56
- /* Shape variants */
57
- .ak-avatar--rounded { border-radius: var(--radius-ak-lg); }
58
- .ak-avatar--square { border-radius: var(--radius-ak-sm); }
59
-
60
- /* Interactive avatar */
61
- .ak-avatar--interactive {
62
- cursor: pointer;
63
- transition: transform var(--duration-ak-fast) var(--ease-ak-default),
64
- box-shadow var(--duration-ak-fast) var(--ease-ak-default);
65
- }
66
- .ak-avatar--interactive:hover { transform: scale(1.08); }
67
- .ak-avatar--interactive:active { transform: scale(0.96); }
68
- .ak-avatar--interactive:focus-visible {
69
- outline: 2px solid var(--color-ak-border-focus);
70
- outline-offset: 2px;
71
- }
72
-
73
- /* Ring variants — outline + box-shadow approach eliminates the subpixel
74
- bleed artifact that occurs with multi-layer box-shadows.
75
- - box-shadow: white gap (covers the element edge cleanly)
76
- - outline: colored ring (separate compositing layer, no bleed) */
77
- .ak-avatar--ring-primary { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-primary); outline-offset: var(--ak-ring-gap, 3px); }
78
- .ak-avatar--ring-success { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-success); outline-offset: var(--ak-ring-gap, 3px); }
79
- .ak-avatar--ring-warning { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-warning); outline-offset: var(--ak-ring-gap, 3px); }
80
- .ak-avatar--ring-info { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-info); outline-offset: var(--ak-ring-gap, 3px); }
81
- .ak-avatar--ring-border { box-shadow: 0 0 0 1px var(--color-ak-border); }
82
-
83
- /* Scale ring per avatar size */
84
- .ak-avatar--md[class*="ak-avatar--ring-"] { --ak-ring-gap: 2px; --ak-ring-width: 2px; }
85
- .ak-avatar--lg[class*="ak-avatar--ring-"] { --ak-ring-gap: 2px; --ak-ring-width: 2px; }
86
- .ak-avatar--xl[class*="ak-avatar--ring-"] { --ak-ring-gap: 2px; --ak-ring-width: 3px; }
87
- .ak-avatar--2xl[class*="ak-avatar--ring-"] { --ak-ring-gap: 3px; --ak-ring-width: 3px; }
88
- .ak-avatar--3xl[class*="ak-avatar--ring-"] { --ak-ring-gap: 3px; --ak-ring-width: 4px; }
89
-
90
- /* Fallback (initials/icon shown when image fails) */
91
- .ak-avatar__fallback { display: none; }
92
- .ak-avatar--fallback img { display: none; }
93
- .ak-avatar--fallback .ak-avatar__fallback {
94
- display: flex;
95
- align-items: center;
96
- justify-content: center;
97
- width: 100%;
98
- height: 100%;
99
- }
100
-
101
- /* Avatar wrap (positions badges/status relative to avatar) */
102
- .ak-avatar-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
103
-
104
- /* Wrap size modifiers for badge/status positioning */
105
- .ak-avatar-wrap--md .ak-status-dot { width: var(--size-ak-status-md); height: var(--size-ak-status-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); bottom: var(--offset-ak-status-md); right: var(--offset-ak-status-md); }
106
- .ak-avatar-wrap--md .ak-status-dot--dnd::after { width: 7px; height: 1.5px; }
107
- .ak-avatar-wrap--md .ak-badge { min-width: var(--size-ak-status-md); height: var(--size-ak-status-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); top: var(--offset-ak-status-md); right: var(--offset-ak-status-md); }
108
- .ak-avatar-wrap--md .ak-badge--count { min-width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); font-size: var(--text-ak-badge-md); top: var(--offset-ak-badge-md-top, var(--offset-ak-badge-md)); right: var(--offset-ak-badge-md-right, var(--offset-ak-badge-md)); --ak-badge-pad: 2px; }
109
- .ak-avatar-wrap--md .ak-notif-badge { min-width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); font-size: var(--text-ak-badge-md); top: var(--offset-ak-badge-md); right: var(--offset-ak-badge-md); }
110
- .ak-avatar-wrap--md .ak-rank-badge { width: var(--size-ak-icon-badge-md); height: var(--size-ak-icon-badge-md); font-size: 0.625rem; border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-md); right: var(--offset-ak-icon-badge-md); }
111
- .ak-avatar-wrap--md .ak-status-icon { width: var(--size-ak-icon-badge-md); height: var(--size-ak-icon-badge-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-md); right: var(--offset-ak-icon-badge-md); }
112
- .ak-avatar-wrap--md .ak-status-icon i { font-size: 12px; }
113
- .ak-avatar-wrap--md .ak-verified-badge { width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-md-top, var(--offset-ak-badge-md)); right: var(--offset-ak-badge-md-right, var(--offset-ak-badge-md)); }
114
- .ak-avatar-wrap--md .ak-verified-badge i { font-size: 10px; }
115
-
116
- .ak-avatar-wrap--lg .ak-status-dot { width: var(--size-ak-status-lg); height: var(--size-ak-status-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); bottom: var(--offset-ak-status-lg); right: var(--offset-ak-status-lg); }
117
- .ak-avatar-wrap--lg .ak-status-dot--dnd::after { width: 8px; height: 1.5px; }
118
- .ak-avatar-wrap--lg .ak-badge { min-width: var(--size-ak-status-lg); height: var(--size-ak-status-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); top: var(--offset-ak-status-lg); right: var(--offset-ak-status-lg); }
119
- .ak-avatar-wrap--lg .ak-badge--count { min-width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); font-size: var(--text-ak-badge-lg); top: var(--offset-ak-badge-lg-top, var(--offset-ak-badge-lg)); right: var(--offset-ak-badge-lg-right, var(--offset-ak-badge-lg)); --ak-badge-pad: 2px; }
120
- .ak-avatar-wrap--lg .ak-notif-badge { min-width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); font-size: var(--text-ak-badge-lg); top: var(--offset-ak-badge-lg); right: var(--offset-ak-badge-lg); }
121
- .ak-avatar-wrap--lg .ak-rank-badge { width: var(--size-ak-icon-badge-lg); height: var(--size-ak-icon-badge-lg); font-size: 0.6875rem; border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-lg); right: var(--offset-ak-icon-badge-lg); }
122
- .ak-avatar-wrap--lg .ak-status-icon { width: var(--size-ak-icon-badge-lg); height: var(--size-ak-icon-badge-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-lg); right: var(--offset-ak-icon-badge-lg); }
123
- .ak-avatar-wrap--lg .ak-status-icon i { font-size: 13px; }
124
- .ak-avatar-wrap--lg .ak-verified-badge { width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-lg-top, var(--offset-ak-badge-lg)); right: var(--offset-ak-badge-lg-right, var(--offset-ak-badge-lg)); }
125
- .ak-avatar-wrap--lg .ak-verified-badge i { font-size: 12px; }
126
-
127
- .ak-avatar-wrap--xl .ak-status-dot { width: var(--size-ak-status-xl); height: var(--size-ak-status-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); bottom: var(--offset-ak-status-xl); right: var(--offset-ak-status-xl); }
128
- .ak-avatar-wrap--xl .ak-status-dot--dnd::after { width: 9px; height: 2px; }
129
- .ak-avatar-wrap--xl .ak-badge { min-width: var(--size-ak-status-xl); height: var(--size-ak-status-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); top: var(--offset-ak-status-xl); right: var(--offset-ak-status-xl); }
130
- .ak-avatar-wrap--xl .ak-badge--count { min-width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); font-size: var(--text-ak-badge-xl); top: var(--offset-ak-badge-xl-top, var(--offset-ak-badge-xl)); right: var(--offset-ak-badge-xl-right, var(--offset-ak-badge-xl)); --ak-badge-pad: 3px; }
131
- .ak-avatar-wrap--xl .ak-notif-badge { min-width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); font-size: var(--text-ak-badge-xl); top: var(--offset-ak-badge-xl); right: var(--offset-ak-badge-xl); }
132
- .ak-avatar-wrap--xl .ak-rank-badge { width: var(--size-ak-icon-badge-xl); height: var(--size-ak-icon-badge-xl); font-size: 0.75rem; border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-xl); right: var(--offset-ak-icon-badge-xl); }
133
- .ak-avatar-wrap--xl .ak-status-icon { width: var(--size-ak-icon-badge-xl); height: var(--size-ak-icon-badge-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-xl); right: var(--offset-ak-icon-badge-xl); }
134
- .ak-avatar-wrap--xl .ak-status-icon i { font-size: 14px; }
135
- .ak-avatar-wrap--xl .ak-verified-badge { width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-xl-top, var(--offset-ak-badge-xl)); right: var(--offset-ak-badge-xl-right, var(--offset-ak-badge-xl)); }
136
- .ak-avatar-wrap--xl .ak-verified-badge i { font-size: 14px; }
137
-
138
- .ak-avatar-wrap--2xl .ak-status-dot { width: var(--size-ak-status-2xl); height: var(--size-ak-status-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); bottom: var(--offset-ak-status-2xl); right: var(--offset-ak-status-2xl); }
139
- .ak-avatar-wrap--2xl .ak-status-dot--dnd::after { width: 11px; height: 2px; }
140
- .ak-avatar-wrap--2xl .ak-badge { min-width: var(--size-ak-status-2xl); height: var(--size-ak-status-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); top: var(--offset-ak-status-2xl); right: var(--offset-ak-status-2xl); }
141
- .ak-avatar-wrap--2xl .ak-badge--count { min-width: var(--size-ak-badge-2xl); height: var(--size-ak-badge-2xl); font-size: var(--text-ak-badge-2xl); top: var(--offset-ak-badge-2xl-top, var(--offset-ak-badge-2xl)); right: var(--offset-ak-badge-2xl-right, var(--offset-ak-badge-2xl)); }
142
- .ak-avatar-wrap--2xl .ak-rank-badge { width: var(--size-ak-icon-badge-2xl); height: var(--size-ak-icon-badge-2xl); font-size: 0.875rem; border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-2xl); right: var(--offset-ak-icon-badge-2xl); }
143
- .ak-avatar-wrap--2xl .ak-status-icon { width: var(--size-ak-icon-badge-2xl); height: var(--size-ak-icon-badge-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-2xl); right: var(--offset-ak-icon-badge-2xl); }
144
- .ak-avatar-wrap--2xl .ak-status-icon i { font-size: 16px; }
145
- .ak-avatar-wrap--2xl .ak-verified-badge { width: var(--size-ak-badge-2xl); height: var(--size-ak-badge-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-2xl-top, var(--offset-ak-badge-2xl)); right: var(--offset-ak-badge-2xl-right, var(--offset-ak-badge-2xl)); }
146
- .ak-avatar-wrap--2xl .ak-verified-badge i { font-size: 18px; }
147
-
148
- .ak-avatar-wrap--3xl .ak-status-dot { width: var(--size-ak-status-3xl); height: var(--size-ak-status-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); bottom: var(--offset-ak-status-3xl); right: var(--offset-ak-status-3xl); }
149
- .ak-avatar-wrap--3xl .ak-status-dot--dnd::after { width: 13px; height: 2.5px; }
150
- .ak-avatar-wrap--3xl .ak-badge { min-width: var(--size-ak-status-3xl); height: var(--size-ak-status-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); top: var(--offset-ak-status-3xl); right: var(--offset-ak-status-3xl); }
151
- .ak-avatar-wrap--3xl .ak-badge--count { min-width: var(--size-ak-badge-3xl); height: var(--size-ak-badge-3xl); font-size: var(--text-ak-badge-3xl); top: var(--offset-ak-badge-3xl-top, var(--offset-ak-badge-3xl)); right: var(--offset-ak-badge-3xl-right, var(--offset-ak-badge-3xl)); }
152
- .ak-avatar-wrap--3xl .ak-rank-badge { width: var(--size-ak-icon-badge-3xl); height: var(--size-ak-icon-badge-3xl); font-size: 1rem; border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-3xl); right: var(--offset-ak-icon-badge-3xl); }
153
- .ak-avatar-wrap--3xl .ak-status-icon { width: var(--size-ak-icon-badge-3xl); height: var(--size-ak-icon-badge-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-3xl); right: var(--offset-ak-icon-badge-3xl); }
154
- .ak-avatar-wrap--3xl .ak-status-icon i { font-size: 20px; }
155
- .ak-avatar-wrap--3xl .ak-verified-badge { width: var(--size-ak-badge-3xl); height: var(--size-ak-badge-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-3xl-top, var(--offset-ak-badge-3xl)); right: var(--offset-ak-badge-3xl-right, var(--offset-ak-badge-3xl)); }
156
- .ak-avatar-wrap--3xl .ak-verified-badge i { font-size: 22px; }
157
-
158
- /* Social badge per-size — sized to match count-badge ratio for visual
159
- parity with other avatar badges (~30-45% of avatar size). Border
160
- width scales with avatar so the "cutout" ring reads at every size. */
161
- .ak-avatar-wrap--md .ak-social-badge { width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); font-size: 10px; border-width: var(--size-ak-badge-border-md); }
162
- .ak-avatar-wrap--lg .ak-social-badge { width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); font-size: 12px; border-width: var(--size-ak-badge-border-lg); }
163
- .ak-avatar-wrap--xl .ak-social-badge { width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); font-size: 14px; border-width: var(--size-ak-badge-border-xl); }
164
- .ak-avatar-wrap--2xl .ak-social-badge { width: var(--size-ak-badge-2xl); height: var(--size-ak-badge-2xl); font-size: 18px; border-width: var(--size-ak-badge-border-2xl); }
165
- .ak-avatar-wrap--3xl .ak-social-badge { width: var(--size-ak-badge-3xl); height: var(--size-ak-badge-3xl); font-size: 22px; border-width: var(--size-ak-badge-border-3xl); }
166
-
167
- /* Status dot offset adjustments for ring avatars — ring (box-shadow) extends
168
- beyond the layout box, so the dot needs to shift outward to sit at the ring edge */
169
- .ak-avatar-wrap--md:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: -2px; right: -2px; }
170
- .ak-avatar-wrap--lg:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: -2px; right: -2px; }
171
- .ak-avatar-wrap--xl:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: 0px; right: 0px; }
172
- .ak-avatar-wrap--2xl:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: 2px; right: 2px; }
173
- .ak-avatar-wrap--3xl:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: 4px; right: 4px; }
174
-
175
- /* Avatar group (stacked/overlapping) */
176
- .ak-avatar-group { display: flex; align-items: center; }
177
- .ak-avatar-group .ak-avatar { position: relative; }
178
- /* White ring only on filled avatars and overflow counter so they
179
- read as separated chips. The "+" add button uses a dashed border
180
- instead — no white ring so the dashes are the only visible edge.
181
- Integer pixel widths to avoid subpixel anti-aliasing. */
182
- .ak-avatar-group .ak-avatar,
183
- .ak-avatar-group .ak-avatar-overflow { box-shadow: 0 0 0 3px var(--color-ak-bg); }
184
- .ak-avatar-group--xl .ak-avatar,
185
- .ak-avatar-group--xl .ak-avatar-overflow { box-shadow: 0 0 0 4px var(--color-ak-bg); }
186
- .ak-avatar-group--2xl .ak-avatar,
187
- .ak-avatar-group--2xl .ak-avatar-overflow { box-shadow: 0 0 0 6px var(--color-ak-bg); }
188
- .ak-avatar-group--3xl .ak-avatar,
189
- .ak-avatar-group--3xl .ak-avatar-overflow { box-shadow: 0 0 0 7px var(--color-ak-bg); }
190
- .ak-avatar-group .ak-avatar:first-child,
191
- .ak-avatar-group .ak-avatar-add:first-child,
192
- .ak-avatar-group .ak-avatar-overflow:first-child { margin-left: 0; }
193
-
194
- /* Hover micro-interaction: diagonal shimmer sweep across the face.
195
- The ::after pseudo is hidden (opacity: 0) at rest so it can never
196
- leak a visible band on dark backgrounds. Hovering triggers a
197
- keyframe animation that slides a soft white gradient across the
198
- circle once, then resets. `overflow: hidden` on .ak-avatar clips
199
- it to the circle so it reads as a sheen, not a square flash.
200
- Skipped under prefers-reduced-motion. */
201
- /* Shimmer is scoped to avatars that contain an <img> (photo avatars) so
202
- static initials/icon avatars don't flash on hover. Works in group
203
- contexts and standalone showcases. */
204
- .ak-avatar:has(img)::after,
205
- .ak-avatar-group .ak-avatar::after,
206
- .ak-avatar-group .ak-avatar-overflow::after {
207
- content: '';
208
- position: absolute;
209
- inset: 0;
210
- border-radius: inherit;
211
- background: linear-gradient(
212
- 110deg,
213
- transparent 30%,
214
- rgba(255, 255, 255, 0.35) 50%,
215
- transparent 70%
216
- );
217
- opacity: 0;
218
- pointer-events: none;
219
- }
220
- .ak-avatar:has(img):hover::after,
221
- .ak-avatar-group .ak-avatar:hover::after,
222
- .ak-avatar-group .ak-avatar-overflow:hover::after {
223
- animation: ak-avatar-shimmer 700ms cubic-bezier(0.4, 0, 0.2, 1);
224
- }
225
- @keyframes ak-avatar-shimmer {
226
- 0% { transform: translateX(-120%); opacity: 1; }
227
- 100% { transform: translateX(120%); opacity: 1; }
228
- }
229
- @media (prefers-reduced-motion: reduce) {
230
- .ak-avatar:has(img):hover::after,
231
- .ak-avatar-group .ak-avatar:hover::after,
232
- .ak-avatar-group .ak-avatar-overflow:hover::after {
233
- animation: none;
234
- }
235
- }
236
-
237
- /* Group size modifiers */
238
- .ak-avatar-group--md .ak-avatar,
239
- .ak-avatar-group--md .ak-avatar-add,
240
- .ak-avatar-group--md .ak-avatar-overflow { margin-left: -8px; }
241
- .ak-avatar-group--md .ak-avatar-overflow { width: var(--size-ak-avatar-md); height: var(--size-ak-avatar-md); font-size: var(--text-ak-avatar-md); font-weight: 600; }
242
- .ak-avatar-group--md .ak-avatar-add { width: var(--size-ak-avatar-md); height: var(--size-ak-avatar-md); }
243
- .ak-avatar-group--md .ak-avatar-add i { font-size: var(--size-ak-icon-md); }
244
-
245
- .ak-avatar-group--lg .ak-avatar,
246
- .ak-avatar-group--lg .ak-avatar-add,
247
- .ak-avatar-group--lg .ak-avatar-overflow { margin-left: -10px; }
248
- .ak-avatar-group--lg .ak-avatar-overflow { width: var(--size-ak-avatar-lg); height: var(--size-ak-avatar-lg); font-size: var(--text-ak-avatar-lg); font-weight: 600; }
249
- .ak-avatar-group--lg .ak-avatar-add { width: var(--size-ak-avatar-lg); height: var(--size-ak-avatar-lg); }
250
- .ak-avatar-group--lg .ak-avatar-add i { font-size: var(--size-ak-icon-lg); }
251
-
252
- .ak-avatar-group--xl .ak-avatar,
253
- .ak-avatar-group--xl .ak-avatar-add,
254
- .ak-avatar-group--xl .ak-avatar-overflow { margin-left: -12px; }
255
- .ak-avatar-group--xl .ak-avatar-overflow { width: var(--size-ak-avatar-xl); height: var(--size-ak-avatar-xl); font-size: var(--text-ak-avatar-xl); font-weight: 500; }
256
- .ak-avatar-group--xl .ak-avatar-add { width: var(--size-ak-avatar-xl); height: var(--size-ak-avatar-xl); }
257
- .ak-avatar-group--xl .ak-avatar-add i { font-size: 1.75rem; }
258
-
259
- .ak-avatar-group--2xl .ak-avatar,
260
- .ak-avatar-group--2xl .ak-avatar-add,
261
- .ak-avatar-group--2xl .ak-avatar-overflow { margin-left: -16px; }
262
- .ak-avatar-group--2xl .ak-avatar-overflow { width: var(--size-ak-avatar-2xl); height: var(--size-ak-avatar-2xl); font-size: var(--text-ak-avatar-2xl); font-weight: 400; }
263
- .ak-avatar-group--2xl .ak-avatar-add { width: var(--size-ak-avatar-2xl); height: var(--size-ak-avatar-2xl); }
264
- .ak-avatar-group--2xl .ak-avatar-add i { font-size: var(--size-ak-icon-2xl); }
265
-
266
- .ak-avatar-group--3xl .ak-avatar,
267
- .ak-avatar-group--3xl .ak-avatar-add,
268
- .ak-avatar-group--3xl .ak-avatar-overflow { margin-left: -20px; }
269
- .ak-avatar-group--3xl .ak-avatar-overflow { width: var(--size-ak-avatar-3xl); height: var(--size-ak-avatar-3xl); font-size: var(--text-ak-avatar-3xl); font-weight: 400; }
270
- .ak-avatar-group--3xl .ak-avatar-add { width: var(--size-ak-avatar-3xl); height: var(--size-ak-avatar-3xl); }
271
- .ak-avatar-group--3xl .ak-avatar-add i { font-size: var(--size-ak-icon-3xl); }
272
-
273
- /* Avatar overflow ("+3" counter) */
274
- .ak-avatar-overflow {
275
- display: flex;
276
- align-items: center;
277
- justify-content: center;
278
- border-radius: var(--radius-ak-full);
279
- background: var(--color-ak-surface-2);
280
- color: var(--color-ak-text-secondary);
281
- font-weight: 600;
282
- cursor: pointer;
283
- transition: background-color var(--duration-ak-fast) var(--ease-ak-default);
284
- /* Clip the shimmer ::after to the circle shape (same reason
285
- .ak-avatar needs overflow:hidden to clip its <img>). */
286
- overflow: hidden;
287
- position: relative;
288
- }
289
- .ak-avatar-overflow:hover { background: var(--color-ak-active); z-index: 5; }
290
- .ak-avatar-overflow:focus-visible {
291
- outline: 2px solid var(--color-ak-border-focus);
292
- outline-offset: 2px;
293
- }
294
-
295
- /* Avatar add button */
296
- .ak-avatar-add {
297
- display: flex;
298
- align-items: center;
299
- justify-content: center;
300
- border-radius: var(--radius-ak-full);
301
- border: 2px dashed var(--color-ak-border);
302
- background: none;
303
- color: var(--color-ak-text-muted);
304
- cursor: pointer;
305
- transition: border-color var(--duration-ak-fast) var(--ease-ak-default),
306
- color var(--duration-ak-fast) var(--ease-ak-default),
307
- background-color var(--duration-ak-fast) var(--ease-ak-default);
308
- }
309
- .ak-avatar-add:hover {
310
- border-color: var(--color-ak-border-strong);
311
- color: var(--color-ak-text);
312
- background: var(--color-ak-hover);
313
- }
314
- .ak-avatar-add:focus-visible {
315
- outline: 2px solid var(--color-ak-border-focus);
316
- outline-offset: 2px;
317
- }
318
-
319
- /* Avatar progress ring */
320
- .ak-avatar-progress { position: relative; display: inline-flex; align-items: center; justify-content: center; }
321
- .ak-avatar-progress--md { width: 56px; height: 56px; }
322
- .ak-avatar-progress--lg { width: 66px; height: 66px; }
323
- .ak-avatar-progress--xl { width: 86px; height: 86px; }
324
- .ak-avatar-progress--2xl { width: 126px; height: 126px; }
325
- .ak-avatar-progress--3xl { width: 166px; height: 166px; }
326
- .ak-avatar-progress--md .ak-progress-ring__track,
327
- .ak-avatar-progress--md .ak-progress-ring__fill { stroke-width: 14; }
328
- .ak-avatar-progress--lg .ak-progress-ring__track,
329
- .ak-avatar-progress--lg .ak-progress-ring__fill { stroke-width: 12; }
330
- .ak-avatar-progress--xl .ak-progress-ring__track,
331
- .ak-avatar-progress--xl .ak-progress-ring__fill { stroke-width: 12; }
332
- .ak-avatar-progress--2xl .ak-progress-ring__track,
333
- .ak-avatar-progress--2xl .ak-progress-ring__fill { stroke-width: 10; }
334
- .ak-avatar-progress--3xl .ak-progress-ring__track,
335
- .ak-avatar-progress--3xl .ak-progress-ring__fill { stroke-width: 8; }
336
-
337
- /* Progress ring SVG */
338
- .ak-progress-ring {
339
- position: absolute;
340
- inset: 0;
341
- width: 100%;
342
- height: 100%;
343
- transform: rotate(-90deg);
344
- }
345
- .ak-progress-ring__track {
346
- fill: none;
347
- stroke: var(--color-ak-border-subtle);
348
- shape-rendering: geometricPrecision;
349
- }
350
- .ak-progress-ring__fill {
351
- fill: none;
352
- stroke: var(--color-ak-primary);
353
- stroke-linecap: round;
354
- shape-rendering: geometricPrecision;
355
- stroke-dasharray: 552.92;
356
- stroke-dashoffset: calc(552.92 - (552.92 * var(--progress, 0) / 100));
357
- transition: stroke-dashoffset 800ms cubic-bezier(0.4, 0, 0.2, 1),
358
- stroke 400ms ease;
359
- }
360
- .ak-progress-ring__fill--primary { stroke: var(--color-ak-primary); }
361
- .ak-progress-ring__fill--success { stroke: var(--color-ak-success); }
362
- .ak-progress-ring__fill--warning { stroke: var(--color-ak-warning); }
363
- .ak-progress-ring__fill--danger { stroke: var(--color-ak-danger); }
364
- .ak-progress-ring__fill--info { stroke: var(--color-ak-info); }
365
-
366
- /* Progress ring shape variants */
367
- .ak-progress-ring--rounded .ak-progress-ring__track,
368
- .ak-progress-ring--rounded .ak-progress-ring__fill { stroke-linecap: round; }
369
- .ak-progress-ring--square .ak-progress-ring__track,
370
- .ak-progress-ring--square .ak-progress-ring__fill { stroke-linecap: square; }
371
- .ak-progress-ring--circle .ak-progress-ring__track,
372
- .ak-progress-ring--circle .ak-progress-ring__fill { stroke-linecap: round; }
373
-
374
- /* Avatar ring (decorative border ring) */
375
- .ak-avatar-ring {
376
- position: absolute;
377
- inset: -3px;
378
- border-radius: var(--radius-ak-full);
379
- border: 2px solid var(--color-ak-primary);
380
- pointer-events: none;
381
- }
382
-
383
- /* Face stack (simpler avatar group variant) */
384
- .ak-faces { display: flex; align-items: center; isolation: isolate; }
385
- .ak-face {
386
- width: 40px;
387
- height: 40px;
388
- margin-left: -10px;
389
- border-radius: var(--radius-ak-full);
390
- overflow: hidden;
391
- outline: 3px solid var(--color-ak-bg);
392
- outline-offset: -0.5px;
393
- flex-shrink: 0;
394
- }
395
- .ak-face:first-child { margin-left: 0; }
396
- .ak-face:nth-child(1) { z-index: 5; }
397
- .ak-face:nth-child(2) { z-index: 4; }
398
- .ak-face:nth-child(3) { z-index: 3; }
399
- .ak-face:nth-child(4) { z-index: 2; }
400
- .ak-face:nth-child(5) { z-index: 1; }
401
- .ak-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
402
- .ak-face--lg { width: 48px; height: 48px; margin-left: -12px; }
403
- .ak-face--lg:first-child { margin-left: 0; }
404
- .ak-face--xl { width: 56px; height: 56px; margin-left: -14px; }
405
- .ak-face--xl:first-child { margin-left: 0; }
406
-
407
-
408
- /* Note: The unlayered override block that was here has been removed.
409
- With @layer gone, the border declarations above now compete with
410
- Tailwind preflight via specificity (.class > *) and win. */
1
+
2
+
3
+ /* Avatar primitives -- base, sizes, colors, shapes, groups, progress, rings, faces */
4
+
5
+
6
+
7
+ /* Avatar base */
8
+ .ak-avatar {
9
+ display: inline-flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+ border-radius: var(--radius-ak-full);
13
+ overflow: hidden;
14
+ position: relative;
15
+ flex-shrink: 0;
16
+ background: var(--color-ak-surface-2);
17
+ color: var(--color-ak-text-secondary);
18
+ font-weight: 600;
19
+ line-height: 1;
20
+ letter-spacing: 0.01em;
21
+ user-select: none;
22
+ -webkit-font-smoothing: antialiased;
23
+ border: none;
24
+ /* Fix jagged circle edge from overflow:hidden + border-radius.
25
+ Inset shadow acts as an AA layer at the clip boundary. */
26
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.04);
27
+ }
28
+ .ak-avatar img {
29
+ width: 100%;
30
+ height: 100%;
31
+ object-fit: cover;
32
+ display: block;
33
+ filter: grayscale(100%);
34
+ }
35
+
36
+ /* Size modifiers */
37
+ .ak-avatar--md { width: var(--size-ak-avatar-md); height: var(--size-ak-avatar-md); font-size: var(--text-ak-avatar-md); font-weight: 600; }
38
+ .ak-avatar--md i { font-size: var(--size-ak-icon-md); }
39
+ .ak-avatar--lg { width: var(--size-ak-avatar-lg); height: var(--size-ak-avatar-lg); font-size: var(--text-ak-avatar-lg); font-weight: 600; }
40
+ .ak-avatar--lg i { font-size: var(--size-ak-icon-lg); }
41
+ .ak-avatar--xl { width: var(--size-ak-avatar-xl); height: var(--size-ak-avatar-xl); font-size: var(--text-ak-avatar-xl); font-weight: 500; }
42
+ .ak-avatar--xl i { font-size: var(--size-ak-icon-xl); }
43
+ .ak-avatar--2xl { width: var(--size-ak-avatar-2xl); height: var(--size-ak-avatar-2xl); font-size: var(--text-ak-avatar-2xl); font-weight: 500; }
44
+ .ak-avatar--2xl i { font-size: var(--size-ak-icon-2xl); }
45
+ .ak-avatar--3xl { width: var(--size-ak-avatar-3xl); height: var(--size-ak-avatar-3xl); font-size: var(--text-ak-avatar-3xl); font-weight: 500; }
46
+ .ak-avatar--3xl i { font-size: var(--size-ak-icon-3xl); }
47
+
48
+ /* Color variants */
49
+ .ak-avatar--primary { background: var(--color-ak-primary); color: var(--color-ak-on-primary); }
50
+ .ak-avatar--success { background: var(--color-ak-success-subtle); color: var(--color-ak-success-text); }
51
+ .ak-avatar--warning { background: var(--color-ak-warning-subtle); color: var(--color-ak-warning-text); }
52
+ .ak-avatar--danger { background: var(--color-ak-danger-subtle); color: var(--color-ak-danger-text); }
53
+ .ak-avatar--info { background: var(--color-ak-info-subtle); color: var(--color-ak-info-text); }
54
+ .ak-avatar--surface { background: var(--color-ak-surface-2); color: var(--color-ak-text-secondary); }
55
+
56
+ /* Shape variants */
57
+ .ak-avatar--rounded { border-radius: var(--radius-ak-lg); }
58
+ .ak-avatar--square { border-radius: var(--radius-ak-sm); }
59
+
60
+ /* Interactive avatar */
61
+ .ak-avatar--interactive {
62
+ cursor: pointer;
63
+ transition: transform var(--duration-ak-fast) var(--ease-ak-default),
64
+ box-shadow var(--duration-ak-fast) var(--ease-ak-default);
65
+ }
66
+ .ak-avatar--interactive:hover { transform: scale(1.08); }
67
+ .ak-avatar--interactive:active { transform: scale(0.96); }
68
+ .ak-avatar--interactive:focus-visible {
69
+ outline: 2px solid var(--color-ak-border-focus);
70
+ outline-offset: 2px;
71
+ }
72
+
73
+ /* Ring variants — outline + box-shadow approach eliminates the subpixel
74
+ bleed artifact that occurs with multi-layer box-shadows.
75
+ - box-shadow: white gap (covers the element edge cleanly)
76
+ - outline: colored ring (separate compositing layer, no bleed) */
77
+ .ak-avatar--ring-primary { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-primary); outline-offset: var(--ak-ring-gap, 3px); }
78
+ .ak-avatar--ring-success { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-success); outline-offset: var(--ak-ring-gap, 3px); }
79
+ .ak-avatar--ring-warning { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-warning); outline-offset: var(--ak-ring-gap, 3px); }
80
+ .ak-avatar--ring-info { box-shadow: 0 0 0 var(--ak-ring-gap, 3px) var(--color-ak-bg); outline: var(--ak-ring-width, 3px) solid var(--color-ak-info); outline-offset: var(--ak-ring-gap, 3px); }
81
+ .ak-avatar--ring-border { box-shadow: 0 0 0 1px var(--color-ak-border); }
82
+
83
+ /* Scale ring per avatar size */
84
+ .ak-avatar--md[class*="ak-avatar--ring-"] { --ak-ring-gap: 2px; --ak-ring-width: 2px; }
85
+ .ak-avatar--lg[class*="ak-avatar--ring-"] { --ak-ring-gap: 2px; --ak-ring-width: 2px; }
86
+ .ak-avatar--xl[class*="ak-avatar--ring-"] { --ak-ring-gap: 2px; --ak-ring-width: 3px; }
87
+ .ak-avatar--2xl[class*="ak-avatar--ring-"] { --ak-ring-gap: 3px; --ak-ring-width: 3px; }
88
+ .ak-avatar--3xl[class*="ak-avatar--ring-"] { --ak-ring-gap: 3px; --ak-ring-width: 4px; }
89
+
90
+ /* Fallback (initials/icon shown when image fails) */
91
+ .ak-avatar__fallback { display: none; }
92
+ .ak-avatar--fallback img { display: none; }
93
+ .ak-avatar--fallback .ak-avatar__fallback {
94
+ display: flex;
95
+ align-items: center;
96
+ justify-content: center;
97
+ width: 100%;
98
+ height: 100%;
99
+ }
100
+
101
+ /* Avatar wrap (positions badges/status relative to avatar) */
102
+ .ak-avatar-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
103
+
104
+ /* Wrap size modifiers for badge/status positioning */
105
+ .ak-avatar-wrap--md .ak-status-dot { width: var(--size-ak-status-md); height: var(--size-ak-status-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); bottom: var(--offset-ak-status-md); right: var(--offset-ak-status-md); }
106
+ .ak-avatar-wrap--md .ak-status-dot--dnd::after { width: 7px; height: 1.5px; }
107
+ .ak-avatar-wrap--md .ak-badge { min-width: var(--size-ak-status-md); height: var(--size-ak-status-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); top: var(--offset-ak-status-md); right: var(--offset-ak-status-md); }
108
+ .ak-avatar-wrap--md .ak-badge--count { min-width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); font-size: var(--text-ak-badge-md); top: var(--offset-ak-badge-md-top, var(--offset-ak-badge-md)); right: var(--offset-ak-badge-md-right, var(--offset-ak-badge-md)); --ak-badge-pad: 2px; }
109
+ .ak-avatar-wrap--md .ak-notif-badge { min-width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); font-size: var(--text-ak-badge-md); top: var(--offset-ak-badge-md); right: var(--offset-ak-badge-md); }
110
+ .ak-avatar-wrap--md .ak-rank-badge { width: var(--size-ak-icon-badge-md); height: var(--size-ak-icon-badge-md); font-size: 0.625rem; border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-md); right: var(--offset-ak-icon-badge-md); }
111
+ .ak-avatar-wrap--md .ak-status-icon { width: var(--size-ak-icon-badge-md); height: var(--size-ak-icon-badge-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-md); right: var(--offset-ak-icon-badge-md); }
112
+ .ak-avatar-wrap--md .ak-status-icon i { font-size: 12px; }
113
+ .ak-avatar-wrap--md .ak-verified-badge { width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); border: var(--size-ak-badge-border-md) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-md-top, var(--offset-ak-badge-md)); right: var(--offset-ak-badge-md-right, var(--offset-ak-badge-md)); }
114
+ .ak-avatar-wrap--md .ak-verified-badge i { font-size: 10px; }
115
+
116
+ .ak-avatar-wrap--lg .ak-status-dot { width: var(--size-ak-status-lg); height: var(--size-ak-status-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); bottom: var(--offset-ak-status-lg); right: var(--offset-ak-status-lg); }
117
+ .ak-avatar-wrap--lg .ak-status-dot--dnd::after { width: 8px; height: 1.5px; }
118
+ .ak-avatar-wrap--lg .ak-badge { min-width: var(--size-ak-status-lg); height: var(--size-ak-status-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); top: var(--offset-ak-status-lg); right: var(--offset-ak-status-lg); }
119
+ .ak-avatar-wrap--lg .ak-badge--count { min-width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); font-size: var(--text-ak-badge-lg); top: var(--offset-ak-badge-lg-top, var(--offset-ak-badge-lg)); right: var(--offset-ak-badge-lg-right, var(--offset-ak-badge-lg)); --ak-badge-pad: 2px; }
120
+ .ak-avatar-wrap--lg .ak-notif-badge { min-width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); font-size: var(--text-ak-badge-lg); top: var(--offset-ak-badge-lg); right: var(--offset-ak-badge-lg); }
121
+ .ak-avatar-wrap--lg .ak-rank-badge { width: var(--size-ak-icon-badge-lg); height: var(--size-ak-icon-badge-lg); font-size: 0.6875rem; border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-lg); right: var(--offset-ak-icon-badge-lg); }
122
+ .ak-avatar-wrap--lg .ak-status-icon { width: var(--size-ak-icon-badge-lg); height: var(--size-ak-icon-badge-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-lg); right: var(--offset-ak-icon-badge-lg); }
123
+ .ak-avatar-wrap--lg .ak-status-icon i { font-size: 13px; }
124
+ .ak-avatar-wrap--lg .ak-verified-badge { width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); border: var(--size-ak-badge-border-lg) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-lg-top, var(--offset-ak-badge-lg)); right: var(--offset-ak-badge-lg-right, var(--offset-ak-badge-lg)); }
125
+ .ak-avatar-wrap--lg .ak-verified-badge i { font-size: 12px; }
126
+
127
+ .ak-avatar-wrap--xl .ak-status-dot { width: var(--size-ak-status-xl); height: var(--size-ak-status-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); bottom: var(--offset-ak-status-xl); right: var(--offset-ak-status-xl); }
128
+ .ak-avatar-wrap--xl .ak-status-dot--dnd::after { width: 9px; height: 2px; }
129
+ .ak-avatar-wrap--xl .ak-badge { min-width: var(--size-ak-status-xl); height: var(--size-ak-status-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); top: var(--offset-ak-status-xl); right: var(--offset-ak-status-xl); }
130
+ .ak-avatar-wrap--xl .ak-badge--count { min-width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); font-size: var(--text-ak-badge-xl); top: var(--offset-ak-badge-xl-top, var(--offset-ak-badge-xl)); right: var(--offset-ak-badge-xl-right, var(--offset-ak-badge-xl)); --ak-badge-pad: 3px; }
131
+ .ak-avatar-wrap--xl .ak-notif-badge { min-width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); font-size: var(--text-ak-badge-xl); top: var(--offset-ak-badge-xl); right: var(--offset-ak-badge-xl); }
132
+ .ak-avatar-wrap--xl .ak-rank-badge { width: var(--size-ak-icon-badge-xl); height: var(--size-ak-icon-badge-xl); font-size: 0.75rem; border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-xl); right: var(--offset-ak-icon-badge-xl); }
133
+ .ak-avatar-wrap--xl .ak-status-icon { width: var(--size-ak-icon-badge-xl); height: var(--size-ak-icon-badge-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-xl); right: var(--offset-ak-icon-badge-xl); }
134
+ .ak-avatar-wrap--xl .ak-status-icon i { font-size: 14px; }
135
+ .ak-avatar-wrap--xl .ak-verified-badge { width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); border: var(--size-ak-badge-border-xl) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-xl-top, var(--offset-ak-badge-xl)); right: var(--offset-ak-badge-xl-right, var(--offset-ak-badge-xl)); }
136
+ .ak-avatar-wrap--xl .ak-verified-badge i { font-size: 14px; }
137
+
138
+ .ak-avatar-wrap--2xl .ak-status-dot { width: var(--size-ak-status-2xl); height: var(--size-ak-status-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); bottom: var(--offset-ak-status-2xl); right: var(--offset-ak-status-2xl); }
139
+ .ak-avatar-wrap--2xl .ak-status-dot--dnd::after { width: 11px; height: 2px; }
140
+ .ak-avatar-wrap--2xl .ak-badge { min-width: var(--size-ak-status-2xl); height: var(--size-ak-status-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); top: var(--offset-ak-status-2xl); right: var(--offset-ak-status-2xl); }
141
+ .ak-avatar-wrap--2xl .ak-badge--count { min-width: var(--size-ak-badge-2xl); height: var(--size-ak-badge-2xl); font-size: var(--text-ak-badge-2xl); top: var(--offset-ak-badge-2xl-top, var(--offset-ak-badge-2xl)); right: var(--offset-ak-badge-2xl-right, var(--offset-ak-badge-2xl)); }
142
+ .ak-avatar-wrap--2xl .ak-rank-badge { width: var(--size-ak-icon-badge-2xl); height: var(--size-ak-icon-badge-2xl); font-size: 0.875rem; border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-2xl); right: var(--offset-ak-icon-badge-2xl); }
143
+ .ak-avatar-wrap--2xl .ak-status-icon { width: var(--size-ak-icon-badge-2xl); height: var(--size-ak-icon-badge-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-2xl); right: var(--offset-ak-icon-badge-2xl); }
144
+ .ak-avatar-wrap--2xl .ak-status-icon i { font-size: 16px; }
145
+ .ak-avatar-wrap--2xl .ak-verified-badge { width: var(--size-ak-badge-2xl); height: var(--size-ak-badge-2xl); border: var(--size-ak-badge-border-2xl) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-2xl-top, var(--offset-ak-badge-2xl)); right: var(--offset-ak-badge-2xl-right, var(--offset-ak-badge-2xl)); }
146
+ .ak-avatar-wrap--2xl .ak-verified-badge i { font-size: 18px; }
147
+
148
+ .ak-avatar-wrap--3xl .ak-status-dot { width: var(--size-ak-status-3xl); height: var(--size-ak-status-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); bottom: var(--offset-ak-status-3xl); right: var(--offset-ak-status-3xl); }
149
+ .ak-avatar-wrap--3xl .ak-status-dot--dnd::after { width: 13px; height: 2.5px; }
150
+ .ak-avatar-wrap--3xl .ak-badge { min-width: var(--size-ak-status-3xl); height: var(--size-ak-status-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); top: var(--offset-ak-status-3xl); right: var(--offset-ak-status-3xl); }
151
+ .ak-avatar-wrap--3xl .ak-badge--count { min-width: var(--size-ak-badge-3xl); height: var(--size-ak-badge-3xl); font-size: var(--text-ak-badge-3xl); top: var(--offset-ak-badge-3xl-top, var(--offset-ak-badge-3xl)); right: var(--offset-ak-badge-3xl-right, var(--offset-ak-badge-3xl)); }
152
+ .ak-avatar-wrap--3xl .ak-rank-badge { width: var(--size-ak-icon-badge-3xl); height: var(--size-ak-icon-badge-3xl); font-size: 1rem; border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); top: var(--offset-ak-icon-badge-3xl); right: var(--offset-ak-icon-badge-3xl); }
153
+ .ak-avatar-wrap--3xl .ak-status-icon { width: var(--size-ak-icon-badge-3xl); height: var(--size-ak-icon-badge-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); bottom: var(--offset-ak-icon-badge-3xl); right: var(--offset-ak-icon-badge-3xl); }
154
+ .ak-avatar-wrap--3xl .ak-status-icon i { font-size: 20px; }
155
+ .ak-avatar-wrap--3xl .ak-verified-badge { width: var(--size-ak-badge-3xl); height: var(--size-ak-badge-3xl); border: var(--size-ak-badge-border-3xl) solid var(--color-ak-bg); bottom: var(--offset-ak-badge-3xl-top, var(--offset-ak-badge-3xl)); right: var(--offset-ak-badge-3xl-right, var(--offset-ak-badge-3xl)); }
156
+ .ak-avatar-wrap--3xl .ak-verified-badge i { font-size: 22px; }
157
+
158
+ /* Social badge per-size — sized to match count-badge ratio for visual
159
+ parity with other avatar badges (~30-45% of avatar size). Border
160
+ width scales with avatar so the "cutout" ring reads at every size. */
161
+ .ak-avatar-wrap--md .ak-social-badge { width: var(--size-ak-badge-md); height: var(--size-ak-badge-md); font-size: 10px; border-width: var(--size-ak-badge-border-md); }
162
+ .ak-avatar-wrap--lg .ak-social-badge { width: var(--size-ak-badge-lg); height: var(--size-ak-badge-lg); font-size: 12px; border-width: var(--size-ak-badge-border-lg); }
163
+ .ak-avatar-wrap--xl .ak-social-badge { width: var(--size-ak-badge-xl); height: var(--size-ak-badge-xl); font-size: 14px; border-width: var(--size-ak-badge-border-xl); }
164
+ .ak-avatar-wrap--2xl .ak-social-badge { width: var(--size-ak-badge-2xl); height: var(--size-ak-badge-2xl); font-size: 18px; border-width: var(--size-ak-badge-border-2xl); }
165
+ .ak-avatar-wrap--3xl .ak-social-badge { width: var(--size-ak-badge-3xl); height: var(--size-ak-badge-3xl); font-size: 22px; border-width: var(--size-ak-badge-border-3xl); }
166
+
167
+ /* Status dot offset adjustments for ring avatars — ring (box-shadow) extends
168
+ beyond the layout box, so the dot needs to shift outward to sit at the ring edge */
169
+ .ak-avatar-wrap--md:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: -2px; right: -2px; }
170
+ .ak-avatar-wrap--lg:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: -2px; right: -2px; }
171
+ .ak-avatar-wrap--xl:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: 0px; right: 0px; }
172
+ .ak-avatar-wrap--2xl:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: 2px; right: 2px; }
173
+ .ak-avatar-wrap--3xl:has([class*="ak-avatar--ring-"]) .ak-status-dot { bottom: 4px; right: 4px; }
174
+
175
+ /* Avatar group (stacked/overlapping) */
176
+ .ak-avatar-group { display: flex; align-items: center; }
177
+ .ak-avatar-group .ak-avatar { position: relative; }
178
+ /* White ring only on filled avatars and overflow counter so they
179
+ read as separated chips. The "+" add button uses a dashed border
180
+ instead — no white ring so the dashes are the only visible edge.
181
+ Integer pixel widths to avoid subpixel anti-aliasing. */
182
+ .ak-avatar-group .ak-avatar,
183
+ .ak-avatar-group .ak-avatar-overflow { box-shadow: 0 0 0 3px var(--color-ak-bg); }
184
+ .ak-avatar-group--xl .ak-avatar,
185
+ .ak-avatar-group--xl .ak-avatar-overflow { box-shadow: 0 0 0 4px var(--color-ak-bg); }
186
+ .ak-avatar-group--2xl .ak-avatar,
187
+ .ak-avatar-group--2xl .ak-avatar-overflow { box-shadow: 0 0 0 6px var(--color-ak-bg); }
188
+ .ak-avatar-group--3xl .ak-avatar,
189
+ .ak-avatar-group--3xl .ak-avatar-overflow { box-shadow: 0 0 0 7px var(--color-ak-bg); }
190
+ .ak-avatar-group .ak-avatar:first-child,
191
+ .ak-avatar-group .ak-avatar-add:first-child,
192
+ .ak-avatar-group .ak-avatar-overflow:first-child { margin-left: 0; }
193
+
194
+ /* Hover micro-interaction: diagonal shimmer sweep across the face.
195
+ The ::after pseudo is hidden (opacity: 0) at rest so it can never
196
+ leak a visible band on dark backgrounds. Hovering triggers a
197
+ keyframe animation that slides a soft white gradient across the
198
+ circle once, then resets. `overflow: hidden` on .ak-avatar clips
199
+ it to the circle so it reads as a sheen, not a square flash.
200
+ Skipped under prefers-reduced-motion. */
201
+ /* Shimmer is scoped to avatars that contain an <img> (photo avatars) so
202
+ static initials/icon avatars don't flash on hover. Works in group
203
+ contexts and standalone showcases. */
204
+ .ak-avatar:has(img)::after,
205
+ .ak-avatar-group .ak-avatar::after,
206
+ .ak-avatar-group .ak-avatar-overflow::after {
207
+ content: '';
208
+ position: absolute;
209
+ inset: 0;
210
+ border-radius: inherit;
211
+ background: linear-gradient(
212
+ 110deg,
213
+ transparent 30%,
214
+ rgba(255, 255, 255, 0.35) 50%,
215
+ transparent 70%
216
+ );
217
+ opacity: 0;
218
+ pointer-events: none;
219
+ }
220
+ .ak-avatar:has(img):hover::after,
221
+ .ak-avatar-group .ak-avatar:hover::after,
222
+ .ak-avatar-group .ak-avatar-overflow:hover::after {
223
+ animation: ak-avatar-shimmer 700ms cubic-bezier(0.4, 0, 0.2, 1);
224
+ }
225
+ @keyframes ak-avatar-shimmer {
226
+ 0% { transform: translateX(-120%); opacity: 1; }
227
+ 100% { transform: translateX(120%); opacity: 1; }
228
+ }
229
+ @media (prefers-reduced-motion: reduce) {
230
+ .ak-avatar:has(img):hover::after,
231
+ .ak-avatar-group .ak-avatar:hover::after,
232
+ .ak-avatar-group .ak-avatar-overflow:hover::after {
233
+ animation: none;
234
+ }
235
+ }
236
+
237
+ /* Group size modifiers */
238
+ .ak-avatar-group--md .ak-avatar,
239
+ .ak-avatar-group--md .ak-avatar-add,
240
+ .ak-avatar-group--md .ak-avatar-overflow { margin-left: -8px; }
241
+ .ak-avatar-group--md .ak-avatar-overflow { width: var(--size-ak-avatar-md); height: var(--size-ak-avatar-md); font-size: var(--text-ak-avatar-md); font-weight: 600; }
242
+ .ak-avatar-group--md .ak-avatar-add { width: var(--size-ak-avatar-md); height: var(--size-ak-avatar-md); }
243
+ .ak-avatar-group--md .ak-avatar-add i { font-size: var(--size-ak-icon-md); }
244
+
245
+ .ak-avatar-group--lg .ak-avatar,
246
+ .ak-avatar-group--lg .ak-avatar-add,
247
+ .ak-avatar-group--lg .ak-avatar-overflow { margin-left: -10px; }
248
+ .ak-avatar-group--lg .ak-avatar-overflow { width: var(--size-ak-avatar-lg); height: var(--size-ak-avatar-lg); font-size: var(--text-ak-avatar-lg); font-weight: 600; }
249
+ .ak-avatar-group--lg .ak-avatar-add { width: var(--size-ak-avatar-lg); height: var(--size-ak-avatar-lg); }
250
+ .ak-avatar-group--lg .ak-avatar-add i { font-size: var(--size-ak-icon-lg); }
251
+
252
+ .ak-avatar-group--xl .ak-avatar,
253
+ .ak-avatar-group--xl .ak-avatar-add,
254
+ .ak-avatar-group--xl .ak-avatar-overflow { margin-left: -12px; }
255
+ .ak-avatar-group--xl .ak-avatar-overflow { width: var(--size-ak-avatar-xl); height: var(--size-ak-avatar-xl); font-size: var(--text-ak-avatar-xl); font-weight: 500; }
256
+ .ak-avatar-group--xl .ak-avatar-add { width: var(--size-ak-avatar-xl); height: var(--size-ak-avatar-xl); }
257
+ .ak-avatar-group--xl .ak-avatar-add i { font-size: 1.75rem; }
258
+
259
+ .ak-avatar-group--2xl .ak-avatar,
260
+ .ak-avatar-group--2xl .ak-avatar-add,
261
+ .ak-avatar-group--2xl .ak-avatar-overflow { margin-left: -16px; }
262
+ .ak-avatar-group--2xl .ak-avatar-overflow { width: var(--size-ak-avatar-2xl); height: var(--size-ak-avatar-2xl); font-size: var(--text-ak-avatar-2xl); font-weight: 400; }
263
+ .ak-avatar-group--2xl .ak-avatar-add { width: var(--size-ak-avatar-2xl); height: var(--size-ak-avatar-2xl); }
264
+ .ak-avatar-group--2xl .ak-avatar-add i { font-size: var(--size-ak-icon-2xl); }
265
+
266
+ .ak-avatar-group--3xl .ak-avatar,
267
+ .ak-avatar-group--3xl .ak-avatar-add,
268
+ .ak-avatar-group--3xl .ak-avatar-overflow { margin-left: -20px; }
269
+ .ak-avatar-group--3xl .ak-avatar-overflow { width: var(--size-ak-avatar-3xl); height: var(--size-ak-avatar-3xl); font-size: var(--text-ak-avatar-3xl); font-weight: 400; }
270
+ .ak-avatar-group--3xl .ak-avatar-add { width: var(--size-ak-avatar-3xl); height: var(--size-ak-avatar-3xl); }
271
+ .ak-avatar-group--3xl .ak-avatar-add i { font-size: var(--size-ak-icon-3xl); }
272
+
273
+ /* Avatar overflow ("+3" counter) */
274
+ .ak-avatar-overflow {
275
+ display: flex;
276
+ align-items: center;
277
+ justify-content: center;
278
+ border-radius: var(--radius-ak-full);
279
+ background: var(--color-ak-surface-2);
280
+ color: var(--color-ak-text-secondary);
281
+ font-weight: 600;
282
+ cursor: pointer;
283
+ transition: background-color var(--duration-ak-fast) var(--ease-ak-default);
284
+ /* Clip the shimmer ::after to the circle shape (same reason
285
+ .ak-avatar needs overflow:hidden to clip its <img>). */
286
+ overflow: hidden;
287
+ position: relative;
288
+ }
289
+ .ak-avatar-overflow:hover { background: var(--color-ak-active); z-index: 5; }
290
+ .ak-avatar-overflow:focus-visible {
291
+ outline: 2px solid var(--color-ak-border-focus);
292
+ outline-offset: 2px;
293
+ }
294
+
295
+ /* Avatar add button */
296
+ .ak-avatar-add {
297
+ display: flex;
298
+ align-items: center;
299
+ justify-content: center;
300
+ border-radius: var(--radius-ak-full);
301
+ border: 2px dashed var(--color-ak-border);
302
+ background: none;
303
+ color: var(--color-ak-text-muted);
304
+ cursor: pointer;
305
+ transition: border-color var(--duration-ak-fast) var(--ease-ak-default),
306
+ color var(--duration-ak-fast) var(--ease-ak-default),
307
+ background-color var(--duration-ak-fast) var(--ease-ak-default);
308
+ }
309
+ .ak-avatar-add:hover {
310
+ border-color: var(--color-ak-border-strong);
311
+ color: var(--color-ak-text);
312
+ background: var(--color-ak-hover);
313
+ }
314
+ .ak-avatar-add:focus-visible {
315
+ outline: 2px solid var(--color-ak-border-focus);
316
+ outline-offset: 2px;
317
+ }
318
+
319
+ /* Avatar progress ring */
320
+ .ak-avatar-progress { position: relative; display: inline-flex; align-items: center; justify-content: center; }
321
+ .ak-avatar-progress--md { width: 56px; height: 56px; }
322
+ .ak-avatar-progress--lg { width: 66px; height: 66px; }
323
+ .ak-avatar-progress--xl { width: 86px; height: 86px; }
324
+ .ak-avatar-progress--2xl { width: 126px; height: 126px; }
325
+ .ak-avatar-progress--3xl { width: 166px; height: 166px; }
326
+ .ak-avatar-progress--md .ak-progress-ring__track,
327
+ .ak-avatar-progress--md .ak-progress-ring__fill { stroke-width: 14; }
328
+ .ak-avatar-progress--lg .ak-progress-ring__track,
329
+ .ak-avatar-progress--lg .ak-progress-ring__fill { stroke-width: 12; }
330
+ .ak-avatar-progress--xl .ak-progress-ring__track,
331
+ .ak-avatar-progress--xl .ak-progress-ring__fill { stroke-width: 12; }
332
+ .ak-avatar-progress--2xl .ak-progress-ring__track,
333
+ .ak-avatar-progress--2xl .ak-progress-ring__fill { stroke-width: 10; }
334
+ .ak-avatar-progress--3xl .ak-progress-ring__track,
335
+ .ak-avatar-progress--3xl .ak-progress-ring__fill { stroke-width: 8; }
336
+
337
+ /* Progress ring SVG */
338
+ .ak-progress-ring {
339
+ position: absolute;
340
+ inset: 0;
341
+ width: 100%;
342
+ height: 100%;
343
+ transform: rotate(-90deg);
344
+ }
345
+ .ak-progress-ring__track {
346
+ fill: none;
347
+ stroke: var(--color-ak-border-subtle);
348
+ shape-rendering: geometricPrecision;
349
+ }
350
+ .ak-progress-ring__fill {
351
+ fill: none;
352
+ stroke: var(--color-ak-primary);
353
+ stroke-linecap: round;
354
+ shape-rendering: geometricPrecision;
355
+ stroke-dasharray: 552.92;
356
+ stroke-dashoffset: calc(552.92 - (552.92 * var(--progress, 0) / 100));
357
+ transition: stroke-dashoffset 800ms cubic-bezier(0.4, 0, 0.2, 1),
358
+ stroke 400ms ease;
359
+ }
360
+ .ak-progress-ring__fill--primary { stroke: var(--color-ak-primary); }
361
+ .ak-progress-ring__fill--success { stroke: var(--color-ak-success); }
362
+ .ak-progress-ring__fill--warning { stroke: var(--color-ak-warning); }
363
+ .ak-progress-ring__fill--danger { stroke: var(--color-ak-danger); }
364
+ .ak-progress-ring__fill--info { stroke: var(--color-ak-info); }
365
+
366
+ /* Progress ring shape variants */
367
+ .ak-progress-ring--rounded .ak-progress-ring__track,
368
+ .ak-progress-ring--rounded .ak-progress-ring__fill { stroke-linecap: round; }
369
+ .ak-progress-ring--square .ak-progress-ring__track,
370
+ .ak-progress-ring--square .ak-progress-ring__fill { stroke-linecap: square; }
371
+ .ak-progress-ring--circle .ak-progress-ring__track,
372
+ .ak-progress-ring--circle .ak-progress-ring__fill { stroke-linecap: round; }
373
+
374
+ /* Avatar ring (decorative border ring) */
375
+ .ak-avatar-ring {
376
+ position: absolute;
377
+ inset: -3px;
378
+ border-radius: var(--radius-ak-full);
379
+ border: 2px solid var(--color-ak-primary);
380
+ pointer-events: none;
381
+ }
382
+
383
+ /* Face stack (simpler avatar group variant) */
384
+ .ak-faces { display: flex; align-items: center; isolation: isolate; }
385
+ .ak-face {
386
+ width: 40px;
387
+ height: 40px;
388
+ margin-left: -10px;
389
+ border-radius: var(--radius-ak-full);
390
+ overflow: hidden;
391
+ outline: 3px solid var(--color-ak-bg);
392
+ outline-offset: -0.5px;
393
+ flex-shrink: 0;
394
+ }
395
+ .ak-face:first-child { margin-left: 0; }
396
+ .ak-face:nth-child(1) { z-index: 5; }
397
+ .ak-face:nth-child(2) { z-index: 4; }
398
+ .ak-face:nth-child(3) { z-index: 3; }
399
+ .ak-face:nth-child(4) { z-index: 2; }
400
+ .ak-face:nth-child(5) { z-index: 1; }
401
+ .ak-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
402
+ .ak-face--lg { width: 48px; height: 48px; margin-left: -12px; }
403
+ .ak-face--lg:first-child { margin-left: 0; }
404
+ .ak-face--xl { width: 56px; height: 56px; margin-left: -14px; }
405
+ .ak-face--xl:first-child { margin-left: 0; }
406
+
407
+
408
+ /* Note: The unlayered override block that was here has been removed.
409
+ With @layer gone, the border declarations above now compete with
410
+ Tailwind preflight via specificity (.class > *) and win. */