<script lang="ts">
	import { onMount } from 'svelte';
	import { slide } from 'svelte/transition';
	import type { QuickInputItem, CreatePreview } from './types';
	import InputBarContextMenu from './InputBarContextMenu.svelte';
	import { getInputBarSettingsStore } from './inputBarSettings.svelte';

	// Settings store
	const settingsStore = getInputBarSettingsStore();

	// Syntax highlighting patterns for command keywords
	interface HighlightPattern {
		pattern: RegExp;
		className: string;
	}

	const HIGHLIGHT_PATTERNS: HighlightPattern[] = [
		// Priority keywords (Todo) - with specific colors per level
		{ pattern: /(!{3,}|!?dringend)\b/gi, className: 'hl-priority-urgent' },
		{ pattern: /(!{2}|!?wichtig)\b/gi, className: 'hl-priority-high' },
		{ pattern: /!?normal\b/gi, className: 'hl-priority-medium' },
		{ pattern: /!?sp[aä]ter\b/gi, className: 'hl-priority-low' },
		// Tags
		{ pattern: /#\w+/g, className: 'hl-tag' },
		// Projects/Calendars/Companies (@reference)
		{ pattern: /@\w+/g, className: 'hl-reference' },
		// Date keywords
		{
			pattern:
				/\b(heute|morgen|übermorgen|montag|dienstag|mittwoch|donnerstag|freitag|samstag|sonntag|nächsten?\s+\w+|in\s+\d+\s+tagen?)\b/gi,
			className: 'hl-date',
		},
		// Time patterns
		{ pattern: /\b(\d{1,2}:\d{2}|um\s+\d{1,2}(\s*uhr)?|\d{1,2}\s*uhr)\b/gi, className: 'hl-time' },
	];

	function highlightText(text: string): string {
		if (!text) return '';

		let result = text;
		// Escape HTML first
		result = result.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');

		// Apply highlights (process in order, avoiding double-highlighting)
		for (const { pattern, className } of HIGHLIGHT_PATTERNS) {
			result = result.replace(pattern, (match) => `<span class="${className}">${match}</span>`);
		}

		return result;
	}

	interface DefaultOption {
		id: string;
		label: string;
	}

	import type { Snippet } from 'svelte';

	interface Props {
		onSearch: (query: string) => Promise<QuickInputItem[]>;
		onSelect: (item: QuickInputItem) => void;
		onParseCreate?: (query: string) => CreatePreview | null;
		onCreate?: (query: string) => Promise<void>;
		onSearchChange?: (query: string, results: QuickInputItem[]) => void;
		placeholder?: string;
		emptyText?: string;
		searchingText?: string;
		createText?: string;
		appIcon?: string;
		/** Bottom offset from viewport bottom (default: '70px') */
		bottomOffset?: string;
		/** Whether to leave space for a FAB button on the right side on mobile (default: false) */
		hasFabRight?: boolean;
		/** Whether to leave space for a FAB button on the left side on mobile (default: false) */
		hasFabLeft?: boolean;
		/** Enable context menu on right-click (default: true) */
		enableContextMenu?: boolean;
		/** App-specific default options for context menu (e.g., calendars) */
		defaultOptions?: DefaultOption[];
		/** Currently selected default option ID */
		selectedDefaultId?: string;
		/** Label for the default option selector (e.g., "Standard-Kalender") */
		defaultOptionLabel?: string;
		/** Callback when default option changes */
		onDefaultChange?: (id: string) => void;
		/** Callback to show keyboard shortcuts help */
		onShowShortcuts?: () => void;
		/** Callback to show syntax help */
		onShowSyntaxHelp?: () => void;
		/** Snippet for left action button (e.g., voice input) - rendered inside the input bar on the left */
		leftAction?: Snippet;
	}

	let {
		onSearch,
		onSelect,
		onParseCreate,
		onCreate,
		onSearchChange,
		placeholder = 'Suchen oder erstellen...',
		emptyText = 'Keine Ergebnisse gefunden',
		searchingText = 'Suche...',
		createText = 'Erstellen',
		appIcon = 'search',
		bottomOffset = '70px',
		hasFabRight = false,
		hasFabLeft = false,
		enableContextMenu = true,
		defaultOptions = [],
		selectedDefaultId,
		defaultOptionLabel = 'Standard-Kalender',
		onDefaultChange,
		onShowShortcuts,
		onShowSyntaxHelp,
		leftAction,
	}: Props = $props();

	// Use settings for autoFocus
	let effectiveAutoFocus = $derived(settingsStore.autoFocus);

	let searchQuery = $state('');
	let results = $state<QuickInputItem[]>([]);
	let loading = $state(false);
	let creating = $state(false);
	let selectedIndex = $state(0);
	let showPanel = $state(false);
	let isFocused = $state(false);
	let searchTimeout: ReturnType<typeof setTimeout>;
	let inputElement = $state<HTMLInputElement | null>(null);

	// Context menu state
	let contextMenuVisible = $state(false);
	let contextMenuX = $state(0);
	let contextMenuY = $state(0);

	// Computed create preview
	let createPreview = $derived(
		searchQuery.trim() && onParseCreate ? onParseCreate(searchQuery) : null
	);

	// Highlighted text for overlay (respects syntax highlighting setting)
	let highlightedQuery = $derived(
		settingsStore.syntaxHighlighting ? highlightText(searchQuery) : searchQuery
	);

	// Check if create option is selected (it's always first when available)
	let isCreateSelected = $derived(selectedIndex === 0 && createPreview !== null);

	// Show panel only when there's actual input
	$effect(() => {
		showPanel = isFocused && searchQuery.trim().length > 0;
	});

	// Auto-focus on mount (respects autoFocus setting)
	onMount(() => {
		if (effectiveAutoFocus) {
			setTimeout(() => inputElement?.focus(), 100);
		}
	});

	// Listen for external quick-input-set events (e.g., from empty state examples)
	$effect(() => {
		const handler = (e: Event) => {
			const customEvent = e as CustomEvent<{ text: string }>;
			if (customEvent.detail?.text) {
				searchQuery = customEvent.detail.text;
				// Trigger search for the new text
				handleSearch();
				// Focus the input after a short delay
				setTimeout(() => inputElement?.focus(), 50);
			}
		};

		window.addEventListener('quick-input-set', handler);

		return () => {
			window.removeEventListener('quick-input-set', handler);
		};
	});

	// Handler for settings changes (to trigger re-render)
	function handleSettingsChange() {
		// Force reactivity update by accessing the store
		settingsStore.refresh();
	}

	async function handleSearch() {
		clearTimeout(searchTimeout);

		if (!searchQuery.trim()) {
			results = [];
			loading = false;
			onSearchChange?.('', []);
			return;
		}

		loading = true;

		searchTimeout = setTimeout(async () => {
			try {
				results = await onSearch(searchQuery);
				selectedIndex = 0;
				onSearchChange?.(searchQuery, results);
			} catch (e) {
				console.error('Search error:', e);
				results = [];
				onSearchChange?.(searchQuery, []);
			} finally {
				loading = false;
			}
		}, 150);
	}

	async function handleCreate() {
		if (!onCreate || !searchQuery.trim() || creating) return;

		creating = true;
		try {
			await onCreate(searchQuery);
			searchQuery = '';
			results = [];
			selectedIndex = 0;
			onSearchChange?.('', []);
			// Keep focus for rapid entry
			inputElement?.focus();
		} catch (error) {
			console.error('Create error:', error);
		} finally {
			creating = false;
		}
	}

	function handleKeydown(event: KeyboardEvent) {
		if (event.key === 'Escape') {
			event.preventDefault();
			searchQuery = '';
			results = [];
			onSearchChange?.('', []);
			inputElement?.blur();
			return;
		}

		// Cmd/Ctrl+Enter to create directly
		if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {
			event.preventDefault();
			if (onCreate && searchQuery.trim()) {
				handleCreate();
			}
			return;
		}

		if (event.key === 'ArrowDown') {
			event.preventDefault();
			const hasCreate = createPreview !== null;
			const maxIndex = (hasCreate ? 1 : 0) + results.length - 1;
			selectedIndex = Math.min(selectedIndex + 1, Math.max(0, maxIndex));
			return;
		}

		if (event.key === 'ArrowUp') {
			event.preventDefault();
			selectedIndex = Math.max(selectedIndex - 1, 0);
			return;
		}

		if (event.key === 'Enter') {
			event.preventDefault();
			if (searchQuery.trim()) {
				// If create option is selected
				if (isCreateSelected && onCreate) {
					handleCreate();
				} else if (results.length > 0) {
					// Adjust index for results (subtract 1 if create option exists)
					const resultIndex = createPreview !== null ? selectedIndex - 1 : selectedIndex;
					if (resultIndex >= 0 && resultIndex < results.length) {
						selectItem(results[resultIndex]);
					}
				}
			}
			return;
		}
	}

	function selectItem(item: QuickInputItem) {
		onSelect(item);
		searchQuery = '';
		results = [];
		onSearchChange?.('', []);
		inputElement?.blur();
	}

	function getInitials(item: QuickInputItem): string {
		const parts = item.title.split(' ');
		if (parts.length >= 2) {
			return (parts[0][0] + parts[1][0]).toUpperCase();
		}
		return item.title.substring(0, 2).toUpperCase();
	}

	function handleFocus() {
		isFocused = true;
	}

	function handleBlur(event: FocusEvent) {
		// Check if the new focus target is within our component
		const relatedTarget = event.relatedTarget as HTMLElement | null;
		const container = (event.currentTarget as HTMLElement)?.closest('.quick-input-bar');
		if (container && relatedTarget && container.contains(relatedTarget)) {
			return; // Don't close if clicking within the component
		}

		// Delay blur to allow click events to fire
		setTimeout(() => {
			isFocused = false;
		}, 150);
	}

	// Context menu handlers
	function handleContextMenu(event: MouseEvent) {
		if (!enableContextMenu) return;

		event.preventDefault();
		event.stopPropagation();

		contextMenuX = event.clientX;
		contextMenuY = event.clientY;
		contextMenuVisible = true;
	}

	function handleContextMenuClose() {
		contextMenuVisible = false;
	}
</script>

<div
	class="quick-input-bar"
	class:has-fab-right={hasFabRight}
	class:has-fab-left={hasFabLeft}
	style="--bottom-offset: {bottomOffset}"
>
	<!-- Results Panel (above input) -->
	{#if showPanel}
		<div class="results-panel" transition:slide={{ duration: 150 }}>
			{#if searchQuery.trim()}
				<!-- Create option (always first when available) -->
				{#if createPreview && onCreate}
					<button
						type="button"
						class="result-item create-option"
						class:selected={selectedIndex === 0}
						onclick={handleCreate}
						onmouseenter={() => (selectedIndex = 0)}
						disabled={creating}
					>
						<div class="result-avatar create-avatar">
							{#if creating}
								<div class="loading-spinner-small"></div>
							{:else}
								<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M12 4v16m8-8H4"
									/>
								</svg>
							{/if}
						</div>
						<div class="result-info">
							<div class="result-name">{createPreview.title}</div>
							{#if createPreview.subtitle}
								<div class="result-subtitle">{createPreview.subtitle}</div>
							{/if}
						</div>
						<kbd class="create-shortcut">↵</kbd>
					</button>
				{/if}

				{#if loading}
					<div class="loading-state">
						<div class="loading-spinner"></div>
						<span>{searchingText}</span>
					</div>
				{:else if results.length === 0 && !createPreview}
					<div class="empty-state">
						<span>{emptyText}</span>
					</div>
				{:else if results.length > 0}
					<div class="results-divider">
						<span>Suchergebnisse</span>
					</div>
					{#each results as item, index (item.id)}
						{@const adjustedIndex = createPreview ? index + 1 : index}
						<button
							type="button"
							class="result-item"
							class:selected={adjustedIndex === selectedIndex}
							onclick={() => selectItem(item)}
							onmouseenter={() => (selectedIndex = adjustedIndex)}
						>
							<div class="result-avatar">
								{#if item.imageUrl}
									<img src={item.imageUrl} alt={item.title} />
								{:else}
									{getInitials(item)}
								{/if}
							</div>
							<div class="result-info">
								<div class="result-name">{item.title}</div>
								{#if item.subtitle}
									<div class="result-subtitle">{item.subtitle}</div>
								{/if}
							</div>
							{#if item.isFavorite}
								<svg class="favorite-icon" fill="currentColor" viewBox="0 0 24 24">
									<path
										d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
									/>
								</svg>
							{/if}
						</button>
					{/each}
				{/if}
			{/if}
		</div>
	{/if}

	<!-- Input Bar (always visible) -->
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="input-container" oncontextmenu={handleContextMenu}>
		<!-- Left action slot (e.g., voice input button) -->
		{#if leftAction}
			<div class="left-action">
				{@render leftAction()}
			</div>
		{/if}

		<div class="app-icon">
			<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
				{#if appIcon === 'check-square' || appIcon === 'todo'}
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
					/>
				{:else if appIcon === 'calendar'}
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
					/>
				{:else if appIcon === 'users' || appIcon === 'contacts'}
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"
					/>
				{:else}
					<!-- Default search icon -->
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
					/>
				{/if}
			</svg>
		</div>

		<div class="input-wrapper">
			<!-- Highlight backdrop (shows colored keywords) -->
			<div class="input-highlight-backdrop" aria-hidden="true">
				{@html highlightedQuery}&nbsp;
			</div>
			<!-- Actual input (transparent text, visible caret) -->
			<input
				bind:this={inputElement}
				type="text"
				{placeholder}
				bind:value={searchQuery}
				oninput={handleSearch}
				onkeydown={handleKeydown}
				onfocus={handleFocus}
				onblur={handleBlur}
				class="input-field"
			/>
		</div>

		{#if searchQuery.trim() && onCreate}
			<button
				type="button"
				class="submit-btn"
				onclick={handleCreate}
				disabled={creating}
				title={createText}
			>
				{#if creating}
					<div class="loading-spinner-small"></div>
				{:else}
					<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M14 5l7 7m0 0l-7 7m7-7H3"
						/>
					</svg>
				{/if}
			</button>
		{/if}
	</div>

	<!-- Context Menu -->
	<InputBarContextMenu
		visible={contextMenuVisible}
		x={contextMenuX}
		y={contextMenuY}
		onClose={handleContextMenuClose}
		onSettingsChange={handleSettingsChange}
		{defaultOptions}
		{selectedDefaultId}
		{defaultOptionLabel}
		{onDefaultChange}
		{onShowShortcuts}
		{onShowSyntaxHelp}
	/>
</div>

<style>
	.quick-input-bar {
		position: fixed;
		bottom: calc(var(--bottom-offset, 70px) + env(safe-area-inset-bottom, 0px));
		left: 0;
		right: 0;
		z-index: 90;
		padding: 0.75rem 1rem;
		pointer-events: none;
		/* Fixed height to prevent layout shift when results appear */
		height: 72px;
		transition: bottom 0.3s ease;
	}

	/* Leave space for FAB on mobile */
	@media (max-width: 900px) {
		.quick-input-bar.has-fab-right {
			padding-right: calc(54px + 1rem + 0.75rem); /* FAB width + FAB right margin + gap */
		}
		.quick-input-bar.has-fab-left {
			padding-left: calc(54px + 1rem + 0.75rem); /* FAB width + FAB left margin + gap */
		}
	}

	.input-container,
	.results-panel,
	.submit-btn,
	.result-item {
		pointer-events: auto;
	}

	.input-container {
		display: flex;
		align-items: center;
		gap: 0.75rem;
		padding: 0.75rem 1.25rem;
		background: hsl(var(--color-surface) / 0.85);
		backdrop-filter: blur(12px);
		-webkit-backdrop-filter: blur(12px);
		border: 1px solid hsl(var(--color-border));
		border-radius: 9999px;
		max-width: 700px;
		margin: 0 auto;
		box-shadow:
			0 4px 6px -1px hsl(var(--color-foreground) / 0.1),
			0 2px 4px -1px hsl(var(--color-foreground) / 0.06);
		transition: all 0.2s ease;
		/* Fixed height to prevent size changes */
		height: 54px;
	}

	.input-container:focus-within {
		border-color: hsl(var(--color-primary));
		box-shadow:
			0 4px 6px -1px hsl(var(--color-foreground) / 0.1),
			0 2px 4px -1px hsl(var(--color-foreground) / 0.06),
			0 0 0 2px hsl(var(--color-primary) / 0.25);
	}

	.left-action {
		display: flex;
		align-items: center;
		justify-content: center;
		flex-shrink: 0;
	}

	.app-icon {
		width: 1.25rem;
		height: 1.25rem;
		color: hsl(var(--color-muted-foreground));
		flex-shrink: 0;
	}

	.app-icon svg {
		width: 100%;
		height: 100%;
	}

	.input-wrapper {
		position: relative;
		flex: 1;
		min-width: 0;
	}

	.input-highlight-backdrop {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		font-size: 1.125rem;
		font-family: inherit;
		white-space: pre;
		pointer-events: none;
		color: hsl(var(--color-foreground));
		overflow: hidden;
		line-height: 1.5;
	}

	.input-field {
		position: relative;
		width: 100%;
		border: none;
		background: transparent;
		font-size: 1.125rem;
		font-family: inherit;
		color: transparent;
		caret-color: hsl(var(--color-foreground));
		outline: none;
		z-index: 1;
		line-height: 1.5;
	}

	.input-field::placeholder {
		color: hsl(var(--color-muted-foreground));
	}

	/* Syntax highlighting colors - using theme-aware semantic colors */
	.input-highlight-backdrop :global(.hl-priority-urgent) {
		color: hsl(var(--color-error, 0 84% 60%));
		font-weight: 600;
	}

	.input-highlight-backdrop :global(.hl-priority-high) {
		color: hsl(var(--color-warning, 25 95% 53%));
		font-weight: 600;
	}

	.input-highlight-backdrop :global(.hl-priority-medium) {
		color: hsl(var(--color-warning, 48 96% 53%));
		font-weight: 600;
	}

	.input-highlight-backdrop :global(.hl-priority-low) {
		color: hsl(var(--color-success, 142 71% 45%));
		font-weight: 600;
	}

	.input-highlight-backdrop :global(.hl-tag) {
		color: hsl(var(--color-primary));
		font-weight: 500;
	}

	.input-highlight-backdrop :global(.hl-reference) {
		color: hsl(var(--color-success, 142 71% 45%));
		font-weight: 500;
	}

	.input-highlight-backdrop :global(.hl-date) {
		color: hsl(var(--color-accent, 262 83% 58%));
		font-weight: 500;
	}

	.input-highlight-backdrop :global(.hl-time) {
		color: hsl(var(--color-accent, 262 83% 58%));
		font-weight: 500;
	}

	.submit-btn {
		width: 2rem;
		height: 2rem;
		border-radius: 9999px;
		background: hsl(var(--color-primary));
		color: hsl(var(--color-primary-foreground, 0 0% 100%));
		border: none;
		cursor: pointer;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-shrink: 0;
		transition: all 0.15s ease;
	}

	.submit-btn:hover {
		transform: scale(1.05);
		filter: brightness(1.1);
	}

	.submit-btn:disabled {
		opacity: 0.7;
		cursor: not-allowed;
		transform: none;
	}

	.submit-btn svg {
		width: 1rem;
		height: 1rem;
	}

	/* Results Panel */
	.results-panel {
		position: absolute;
		bottom: 100%;
		left: 1rem;
		right: 1rem;
		max-width: 700px;
		margin: 0 auto 0.5rem;
		max-height: 320px;
		overflow-y: auto;
		background: hsl(var(--color-surface) / 0.95);
		backdrop-filter: blur(12px);
		-webkit-backdrop-filter: blur(12px);
		border-radius: 1rem;
		border: 1px solid hsl(var(--color-border));
		box-shadow:
			0 4px 6px -1px hsl(var(--color-foreground) / 0.1),
			0 2px 4px -1px hsl(var(--color-foreground) / 0.06);
	}

	/* Result Items */
	.result-item {
		display: flex;
		align-items: center;
		gap: 0.75rem;
		width: 100%;
		padding: 0.75rem 1rem;
		background: transparent;
		border: none;
		cursor: pointer;
		text-align: left;
		transition: background 0.1s ease;
		color: hsl(var(--color-foreground));
	}

	.result-item:hover,
	.result-item.selected {
		background: hsl(var(--color-surface-hover));
	}

	.result-item.create-option {
		border-bottom: 1px solid hsl(var(--color-border));
	}

	.result-item.create-option:hover,
	.result-item.create-option.selected {
		background: hsl(var(--color-success) / 0.1);
	}

	.result-avatar {
		width: 36px;
		height: 36px;
		min-width: 36px;
		border-radius: 9999px;
		background: hsl(var(--color-primary));
		color: hsl(var(--color-primary-foreground, 0 0% 100%));
		display: flex;
		align-items: center;
		justify-content: center;
		font-weight: 600;
		font-size: 0.8125rem;
	}

	.result-avatar img {
		width: 100%;
		height: 100%;
		border-radius: 9999px;
		object-fit: cover;
	}

	.result-avatar.create-avatar {
		background: hsl(var(--color-success));
	}

	.result-avatar.create-avatar svg {
		width: 1.25rem;
		height: 1.25rem;
	}

	.result-info {
		flex: 1;
		min-width: 0;
	}

	.result-name {
		font-weight: 500;
		color: hsl(var(--color-foreground));
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.result-subtitle {
		font-size: 0.8125rem;
		color: hsl(var(--color-muted-foreground));
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.favorite-icon {
		width: 1rem;
		height: 1rem;
		color: hsl(var(--color-error, 0 84% 60%));
		flex-shrink: 0;
	}

	.create-shortcut {
		padding: 0.25rem 0.5rem;
		font-size: 0.6875rem;
		font-family: inherit;
		background: hsl(var(--color-surface));
		border: 1px solid hsl(var(--color-border));
		border-radius: 4px;
		color: hsl(var(--color-muted-foreground));
		flex-shrink: 0;
	}

	.results-divider {
		padding: 0.5rem 1rem 0.25rem;
		font-size: 0.6875rem;
		font-weight: 500;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		color: hsl(var(--color-muted-foreground));
	}

	/* Loading & Empty States */
	.loading-state,
	.empty-state {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.75rem;
		padding: 2rem;
		color: hsl(var(--color-muted-foreground));
		font-size: 0.875rem;
	}

	.loading-spinner {
		width: 1.25rem;
		height: 1.25rem;
		border: 2px solid hsl(var(--color-border));
		border-top-color: hsl(var(--color-primary));
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

	.loading-spinner-small {
		width: 1rem;
		height: 1rem;
		border: 2px solid hsl(var(--color-border));
		border-top-color: currentColor;
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

	@keyframes spin {
		to {
			transform: rotate(360deg);
		}
	}
</style>
