sdaia-ui 1.6.4 → 1.6.5

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 (2) hide show
  1. package/dist/index.js +104 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -188,6 +188,89 @@ var GLASS_SURFACE_RULE = `/* \u2500\u2500 Liquid-glass surface \u2500\u2500\u250
188
188
  --ds-glass-bg-dark: rgba(38, 38, 38, 0.92);
189
189
  }
190
190
  }`;
191
+ var MOTION_RULE = `/* \u2500\u2500 SDAIA motion \u2014 voice session + AI activity animations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
192
+ * Consumed by sdaia-ui components (VoiceSession, AiThinkingIndicator,
193
+ * AiStatusIndicator, ThinkingPanel, ToolStatusRow, ToolCallCard,
194
+ * AgentActivity). All collapse to a static, fully readable state under
195
+ * prefers-reduced-motion. */
196
+ @keyframes sdaia-voice-ripple {
197
+ 0% { transform: scale(0.45); opacity: 0.55; }
198
+ 70% { opacity: 0.12; }
199
+ 100% { transform: scale(1); opacity: 0; }
200
+ }
201
+ @keyframes sdaia-voice-breathe {
202
+ 0%, 100% { transform: scale(1); }
203
+ 50% { transform: scale(1.06); }
204
+ }
205
+ @keyframes sdaia-voice-wave {
206
+ 0%, 100% { transform: scaleY(0.32); }
207
+ 50% { transform: scaleY(1); }
208
+ }
209
+
210
+ /* \`backwards\` keeps delayed rings at the faded 0% frame during their
211
+ * animation-delay \u2014 otherwise they flash at full opacity on mount. */
212
+ .voice-ripple { transform-origin: center; animation: sdaia-voice-ripple 2.2s cubic-bezier(0.16, 1, 0.3, 1) infinite backwards; }
213
+ .voice-breathe { animation: sdaia-voice-breathe 2s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
214
+ .voice-wave-bar { transform-origin: center; animation: sdaia-voice-wave 1.1s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
215
+
216
+ @media (prefers-reduced-motion: reduce) {
217
+ .voice-ripple, .voice-breathe, .voice-wave-bar { animation: none !important; }
218
+ .voice-wave-bar { transform: none !important; }
219
+ /* the rings are a solid brand fill (the keyframe fades them) \u2014 settle
220
+ them into a static pale halo when motion is off */
221
+ .voice-ripple { opacity: 0.15; }
222
+ }
223
+
224
+ @keyframes sdaia-ai-shimmer {
225
+ 0% { background-position: 100% 0; }
226
+ 100% { background-position: -100% 0; }
227
+ }
228
+ @keyframes sdaia-ai-dot-bounce {
229
+ 0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
230
+ 30% { opacity: 1; transform: translateY(-3px); }
231
+ }
232
+ @keyframes sdaia-ai-fade-in {
233
+ from { opacity: 0; transform: translateY(4px); }
234
+ to { opacity: 1; transform: none; }
235
+ }
236
+ @keyframes sdaia-ai-rise-in {
237
+ from { opacity: 0; transform: translateY(6px); }
238
+ to { opacity: 1; transform: none; }
239
+ }
240
+
241
+ .ai-shimmer-text {
242
+ background-image: linear-gradient(
243
+ 90deg,
244
+ currentColor 38%,
245
+ color-mix(in srgb, currentColor 30%, transparent) 50%,
246
+ currentColor 62%
247
+ );
248
+ background-size: 200% 100%;
249
+ -webkit-background-clip: text;
250
+ background-clip: text;
251
+ -webkit-text-fill-color: transparent;
252
+ animation: sdaia-ai-shimmer 1.8s linear infinite;
253
+ }
254
+ .ai-shimmer-muted { animation-duration: 2.4s; }
255
+ /* Sweep follows the reading direction. */
256
+ [dir="rtl"] .ai-shimmer-text { animation-direction: reverse; }
257
+
258
+ .ai-dot-bounce { animation: sdaia-ai-dot-bounce 1.2s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
259
+ .ai-fade-in { animation: sdaia-ai-fade-in 0.8s cubic-bezier(0.16, 1, 0.3, 1) both; }
260
+ .ai-rise-in { animation: sdaia-ai-rise-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
261
+
262
+ @media (prefers-reduced-motion: reduce) {
263
+ .ai-shimmer-text {
264
+ animation: none !important;
265
+ background-image: none;
266
+ -webkit-text-fill-color: currentColor;
267
+ }
268
+ .ai-dot-bounce, .ai-fade-in, .ai-rise-in {
269
+ animation: none !important;
270
+ opacity: 1 !important;
271
+ transform: none !important;
272
+ }
273
+ }`;
191
274
  function isTailwindInstalled() {
192
275
  const pkgJsonPath = path3.resolve(process.cwd(), "package.json");
193
276
  if (!fs3.existsSync(pkgJsonPath)) return false;
@@ -254,6 +337,16 @@ ${GLASS_SURFACE_RULE}
254
337
  `);
255
338
  return true;
256
339
  }
340
+ function ensureMotionRule(cssFilePath) {
341
+ const content = fs3.readFileSync(cssFilePath, "utf-8");
342
+ if (/@keyframes\s+sdaia-ai-shimmer\b/.test(content)) return false;
343
+ const trimmed = content.replace(/\s*$/, "");
344
+ fs3.writeFileSync(cssFilePath, `${trimmed}
345
+
346
+ ${MOTION_RULE}
347
+ `);
348
+ return true;
349
+ }
257
350
  async function init() {
258
351
  logger.break();
259
352
  logger.info("Initializing SDAIA Design System in your project...");
@@ -413,13 +506,23 @@ export default config;
413
506
  } else {
414
507
  logger.info("Liquid-glass surface styles already present in CSS file");
415
508
  }
509
+ const addedMotion = ensureMotionRule(cssFilePath);
510
+ if (addedMotion) {
511
+ logger.success(
512
+ `Added voice + AI motion styles to ${path3.relative(process.cwd(), cssFilePath)}`
513
+ );
514
+ } else {
515
+ logger.info("Voice + AI motion styles already present in CSS file");
516
+ }
416
517
  } else {
417
518
  logger.warn(
418
519
  `Could not find a CSS entry file. Add these to your main CSS file:
419
520
  ${TOKENS_IMPORT}
420
521
  ${DARK_VARIANT_RULE}
421
522
 
422
- ${GLASS_SURFACE_RULE}`
523
+ ${GLASS_SURFACE_RULE}
524
+
525
+ ${MOTION_RULE}`
423
526
  );
424
527
  }
425
528
  const utilsPath = path3.resolve(process.cwd(), config.utilsDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdaia-ui",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "CLI for installing SDAIA Design System components into your project",
5
5
  "type": "module",
6
6
  "bin": {