/**
 * <rstack-user-dashboard> — Customizable space dashboard with widget cards.
 *
 * Always accessible via the persistent home icon in the tab bar.
 * Users can toggle and reorder summary widget cards from any rApp.
 *
 * Attributes:
 *   space — current space slug
 */

import { getSession, getAccessToken } from "./rstack-identity";
import { getModuleApiBase } from "../url-helpers";

interface MemberInfo {
	did: string;
	username: string;
	displayName: string;
}

interface NotificationItem {
	id: string;
	category: string;
	title: string;
	body: string | null;
	actionUrl: string | null;
	createdAt: string;
	read: boolean;
}

interface TabLayer {
	moduleId: string;
	label?: string;
	icon?: string;
}

interface WidgetConfig {
	id: string;
	enabled: boolean;
	order: number;
}

interface SummaryTask {
	id: string;
	title: string;
	status: string;
	priority: string;
	createdAt: number;
}

interface SummaryEvent {
	title: string;
	start: string;
	end: string;
	allDay: boolean;
	location: string | null;
}

interface SummaryFlow {
	id: string;
	name: string;
	nodeCount: number;
	createdAt: number;
}

interface WalletBalance {
	tokenId: string;
	symbol: string;
	balance: number;
}

// ── Widget registry ──

const WIDGET_REGISTRY: Record<string, {
	label: string;
	icon: string;
	requiresAuth: boolean;
	defaultEnabled: boolean;
}> = {
	tasks:        { label: "Open Tasks",        icon: "\u{1F4CB}", requiresAuth: false, defaultEnabled: true },
	calendar:     { label: "Upcoming Events",   icon: "\u{1F4C5}", requiresAuth: false, defaultEnabled: true },
	activity:     { label: "Recent Activity",   icon: "\u{1F514}", requiresAuth: true,  defaultEnabled: true },
	members:      { label: "Members",           icon: "\u{1F465}", requiresAuth: false, defaultEnabled: true },
	tools:        { label: "Recently Open",     icon: "\u{1F527}", requiresAuth: false, defaultEnabled: true },
	quickactions: { label: "Quick Actions",     icon: "\u26A1",    requiresAuth: false, defaultEnabled: true },
	wallet:       { label: "Wallet Balances",   icon: "\u{1F4B0}", requiresAuth: true,  defaultEnabled: false },
	flows:        { label: "Active Flows",      icon: "\u{1F30A}", requiresAuth: false, defaultEnabled: false },
};

const WIDGET_ORDER = ["tasks", "calendar", "activity", "members", "tools", "quickactions", "wallet", "flows"];

const CACHE_TTL = 30_000; // 30s

const PRIORITY_COLORS: Record<string, string> = {
	HIGH: "#ef4444",
	MEDIUM: "#f59e0b",
	LOW: "#22c55e",
};

export class RStackUserDashboard extends HTMLElement {
	#shadow: ShadowRoot;
	#members: MemberInfo[] = [];
	#notifications: NotificationItem[] = [];
	#openTabs: TabLayer[] = [];
	#tasks: SummaryTask[] = [];
	#events: SummaryEvent[] = [];
	#flows: SummaryFlow[] = [];
	#walletBalances: WalletBalance[] = [];
	#membersLoading = true;
	#notifLoading = true;
	#summaryLoading = true;
	#walletLoading = true;
	#lastFetch = 0;
	#widgetConfigs: WidgetConfig[] = [];
	#isCustomizing = false;

	constructor() {
		super();
		this.#shadow = this.attachShadow({ mode: "open" });
	}

	static get observedAttributes() {
		return ["space"];
	}

	get space(): string {
		return this.getAttribute("space") || "";
	}

	connectedCallback() {
		this.#loadWidgetConfigs();
		this.#render();
		if (this.offsetParent !== null) {
			this.#loadData();
		}
	}

	attributeChangedCallback() {
		this.#lastFetch = 0;
		this.#loadWidgetConfigs();
		this.#render();
	}

	setOpenTabs(tabs: TabLayer[]) {
		this.#openTabs = tabs;
	}

	refresh() {
		if (Date.now() - this.#lastFetch < CACHE_TTL) {
			this.#render();
			return;
		}
		this.#membersLoading = true;
		this.#notifLoading = true;
		this.#summaryLoading = true;
		this.#walletLoading = true;
		this.#render();
		this.#loadData();
	}

