/* ============================================================================= * Multica shared base styles — imported by all apps * ============================================================================= */ /* Shiki dual themes: CSS-only light/dark switching via CSS variables */ /* @see https://shiki.style/guide/dual-themes */ .shiki, .shiki span { color: var(--shiki-light); } .dark .shiki, .dark .shiki span { color: var(--shiki-dark) !important; } /* Multica icon: entrance spin animation */ @keyframes entrance-spin { 0% { transform: rotate(0deg); opacity: 0; } 50% { opacity: 1; } 100% { transform: rotate(360deg); opacity: 1; } } .animate-entrance-spin { animation: entrance-spin 0.6s ease-out forwards; } /* Onboarding: step / phase entry — 400ms fade + 4px rise. * Matches the design prototype's .fade-in. Applied on mount so every new * step (and intra-step phase switch, via key=phase remount) plays once. * `both` fill-mode commits the `from` styles pre-animation to avoid a * single-frame flash at natural state before the animation grabs. */ @keyframes onboarding-enter { from { opacity: 0; transform: translateY(4px); } } .animate-onboarding-enter { animation: onboarding-enter 0.4s ease both; } /* Onboarding completion: success badge spring-pop. * Lands with a subtle overshoot (scale 1.12 → 1) so the circle feels * physical rather than linearly interpolated. Paired with the drawn * checkmark below which kicks in after the badge has settled. */ @keyframes completion-badge { 0% { transform: scale(0); opacity: 0; } 60% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); opacity: 1; } } .animate-completion-badge { animation: completion-badge 500ms cubic-bezier(0.5, 1.5, 0.4, 1) both; } /* Onboarding completion: SVG checkmark drawn by animating * stroke-dashoffset from 1 → 0. Requires the target to declare * `pathLength={1}` and `strokeDasharray={1}` so the stroke length is * normalized and the animation is geometry-agnostic. */ @keyframes completion-check { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } } .animate-completion-check { animation: completion-check 400ms ease-out 350ms both; } /* Chat FAB: gentle color + border tint while a chat task is running. * Keeps the ring at the same thickness — only hue shifts towards brand * at half-cycle, no outer glow. */ @keyframes chat-impulse { 0%, 100% { color: var(--muted-foreground); box-shadow: 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent); } 50% { color: var(--brand); box-shadow: 0 0 0 1px color-mix(in oklab, var(--brand) 40%, transparent); } } .animate-chat-impulse { animation: chat-impulse 1.6s ease-in-out infinite; } /* Sidebar: open triggers (dropdown/popover) get active background */ [data-sidebar="menu-button"][data-popup-open] { background-color: var(--sidebar-accent); color: var(--sidebar-accent-foreground); } /* Sonner toast: align icon to first line of text, not vertically centered */ [data-sonner-toast] { align-items: flex-start !important; } [data-sonner-toast] [data-icon] { margin-top: 2.5px; } @layer base { * { @apply border-border outline-ring/50; scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); } *::-webkit-scrollbar { width: 6px; height: 6px; } *::-webkit-scrollbar-track { background: var(--scrollbar-track); } *::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 3px; } *::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); } body { @apply bg-background text-foreground; } html { @apply font-sans; /* Auto-insert 1/4em space between CJK ideographs and Latin letters/numerals. * Native CSS text-autospace (Chrome 119+, Electron recent versions). * Progressive enhancement: browsers that don't support it simply ignore the rule. */ text-autospace: ideograph-alpha ideograph-numeric; } }