Files
wehub-resource-sync c48612c494
CI / E2E Tests (push) Waiting to run
CI / Lint, Typecheck & Unit Tests (push) Waiting to run
Docs Build / Build docs site (push) Waiting to run
Publish @openmaic packages / Build, validate & publish (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:03:23 +08:00

571 lines
19 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import 'tailwindcss';
@import 'tw-animate-css';
@import 'shadcn/tailwind.css';
/* Streamdown (AI sidebar markdown) styles itself with Tailwind utilities —
Tailwind must scan its dist so those classes get generated. */
@source '../node_modules/streamdown/dist/*.js';
@source '../node_modules/@streamdown/code/dist/*.js';
@source "../node_modules/@openmaic/renderer/dist/**/*.{js,cjs}";
/* slide-renderer-demo is gitignored (local sandbox), which makes Tailwind v4's
auto source detection skip it. Re-include it explicitly so the demo's
Tailwind classes (e.g. bg-violet-600) still get generated. */
@source "./slide-renderer-demo/**/*.{tsx,ts,jsx,js}";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-sans);
--font-mono: var(--font-geist-mono);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--radius-2xl: calc(var(--radius) + 8px);
--radius-3xl: calc(var(--radius) + 12px);
--radius-4xl: calc(var(--radius) + 16px);
}
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: #722ed1;
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.58 0.22 27);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.809 0.105 251.813);
--chart-2: oklch(0.623 0.214 259.815);
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: #8b47ea;
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.371 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.809 0.105 251.813);
--chart-2: oklch(0.623 0.214 259.815);
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
html {
/* Always render the vertical scrollbar so layout doesn't horizontally
shift when content grows/shrinks across the viewport-height threshold
(e.g. expanding/collapsing recent classrooms). scrollbar-gutter:
stable doesn't cover every browser/config combo we see, so fall back
to forcing overflow-y: scroll as well. */
scrollbar-gutter: stable;
overflow-y: scroll;
}
body {
@apply bg-background text-foreground;
}
/* Radix modal overlays wrap with `react-remove-scroll`, which compensates
for the removed page scrollbar by adding right-side body spacing. This
app already reserves the scrollbar gutter on <html> (above), so that
extra compensation creates a visible horizontal layout shift when opening
Settings on the homepage/classroom shells. Keep Radix's modal focus and
interaction locking, but neutralize only the redundant gap compensation. */
body[data-maic-editor='true'],
body[data-scroll-locked] {
padding-right: 0 !important;
margin-right: 0 !important;
}
}
/* ProseMirror Editor Styles */
.prosemirror-editor {
cursor: text;
}
/* The slide editor draws a text element's frame via the renderer's Operate
layer. The focused contenteditable must not also paint a UA focus ring on
top of it (the base `* { @apply outline-ring/50 }` rule gives every focused
element an outline). `.prosemirror-editor` is an editor-only class —
playback's BaseTextElement never carries it, so playback is unaffected. */
.prosemirror-editor :focus,
.prosemirror-editor :focus-visible {
outline: none;
}
/* Tailwind's preflight resets `list-style: none` and `padding: 0` on
`<ul>`/`<ol>`. The text element's `bulletList` / `orderedList` commands
genuinely wrap content in `<ul><li>` / `<ol><li>`, but without those
resets undone no marker would be visible. `!important` defeats any
layered preflight specificity we'd otherwise have to chase.
`.editable-element-text` is the PLAYBACK text wrapper, rendered for every
classroom/playback user — not just in the editor. So its rules MUST be
scoped to editor mode (`body[data-maic-editor='true']`, set by
EditChromeRoot while Pro mode is mounted) to keep flag-off playback
rendering byte-unchanged: the editor surface isn't GA yet, so playback
display of editor-authored lists is deferred. Scoping keeps list markers
visible while editing (the user needs to see their bullets) without
altering how the same wrapper renders during normal playback for all
users. `.prosemirror-editor` is an editor-only class already (playback's
BaseTextElement never carries it), so it stays unscoped. */
body[data-maic-editor='true'] .editable-element-text ul,
.prosemirror-editor ul {
list-style: disc outside !important;
padding-inline-start: 1.5rem !important;
}
body[data-maic-editor='true'] .editable-element-text ol,
.prosemirror-editor ol {
list-style: decimal outside !important;
padding-inline-start: 1.5rem !important;
}
body[data-maic-editor='true'] .editable-element-text li,
.prosemirror-editor li {
display: list-item !important;
}
/* Compact react-colorful for the slide editor's color popover. Defaults are
a 200×200 square with a thick separator — we squeeze it tight + round it
so the popover feels intentional, not stock. */
.color-picker .react-colorful {
width: 100%;
height: auto;
}
.color-picker .react-colorful__saturation {
height: 128px;
border-radius: 6px;
border-bottom: none;
}
.color-picker .react-colorful__hue {
height: 10px;
margin-top: 10px;
border-radius: 999px;
}
.color-picker .react-colorful__pointer {
width: 14px;
height: 14px;
border-width: 2px;
}
.prosemirror-editor.format-painter {
cursor:
url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMzUuMDEybC0uMDY2Ljk5OGE1LjI3MSA1LjI3MSAwIDAwLTEuMTg0LjA2IDMuOCAzLjggMCAwMC0uOTMzLjQ3MmMtLjQ0LjM1Ni0uNzgzLjgxMS0uOTk4IDEuMzI0bC4wMTgtLjAzNnY1LjEySDEuMDR2Ljk4aC0xLjA0bC0uMDAyIDQuMTVjLjE4Ny40MjYuNDYuODEuNzkxIDEuMTE3bC4xNzUuMTUyYy4yOTMuMjA4LjYxNS4zNzMuODkuNDcyLjQxLjA4Mi44My4xMTIgMS4yNDkuMDlsLjA1Ny45OTlhNi4wNjMgNi4wNjMgMCAwMS0xLjU4OC0uMTI5IDQuODM2IDQuODM2IDAgMDEtMS4yNS0uNjQ3IDQuNDYzIDQuNDYzIDAgMDEtLjgzOC0uODgzYy0uMjI0LjMzMi0uNS42NDItLjgyNC45MjdhNC4xMSA0LjExIDAgMDEtMS4zMDUuNjMzQTYuMTI2IDYuMTI2IDAgMDEwIDE1LjkwOWwuMDY4LS45OTdjLjQyNC4wMjYuODUtLjAwMSAxLjIxNy0uMDcuMzM2LS4wOTkuNjUxLS4yNTQuODk0LS40My40My0uMzguNzY1LS44NDcuOTgyLTEuMzY4bC0uMDA1LjAxNFY4LjkzSDIuMTE1di0uOThoMS4wNFYyLjg2MmEzLjc3IDMuNzcgMCAwMC0uNzc0LTEuMTY3bC0uMTY1LS4xNTZhMy4wNjQgMy4wNjQgMCAwMC0uODgtLjQ0OEE1LjA2MiA1LjA2MiAwIDAwLjA2NyAxLjAxTDAgLjAxMmE2LjE0IDYuMTQgMCAwMTEuNTkyLjExYy40NTMuMTM1Ljg3Ny4zNDUgMS4yOS42NS4zLjI2NS41NjUuNTY0Ljc4Ny44OS4yMzMtLjMzMS41Mi0uNjM0Ljg1My0uOTA0YTQuODM1IDQuODM1IDAgMDExLjMtLjY0OEE2LjE1NSA2LjE1NSAwIDAxNy4zNS4wMTJ6IiBmaWxsPSIjMEQwRDBEIi8+PHBhdGggZD0iTTE3LjM1IDE0LjVsNC41LTQuNS02LTZjLTIgMi0zIDItNS41IDIuNS40IDMuMiA0LjgzMyA2LjY2NyA3IDh6bTQuNTg4LTQuNDkzYS4zLjMgMCAwMC40MjQgMGwuNjgtLjY4YTEuNSAxLjUgMCAwMDAtMi4xMjJMMjEuNjkgNS44NTNsMi4wMjUtMS41ODNhMS42MjkgMS42MjkgMCAxMC0yLjI3OS0yLjI5NmwtMS42MDMgMi4wMjItMS4zNTctMS4zNTdhMS41IDEuNSAwIDAwLTIuMTIxIDBsLS42OC42OGEuMy4zIDAgMDAwIC40MjVsNi4yNjMgNi4yNjN6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTE1Ljg5MiAzLjk2MnMtMS4wMyAxLjIwMi0yLjQ5NCAxLjg5Yy0xLjAwNi40NzQtMi4xOC41ODYtMi43MzQuNjI3LS4yLjAxNS0uMzQ0LjIxLS4yNzYuMzk5LjI5Mi44MiAxLjExMiAyLjggMi42NTggNC4zNDYgMi4xMjYgMi4xMjcgMy42NTggMi45NjggNC4xNDIgMy4yMDMuMS4wNDguMjE0LjAzLjI5OC0uMDQyLjM4Ni0uMzI1IDEuNS0xLjI3NyAyLjIxLTEuOTg2Ljg5Mi0uODg5IDIuMTg3LTIuNDQ3IDIuMTg3LTIuNDQ3bS40NzkuMDU1YS4zLjMgMCAwMS0uNDI0IDBsLTYuMjY0LTYuMjYzYS4zLjMgMCAwMTAtLjQyNWwuNjgtLjY4YTEuNSAxLjUgMCAwMTIuMTIyIDBsMS4zNTcgMS4zNTcgMS42MDMtMi4wMjJhMS42MjkgMS42MjkgMCAxMTIuMjggMi4yOTZMMjEuNjkgNS44NTNsMS4zNTIgMS4zNTJhMS41IDEuNSAwIDAxMCAyLjEyMmwtLjY4LjY4eiIgc3Ryb2tlPSIjMzMzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+')
2 5,
default !important;
}
/* Animation for audio visualizer */
@keyframes wave {
0%,
100% {
height: 30%;
}
50% {
height: 100%;
}
}
/* Breathing bars for presentation speech bubbles (parent is h-3.5 = 14px) */
@keyframes breathing-bar-1 {
0%,
100% {
height: 3px;
}
50% {
height: 14px;
}
}
@keyframes breathing-bar-2 {
0%,
100% {
height: 6px;
}
50% {
height: 14px;
}
}
@keyframes breathing-bar-3 {
0%,
100% {
height: 3px;
}
50% {
height: 11px;
}
}
/* Hide scrollbar by default, show on hover */
@utility scrollbar-hide {
&::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none;
scrollbar-width: none;
}
/* PBL v2 workspace scrollbars: scoped so the rest of OpenMAIC keeps native behavior. */
[data-pbl-workspace='true'] .pbl-v2-scrollbar,
[data-pbl-workspace='true'] .pbl-v2-scroll-fade {
scrollbar-color: rgb(224 231 255 / 0.44) transparent;
scrollbar-gutter: stable;
scrollbar-width: thin;
}
[data-pbl-workspace='true'] .pbl-v2-scrollbar::-webkit-scrollbar,
[data-pbl-workspace='true'] .pbl-v2-scroll-fade::-webkit-scrollbar {
height: 10px;
width: 10px;
}
[data-pbl-workspace='true'] .pbl-v2-scrollbar::-webkit-scrollbar-track,
[data-pbl-workspace='true'] .pbl-v2-scroll-fade::-webkit-scrollbar-track {
background: transparent;
border-radius: 999px;
}
[data-pbl-workspace='true'] .pbl-v2-scrollbar::-webkit-scrollbar-corner,
[data-pbl-workspace='true'] .pbl-v2-scroll-fade::-webkit-scrollbar-corner {
background: transparent;
}
[data-pbl-workspace='true'] .pbl-v2-scrollbar::-webkit-scrollbar-thumb,
[data-pbl-workspace='true'] .pbl-v2-scroll-fade::-webkit-scrollbar-thumb {
background-color: rgb(224 231 255 / 0.38);
background: linear-gradient(
180deg,
rgb(224 231 255 / 0.08) 0,
rgb(224 231 255 / 0.26) 15%,
rgb(199 210 254 / 0.5) 34%,
rgb(165 243 252 / 0.42) 52%,
rgb(199 210 254 / 0.5) 70%,
rgb(224 231 255 / 0.26) 86%,
rgb(224 231 255 / 0.08) 100%
)
content-box;
background-clip: content-box;
border: 3px solid transparent;
border-radius: 999px;
min-height: 48px;
box-shadow:
inset 0 0 0 1px rgb(255 255 255 / 0.06),
0 0 12px rgb(125 211 252 / 0.16);
}
[data-pbl-workspace='true'] .pbl-v2-scrollbar::-webkit-scrollbar-thumb:hover,
[data-pbl-workspace='true'] .pbl-v2-scroll-fade::-webkit-scrollbar-thumb:hover {
background: linear-gradient(
180deg,
rgb(224 231 255 / 0.12) 0,
rgb(224 231 255 / 0.34) 14%,
rgb(216 203 255 / 0.62) 32%,
rgb(165 243 252 / 0.5) 52%,
rgb(216 203 255 / 0.62) 70%,
rgb(224 231 255 / 0.34) 86%,
rgb(224 231 255 / 0.12) 100%
)
content-box;
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown {
color: rgb(51 65 85);
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown :where(p, li, blockquote) {
color: rgb(51 65 85);
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown :where(strong, b) {
color: rgb(15 23 42);
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown :where(code):not(pre code) {
background: rgb(226 232 240 / 0.9);
border: 1px solid rgb(148 163 184 / 0.28);
border-radius: 0.375rem;
color: rgb(30 41 59);
font-weight: 600;
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown div[data-streamdown='code-block'] {
border-color: rgb(148 163 184 / 0.22);
box-shadow: 0 12px 24px rgb(15 23 42 / 0.16);
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown div[data-streamdown='code-block-body'],
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown div[data-streamdown='code-block-body'] pre {
background: rgb(15 23 42) !important;
color: rgb(248 250 252) !important;
}
[data-pbl-workspace='true'] .pbl-v2-light-card-markdown div[data-streamdown='code-block-body'] code,
[data-pbl-workspace='true']
.pbl-v2-light-card-markdown
div[data-streamdown='code-block-body']
span {
color: rgb(248 250 252) !important;
}
[data-pbl-workspace='true'] .pbl-v2-task-review-markdown :where(code):not(pre code) {
background: rgb(255 255 255 / 0.34);
border: 1px solid rgb(165 180 252 / 0.34);
box-shadow:
inset 0 1px 0 rgb(255 255 255 / 0.35),
0 6px 14px rgb(51 65 85 / 0.1);
color: rgb(36 50 76);
}
[data-pbl-workspace='true'] .pbl-v2-task-review-markdown :where(li)::marker {
color: rgb(99 102 241 / 0.65);
}
[data-pbl-workspace='true'] .pbl-v2-instructor-bubble {
position: relative;
overflow: hidden;
border: 1px solid rgb(147 197 253 / 0.2);
background:
radial-gradient(circle at 8% 0%, rgb(157 140 255 / 0.16), transparent 34%),
radial-gradient(circle at 96% 15%, rgb(34 211 238 / 0.1), transparent 30%),
linear-gradient(145deg, rgb(22 35 62 / 0.78), rgb(17 31 56 / 0.72) 58%, rgb(15 28 50 / 0.8));
box-shadow:
inset 0 1px 0 rgb(255 255 255 / 0.1),
inset 0 0 0 1px rgb(255 255 255 / 0.025),
0 18px 42px rgb(3 10 26 / 0.32),
0 0 34px rgb(96 165 250 / 0.08);
backdrop-filter: blur(18px);
}
[data-pbl-workspace='true'] .pbl-v2-instructor-bubble::before {
content: '';
position: absolute;
inset: 0 0 auto;
height: 1px;
background: linear-gradient(
90deg,
transparent,
rgb(165 180 252 / 0.55),
rgb(103 232 249 / 0.34),
transparent
);
}
[data-pbl-workspace='true'] .pbl-v2-instructor-bubble::after {
content: '';
position: absolute;
right: -48px;
top: -48px;
height: 120px;
width: 120px;
border-radius: 999px;
background: rgb(125 211 252 / 0.08);
filter: blur(20px);
}
[data-pbl-workspace='true'] .pbl-v2-instructor-bubble > * {
position: relative;
z-index: 1;
}
[data-pbl-workspace='true'] .pbl-v2-instructor-label {
color: rgb(165 180 252 / 0.82);
letter-spacing: 0.04em;
}
[data-pbl-workspace='true'] .pbl-v2-task-review-shell {
position: relative;
overflow: hidden;
border: 1px solid rgb(199 210 254 / 0.55);
background:
radial-gradient(circle at 12% 0%, rgb(167 139 250 / 0.26), transparent 34%),
radial-gradient(circle at 92% 12%, rgb(103 232 249 / 0.2), transparent 28%),
linear-gradient(
145deg,
rgb(245 243 255 / 0.7),
rgb(239 246 255 / 0.5) 54%,
rgb(236 254 255 / 0.56)
);
box-shadow:
inset 0 1px 0 rgb(255 255 255 / 0.65),
0 20px 54px rgb(3 10 26 / 0.3),
0 0 0 1px rgb(139 92 246 / 0.12),
0 0 42px rgb(99 102 241 / 0.14);
backdrop-filter: blur(20px) saturate(1.08);
}
[data-pbl-workspace='true'] .pbl-v2-task-review-shell::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background:
linear-gradient(135deg, rgb(255 255 255 / 0.5), transparent 34%),
linear-gradient(90deg, rgb(167 139 250 / 0.72), rgb(103 232 249 / 0.42), transparent) top / 100%
1px no-repeat;
}
[data-pbl-workspace='true'] .pbl-v2-task-review-shell > * {
position: relative;
z-index: 1;
}
[data-pbl-workspace='true'] .pbl-v2-task-review-card {
border: 1px solid rgb(199 210 254 / 0.52);
background:
linear-gradient(
145deg,
rgb(255 255 255 / 0.48),
rgb(238 242 255 / 0.34),
rgb(236 254 255 / 0.3)
),
rgb(255 255 255 / 0.2);
box-shadow:
inset 0 1px 0 rgb(255 255 255 / 0.58),
0 16px 38px rgb(4 20 28 / 0.14),
0 0 30px rgb(129 140 248 / 0.12);
backdrop-filter: blur(12px) saturate(1.05);
}
/* Shimmer sweep for skeleton loading */
@keyframes shimmer {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
/* Breathing animation for interactive mode button */
@keyframes interactive-mode-breathe {
0%,
100% {
opacity: 0.3;
transform: scale(1);
}
50% {
opacity: 0.7;
transform: scale(1.08);
}
}
/* PBL v2 — thinking dots pulse (wider swing for visibility on dark bg) */
@keyframes think-dot-pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.15;
}
}
/* Cursor-style "Thinking…" indicator: a bright band sweeps left→right across
muted text (gradient clipped to glyphs). Used by the AI sidebar while the
agent run streams and nothing has arrived yet. */
@keyframes ai-thinking-shimmer {
0% {
background-position: 150% 0;
}
100% {
background-position: -50% 0;
}
}
.ai-thinking-shimmer {
background: linear-gradient(
100deg,
var(--muted-foreground) 0%,
var(--muted-foreground) 40%,
var(--foreground) 50%,
var(--muted-foreground) 60%,
var(--muted-foreground) 100%
);
background-size: 200% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
animation: ai-thinking-shimmer 1.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.ai-thinking-shimmer {
animation: none;
color: var(--muted-foreground);
-webkit-text-fill-color: var(--muted-foreground);
}
}