	// ── Widget config persistence ──

	#widgetConfigKey(): string {
		return `rspace_dashboard_widgets_${this.space || "default"}`;
	}

	#loadWidgetConfigs() {
		try {
			const raw = localStorage.getItem(this.#widgetConfigKey());
			if (raw) {
				const parsed = JSON.parse(raw) as WidgetConfig[];
				if (Array.isArray(parsed) && parsed.length > 0) {
					// Merge with registry in case new widgets were added
					const known = new Set(parsed.map(c => c.id));
					let maxOrder = Math.max(...parsed.map(c => c.order));
					for (const id of WIDGET_ORDER) {
						if (!known.has(id)) {
							const w = WIDGET_REGISTRY[id];
							parsed.push({ id, enabled: w.defaultEnabled, order: ++maxOrder });
						}
					}
					this.#widgetConfigs = parsed;
					return;
				}
			}
		} catch { /* ignore */ }

		// Default config
		this.#widgetConfigs = WIDGET_ORDER.map((id, i) => ({
			id,
			enabled: WIDGET_REGISTRY[id].defaultEnabled,
			order: i,
		}));
	}

	#saveWidgetConfigs() {
		try {
			localStorage.setItem(this.#widgetConfigKey(), JSON.stringify(this.#widgetConfigs));
		} catch { /* ignore */ }
	}

	// ── Data loading ──

	async #loadData() {
		this.#lastFetch = Date.now();
		const enabled = new Set(this.#widgetConfigs.filter(c => c.enabled).map(c => c.id));
		const fetches: Promise<void>[] = [];

		if (enabled.has("members")) fetches.push(this.#fetchMembers());
		else { this.#membersLoading = false; }

		if (enabled.has("activity")) fetches.push(this.#fetchNotifications());
		else { this.#notifLoading = false; }

		if (enabled.has("tasks") || enabled.has("calendar") || enabled.has("flows")) {
			fetches.push(this.#fetchSummary());
		} else { this.#summaryLoading = false; }

		if (enabled.has("wallet")) fetches.push(this.#fetchWallet());
		else { this.#walletLoading = false; }

		await Promise.all(fetches);
	}

	async #fetchMembers() {
		this.#membersLoading = true;
		try {
			const res = await fetch(`${getModuleApiBase("rspace")}/api/space-members`);
			if (res.ok) {
				const data = await res.json();
				this.#members = data.members || [];
			}
		} catch { /* offline */ }
		this.#membersLoading = false;
		this.#render();
	}

	async #fetchNotifications() {
		this.#notifLoading = true;
		const token = getAccessToken();
		if (!token) {
			this.#notifLoading = false;
			this.#render();
			return;
		}
		try {
			const res = await fetch("/api/notifications?limit=5", {
				headers: { Authorization: `Bearer ${token}` },
			});
			if (res.ok) {
				const data = await res.json();
				this.#notifications = data.notifications || [];
			}
		} catch { /* offline */ }
		this.#notifLoading = false;
		this.#render();
	}

	async #fetchSummary() {
		this.#summaryLoading = true;
		try {
			const res = await fetch(`/api/dashboard-summary/${encodeURIComponent(this.space)}`);
			if (res.ok) {
				const data = await res.json();
				this.#tasks = data.tasks || [];
				this.#events = data.calendar || [];
				this.#flows = data.flows || [];
			}
		} catch { /* offline */ }
		this.#summaryLoading = false;
		this.#render();
	}

	async #fetchWallet() {
		this.#walletLoading = true;
		const token = getAccessToken();
		if (!token) {
			this.#walletLoading = false;
			this.#render();
			return;
		}
		try {
			const res = await fetch("/api/crdt-tokens/my-balances", {
				headers: { Authorization: `Bearer ${token}` },
			});
			if (res.ok) {
				const data = await res.json();
				this.#walletBalances = data.balances || [];
			}
		} catch { /* offline */ }
		this.#walletLoading = false;
		this.#render();
	}

	// ── Helpers ──

	#timeAgo(iso: string): string {
		const diff = Date.now() - new Date(iso).getTime();
		const mins = Math.floor(diff / 60_000);
		if (mins < 1) return "just now";
		if (mins < 60) return `${mins}m ago`;
		const hrs = Math.floor(mins / 60);
		if (hrs < 24) return `${hrs}h ago`;
		const days = Math.floor(hrs / 24);
		if (days < 30) return `${days}d ago`;
		return `${Math.floor(days / 30)}mo ago`;
	}

	#formatEventTime(iso: string, allDay: boolean): string {
		if (allDay) return new Date(iso).toLocaleDateString(undefined, { month: "short", day: "numeric" });
		return new Date(iso).toLocaleString(undefined, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
	}

	#dispatch(moduleId: string) {
		this.dispatchEvent(new CustomEvent("dashboard-navigate", {
			bubbles: true,
			detail: { moduleId, spaceSlug: this.space },
		}));
	}

	#parseActionUrl(url: string | null): { moduleId: string; spaceSlug?: string } | null {
		if (!url) return null;
		try {
			const parts = url.replace(/^\//, "").split("/");
			if (parts.length >= 2) return { spaceSlug: parts[0], moduleId: parts[1] };
			if (parts.length === 1 && parts[0]) return { moduleId: parts[0] };
		} catch { /* fall through */ }
		return null;
	}

	#memberInitial(m: MemberInfo): string {
		return (m.displayName || m.username || "?").charAt(0).toUpperCase();
	}

	#moduleIcon(moduleId: string): string {
		const icons: Record<string, string> = {
			rspace: "\u{1F30C}", rnotes: "\u{1F4DD}", rmeets: "\u{1F4F9}", rvote: "\u{1F5F3}",
			rnetwork: "\u{1F465}", rcalendar: "\u{1F4C5}", rtasks: "\u2705",
			rwallet: "\u{1F4B0}", rmail: "\u{1F4E7}", rmaps: "\u{1F5FA}",
			rprompt: "\u{1F916}", rzine: "\u{1F4D6}", rfiles: "\u{1F4C1}",
		};
		return icons[moduleId] || "\u{1F4E6}";
	}

	#moduleLabel(tab: TabLayer): string {
		if (tab.label) return tab.label;
		const id = tab.moduleId;
		return id.charAt(0).toUpperCase() + id.slice(1);
	}

	// ── Per-widget renderers ──

	#renderWidgetTasks(): string {
		if (this.#summaryLoading) return `<div class="section-empty">Loading...</div>`;
		if (this.#tasks.length === 0) return `<div class="section-empty">No open tasks</div>`;
		return `<div class="widget-list">${this.#tasks.map(t => `
			<button class="widget-list-item" data-navigate="rtasks">
				<span class="priority-dot" style="background:${PRIORITY_COLORS[t.priority] || "#94a3b8"}"></span>
				<span class="widget-list-text">${this.#escHtml(t.title)}</span>
				<span class="widget-list-meta">${t.status}</span>
			</button>
		`).join("")}</div>`;
	}

	#renderWidgetCalendar(): string {
		if (this.#summaryLoading) return `<div class="section-empty">Loading...</div>`;
		if (this.#events.length === 0) return `<div class="section-empty">No upcoming events</div>`;
		return `<div class="widget-list">${this.#events.map(e => `
			<button class="widget-list-item" data-navigate="rcal">
				<span class="widget-list-text">${this.#escHtml(e.title)}</span>
				<span class="widget-list-meta">${this.#formatEventTime(e.start, e.allDay)}</span>
			</button>
		`).join("")}</div>`;
	}

	#renderWidgetActivity(): string {
		const session = getSession();
		if (!session) return `<div class="section-empty">Sign in to see recent activity</div>`;
		if (this.#notifLoading) return `<div class="section-empty">Loading...</div>`;
		if (this.#notifications.length === 0) return `<div class="section-empty">No recent activity</div>`;
		return `<div class="activity-list">${this.#notifications.map(n => `
			<button class="activity-item ${n.read ? "read" : "unread"}" data-action-url="${n.actionUrl || ""}">
				<div class="activity-content">
					<div class="activity-title">${n.title}</div>
					${n.body ? `<div class="activity-body">${n.body}</div>` : ""}
				</div>
				<span class="activity-time">${this.#timeAgo(n.createdAt)}</span>
			</button>
		`).join("")}</div>`;
	}

	#renderWidgetMembers(): string {
		if (this.#membersLoading) return `<div class="section-empty">Loading members...</div>`;
		if (this.#members.length === 0) return `<div class="section-empty">No members found</div>`;
		return `<div class="members-row">${this.#members.map(m => `
			<button class="member-circle" data-navigate="rnetwork" title="${this.#escHtml(m.displayName || m.username)}">
				${this.#memberInitial(m)}
			</button>
		`).join("")}
		<span class="member-count">${this.#members.length} member${this.#members.length !== 1 ? "s" : ""}</span>
		</div>`;
	}

	#renderWidgetTools(): string {
		if (this.#openTabs.length === 0) return `<div class="section-empty">No recent tabs</div>`;
		return `<div class="tools-grid">${this.#openTabs.map(t => `
			<button class="tool-chip" data-module="${t.moduleId}">
				<span class="tool-icon">${this.#moduleIcon(t.moduleId)}</span>
				<span>${this.#moduleLabel(t)}</span>
			</button>
		`).join("")}</div>`;
	}

	#renderWidgetQuickActions(): string {
		return `<div class="actions-row">
			<button class="action-btn" data-action-module="rmeets">
				<span class="action-icon">\u{1F4F9}</span><span>Quick Meet</span>
			</button>
			<button class="action-btn" data-action-module="rnotes">
				<span class="action-icon">\u{1F4DD}</span><span>New Note</span>
			</button>
			<button class="action-btn" data-action-module="rspace">
				<span class="action-icon">\u{1F30C}</span><span>Canvas</span>
			</button>
		</div>`;
	}

	#renderWidgetWallet(): string {
		const session = getSession();
		if (!session) return `<div class="section-empty">Sign in to see wallet</div>`;
		if (this.#walletLoading) return `<div class="section-empty">Loading...</div>`;
		if (this.#walletBalances.length === 0) return `<div class="section-empty">No token balances</div>`;
		return `<div class="widget-list">${this.#walletBalances.map(b => `
			<button class="widget-list-item" data-navigate="rwallet">
				<span class="widget-list-text">${this.#escHtml(b.symbol)}</span>
				<span class="widget-list-meta">${b.balance.toLocaleString()}</span>
			</button>
		`).join("")}</div>`;
	}

	#renderWidgetFlows(): string {
		if (this.#summaryLoading) return `<div class="section-empty">Loading...</div>`;
		if (this.#flows.length === 0) return `<div class="section-empty">No active flows</div>`;
		return `<div class="widget-list">${this.#flows.map(f => `
			<button class="widget-list-item" data-navigate="rflows">
				<span class="widget-list-text">${this.#escHtml(f.name)}</span>
				<span class="widget-list-meta">${f.nodeCount} nodes</span>
			</button>
		`).join("")}</div>`;
	}

	#escHtml(s: string): string {
		return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
	}

	// ── Widget card wrapper ──

	#renderWidget(config: WidgetConfig): string {
		const w = WIDGET_REGISTRY[config.id];
		if (!w) return "";

		const renderers: Record<string, () => string> = {
			tasks: () => this.#renderWidgetTasks(),
			calendar: () => this.#renderWidgetCalendar(),
			activity: () => this.#renderWidgetActivity(),
			members: () => this.#renderWidgetMembers(),
			tools: () => this.#renderWidgetTools(),
			quickactions: () => this.#renderWidgetQuickActions(),
			wallet: () => this.#renderWidgetWallet(),
			flows: () => this.#renderWidgetFlows(),
		};

		const count = this.#getWidgetCount(config.id);
		const countBadge = count !== null ? `<span class="widget-card__count">${count}</span>` : "";
		const content = renderers[config.id]?.() || "";

		return `
			<div class="widget-card" data-widget="${config.id}">
				<div class="widget-card__header">
					<span class="widget-card__title">${w.icon} ${w.label}</span>
					${countBadge}
				</div>
				${content}
			</div>
		`;
	}

	#getWidgetCount(id: string): number | null {
		switch (id) {
			case "tasks": return this.#summaryLoading ? null : this.#tasks.length || null;
			case "calendar": return this.#summaryLoading ? null : this.#events.length || null;
			case "activity": return this.#notifLoading ? null : this.#notifications.filter(n => !n.read).length || null;
			case "members": return this.#membersLoading ? null : this.#members.length || null;
			case "flows": return this.#summaryLoading ? null : this.#flows.length || null;
			default: return null;
		}
	}

	// ── Customize panel ──

	#renderCustomizePanel(): string {
		const sorted = [...this.#widgetConfigs].sort((a, b) => a.order - b.order);
		return `
			<div class="customize-panel">
				<div class="customize-header">
					<span>Customize Dashboard</span>
					<button class="customize-done" id="customize-done">Done</button>
				</div>
				${sorted.map((c, i) => {
					const w = WIDGET_REGISTRY[c.id];
					if (!w) return "";
					return `
						<div class="customize-row">
							<label class="customize-toggle">
								<input type="checkbox" ${c.enabled ? "checked" : ""} data-widget-toggle="${c.id}" />
								<span>${w.icon} ${w.label}</span>
							</label>
							<div class="customize-arrows">
								${i > 0 ? `<button class="customize-arrow" data-move-up="${c.id}" title="Move up">\u25B2</button>` : `<span class="customize-arrow-placeholder"></span>`}
								${i < sorted.length - 1 ? `<button class="customize-arrow" data-move-down="${c.id}" title="Move down">\u25BC</button>` : `<span class="customize-arrow-placeholder"></span>`}
							</div>
						</div>
					`;
				}).join("")}
			</div>
		`;
	}

	// ── Main render ──

	#render() {
		const space = this.space;
		const spaceName = space.charAt(0).toUpperCase() + space.slice(1);

		// Stats pills
		const statPills: string[] = [];
		if (!this.#membersLoading) {
			statPills.push(`<span class="stat-pill">${this.#members.length} member${this.#members.length !== 1 ? "s" : ""}</span>`);
		}
		if (this.#openTabs.length > 0) {
			statPills.push(`<span class="stat-pill">${this.#openTabs.length} tab${this.#openTabs.length !== 1 ? "s" : ""} open</span>`);
		}

		// Enabled widgets sorted by order
		const enabled = this.#widgetConfigs
			.filter(c => c.enabled)
			.sort((a, b) => a.order - b.order);

		this.#shadow.innerHTML = `
			<style>${STYLES}</style>
			<div class="dashboard">
				<div class="dashboard-inner">
					<div class="space-header">
						<div class="space-icon">${spaceName.charAt(0)}</div>
						<div class="space-header__info">
							<h1 class="space-title">${spaceName}</h1>
							${statPills.length > 0 ? `<div class="stat-row">${statPills.join("")}</div>` : ""}
						</div>
						<button class="customize-btn" id="customize-btn" title="Customize dashboard">
							<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
						</button>
					</div>

					${this.#isCustomizing ? this.#renderCustomizePanel() : ""}

					${enabled.map(c => this.#renderWidget(c)).join("")}
				</div>
			</div>
		`;

		this.#attachEvents();
	}

	#attachEvents() {
		// Customize button
		this.#shadow.getElementById("customize-btn")?.addEventListener("click", () => {
			this.#isCustomizing = !this.#isCustomizing;
			this.#render();
		});

		// Customize done button
		this.#shadow.getElementById("customize-done")?.addEventListener("click", () => {
			this.#isCustomizing = false;
			this.#render();
			// Reload data for newly enabled widgets
			this.#lastFetch = 0;
			this.#loadData();
		});

		// Widget toggles
		this.#shadow.querySelectorAll<HTMLInputElement>("[data-widget-toggle]").forEach(input => {
			input.addEventListener("change", () => {
				const id = input.dataset.widgetToggle!;
				const config = this.#widgetConfigs.find(c => c.id === id);
				if (config) {
					config.enabled = input.checked;
					this.#saveWidgetConfigs();
					this.#render();
				}
			});
		});

		// Move up/down arrows
		this.#shadow.querySelectorAll<HTMLElement>("[data-move-up]").forEach(btn => {
			btn.addEventListener("click", () => this.#moveWidget(btn.dataset.moveUp!, -1));
		});
		this.#shadow.querySelectorAll<HTMLElement>("[data-move-down]").forEach(btn => {
			btn.addEventListener("click", () => this.#moveWidget(btn.dataset.moveDown!, 1));
		});

		// Navigation from widget items
		this.#shadow.querySelectorAll<HTMLElement>("[data-navigate]").forEach(el => {
			el.addEventListener("click", () => {
				this.#dispatch(el.dataset.navigate!);
			});
		});

		// Tool chips
		this.#shadow.querySelectorAll(".tool-chip").forEach(el => {
			el.addEventListener("click", () => {
				this.#dispatch((el as HTMLElement).dataset.module!);
			});
		});

		// Activity items
		this.#shadow.querySelectorAll(".activity-item").forEach(el => {
			el.addEventListener("click", () => {
				const url = (el as HTMLElement).dataset.actionUrl;
				const parsed = this.#parseActionUrl(url || null);
				this.#dispatch(parsed?.moduleId || "rspace");
			});
		});

		// Quick action buttons
		this.#shadow.querySelectorAll(".action-btn").forEach(el => {
			el.addEventListener("click", () => {
				this.#dispatch((el as HTMLElement).dataset.actionModule!);
			});
		});
	}

	#moveWidget(id: string, direction: number) {
		const sorted = [...this.#widgetConfigs].sort((a, b) => a.order - b.order);
		const idx = sorted.findIndex(c => c.id === id);
		if (idx < 0) return;
		const targetIdx = idx + direction;
		if (targetIdx < 0 || targetIdx >= sorted.length) return;

		// Swap order values
		const tmp = sorted[idx].order;
		sorted[idx].order = sorted[targetIdx].order;
		sorted[targetIdx].order = tmp;

		this.#saveWidgetConfigs();
		this.#render();
	}

	static define(tag = "rstack-user-dashboard") {
		if (!customElements.get(tag)) customElements.define(tag, RStackUserDashboard);
	}
}

// ============================================================================
// STYLES
// ============================================================================

const STYLES = `
:host {
  display: block;
  position: fixed;
  top: 92px;
  left: 0; right: 0; bottom: 0;
  overflow-y: auto;
  background: var(--rs-bg, var(--rs-bg-page, #0f172a));
  z-index: 1;
}

.dashboard {
  padding: 32px 24px;
}

.dashboard-inner {
  max-width: 800px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ── Space header ── */

.space-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.space-header__info { flex: 1; min-width: 0; }

.space-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(6,182,212,0.2), rgba(94,234,212,0.12));
  color: var(--rs-accent, #06b6d4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  font-weight: 700;
  flex-shrink: 0;
}

.space-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--rs-text-primary, #e2e8f0);
}

.stat-row {
  display: flex;
  gap: 8px;
  margin-top: 4px;
  flex-wrap: wrap;
}

.stat-pill {
  font-size: 0.7rem;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--rs-bg-surface, rgba(255,255,255,0.06));
  color: var(--rs-text-muted, #94a3b8);
  white-space: nowrap;
}

.customize-btn {
  flex-shrink: 0;
  background: none;
  border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
  color: var(--rs-text-muted, #94a3b8);
  border-radius: 8px;
  padding: 8px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.customize-btn:hover {
  color: var(--rs-text-primary, #e2e8f0);
  border-color: var(--rs-accent, #06b6d4);
}

/* ── Widget cards ���─ */

.widget-card {
  background: var(--rs-bg-surface, #1e293b);
  border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
  border-radius: 10px;
  padding: 16px;
}

.widget-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.widget-card__title {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--rs-text-secondary, #cbd5e1);
}

.widget-card__count {
  font-size: 0.7rem;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(20,184,166,0.15);
  color: #14b8a6;
  font-weight: 600;
}

/* ── Widget list (tasks, calendar, flows, wallet) ── */

.widget-list {
  display: flex;
  flex-direction: column;
}

.widget-list-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 4px;
  cursor: pointer;
  transition: background 0.15s;
  border: none;
  border-bottom: 1px solid var(--rs-border, rgba(255,255,255,0.04));
  background: none;
  text-align: left;
  color: inherit;
  font: inherit;
  width: 100%;
}
.widget-list-item:last-child { border-bottom: none; }
.widget-list-item:hover {
  background: var(--rs-bg-hover, rgba(255,255,255,0.04));
}

.widget-list-text {
  flex: 1;
  font-size: 0.8rem;
  color: var(--rs-text-primary, #e2e8f0);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.widget-list-meta {
  font-size: 0.7rem;
  color: var(--rs-text-muted, #64748b);
  flex-shrink: 0;
  white-space: nowrap;
}

.priority-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* ── Members (compact row) ── */

.members-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.member-circle {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, rgba(6,182,212,0.2), rgba(94,234,212,0.12));
  color: var(--rs-accent, #06b6d4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 700;
  flex-shrink: 0;
  border: none;
  cursor: pointer;
  transition: transform 0.15s;
}
.member-circle:hover { transform: scale(1.1); }

.member-count {
  font-size: 0.7rem;
  color: var(--rs-text-muted, #94a3b8);
  margin-left: 4px;
}

/* ── Tools grid ── */

.tools-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tool-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 8px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
  color: var(--rs-text-primary, #e2e8f0);
  font-size: 0.78rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  font: inherit;
}
.tool-chip:hover {
  background: var(--rs-bg-hover, rgba(255,255,255,0.06));
  border-color: var(--rs-accent, #06b6d4);
}

.tool-icon { font-size: 0.95rem; }

/* ── Activity list ── */

.activity-list {
  display: flex;
  flex-direction: column;
}

.activity-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 4px;
  cursor: pointer;
  transition: background 0.15s;
  border: none;
  border-bottom: 1px solid var(--rs-border, rgba(255,255,255,0.04));
  background: none;
  text-align: left;
  color: inherit;
  font: inherit;
  width: 100%;
}
.activity-item:last-child { border-bottom: none; }
.activity-item:hover {
  background: var(--rs-bg-hover, rgba(255,255,255,0.04));
}
.activity-item.unread {
  background: rgba(6,182,212,0.04);
}
.activity-item.unread .activity-title {
  font-weight: 600;
}

.activity-content { flex: 1; min-width: 0; }

.activity-title {
  font-size: 0.8rem;
  color: var(--rs-text-primary, #e2e8f0);
  line-height: 1.3;
}

.activity-body {
  font-size: 0.73rem;
  color: var(--rs-text-muted, #94a3b8);
  margin-top: 2px;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.activity-time {
  font-size: 0.7rem;
  color: var(--rs-text-muted, #64748b);
  flex-shrink: 0;
  white-space: nowrap;
  margin-top: 2px;
}

/* ── Quick Actions ── */

.actions-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 8px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
  color: var(--rs-text-primary, #e2e8f0);
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  font: inherit;
}
.action-btn:hover {
  background: var(--rs-bg-hover, rgba(255,255,255,0.06));
  border-color: var(--rs-accent, #06b6d4);
}

.action-icon { font-size: 1rem; }

.section-empty {
  padding: 16px 8px;
  text-align: center;
  color: var(--rs-text-muted, #94a3b8);
  font-size: 0.78rem;
}

/* ─��� Customize panel ── */

.customize-panel {
  background: var(--rs-bg-surface, #1e293b);
  border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
  border-radius: 10px;
  padding: 16px;
}

.customize-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--rs-text-primary, #e2e8f0);
}

.customize-done {
  padding: 4px 12px;
  border-radius: 6px;
  background: rgba(20,184,166,0.15);
  color: #14b8a6;
  border: none;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}
.customize-done:hover { background: rgba(20,184,166,0.25); }

.customize-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0;
  border-bottom: 1px solid var(--rs-border, rgba(255,255,255,0.04));
}
.customize-row:last-child { border-bottom: none; }

.customize-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
  color: var(--rs-text-primary, #e2e8f0);
  cursor: pointer;
}

.customize-toggle input[type="checkbox"] {
  accent-color: #14b8a6;
  width: 16px;
  height: 16px;
}

.customize-arrows {
  display: flex;
  gap: 4px;
}

.customize-arrow {
  background: none;
  border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
  color: var(--rs-text-muted, #94a3b8);
  border-radius: 4px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 0.6rem;
  transition: color 0.15s, border-color 0.15s;
}
.customize-arrow:hover {
  color: var(--rs-text-primary, #e2e8f0);
  border-color: var(--rs-accent, #06b6d4);
}

.customize-arrow-placeholder {
  width: 24px;
  height: 24px;
}

/* ── Responsive ── */

@media (max-width: 640px) {
  :host {
    position: static;
    overflow-y: visible;
  }
  .dashboard { padding: 20px 12px; }
}

@media (max-width: 480px) {
  .dashboard { padding: 16px 8px; }
  .actions-row { flex-direction: column; }
  .action-btn { justify-content: center; }
}
`;
