<script lang="ts">
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { connectionState, nodeStore, edgeStore, nodeAccessStore, nodeVisibility } from '$lib/realtime';
	import type { Node } from '$lib/realtime';
	import { fetchMyWorkspace, updateNode } from '$lib/api';

	// Canvas + BlockShell
	import Canvas from '$lib/components/canvas/Canvas.svelte';
	import type { CanvasObject } from '$lib/components/canvas/types.js';
	import BlockShell from '$lib/components/blockshell/BlockShell.svelte';

	// Workspace layout
	import {
		type PanelLayout,
		type WorkspaceLayout,
		getPanelInfo,
		TRAIT_PANEL_INFO,
		PANEL_HEADER_HEIGHT,
	} from '$lib/workspace/types.js';

	// Recency tracking for context selector
	import { getRankedNodeIds } from '$lib/workspace/recency.js';

	// Trait components (reuse from collection page)
	import EditorTrait from '$lib/components/traits/EditorTrait.svelte';
	import ChatTrait from '$lib/components/traits/ChatTrait.svelte';
	import KanbanTrait from '$lib/components/traits/KanbanTrait.svelte';
	import PodcastTrait from '$lib/components/traits/PodcastTrait.svelte';
	import PublishingTrait from '$lib/components/traits/PublishingTrait.svelte';
	import RssTrait from '$lib/components/traits/RssTrait.svelte';
	import CalendarTrait from '$lib/components/traits/CalendarTrait.svelte';
	import RecordingTrait from '$lib/components/traits/RecordingTrait.svelte';
	import TranscriptionTrait from '$lib/components/traits/TranscriptionTrait.svelte';
	import StudioTrait from '$lib/components/traits/StudioTrait.svelte';
	import MixerTrait from '$lib/components/traits/MixerTrait.svelte';
	import GenericTrait from '$lib/components/traits/GenericTrait.svelte';
	import AiToolPanel from '$lib/components/AiToolPanel.svelte';
	import { createBlockReceiver, executeTransfer, resolveTransferMode, type DragPayload } from '$lib/transfer';
	import type { BlockReceiver } from '$lib/components/blockshell/types';

	const session = $derived($page.data.session as Record<string, unknown> | undefined);
	const nodeId = $derived(session?.nodeId as string | undefined);
	const accessToken = $derived(session?.accessToken as string | undefined);
	const connected = $derived(connectionState.current === 'connected');

	// =========================================================================
	// Workspace node (fetched from backend)
	// =========================================================================

	let workspaceNodeId = $state<string | undefined>(undefined);
	let workspaceLoading = $state(true);
	let workspaceError = $state<string | undefined>(undefined);

	// Fetch or create workspace on load
	$effect(() => {
		if (!accessToken) return;
		workspaceLoading = true;
		fetchMyWorkspace(accessToken)
			.then((res) => {
				workspaceNodeId = res.node_id;
				// Initialize layout from backend metadata if we don't have one yet
				if (!layoutInitialized && res.metadata?.workspace_layout) {
					const saved = res.metadata.workspace_layout as WorkspaceLayout;
					if (saved.panels && Array.isArray(saved.panels) && saved.panels.length > 0) {
						layout = saved;
					}
					layoutInitialized = true;
				} else if (!layoutInitialized) {
					layoutInitialized = true;
				}
			})
			.catch((err) => {
				workspaceError = err.message;
			})
			.finally(() => {
				workspaceLoading = false;
			});
	});

	// Also try to read layout from WS node store (for real-time sync)
	const workspaceNode = $derived(
		workspaceNodeId && connected ? nodeStore.get(workspaceNodeId) : undefined
	);

	// =========================================================================
	// Layout state
	// =========================================================================

	let layout = $state<WorkspaceLayout>({ panels: [] });
	let layoutInitialized = $state(false);

	// When workspace node appears in store (after creation), load its layout
	$effect(() => {
		if (!workspaceNode || layoutInitialized) return;
		try {
			const meta = JSON.parse(workspaceNode.metadata ?? '{}');
			if (meta.workspace_layout?.panels?.length > 0) {
				layout = meta.workspace_layout as WorkspaceLayout;
			}
		} catch { /* ignore */ }
		layoutInitialized = true;
	});

	/** Convert layout panels to CanvasObjects */
	const canvasObjects = $derived<CanvasObject[]>(
		layout.panels.map(p => ({
			id: p.trait,
			x: p.x,
			y: p.y,
			width: p.width,
			height: p.minimized ? PANEL_HEADER_HEIGHT : p.height,
		}))
	);

	// =========================================================================
	// Layout persistence (debounced save to workspace node metadata)
	// =========================================================================

	let saveTimeout: ReturnType<typeof setTimeout> | undefined;

	function persistLayout() {
		if (!accessToken || !workspaceNodeId) return;
		clearTimeout(saveTimeout);
		saveTimeout = setTimeout(async () => {
			try {
				// Read current metadata from node store
				const currentMeta = workspaceNode
					? JSON.parse(workspaceNode.metadata ?? '{}')
					: {};
				await updateNode(accessToken!, {
					node_id: workspaceNodeId!,
					metadata: {
						...currentMeta,
						workspace_layout: layout,
					},
				});
			} catch (err) {
				console.warn('Failed to persist workspace layout:', err);
			}
		}, 1000);
	}

	function handleObjectMove(id: string, x: number, y: number) {
		const idx = layout.panels.findIndex(p => p.trait === id);
		if (idx >= 0) {
			layout.panels[idx] = { ...layout.panels[idx], x, y };
			layout = { ...layout };
			persistLayout();
		}
	}

	function handlePanelResize(trait: string, width: number, height: number) {
		const idx = layout.panels.findIndex(p => p.trait === trait);
		if (idx >= 0) {
			layout.panels[idx] = { ...layout.panels[idx], width, height };
			layout = { ...layout };
			persistLayout();
		}
	}

	function handlePanelClose(trait: string) {
		layout = {
			panels: layout.panels.filter(p => p.trait !== trait),
		};
		persistLayout();
	}

	function handlePanelMinimize(trait: string, isMinimized: boolean) {
		const idx = layout.panels.findIndex(p => p.trait === trait);
		if (idx >= 0) {
			layout.panels[idx] = { ...layout.panels[idx], minimized: isMinimized };
			layout = { ...layout };
			persistLayout();
		}
	}

	function handleAddPanel(trait: string) {
		if (layout.panels.some(p => p.trait === trait)) return;
		const info = getPanelInfo(trait);
		const maxY = layout.panels.length > 0
			? Math.max(...layout.panels.map(p => p.y + p.height))
			: 0;
		layout = {
			panels: [
				...layout.panels,
				{
					trait,
					x: 30,
					y: maxY + 30,
					width: info.defaultWidth,
					height: info.defaultHeight,
				},
			],
		};
		persistLayout();
	}

	const activeLayoutTraits = $derived(layout.panels.map(p => p.trait));

	// =========================================================================
	// Context selector (navigate to collections)
	// =========================================================================

	let selectorOpen = $state(false);
	let searchQuery = $state('');
	let searchInput = $state<HTMLInputElement | undefined>(undefined);

	const collectionNodes = $derived.by((): Node[] => {
		if (!connected || !nodeId) return [];
		const accessibleIds = new Set<string>();
		for (const edge of edgeStore.bySource(nodeId)) {
			if (!edge.system) accessibleIds.add(edge.targetId);
		}
		for (const id of nodeAccessStore.objectsForSubject(nodeId)) {
			accessibleIds.add(id);
		}
		const collections: Node[] = [];
		for (const id of accessibleIds) {
			const node = nodeStore.get(id);
			if (node && node.nodeKind === 'collection' && nodeVisibility(node, nodeId) !== 'hidden') {
				collections.push(node);
			}
		}
		const ranked = getRankedNodeIds();
		const rankMap = new Map(ranked.map((id, i) => [id, i]));
		collections.sort((a, b) => {
			const ra = rankMap.get(a.id) ?? 999;
			const rb = rankMap.get(b.id) ?? 999;
			if (ra !== rb) return ra - rb;
			return (a.title ?? '').localeCompare(b.title ?? '');
		});
		return collections;
	});

	const filteredCollections = $derived.by(() => {
		if (!searchQuery.trim()) return collectionNodes;
		const q = searchQuery.toLowerCase().trim();
		return collectionNodes.filter(n => (n.title ?? '').toLowerCase().includes(q));
	});

	function toggleSelector() {
		selectorOpen = !selectorOpen;
		toolMenuOpen = false;
		if (selectorOpen) {
			searchQuery = '';
			requestAnimationFrame(() => searchInput?.focus());
		}
	}

	function selectCollection(id: string) {
		selectorOpen = false;
		goto(`/collection/${id}`);
	}

	// =========================================================================
	// Tool menu
	// =========================================================================

	let toolMenuOpen = $state(false);

	const availableTools = $derived.by(() => {
		return Object.entries(TRAIT_PANEL_INFO).map(([key, info]) => ({
			key,
			...info,
			active: activeLayoutTraits.includes(key),
		}));
	});

	function toggleToolMenu() {
		toolMenuOpen = !toolMenuOpen;
		selectorOpen = false;
	}

	function addTool(trait: string) {
		handleAddPanel(trait);
		toolMenuOpen = false;
	}

	// =========================================================================
	// Mobile detection
	// =========================================================================

	let windowWidth = $state(typeof window !== 'undefined' ? window.innerWidth : 1024);
	const isMobile = $derived(windowWidth < 768);
	let activeTab = $state(0);

	$effect(() => {
		function onResize() { windowWidth = window.innerWidth; }
		window.addEventListener('resize', onResize);
		return () => window.removeEventListener('resize', onResize);
	});

	$effect(() => {
		if (activeTab >= layout.panels.length && layout.panels.length > 0) {
			activeTab = 0;
		}
	});

	// =========================================================================
	// Click outside
	// =========================================================================

	function handleClickOutside(e: MouseEvent) {
		const target = e.target as HTMLElement;
		if (selectorOpen && !target.closest('.context-selector')) {
			selectorOpen = false;
		}
		if (toolMenuOpen && !target.closest('.tool-menu')) {
			toolMenuOpen = false;
		}
	}

	function handleKeydown(e: KeyboardEvent) {
		if (e.key === 'Escape') {
			selectorOpen = false;
			toolMenuOpen = false;
		}
	}

	/** Trait components that have dedicated implementations */
	const knownTraits = new Set([
		'editor', 'chat', 'kanban', 'podcast', 'publishing',
		'rss', 'calendar', 'recording', 'transcription', 'studio', 'mixer'
	]);

	// =========================================================================
	// BlockReceiver per tool type — wired into BlockShell for drop compatibility
	// Ref: docs/features/universell_overfoering.md § 4
	// =========================================================================

	/** Traits that support BlockReceiver drops */
	const RECEIVER_TRAITS = new Set(['editor', 'chat', 'kanban', 'calendar', 'studio']);

	/** Cache receivers by trait name — one per type */
	const receiverCache = new Map<string, BlockReceiver>();

	function getReceiverForTrait(trait: string): BlockReceiver | undefined {
		if (!RECEIVER_TRAITS.has(trait)) return undefined;
		if (!receiverCache.has(trait)) {
			const toolType = trait as import('$lib/transfer').ToolType;
			receiverCache.set(trait, createBlockReceiver(toolType));
		}
		return receiverCache.get(trait);
	}

	function handlePanelDrop(trait: string, payload: DragPayload, shiftKey: boolean = false) {
		const receiver = getReceiverForTrait(trait);
		if (!receiver?.receive) {
			console.warn(`[universell-overføring] Ingen mottaker for ${trait}`);
			return;
		}

		const intent = receiver.receive(payload);
		const mode = resolveTransferMode(
			payload.sourcePanel,
			trait as import('$lib/transfer').ToolType,
			shiftKey,
		);
		// Override intent mode with centrally resolved mode
		intent.mode = mode;

		if (!accessToken) {
			console.error('[universell-overføring] Mangler accessToken — kan ikke utføre overføring');
			return;
		}

		console.log(`[universell-overføring] ${payload.sourcePanel} → ${trait} (${mode}${shiftKey ? ', shift' : ''}):`, intent);

		executeTransfer(accessToken, payload, intent, shiftKey)
			.then((result) => {
				console.log(`[universell-overføring] Fullført:`, result);
			})
			.catch((err) => {
				console.error(`[universell-overføring] Feil:`, err);
			});
	}
</script>

<svelte:window onclick={handleClickOutside} onkeydown={handleKeydown} />

<div class="workspace-page">
	<!-- Header -->
	<header class="context-header">
		<div class="context-header-inner">
			<div class="context-header-left">
				<a href="/" class="context-back" title="Tilbake til mottak">&larr;</a>

				<div class="context-selector">
					<button
						class="context-selector-trigger"
						onclick={toggleSelector}
						title="Bytt kontekst"
					>
						<span class="context-selector-title">Min arbeidsflate</span>
						<span class="context-selector-chevron" class:open={selectorOpen}>&#9662;</span>
					</button>

					{#if selectorOpen}
						<div class="context-selector-dropdown">
							<div class="context-selector-search">
								<input
									bind:this={searchInput}
									bind:value={searchQuery}
									type="text"
									placeholder="Søk samlinger..."
									class="context-selector-search-input"
									onclick={(e) => e.stopPropagation()}
								/>
							</div>
							<div class="context-selector-list">
								{#each filteredCollections as node (node.id)}
									<button
										class="context-selector-item"
										onclick={() => selectCollection(node.id)}
									>
										<span class="context-selector-item-title">{node.title || 'Uten tittel'}</span>
									</button>
								{:else}
									<div class="context-selector-empty">
										{searchQuery ? 'Ingen treff' : 'Ingen samlinger'}
									</div>
								{/each}
							</div>
						</div>
					{/if}
				</div>
			</div>

			<div class="context-header-right">
				<div class="tool-menu">
					<button
						class="context-btn tool-menu-trigger"
						onclick={toggleToolMenu}
						title="Legg til verktøy-panel"
					>
						+ Verktøy
					</button>

					{#if toolMenuOpen}
						<div class="tool-menu-dropdown">
							<div class="tool-menu-title">Legg til panel</div>
							{#each availableTools as tool (tool.key)}
								<button
									class="tool-menu-item"
									class:tool-menu-item-active={tool.active}
									onclick={() => addTool(tool.key)}
									disabled={tool.active}
									title={tool.active ? 'Allerede på flaten' : `Legg til ${tool.title}`}
								>
									<span class="tool-menu-item-icon">{tool.icon}</span>
									<span class="tool-menu-item-label">{tool.title}</span>
									{#if tool.active}
										<span class="tool-menu-item-badge">aktiv</span>
									{/if}
								</button>
							{/each}
						</div>
					{/if}
				</div>

				{#if connected}
					<span class="context-status context-status-ok" title="Tilkoblet sanntid">&#9679;</span>
				{:else}
					<span class="context-status" title="{connectionState.current}">&#9679;</span>
				{/if}
			</div>
		</div>
	</header>

	<!-- Main content -->
	{#if workspaceLoading}
		<div class="workspace-message">
			<p>Laster arbeidsflate...</p>
		</div>
	{:else if workspaceError}
		<div class="workspace-message workspace-message-warn">
			<p class="workspace-message-title">Kunne ikke laste arbeidsflate</p>
			<p>{workspaceError}</p>
		</div>
	{:else if !connected}
		<div class="workspace-message">
			<p>Venter på tilkobling...</p>
		</div>
	{:else if layout.panels.length === 0}
		<div class="workspace-empty">
			<div class="workspace-empty-inner">
				<p class="workspace-empty-title">Din personlige arbeidsflate</p>
				<p class="workspace-empty-desc">
					Legg til verktøy-paneler for å bygge opp arbeidsflaten din.
					Arrangementet huskes mellom besøk.
				</p>
				<div class="workspace-empty-tools">
					{#each Object.entries(TRAIT_PANEL_INFO) as [key, info] (key)}
						<button
							class="workspace-empty-tool"
							onclick={() => handleAddPanel(key)}
						>
							<span class="workspace-empty-tool-icon">{info.icon}</span>
							<span class="workspace-empty-tool-label">{info.title}</span>
						</button>
					{/each}
				</div>
			</div>
		</div>
	{:else if isMobile}
		<!-- MOBILE: Stacked tabs -->
		<div class="mobile-tabs">
			{#each layout.panels as panel, i (panel.trait)}
				<button
					class="mobile-tab {activeTab === i ? 'mobile-tab-active' : ''}"
					onclick={() => { activeTab = i; }}
				>
					{getPanelInfo(panel.trait).icon}
					<span class="mobile-tab-label">{getPanelInfo(panel.trait).title}</span>
				</button>
			{/each}
		</div>

		<div class="mobile-panel">
			{#each layout.panels as panel, i (panel.trait)}
				{#if activeTab === i}
					<div class="mobile-panel-content">
						{#if knownTraits.has(panel.trait)}
							{#if panel.trait === 'editor'}
								<EditorTrait collection={undefined} config={{}} userId={nodeId} {accessToken} collectionMetadata={{}} />
							{:else if panel.trait === 'chat'}
								<ChatTrait collection={undefined} config={{}} userId={nodeId} {accessToken} />
							{:else if panel.trait === 'kanban'}
								<KanbanTrait collection={undefined} config={{}} userId={nodeId} />
							{:else if panel.trait === 'calendar'}
								<CalendarTrait collection={undefined} config={{}} userId={nodeId} />
							{:else if panel.trait === 'podcast'}
								<PodcastTrait collection={undefined} config={{}} userId={nodeId} {accessToken} />
							{:else if panel.trait === 'publishing'}
								<PublishingTrait collection={undefined} config={{}} />
							{:else if panel.trait === 'rss'}
								<RssTrait collection={undefined} config={{}} />
							{:else if panel.trait === 'recording'}
								<RecordingTrait collection={undefined} config={{}} {accessToken} />
							{:else if panel.trait === 'transcription'}
								<TranscriptionTrait collection={undefined} config={{}} />
							{:else if panel.trait === 'studio'}
								<StudioTrait collection={undefined} config={{}} userId={nodeId} />
							{:else if panel.trait === 'mixer'}
								<MixerTrait collection={undefined} config={{}} {accessToken} />
							{/if}
						{:else}
							<GenericTrait name={panel.trait} config={{}} />
						{/if}
					</div>
				{/if}
			{/each}
		</div>
	{:else}
		<!-- DESKTOP: Spatial Canvas -->
		<div class="workspace-canvas">
			<Canvas
				objects={canvasObjects}
				onObjectMove={handleObjectMove}
				grid={{ enabled: false, size: 20 }}
			>
				{#snippet renderObject(obj)}
					{@const trait = obj.id}
					{@const info = getPanelInfo(trait)}
					{@const panel = layout.panels.find(p => p.trait === trait)}
					<BlockShell
						title={info.title}
						icon={info.icon}
						width={panel?.width ?? obj.width}
						height={panel?.height ?? obj.height}
						minimized={panel?.minimized ?? false}
						receiver={getReceiverForTrait(trait)}
						onResize={(w, h) => handlePanelResize(trait, w, h)}
						onClose={() => handlePanelClose(trait)}
						onMinimizeChange={(m) => handlePanelMinimize(trait, m)}
						onDrop={(payload, shiftKey) => handlePanelDrop(trait, payload, shiftKey)}
					>
						{#if knownTraits.has(trait)}
							{#if trait === 'editor'}
								<EditorTrait collection={undefined} config={{}} userId={nodeId} {accessToken} collectionMetadata={{}} />
							{:else if trait === 'chat'}
								<ChatTrait collection={undefined} config={{}} userId={nodeId} {accessToken} />
							{:else if trait === 'kanban'}
								<KanbanTrait collection={undefined} config={{}} userId={nodeId} />
							{:else if trait === 'calendar'}
								<CalendarTrait collection={undefined} config={{}} userId={nodeId} />
							{:else if trait === 'podcast'}
								<PodcastTrait collection={undefined} config={{}} userId={nodeId} {accessToken} />
							{:else if trait === 'publishing'}
								<PublishingTrait collection={undefined} config={{}} />
							{:else if trait === 'rss'}
								<RssTrait collection={undefined} config={{}} />
							{:else if trait === 'recording'}
								<RecordingTrait collection={undefined} config={{}} {accessToken} />
							{:else if trait === 'transcription'}
								<TranscriptionTrait collection={undefined} config={{}} />
							{:else if trait === 'studio'}
								<StudioTrait collection={undefined} config={{}} userId={nodeId} />
							{:else if trait === 'mixer'}
								<MixerTrait collection={undefined} config={{}} {accessToken} />
							{/if}
						{:else}
							<GenericTrait name={trait} config={{}} />
						{/if}
					</BlockShell>
				{/snippet}
			</Canvas>
		</div>
	{/if}

	<!-- AI-verktøy (vises under canvas) -->
	{#if connected && accessToken}
		<div class="workspace-footer-tools">
			<AiToolPanel {accessToken} userId={nodeId} />
		</div>
	{/if}
</div>

<style>
	.workspace-page {
		display: flex;
		flex-direction: column;
		height: 100vh;
		background: #f0f2f5;
	}

	/* ================================================================= */
	/* Context header (inline — personal workspace variant)              */
	/* ================================================================= */
	.context-header {
		border-bottom: 1px solid #e5e7eb;
		background: white;
		flex-shrink: 0;
		z-index: 30;
		position: relative;
	}

	.context-header-inner {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 6px 16px;
		max-width: 100%;
		min-height: 44px;
	}

	.context-header-left {
		display: flex;
		align-items: center;
		gap: 8px;
		min-width: 0;
		flex: 1;
	}

	.context-header-right {
		display: flex;
		align-items: center;
		gap: 10px;
		flex-shrink: 0;
	}

	.context-back {
		font-size: 16px;
		color: #9ca3af;
		text-decoration: none;
		flex-shrink: 0;
		padding: 4px;
		line-height: 1;
	}

	.context-back:hover {
		color: #4b5563;
	}

	/* ================================================================= */
	/* Context Selector                                                  */
	/* ================================================================= */
	.context-selector {
		position: relative;
		min-width: 0;
	}

	.context-selector-trigger {
		display: flex;
		align-items: center;
		gap: 6px;
		padding: 4px 10px;
		border: 1px solid transparent;
		border-radius: 6px;
		background: transparent;
		cursor: pointer;
		font-size: 15px;
		font-weight: 600;
		color: #111827;
		max-width: 300px;
		transition: background 0.12s, border-color 0.12s;
	}

	.context-selector-trigger:hover {
		background: #f3f4f6;
		border-color: #e5e7eb;
	}

	.context-selector-title {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.context-selector-chevron {
		font-size: 10px;
		color: #9ca3af;
		transition: transform 0.15s;
		flex-shrink: 0;
	}

	.context-selector-chevron.open {
		transform: rotate(180deg);
	}

	.context-selector-dropdown {
		position: absolute;
		top: calc(100% + 4px);
		left: 0;
		min-width: 260px;
		max-width: 360px;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 8px;
		box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
		z-index: 50;
		overflow: hidden;
	}

	.context-selector-search {
		padding: 8px;
		border-bottom: 1px solid #f3f4f6;
	}

	.context-selector-search-input {
		width: 100%;
		padding: 6px 10px;
		border: 1px solid #e5e7eb;
		border-radius: 6px;
		font-size: 13px;
		outline: none;
		background: #fafbfc;
	}

	.context-selector-search-input:focus {
		border-color: #4f46e5;
		background: white;
	}

	.context-selector-list {
		max-height: 280px;
		overflow-y: auto;
		padding: 4px;
	}

	.context-selector-item {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		padding: 8px 10px;
		border: none;
		border-radius: 6px;
		background: transparent;
		cursor: pointer;
		font-size: 13px;
		color: #374151;
		text-align: left;
		transition: background 0.1s;
	}

	.context-selector-item:hover {
		background: #f3f4f6;
	}

	.context-selector-item-title {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.context-selector-empty {
		padding: 16px;
		text-align: center;
		font-size: 12px;
		color: #9ca3af;
	}

	/* ================================================================= */
	/* Tool Menu                                                         */
	/* ================================================================= */
	.tool-menu {
		position: relative;
	}

	.tool-menu-trigger {
		font-weight: 500;
	}

	.tool-menu-dropdown {
		position: absolute;
		top: calc(100% + 4px);
		right: 0;
		min-width: 200px;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 8px;
		box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
		z-index: 50;
		overflow: hidden;
		padding: 4px;
	}

	.tool-menu-title {
		padding: 6px 10px 4px;
		font-size: 11px;
		font-weight: 600;
		color: #9ca3af;
		text-transform: uppercase;
		letter-spacing: 0.05em;
	}

	.tool-menu-item {
		display: flex;
		align-items: center;
		gap: 8px;
		width: 100%;
		padding: 7px 10px;
		border: none;
		border-radius: 6px;
		background: transparent;
		cursor: pointer;
		font-size: 13px;
		color: #374151;
		text-align: left;
		transition: background 0.1s;
	}

	.tool-menu-item:hover:not(:disabled) {
		background: #f3f4f6;
	}

	.tool-menu-item:disabled {
		cursor: default;
		opacity: 0.5;
	}

	.tool-menu-item-active {
		color: #9ca3af;
	}

	.tool-menu-item-icon {
		font-size: 15px;
		flex-shrink: 0;
	}

	.tool-menu-item-label {
		flex: 1;
	}

	.tool-menu-item-badge {
		font-size: 10px;
		color: #9ca3af;
		background: #f3f4f6;
		padding: 1px 6px;
		border-radius: 4px;
	}

	/* ================================================================= */
	/* Status + buttons                                                  */
	/* ================================================================= */
	.context-status {
		font-size: 8px;
		color: #d1d5db;
	}

	.context-status-ok {
		color: #16a34a;
	}

	.context-btn {
		padding: 4px 10px;
		border: none;
		border-radius: 6px;
		font-size: 12px;
		font-weight: 500;
		cursor: pointer;
		background: #f3f4f6;
		color: #4b5563;
		transition: background 0.12s;
	}

	.context-btn:hover {
		background: #e5e7eb;
	}

	/* ================================================================= */
	/* Messages                                                          */
	/* ================================================================= */
	.workspace-message {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		flex: 1;
		padding: 24px;
		text-align: center;
		font-size: 14px;
		color: #6b7280;
	}

	.workspace-message-warn {
		color: #92400e;
		background: #fffbeb;
	}

	.workspace-message-title {
		font-weight: 600;
		margin-bottom: 4px;
	}

	/* ================================================================= */
	/* Empty state (no panels)                                           */
	/* ================================================================= */
	.workspace-empty {
		display: flex;
		align-items: center;
		justify-content: center;
		flex: 1;
		padding: 24px;
	}

	.workspace-empty-inner {
		text-align: center;
		max-width: 480px;
	}

	.workspace-empty-title {
		font-size: 18px;
		font-weight: 600;
		color: #111827;
		margin-bottom: 8px;
	}

	.workspace-empty-desc {
		font-size: 14px;
		color: #6b7280;
		margin-bottom: 24px;
	}

	.workspace-empty-tools {
		display: flex;
		flex-wrap: wrap;
		justify-content: center;
		gap: 8px;
	}

	.workspace-empty-tool {
		display: flex;
		align-items: center;
		gap: 6px;
		padding: 8px 14px;
		border: 1px solid #e5e7eb;
		border-radius: 8px;
		background: white;
		cursor: pointer;
		font-size: 13px;
		color: #374151;
		transition: border-color 0.12s, box-shadow 0.12s;
	}

	.workspace-empty-tool:hover {
		border-color: #4f46e5;
		box-shadow: 0 2px 8px rgba(79, 70, 229, 0.1);
	}

	.workspace-empty-tool-icon {
		font-size: 16px;
	}

	.workspace-empty-tool-label {
		font-weight: 500;
	}

	/* ================================================================= */
	/* Canvas                                                            */
	/* ================================================================= */
	.workspace-canvas {
		flex: 1;
		min-height: 0;
	}

	/* ================================================================= */
	/* Mobile tabs                                                       */
	/* ================================================================= */
	.mobile-tabs {
		display: flex;
		overflow-x: auto;
		gap: 0;
		background: white;
		border-bottom: 1px solid #e5e7eb;
		flex-shrink: 0;
		-webkit-overflow-scrolling: touch;
	}

	.mobile-tab {
		display: flex;
		align-items: center;
		gap: 4px;
		padding: 10px 14px;
		border: none;
		background: transparent;
		font-size: 13px;
		color: #6b7280;
		cursor: pointer;
		white-space: nowrap;
		border-bottom: 2px solid transparent;
		transition: color 0.12s, border-color 0.12s;
	}

	.mobile-tab:hover {
		color: #374151;
	}

	.mobile-tab-active {
		color: #4f46e5;
		border-bottom-color: #4f46e5;
		font-weight: 500;
	}

	.mobile-tab-label {
		font-size: 12px;
	}

	.mobile-panel {
		flex: 1;
		overflow: auto;
		min-height: 0;
	}

	.mobile-panel-content {
		min-height: 100%;
	}

	/* ================================================================= */
	/* Footer tools                                                      */
	/* ================================================================= */
	.workspace-footer-tools {
		flex-shrink: 0;
		padding: 8px 16px;
		background: white;
		border-top: 1px solid #e5e7eb;
		display: flex;
		gap: 16px;
	}

	/* ================================================================= */
	/* Responsive                                                        */
	/* ================================================================= */
	@media (max-width: 768px) {
		.context-header-inner {
			padding: 6px 12px;
		}

		.context-selector-trigger {
			font-size: 14px;
			max-width: 200px;
		}

		.context-selector-dropdown {
			min-width: 220px;
			max-width: calc(100vw - 24px);
		}

		.tool-menu-dropdown {
			max-width: calc(100vw - 24px);
		}

		.context-header-right {
			gap: 6px;
		}

		.workspace-footer-tools {
			flex-direction: column;
			gap: 8px;
			padding: 8px 12px;
		}

		.workspace-empty-tools {
			gap: 6px;
		}

		.workspace-empty-tool {
			padding: 6px 10px;
			font-size: 12px;
		}
	}
</style>
