diff --git a/src/plus/webviews/timeline/protocol.ts b/src/plus/webviews/timeline/protocol.ts
index 52257f9..30c2a1a 100644
--- a/src/plus/webviews/timeline/protocol.ts
+++ b/src/plus/webviews/timeline/protocol.ts
@@ -5,9 +5,8 @@ export interface State {
 	timestamp: number;
 
 	dataset?: Commit[];
-	emptyMessage?: string;
 	period: Period;
-	title: string;
+	title?: string;
 	sha?: string;
 	uri?: string;
 
diff --git a/src/plus/webviews/timeline/registration.ts b/src/plus/webviews/timeline/registration.ts
index 7b8b14f..957cb20 100644
--- a/src/plus/webviews/timeline/registration.ts
+++ b/src/plus/webviews/timeline/registration.ts
@@ -16,7 +16,7 @@ export function registerTimelineWebviewPanel(controller: WebviewsController) {
 			plusFeature: true,
 			column: ViewColumn.Active,
 			webviewHostOptions: {
-				retainContextWhenHidden: true,
+				retainContextWhenHidden: false,
 				enableFindWidget: false,
 			},
 		},
diff --git a/src/plus/webviews/timeline/timelineWebview.ts b/src/plus/webviews/timeline/timelineWebview.ts
index d2fcc0c..3c9996e 100644
--- a/src/plus/webviews/timeline/timelineWebview.ts
+++ b/src/plus/webviews/timeline/timelineWebview.ts
@@ -55,7 +55,6 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 			etagSubscription: this.container.subscription.etag,
 		};
 
-		this.updatePendingEditor(window.activeTextEditor);
 		this._context = { ...this._context, ...this._pendingContext };
 		this._pendingContext = undefined;
 
@@ -134,6 +133,10 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 	onVisibilityChanged(visible: boolean) {
 		if (!visible) return;
 
+		if (this.host.isView()) {
+			this.updatePendingEditor(window.activeTextEditor);
+		}
+
 		// Since this gets called even the first time the webview is shown, avoid sending an update, because the bootstrap has the data
 		if (this._bootstraping) {
 			this._bootstraping = false;
@@ -257,44 +260,32 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 		const shortDateFormat = configuration.get('defaultDateShortFormat') ?? 'short';
 		const period = current.period ?? defaultPeriod;
 
-		if (current.uri == null) {
-			const access = await this.container.git.access(PlusFeatures.Timeline);
-			return {
-				timestamp: Date.now(),
-				emptyMessage: 'There are no editors open that can provide file history information',
-				period: period,
-				title: '',
-				dateFormat: dateFormat,
-				shortDateFormat: shortDateFormat,
-				access: access,
-			};
-		}
+		const gitUri = current.uri != null ? await GitUri.fromUri(current.uri) : undefined;
+		const repoPath = gitUri?.repoPath;
 
-		const gitUri = await GitUri.fromUri(current.uri);
-		const repoPath = gitUri.repoPath!;
+		if (this.host.isEditor()) {
+			this.host.title =
+				gitUri == null ? this.host.originalTitle : `${this.host.originalTitle}: ${gitUri.fileName}`;
+		} else {
+			this.host.description = gitUri?.fileName ?? '✨';
+		}
 
 		const access = await this.container.git.access(PlusFeatures.Timeline, repoPath);
-		if (access.allowed === false) {
-			const dataset = generateRandomTimelineDataset();
+
+		if (current.uri == null || gitUri == null || repoPath == null || access.allowed === false) {
+			const access = await this.container.git.access(PlusFeatures.Timeline, repoPath);
 			return {
 				timestamp: Date.now(),
-				dataset: dataset.sort((a, b) => b.sort - a.sort),
 				period: period,
-				title: 'src/app/index.ts',
-				uri: Uri.file('src/app/index.ts').toString(),
+				title: gitUri?.relativePath,
+				sha: gitUri?.shortSha,
+				uri: current.uri?.toString(),
 				dateFormat: dateFormat,
 				shortDateFormat: shortDateFormat,
 				access: access,
 			};
 		}
 
-		const title = gitUri.relativePath;
-		if (this.host.isEditor()) {
-			this.host.title = `${this.host.originalTitle}: ${gitUri.fileName}`;
-		} else {
-			this.host.description = gitUri.fileName;
-		}
-
 		const [currentUser, log] = await Promise.all([
 			this.container.git.getCurrentUser(repoPath),
 			this.container.git.getLogForFile(repoPath, gitUri.fsPath, {
@@ -308,9 +299,8 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 			return {
 				timestamp: Date.now(),
 				dataset: [],
-				emptyMessage: 'No commits found for the specified time period',
 				period: period,
-				title: title,
+				title: gitUri.relativePath,
 				sha: gitUri.shortSha,
 				uri: current.uri.toString(),
 				dateFormat: dateFormat,
@@ -368,7 +358,7 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 			timestamp: Date.now(),
 			dataset: dataset,
 			period: period,
-			title: title,
+			title: gitUri.relativePath,
 			sha: gitUri.shortSha,
 			uri: current.uri.toString(),
 			dateFormat: dateFormat,
@@ -377,8 +367,8 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 		};
 	}
 
-	private updatePendingContext(context: Partial<Context>): boolean {
-		const [changed, pending] = updatePendingContext(this._context, this._pendingContext, context);
+	private updatePendingContext(context: Partial<Context>, force?: boolean): boolean {
+		const [changed, pending] = updatePendingContext(this._context, this._pendingContext, context, force);
 		if (changed) {
 			this._pendingContext = pending;
 		}
@@ -386,14 +376,14 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 		return changed;
 	}
 
-	private updatePendingEditor(editor: TextEditor | undefined): boolean {
-		if (editor == null && hasVisibleTextEditor()) return false;
+	private updatePendingEditor(editor: TextEditor | undefined, force?: boolean): boolean {
+		if (editor == null && hasVisibleTextEditor(this._context.uri ?? this._pendingContext?.uri)) return false;
 		if (editor != null && !isTextEditor(editor)) return false;
 
-		return this.updatePendingUri(editor?.document.uri);
+		return this.updatePendingUri(editor?.document.uri, force);
 	}
 
-	private updatePendingUri(uri: Uri | undefined): boolean {
+	private updatePendingUri(uri: Uri | undefined, force?: boolean): boolean {
 		let etag;
 		if (uri != null) {
 			const repository = this.container.git.getRepository(uri);
@@ -402,19 +392,13 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 			etag = 0;
 		}
 
-		return this.updatePendingContext({ uri: uri, etagRepository: etag });
+		return this.updatePendingContext({ uri: uri, etagRepository: etag }, force);
 	}
 
 	private _notifyDidChangeStateDebounced: Deferrable<() => void> | undefined = undefined;
 
 	@debug()
 	private updateState(immediate: boolean = false) {
-		if (!this.host.ready || !this.host.visible) return;
-
-		if (this._pendingContext == null && this.host.isView()) {
-			this.updatePendingEditor(window.activeTextEditor);
-		}
-
 		if (immediate) {
 			void this.notifyDidChangeState();
 			return;
@@ -429,22 +413,17 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 
 	@debug()
 	private async notifyDidChangeState() {
-		if (!this.host.ready || !this.host.visible) return false;
-
 		this._notifyDidChangeStateDebounced?.cancel();
 		if (this._pendingContext == null) return false;
 
 		const context = { ...this._context, ...this._pendingContext };
+		this._context = context;
+		this._pendingContext = undefined;
 
-		const task = async () => {
-			const success = await this.host.notify(DidChangeNotificationType, {
+		const task = async () =>
+			this.host.notify(DidChangeNotificationType, {
 				state: await this.getState(context),
 			});
-			if (success) {
-				this._context = context;
-				this._pendingContext = undefined;
-			}
-		};
 
 		if (!this.host.isView()) return task();
 		return window.withProgress({ location: { viewId: this.host.id } }, task);
@@ -458,30 +437,6 @@ export class TimelineWebviewProvider implements WebviewProvider<State> {
 	}
 }
 
-function generateRandomTimelineDataset(): Commit[] {
-	const dataset: Commit[] = [];
-	const authors = ['Eric Amodio', 'Justin Roberts', 'Ada Lovelace', 'Grace Hopper'];
-
-	const count = 10;
-	for (let i = 0; i < count; i++) {
-		// Generate a random date between now and 3 months ago
-		const date = new Date(new Date().getTime() - Math.floor(Math.random() * (3 * 30 * 24 * 60 * 60 * 1000)));
-
-		dataset.push({
-			commit: String(i),
-			author: authors[Math.floor(Math.random() * authors.length)],
-			date: date.toISOString(),
-			message: '',
-			// Generate random additions/deletions between 1 and 20, but ensure we have a tiny and large commit
-			additions: i === 0 ? 2 : i === count - 1 ? 50 : Math.floor(Math.random() * 20) + 1,
-			deletions: i === 0 ? 1 : i === count - 1 ? 25 : Math.floor(Math.random() * 20) + 1,
-			sort: date.getTime(),
-		});
-	}
-
-	return dataset;
-}
-
 function getPeriodDate(period: Period): Date | undefined {
 	if (period == 'all') return undefined;
 
diff --git a/src/subscription.ts b/src/subscription.ts
index f53078c..845e38c 100644
--- a/src/subscription.ts
+++ b/src/subscription.ts
@@ -190,3 +190,11 @@ export function isSubscriptionPreviewTrialExpired(subscription: Optional<Subscri
 	const remaining = getTimeRemaining(subscription.previewTrial?.expiresOn);
 	return remaining != null ? remaining <= 0 : undefined;
 }
+
+export function isSubscriptionStatePaidOrTrial(state: SubscriptionState): boolean {
+	return (
+		state === SubscriptionState.Paid ||
+		state === SubscriptionState.FreeInPreviewTrial ||
+		state === SubscriptionState.FreePlusInTrial
+	);
+}
diff --git a/src/system/utils.ts b/src/system/utils.ts
index ab33f6f..f595fa8 100644
--- a/src/system/utils.ts
+++ b/src/system/utils.ts
@@ -67,10 +67,13 @@ export function getQuickPickIgnoreFocusOut() {
 	return !configuration.get('advanced.quickPick.closeOnFocusOut');
 }
 
-export function hasVisibleTextEditor(): boolean {
+export function hasVisibleTextEditor(uri?: Uri): boolean {
 	if (window.visibleTextEditors.length === 0) return false;
 
-	return window.visibleTextEditors.some(e => isTextEditor(e));
+	if (uri == null) return window.visibleTextEditors.some(e => isTextEditor(e));
+
+	const url = uri.toString();
+	return window.visibleTextEditors.some(e => e.document.uri.toString() === url && isTextEditor(e));
 }
 
 export function isActiveDocument(document: TextDocument): boolean {
diff --git a/src/webviews/apps/plus/shared/components/plus-feature-gate.ts b/src/webviews/apps/plus/shared/components/plus-feature-gate.ts
new file mode 100644
index 0000000..cf5e647
--- /dev/null
+++ b/src/webviews/apps/plus/shared/components/plus-feature-gate.ts
@@ -0,0 +1,88 @@
+import { css, html, LitElement, nothing } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { SubscriptionState } from '../../../../../subscription';
+import '../../../shared/components/button';
+import { linkStyles } from './vscode.css';
+
+@customElement('plus-feature-gate')
+export class PlusFeatureGate extends LitElement {
+	static override styles = [
+		linkStyles,
+		css`
+			:host {
+				container-type: inline-size;
+			}
+
+			gk-button {
+				width: 100%;
+				max-width: 300px;
+			}
+
+			@container (max-width: 640px) {
+				gk-button {
+					display: block;
+					margin-left: auto;
+					margin-right: auto;
+				}
+			}
+		`,
+	];
+
+	@property({ type: String })
+	appearance?: 'alert' | 'welcome';
+
+	@property({ type: Number })
+	state?: SubscriptionState;
+
+	override render() {
+		const appearance = (this.appearance ?? 'alert') === 'alert' ? 'alert' : nothing;
+
+		switch (this.state) {
+			case SubscriptionState.VerificationRequired:
+				return html`
+					<p>You must verify your email before you can continue.</p>
+					<gk-button appearance="${appearance}" href="command:gitlens.plus.resendVerification"
+						>Resend verification email</gk-button
+					>
+					<gk-button appearance="${appearance}" href="command:gitlens.plus.validate"
+						>Refresh verification status</gk-button
+					>
+				`;
+
+			case SubscriptionState.Free:
+				return html`
+					<gk-button appearance="${appearance}" href="command:gitlens.plus.startPreviewTrial"
+						>Start Free Pro Trial</gk-button
+					>
+					<p>
+						Instantly start a free 3-day Pro trial, or
+						<a href="command:gitlens.plus.loginOrSignUp">sign in</a>.
+					</p>
+					<p>✨ A trial or subscription is required to use this on privately hosted repos.</p>
+				`;
+
+			case SubscriptionState.FreePreviewTrialExpired:
+				return html`
+					<p>
+						Your free 3-day Pro trial has ended, extend your free trial to get an additional 7-days, or
+						<a href="command:gitlens.plus.loginOrSignUp">sign in</a>.
+					</p>
+					<gk-button appearance="${appearance}" href="command:gitlens.plus.loginOrSignUp"
+						>Extend Free Pro Trial</gk-button
+					>
+					<p>✨ A trial or subscription is required to use this on privately hosted repos.</p>
+				`;
+
+			case SubscriptionState.FreePlusTrialExpired:
+				return html`
+					<p>Your Pro trial has ended, please upgrade to continue to use this on privately hosted repos.</p>
+					<gk-button appearance="${appearance}" href="command:gitlens.plus.purchase"
+						>Upgrade to Pro</gk-button
+					>
+					<p>✨ A subscription is required to use this on privately hosted repos.</p>
+				`;
+		}
+
+		return undefined;
+	}
+}
diff --git a/src/webviews/apps/plus/shared/components/plus-feature-welcome.ts b/src/webviews/apps/plus/shared/components/plus-feature-welcome.ts
new file mode 100644
index 0000000..6c46815
--- /dev/null
+++ b/src/webviews/apps/plus/shared/components/plus-feature-welcome.ts
@@ -0,0 +1,92 @@
+import { css, html, LitElement, nothing } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { isSubscriptionStatePaidOrTrial, SubscriptionState } from '../../../../../subscription';
+import './plus-feature-gate';
+
+@customElement('plus-feature-welcome')
+export class PlusFeatureWelcome extends LitElement {
+	static override styles = css`
+		:host {
+			--background: var(--vscode-sideBar-background);
+			--foreground: var(--vscode-sideBar-foreground);
+			--link-foreground: var(--vscode-textLink-foreground);
+			--link-foreground-active: var(--vscode-textLink-activeForeground);
+
+			position: absolute;
+			top: 0;
+			left: 0;
+			bottom: 0;
+			right: 0;
+			font-size: 1.3rem;
+			overflow: auto;
+			z-index: 100;
+
+			box-sizing: border-box;
+		}
+
+		:host-context(body[data-placement='editor']) {
+			--background: transparent;
+			--foreground: var(--vscode-editor-foreground);
+
+			backdrop-filter: blur(3px) saturate(0.8);
+			padding: 0 2rem;
+		}
+
+		section {
+			--section-foreground: var(--foreground);
+			--section-background: var(--background);
+			--section-border-color: transparent;
+
+			display: flex;
+			flex-direction: column;
+			padding: 0 2rem 1.3rem 2rem;
+			background: var(--section-background);
+			color: var(--section-foreground);
+			border: 1px solid var(--section-border-color);
+
+			height: min-content;
+		}
+
+		:host-context(body[data-placement='editor']) section {
+			--section-foreground: var(--color-alert-foreground);
+			--section-background: var(--color-alert-infoBackground);
+			--section-border-color: var(--color-alert-infoBorder);
+
+			--link-decoration-default: underline;
+			--link-foreground: var(--vscode-foreground);
+			--link-foreground-active: var(--vscode-foreground);
+
+			border-radius: 0.3rem;
+			max-width: 600px;
+			max-height: min-content;
+			margin: 0.2rem auto;
+			padding: 0 1.3rem;
+		}
+	`;
+
+	@property({ type: Boolean })
+	allowed?: boolean;
+
+	@property({ type: Number })
+	state?: SubscriptionState;
+
+	@property({ reflect: true })
+	get appearance() {
+		return (document.body.getAttribute('data-placement') ?? 'editor') === 'editor' ? 'alert' : 'welcome';
+	}
+
+	override render() {
+		if (this.allowed || this.state == null || isSubscriptionStatePaidOrTrial(this.state)) {
+			this.hidden = true;
+			return undefined;
+		}
+
+		this.hidden = false;
+		return html`
+			<section>
+				<slot hidden=${this.state === SubscriptionState.Free ? nothing : ''}></slot>
+				<plus-feature-gate appearance=${this.appearance} state=${this.state}></plus-feature-gate>
+			</section>
+		`;
+	}
+}
diff --git a/src/webviews/apps/plus/shared/components/vscode.css.ts b/src/webviews/apps/plus/shared/components/vscode.css.ts
new file mode 100644
index 0000000..c06e645
--- /dev/null
+++ b/src/webviews/apps/plus/shared/components/vscode.css.ts
@@ -0,0 +1,15 @@
+import { css } from 'lit';
+
+export const linkStyles = css`
+	a {
+		color: var(--link-foreground);
+		text-decoration: var(--link-decoration-default, none);
+	}
+	a:focus {
+		outline-color: var(--focus-border);
+	}
+	a:hover {
+		color: var(--link-foreground-active);
+		text-decoration: underline;
+	}
+`;
diff --git a/src/webviews/apps/plus/timeline/chart.ts b/src/webviews/apps/plus/timeline/chart.ts
index 5db72cb..3216059 100644
--- a/src/webviews/apps/plus/timeline/chart.ts
+++ b/src/webviews/apps/plus/timeline/chart.ts
@@ -5,7 +5,7 @@ import { bar, bb, bubble, zoom } from 'billboard.js';
 // import { scaleSqrt } from 'd3-scale';
 import type { Commit, State } from '../../../../plus/webviews/timeline/protocol';
 import { formatDate, fromNow } from '../../shared/date';
-import type { Event } from '../../shared/events';
+import type { Disposable, Event } from '../../shared/events';
 import { Emitter } from '../../shared/events';
 
 export interface DataPointClickEvent {
@@ -15,7 +15,7 @@ export interface DataPointClickEvent {
 	};
 }
 
-export class TimelineChart {
+export class TimelineChart implements Disposable {
 	private _onDidClickDataPoint = new Emitter<DataPointClickEvent>();
 	get onDidClickDataPoint(): Event<DataPointClickEvent> {
 		return this._onDidClickDataPoint.event;
@@ -23,9 +23,9 @@ export class TimelineChart {
 
 	private readonly $container: HTMLElement;
 	private _chart: Chart | undefined;
-	private _chartDimensions: { height: number; width: number };
 	private readonly _resizeObserver: ResizeObserver;
 	private readonly _selector: string;
+	private _size: { height: number; width: number };
 
 	private readonly _commitsByTimestamp = new Map<string, Commit>();
 	private readonly _authorsByIndex = new Map<number, string>();
@@ -34,48 +34,48 @@ export class TimelineChart {
 	private _dateFormat: string = undefined!;
 	private _shortDateFormat: string = undefined!;
 
-	constructor(selector: string) {
-		this._selector = selector;
+	private get compact(): boolean {
+		return this.placement !== 'editor';
+	}
 
-		let idleRequest: number | undefined;
+	constructor(selector: string, private readonly placement: 'editor' | 'view') {
+		this._selector = selector;
 
 		const fn = () => {
-			idleRequest = undefined;
-
-			const dimensions = this._chartDimensions;
+			const size = this._size;
 			this._chart?.resize({
-				width: dimensions.width,
-				height: dimensions.height - 10,
+				width: size.width,
+				height: size.height,
 			});
 		};
 
+		const widthOffset = this.compact ? 32 : 0;
+		const heightOffset = this.compact ? 16 : 0;
+
+		this.$container = document.querySelector(selector)!.parentElement!;
 		this._resizeObserver = new ResizeObserver(entries => {
-			const size = entries[0].borderBoxSize[0];
-			const dimensions = {
-				width: Math.floor(size.inlineSize),
-				height: Math.floor(size.blockSize),
+			const boxSize = entries[0].borderBoxSize[0];
+			const size = {
+				width: Math.floor(boxSize.inlineSize) + widthOffset,
+				height: Math.floor(boxSize.blockSize) + heightOffset,
 			};
 
-			if (
-				this._chartDimensions.height === dimensions.height &&
-				this._chartDimensions.width === dimensions.width
-			) {
-				return;
-			}
-
-			this._chartDimensions = dimensions;
-			if (idleRequest != null) {
-				cancelIdleCallback(idleRequest);
-				idleRequest = undefined;
-			}
-			idleRequest = requestIdleCallback(fn, { timeout: 1000 });
+			this._size = size;
+			requestAnimationFrame(fn);
 		});
 
-		this.$container = document.querySelector(selector)!.parentElement!;
 		const rect = this.$container.getBoundingClientRect();
-		this._chartDimensions = { height: Math.floor(rect.height), width: Math.floor(rect.width) };
+		this._size = {
+			height: Math.floor(rect.height) + widthOffset,
+			width: Math.floor(rect.width) + heightOffset,
+		};
 
-		this._resizeObserver.observe(this.$container);
+		this._resizeObserver.observe(this.$container, { box: 'border-box' });
+	}
+
+	dispose(): void {
+		this._resizeObserver.disconnect();
+		this._chart?.destroy();
 	}
 
 	reset() {
@@ -83,6 +83,28 @@ export class TimelineChart {
 		this._chart?.unzoom();
 	}
 
+	private setEmptyState(dataset: Commit[] | undefined, state: State) {
+		const $empty = document.getElementById('empty')!;
+		const $header = document.getElementById('header')!;
+
+		if (state.uri != null) {
+			if (dataset?.length === 0) {
+				$empty.innerHTML = '<p>No commits found for the specified time period.</p>';
+				$empty.removeAttribute('hidden');
+			} else {
+				$empty.setAttribute('hidden', '');
+			}
+			$header.removeAttribute('hidden');
+		} else if (dataset == null) {
+			$empty.innerHTML = '<p>There are no editors open that can provide file history information.</p>';
+			$empty.removeAttribute('hidden');
+			$header.setAttribute('hidden', '');
+		} else {
+			$empty.setAttribute('hidden', '');
+			$header.removeAttribute('hidden');
+		}
+	}
+
 	updateChart(state: State) {
 		this._dateFormat = state.dateFormat;
 		this._shortDateFormat = state.shortDateFormat;
@@ -91,22 +113,19 @@ export class TimelineChart {
 		this._authorsByIndex.clear();
 		this._indexByAuthors.clear();
 
-		if (state?.dataset == null || state.dataset.length === 0) {
+		let dataset = state?.dataset;
+		if (dataset == null && !state.access.allowed && this.placement === 'editor') {
+			dataset = generateRandomTimelineDataset();
+		}
+
+		this.setEmptyState(dataset, state);
+		if (dataset == null || dataset.length === 0) {
 			this._chart?.destroy();
 			this._chart = undefined;
 
-			const $overlay = document.getElementById('chart-empty-overlay') as HTMLDivElement;
-			$overlay?.classList.toggle('hidden', false);
-
-			const $emptyMessage = $overlay.querySelector<HTMLHeadingElement>('[data-bind="empty"]')!;
-			$emptyMessage.textContent = state.emptyMessage ?? '';
-
 			return;
 		}
 
-		const $overlay = document.getElementById('chart-empty-overlay') as HTMLDivElement;
-		$overlay?.classList.toggle('hidden', true);
-
 		const xs: { [key: string]: string } = {};
 		const colors: { [key: string]: string } = {};
 		const names: { [key: string]: string } = {};
@@ -128,7 +147,7 @@ export class TimelineChart {
 		// let minChanges = Infinity;
 		// let maxChanges = -Infinity;
 
-		// for (const commit of state.dataset) {
+		// for (const commit of dataset) {
 		// 	const changes = commit.additions + commit.deletions;
 		// 	if (changes < minChanges) {
 		// 		minChanges = changes;
@@ -140,7 +159,7 @@ export class TimelineChart {
 
 		// const bubbleScale = scaleSqrt([minChanges, maxChanges], [6, 100]);
 
-		for (commit of state.dataset) {
+		for (commit of dataset) {
 			({ author, date, additions, deletions } = commit);
 
 			if (!this._indexByAuthors.has(author)) {
@@ -211,48 +230,52 @@ export class TimelineChart {
 		// eslint-disable-next-line @typescript-eslint/no-unsafe-return
 		const columns = Object.entries(series).map(([key, value]) => [key, ...value]);
 
-		if (this._chart == null) {
-			const options = this.getChartOptions();
-
-			if (options.axis == null) {
-				options.axis = { y: { tick: {} } };
+		try {
+			if (this._chart == null) {
+				const options = this.getChartOptions();
+
+				if (options.axis == null) {
+					options.axis = { y: { tick: {} } };
+				}
+				if (options.axis.y == null) {
+					options.axis.y = { tick: {} };
+				}
+				if (options.axis.y.tick == null) {
+					options.axis.y.tick = {};
+				}
+
+				options.axis.y.min = index - 2;
+				options.axis.y.tick.values = [...this._authorsByIndex.keys()];
+
+				options.data = {
+					...options.data,
+					axes: axes,
+					colors: colors,
+					columns: columns,
+					groups: groups,
+					names: names,
+					types: types,
+					xs: xs,
+				};
+
+				this._chart = bb.generate(options);
+			} else {
+				this._chart.config('axis.y.tick.values', [...this._authorsByIndex.keys()], false);
+				this._chart.config('axis.y.min', index - 2, false);
+				this._chart.groups(groups);
+
+				this._chart.load({
+					axes: axes,
+					colors: colors,
+					columns: columns,
+					names: names,
+					types: types,
+					xs: xs,
+					unload: true,
+				});
 			}
-			if (options.axis.y == null) {
-				options.axis.y = { tick: {} };
-			}
-			if (options.axis.y.tick == null) {
-				options.axis.y.tick = {};
-			}
-
-			options.axis.y.min = index - 2;
-			options.axis.y.tick.values = [...this._authorsByIndex.keys()];
-
-			options.data = {
-				...options.data,
-				axes: axes,
-				colors: colors,
-				columns: columns,
-				groups: groups,
-				names: names,
-				types: types,
-				xs: xs,
-			};
-
-			this._chart = bb.generate(options);
-		} else {
-			this._chart.config('axis.y.tick.values', [...this._authorsByIndex.keys()], false);
-			this._chart.config('axis.y.min', index - 2, false);
-			this._chart.groups(groups);
-
-			this._chart.load({
-				axes: axes,
-				colors: colors,
-				columns: columns,
-				names: names,
-				types: types,
-				xs: xs,
-				unload: true,
-			});
+		} catch (ex) {
+			debugger;
 		}
 	}
 
@@ -275,16 +298,20 @@ export class TimelineChart {
 					type: 'timeseries',
 					clipPath: false,
 					localtime: true,
+					show: true,
 					tick: {
-						// autorotate: true,
 						centered: true,
 						culling: false,
 						fit: false,
 						format: (x: number | Date) =>
-							typeof x === 'number' ? x : formatDate(x, this._shortDateFormat ?? 'short'),
+							this.compact
+								? ''
+								: typeof x === 'number'
+								? x
+								: formatDate(x, this._shortDateFormat ?? 'short'),
 						multiline: false,
-						// rotate: 15,
 						show: false,
+						outer: !this.compact,
 					},
 				},
 				y: {
@@ -295,22 +322,30 @@ export class TimelineChart {
 					},
 					show: true,
 					tick: {
-						format: (y: number) => this._authorsByIndex.get(y) ?? '',
-						outer: false,
+						format: (y: number) => (this.compact ? '' : this._authorsByIndex.get(y) ?? ''),
+						outer: !this.compact,
+						show: this.compact,
 					},
 				},
 				y2: {
-					label: {
-						text: 'Lines changed',
-						position: 'outer-middle',
-					},
+					padding: this.compact
+						? {
+								top: 0,
+								bottom: 0,
+						  }
+						: undefined,
+					label: this.compact
+						? undefined
+						: {
+								text: 'Lines changed',
+								position: 'outer-middle',
+						  },
 					// min: 0,
 					show: true,
-					// tick: {
-					// 	outer: true,
-					// 	// culling: true,
-					// 	// stepSize: 1,
-					// },
+					tick: {
+						format: (y: number) => (this.compact ? '' : y),
+						outer: !this.compact,
+					},
 				},
 			},
 			bar: {
@@ -340,16 +375,14 @@ export class TimelineChart {
 				},
 			},
 			legend: {
-				show: true,
+				show: !this.compact,
+				// hide: this.compact ? [...this._authorsByIndex.values()] : undefined,
 				padding: 10,
 			},
 			resize: {
 				auto: false,
 			},
-			size: {
-				height: this._chartDimensions.height - 10,
-				width: this._chartDimensions.width,
-			},
+			size: this._size,
 			tooltip: {
 				grouped: true,
 				format: {
@@ -436,3 +469,27 @@ export class TimelineChart {
 function capitalize(s: string): string {
 	return s.charAt(0).toUpperCase() + s.slice(1);
 }
+
+function generateRandomTimelineDataset(): Commit[] {
+	const dataset: Commit[] = [];
+	const authors = ['Eric Amodio', 'Justin Roberts', 'Keith Daulton', 'Ramin Tadayon', 'Ada Lovelace', 'Grace Hopper'];
+
+	const count = 10;
+	for (let i = 0; i < count; i++) {
+		// Generate a random date between now and 3 months ago
+		const date = new Date(new Date().getTime() - Math.floor(Math.random() * (3 * 30 * 24 * 60 * 60 * 1000)));
+
+		dataset.push({
+			commit: String(i),
+			author: authors[Math.floor(Math.random() * authors.length)],
+			date: date.toISOString(),
+			message: '',
+			// Generate random additions/deletions between 1 and 20, but ensure we have a tiny and large commit
+			additions: i === 0 ? 2 : i === count - 1 ? 50 : Math.floor(Math.random() * 20) + 1,
+			deletions: i === 0 ? 1 : i === count - 1 ? 25 : Math.floor(Math.random() * 20) + 1,
+			sort: date.getTime(),
+		});
+	}
+
+	return dataset.sort((a, b) => b.sort - a.sort);
+}
diff --git a/src/webviews/apps/plus/timeline/partials/state.free-preview-trial-expired.html b/src/webviews/apps/plus/timeline/partials/state.free-preview-trial-expired.html
deleted file mode 100644
index 2f5a717..0000000
--- a/src/webviews/apps/plus/timeline/partials/state.free-preview-trial-expired.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<template id="state:free-preview-trial-expired">
-	<section>
-		<vscode-button data-action="command:gitlens.plus.loginOrSignUp">Extend Pro Trial</vscode-button>
-		<p>
-			Your free 3-day GitLens Pro trial has ended, extend your trial to get an additional free 7-days of the
-			Visual File History and other <a href="command:gitlens.plus.learn">GitLens+ features</a> on private repos.
-		</p>
-	</section>
-</template>
diff --git a/src/webviews/apps/plus/timeline/partials/state.free.html b/src/webviews/apps/plus/timeline/partials/state.free.html
deleted file mode 100644
index 6b99c87..0000000
--- a/src/webviews/apps/plus/timeline/partials/state.free.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<template id="state:free">
-	<section>
-		<vscode-button data-action="command:gitlens.plus.startPreviewTrial"
-			>Try the Visual File History on private repos</vscode-button
-		>
-		<p>
-			To use the Visual File History and other <a href="command:gitlens.plus.learn">GitLens+ features</a> on
-			private repos, start a free trial of GitLens Pro, without an account, or
-			<a href="command:gitlens.plus.loginOrSignUp">sign in</a>.
-		</p>
-	</section>
-</template>
diff --git a/src/webviews/apps/plus/timeline/partials/state.plus-trial-expired.html b/src/webviews/apps/plus/timeline/partials/state.plus-trial-expired.html
deleted file mode 100644
index a62db4e..0000000
--- a/src/webviews/apps/plus/timeline/partials/state.plus-trial-expired.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<template id="state:plus-trial-expired">
-	<section>
-		<vscode-button data-action="command:gitlens.plus.purchase">Upgrade to Pro</vscode-button>
-		<p>
-			Your GitLens Pro trial has ended, please upgrade to GitLens Pro to continue to use the Visual File History
-			and other <a href="command:gitlens.plus.learn">GitLens+ features</a> on private repos.
-		</p>
-	</section>
-</template>
diff --git a/src/webviews/apps/plus/timeline/partials/state.verify-email.html b/src/webviews/apps/plus/timeline/partials/state.verify-email.html
deleted file mode 100644
index 2a54697..0000000
--- a/src/webviews/apps/plus/timeline/partials/state.verify-email.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<template id="state:verify-email">
-	<section>
-		<h3>Please verify your email</h3>
-		<p>To use the Visual File History, please verify your email address.</p>
-		<vscode-button data-action="command:gitlens.plus.resendVerification">Resend verification email</vscode-button>
-		<vscode-button data-action="command:gitlens.plus.validate">Refresh verification status</vscode-button>
-	</section>
-</template>
diff --git a/src/webviews/apps/plus/timeline/timeline.html b/src/webviews/apps/plus/timeline/timeline.html
index 0d94b30..27e1086 100644
--- a/src/webviews/apps/plus/timeline/timeline.html
+++ b/src/webviews/apps/plus/timeline/timeline.html
@@ -10,12 +10,20 @@
 	</head>
 
 	<body class="preload" data-placement="#{placement}">
+		<plus-feature-welcome class="scrollable">
+			<p>
+				Visualize the evolution of a file, including when changes were made, how large they were, and who made
+				them.
+			</p>
+		</plus-feature-welcome>
 		<div class="container">
 			<progress-indicator id="spinner" position="top" active="true"></progress-indicator>
-			<section class="header">
-				<h2 data-bind="title"></h2>
-				<h2 data-bind="sha"></h2>
-				<h2 data-bind="description"></h2>
+			<section id="header" class="header">
+				<div class="header--context">
+					<h2 data-bind="title"></h2>
+					<h2 data-bind="sha"></h2>
+					<h2 data-bind="description"></h2>
+				</div>
 				<div class="toolbox">
 					<div class="select-container">
 						<label for="periods">Timeframe</label>
@@ -31,40 +39,26 @@
 							<vscode-option value="all">Full history</vscode-option>
 						</vscode-dropdown>
 					</div>
+					<gk-button
+						data-placement-visible="view"
+						href="command:gitlens.views.timeline.openInTab"
+						title="Open in Editor Area"
+						aria-label="Open in Editor Area"
+						appearance="toolbar"
+					>
+						<code-icon icon="link-external"></code-icon>
+					</gk-button>
 				</div>
 			</section>
 			<section id="content">
+				<div id="empty" hidden></div>
 				<div id="chart"></div>
-				<div id="chart-empty-overlay" class="hidden">
-					<h1 data-bind="empty"></h1>
-				</div>
 			</section>
 			<section id="footer"></section>
 		</div>
-		<div id="overlay" class="hidden">
-			<div class="modal">
-				<p>
-					The Visual File History, a
-					<a title="Learn more about GitLens+ features" href="command:gitlens.plus.learn"
-						>✨GitLens+ feature</a
-					>, allows you to quickly see the evolution of a file, including when changes were made, how large
-					they were, and who made them.
-				</p>
-				<p>
-					Use it to quickly find when the most impactful changes were made to a file or who best to talk to
-					about file changes and more.
-				</p>
-				<div id="overlay-slot"></div>
-			</div>
-		</div>
 		#{endOfBody}
 
 		<style nonce="#{cspNonce}">
-			:root {
-				--gl-plus-bg: url(#{webroot}/media/gitlens-backdrop.webp);
-			}
-		</style>
-		<style nonce="#{cspNonce}">
 			@font-face {
 				font-family: 'codicon';
 				font-display: block;
@@ -77,10 +71,4 @@
 			}
 		</style>
 	</body>
-
-	<!-- prettier-ignore -->
-	<%= require('html-loader?{"esModule":false}!./partials/state.free.html') %>
-	<%= require('html-loader?{"esModule":false}!./partials/state.free-preview-trial-expired.html') %>
-	<%= require('html-loader?{"esModule":false}!./partials/state.plus-trial-expired.html') %>
-	<%= require('html-loader?{"esModule":false}!./partials/state.verify-email.html') %>
 </html>
diff --git a/src/webviews/apps/plus/timeline/timeline.scss b/src/webviews/apps/plus/timeline/timeline.scss
index 1471a72..357aaae 100644
--- a/src/webviews/apps/plus/timeline/timeline.scss
+++ b/src/webviews/apps/plus/timeline/timeline.scss
@@ -1,3 +1,5 @@
+@use '../../shared/styles/properties';
+
 * {
 	box-sizing: border-box;
 }
@@ -14,11 +16,8 @@ body {
 	line-height: 1.4;
 	font-size: 100% !important;
 	overflow: hidden;
-	margin: 0 20px 20px 20px;
+	margin: 0;
 	padding: 0;
-
-	min-width: 400px;
-	overflow-x: scroll;
 }
 
 body[data-placement='editor'] {
@@ -57,72 +56,38 @@ h4 {
 	margin: 0.5rem 0 1rem 0;
 }
 
-a {
-	text-decoration: none;
-
-	&:focus {
-		outline-color: var(--focus-border);
-	}
-
-	&:hover {
-		text-decoration: underline;
-	}
-}
-
-b {
-	font-weight: 600;
-}
-
-p {
-	margin-bottom: 0;
-}
-
-vscode-button:not([appearance='icon']) {
-	align-self: center;
-	margin-top: 1.5rem;
-	max-width: 300px;
-	width: 100%;
-}
-
-span.button-subaction {
-	align-self: center;
-	margin-top: 0.75rem;
-}
-
-@media (min-width: 640px) {
-	vscode-button:not([appearance='icon']) {
-		align-self: flex-start;
-	}
-	span.button-subaction {
-		align-self: flex-start;
-	}
-}
-
 .header {
 	display: grid;
-	grid-template-columns: max-content min-content minmax(min-content, 1fr) max-content;
+	grid-template-columns: 1fr min-content;
 	align-items: baseline;
-	grid-template-areas: 'title sha description toolbox';
-	justify-content: start;
-	margin-bottom: 1rem;
-
-	@media all and (max-width: 500px) {
-		grid-template-areas:
-			'title sha description'
-			'empty toolbox';
-		grid-template-columns: max-content min-content minmax(min-content, 1fr);
+	grid-template-areas: 'context toolbox';
+	margin: 1rem;
+
+	body[data-placement='editor'] & {
+		margin-top: 0;
 	}
 
-	h2[data-bind='title'] {
-		grid-area: title;
-		margin-bottom: 0;
+	&--context {
+		grid-area: context;
+		display: grid;
+		grid-template-columns: minmax(0, min-content) minmax(0, min-content) minmax(0, 1fr);
+		gap: 0.5rem;
+		align-items: baseline;
+
+		h2 {
+			text-overflow: ellipsis;
+			white-space: nowrap;
+			overflow: hidden;
+		}
+
+		body:not([data-placement='editor']) & {
+			display: none;
+		}
 	}
 
 	h2[data-bind='sha'] {
-		grid-area: sha;
 		font-size: 1.3em;
 		font-weight: 200;
-		margin-left: 1.5rem;
 		opacity: 0.7;
 		white-space: nowrap;
 
@@ -132,17 +97,16 @@ span.button-subaction {
 	}
 
 	h2[data-bind='description'] {
-		grid-area: description;
 		font-size: 1.3em;
 		font-weight: 200;
-		margin-left: 1.5rem;
+		margin-left: 0.5rem;
 		opacity: 0.7;
-		overflow-wrap: anywhere;
 	}
 
 	.toolbox {
 		grid-area: toolbox;
 		display: flex;
+		gap: 0.3rem;
 	}
 }
 
@@ -160,30 +124,32 @@ span.button-subaction {
 
 #content {
 	position: relative;
-	overflow: hidden;
 	width: 100%;
+	height: 100%;
 }
 
 #chart {
+	position: absolute !important;
 	height: 100%;
 	width: 100%;
-	overflow: hidden;
-}
 
-#chart-empty-overlay {
-	display: flex;
-	align-items: center;
-	justify-content: center;
+	body:not([data-placement='editor']) & {
+		left: -16px;
+	}
+}
 
+#empty {
 	position: absolute;
 	top: 0;
 	left: 0;
-	width: 100vw;
-	height: 60vh;
+	bottom: 0;
+	right: 0;
+	padding: 0.4rem 2rem 1.3rem 2rem;
 
-	h1 {
-		font-size: var(--font-size);
-		font-weight: 400;
+	font-size: var(--font-size);
+
+	p {
+		margin-top: 0;
 	}
 }
 
@@ -191,60 +157,28 @@ span.button-subaction {
 	display: none;
 }
 
-#overlay {
-	position: absolute;
-	top: 0;
-	left: 0;
-	width: 100%;
-	height: 100%;
-	font-size: 1.3em;
-	min-height: 100%;
-	padding: 0 2rem 2rem 2rem;
-
-	backdrop-filter: blur(3px) saturate(0.8);
-
-	display: flex;
-	flex-direction: column;
-	align-items: center;
-	justify-content: center;
+body[data-placement='editor'] {
+	[data-placement-hidden='editor'],
+	[data-placement-visible]:not([data-placement-visible='editor']) {
+		display: none !important;
+	}
 }
 
-.modal {
-	max-width: 600px;
-	background: var(--color-hover-background) no-repeat left top;
-	background-image: var(--gl-plus-bg);
-	border: 1px solid var(--color-hover-border);
-	border-radius: 0.4rem;
-	margin: 1rem;
-	padding: 1.2rem;
-
-	> p:first-child {
-		margin-top: 0;
+body[data-placement='view'] {
+	[data-placement-hidden='view'],
+	[data-placement-visible]:not([data-placement-visible='view']) {
+		display: none !important;
 	}
+}
 
-	vscode-button:not([appearance='icon']) {
-		align-self: center !important;
+body:not([data-placement='editor']) {
+	.bb-tooltip-container {
+		padding-left: 16px;
 	}
 }
 
-.hidden {
+[hidden] {
 	display: none !important;
 }
 
 @import './chart';
-@import '../../shared/codicons.scss';
-@import '../../shared/glicons.scss';
-
-.glicon {
-	vertical-align: middle;
-}
-
-.glicon,
-.codicon {
-	position: relative;
-	top: -1px;
-}
-
-.mt-tight {
-	margin-top: 0.3rem;
-}
diff --git a/src/webviews/apps/plus/timeline/timeline.ts b/src/webviews/apps/plus/timeline/timeline.ts
index 656a75f..7036e5c 100644
--- a/src/webviews/apps/plus/timeline/timeline.ts
+++ b/src/webviews/apps/plus/timeline/timeline.ts
@@ -1,22 +1,23 @@
 /*global*/
 import './timeline.scss';
-import { provideVSCodeDesignSystem, vsCodeButton, vsCodeDropdown, vsCodeOption } from '@vscode/webview-ui-toolkit';
-import { GlyphChars } from '../../../../constants';
+import { provideVSCodeDesignSystem, vsCodeDropdown, vsCodeOption } from '@vscode/webview-ui-toolkit';
 import type { Period, State } from '../../../../plus/webviews/timeline/protocol';
 import {
 	DidChangeNotificationType,
 	OpenDataPointCommandType,
 	UpdatePeriodCommandType,
 } from '../../../../plus/webviews/timeline/protocol';
-import { SubscriptionPlanId, SubscriptionState } from '../../../../subscription';
 import type { IpcMessage } from '../../../protocol';
-import { ExecuteCommandType, onIpc } from '../../../protocol';
+import { onIpc } from '../../../protocol';
 import { App } from '../../shared/appBase';
 import { DOM } from '../../shared/dom';
+import type { PlusFeatureWelcome } from '../shared/components/plus-feature-welcome';
 import type { DataPointClickEvent } from './chart';
 import { TimelineChart } from './chart';
 import '../../shared/components/code-icon';
 import '../../shared/components/progress';
+import '../../shared/components/button';
+import '../shared/components/plus-feature-welcome';
 
 export class TimelineApp extends App<State> {
 	private _chart: TimelineChart | undefined;
@@ -26,7 +27,7 @@ export class TimelineApp extends App<State> {
 	}
 
 	protected override onInitialize() {
-		provideVSCodeDesignSystem().register(vsCodeButton(), vsCodeDropdown(), vsCodeOption());
+		provideVSCodeDesignSystem().register(vsCodeDropdown(), vsCodeOption());
 
 		this.updateState();
 	}
@@ -35,11 +36,11 @@ export class TimelineApp extends App<State> {
 		const disposables = super.onBind?.() ?? [];
 
 		disposables.push(
-			DOM.on('[data-action]', 'click', (e, target: HTMLElement) => this.onActionClicked(e, target)),
 			DOM.on(document, 'keydown', (e: KeyboardEvent) => this.onKeyDown(e)),
 			DOM.on(document.getElementById('periods')! as HTMLSelectElement, 'change', (e, target) =>
 				this.onPeriodChanged(e, target),
 			),
+			{ dispose: () => this._chart?.dispose() },
 		);
 
 		return disposables;
@@ -64,17 +65,6 @@ export class TimelineApp extends App<State> {
 		}
 	}
 
-	protected override setState(state: Partial<State>) {
-		super.setState({ period: state.period, uri: state.uri });
-	}
-
-	private onActionClicked(e: MouseEvent, target: HTMLElement) {
-		const action = target.dataset.action;
-		if (action?.startsWith('command:')) {
-			this.sendCommand(ExecuteCommandType, { command: action.slice(8) });
-		}
-	}
-
 	private onChartDataPointClicked(e: DataPointClickEvent) {
 		this.sendCommand(OpenDataPointCommandType, e);
 	}
@@ -96,69 +86,39 @@ export class TimelineApp extends App<State> {
 	}
 
 	private updateState(): void {
-		const $overlay = document.getElementById('overlay') as HTMLDivElement;
-		$overlay.classList.toggle('hidden', this.state.access.allowed === true);
-
-		const $slot = document.getElementById('overlay-slot') as HTMLDivElement;
-
-		if (this.state.access.allowed === false) {
-			const { current: subscription, required } = this.state.access.subscription;
-
-			const requiresPublic = required === SubscriptionPlanId.FreePlus;
-			const options = { visible: { public: requiresPublic, private: !requiresPublic } };
-
-			if (subscription.account?.verified === false) {
-				DOM.insertTemplate('state:verify-email', $slot, options);
-				return;
-			}
-
-			switch (subscription.state) {
-				case SubscriptionState.Free:
-					DOM.insertTemplate('state:free', $slot, options);
-					break;
-				case SubscriptionState.FreePreviewTrialExpired:
-					DOM.insertTemplate('state:free-preview-trial-expired', $slot, options);
-					break;
-				case SubscriptionState.FreePlusTrialExpired:
-					DOM.insertTemplate('state:plus-trial-expired', $slot, options);
-					break;
-			}
-
-			if (this.state.dataset == null) return;
-		} else {
-			$slot.innerHTML = '';
+		const $welcome = document.getElementsByTagName('plus-feature-welcome')?.[0] as PlusFeatureWelcome;
+		if ($welcome != null) {
+			$welcome.state = this.state.access.subscription.current.state;
+			$welcome.allowed = this.state.access.allowed === true || this.state.uri == null;
 		}
 
 		if (this._chart == null) {
-			this._chart = new TimelineChart('#chart');
+			this._chart = new TimelineChart('#chart', this.placement);
 			this._chart.onDidClickDataPoint(this.onChartDataPointClicked, this);
 		}
 
 		let { title, sha } = this.state;
 
 		let description = '';
-		const index = title.lastIndexOf('/');
-		if (index >= 0) {
-			const name = title.substring(index + 1);
-			description = title.substring(0, index);
-			title = name;
+		if (title != null) {
+			const index = title.lastIndexOf('/');
+			if (index >= 0) {
+				const name = title.substring(index + 1);
+				description = title.substring(0, index);
+				title = name;
+			}
+		} else if (this.placement === 'editor' && this.state.dataset == null && !this.state.access.allowed) {
+			title = 'index.ts';
+			description = 'src/app';
 		}
 
-		function updateBoundData(
-			key: string,
-			value: string | undefined,
-			options?: { hideIfEmpty?: boolean; html?: boolean },
-		) {
+		function updateBoundData(key: string, value: string | undefined, options?: { html?: boolean }) {
 			const $el = document.querySelector(`[data-bind="${key}"]`);
 			if ($el != null) {
-				const empty = value == null || value.length === 0;
-				if (options?.hideIfEmpty) {
-					$el.classList.toggle('hidden', empty);
-				}
-				if (options?.html && !empty) {
-					$el.innerHTML = value;
+				if (options?.html) {
+					$el.innerHTML = value ?? '';
 				} else {
-					$el.textContent = String(value) || GlyphChars.Space;
+					$el.textContent = value ?? '';
 				}
 			}
 		}
@@ -171,7 +131,6 @@ export class TimelineApp extends App<State> {
 				? /*html*/ `<code-icon icon="git-commit" size="16"></code-icon><span class="sha">${sha}</span>`
 				: undefined,
 			{
-				hideIfEmpty: true,
 				html: true,
 			},
 		);
diff --git a/src/webviews/apps/shared/components/button.ts b/src/webviews/apps/shared/components/button.ts
new file mode 100644
index 0000000..e9112a4
--- /dev/null
+++ b/src/webviews/apps/shared/components/button.ts
@@ -0,0 +1,106 @@
+import { css, html, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { focusOutline } from './styles/lit/a11y.css';
+import { elementBase } from './styles/lit/base.css';
+
+@customElement('gk-button')
+export class GKButton extends LitElement {
+	static override styles = [
+		elementBase,
+		css`
+			:host {
+				--button-foreground: var(--vscode-button-foreground);
+				--button-background: var(--vscode-button-background);
+				--button-hover-background: var(--vscode-button-hoverBackground);
+				--button-padding: 0.4rem 1.1rem;
+				--button-border: var(--vscode-button-border, transparent);
+
+				display: inline-block;
+				border: none;
+				font-family: inherit;
+				font-size: inherit;
+				line-height: 1.694;
+				text-align: center;
+				text-decoration: none;
+				user-select: none;
+				background: var(--button-background);
+				color: var(--button-foreground);
+				cursor: pointer;
+				border: 1px solid var(--button-border);
+				border-radius: var(--gk-action-radius);
+			}
+
+			:host(:not([href])) {
+				padding: var(--button-padding);
+			}
+
+			:host([href]) > a {
+				display: inline-block;
+				padding: var(--button-padding);
+
+				color: inherit;
+				text-decoration: none;
+
+				width: 100%;
+				height: 100%;
+			}
+
+			:host(:hover) {
+				background: var(--button-hover-background);
+			}
+
+			:host(:focus) {
+				${focusOutline}
+			}
+
+			:host([full]) {
+				width: 100%;
+			}
+
+			:host([appearance='secondary']) {
+				--button-background: var(--vscode-button-secondaryBackground);
+				--button-foreground: var(--vscode-button-secondaryForeground);
+				--button-hover-background: var(--vscode-button-secondaryHoverBackground);
+			}
+
+			:host([appearance='toolbar']) {
+				--button-background: transparent;
+				--button-foreground: var(--vscode-foreground);
+				--button-hover-background: var(--vscode-toolbar-hoverBackground);
+				--button-padding: 0.45rem 0.4rem 0.14rem 0.4rem;
+				line-height: 1.64;
+			}
+
+			:host([appearance='alert']) {
+				--button-background: transparent;
+				--button-border: var(--color-alert-infoBorder);
+				--button-foreground: var(--color-button-foreground);
+				--button-hover-background: var(--color-alert-infoBorder);
+				--button-padding: 0.4rem;
+				line-height: 1.64;
+			}
+		`,
+	];
+
+	@property({ type: Boolean, reflect: true })
+	full = false;
+
+	@property()
+	href?: string;
+
+	@property({ reflect: true })
+	override get role() {
+		return this.href ? 'link' : 'button';
+	}
+
+	@property()
+	appearance?: string;
+
+	@property({ type: Number, reflect: true })
+	override tabIndex = 0;
+
+	override render() {
+		const main = html`<slot></slot>`;
+		return this.href != null ? html`<a href=${this.href}>${main}</a>` : main;
+	}
+}
diff --git a/src/webviews/apps/shared/components/code-icon.ts b/src/webviews/apps/shared/components/code-icon.ts
index 7edf875..f469001 100644
--- a/src/webviews/apps/shared/components/code-icon.ts
+++ b/src/webviews/apps/shared/components/code-icon.ts
@@ -1,1551 +1,1646 @@
-import { attr, css, customElement, FASTElement } from '@microsoft/fast-element';
+import { css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
 
-const styles = css`
-	:host {
-		font: normal normal normal var(--code-icon-size, 16px) / 1 codicon;
-		display: inline-block;
-		text-decoration: none;
-		text-rendering: auto;
-		text-align: center;
-		-webkit-font-smoothing: antialiased;
-		-moz-osx-font-smoothing: grayscale;
-		user-select: none;
-		-webkit-user-select: none;
-		-ms-user-select: none;
-		color: inherit;
-		vertical-align: text-bottom;
-		letter-spacing: normal;
-	}
+@customElement('code-icon')
+export class CodeIcon extends LitElement {
+	static override styles = css`
+		:host {
+			font: normal normal normal var(--code-icon-size, 16px) / 1 codicon;
+			display: inline-block;
+			text-decoration: none;
+			text-rendering: auto;
+			text-align: center;
+			-webkit-font-smoothing: antialiased;
+			-moz-osx-font-smoothing: grayscale;
+			user-select: none;
+			-webkit-user-select: none;
+			-ms-user-select: none;
+			color: inherit;
+			vertical-align: text-bottom;
+			letter-spacing: normal;
+		}
 
-	:host([icon='add']):before {
-		content: '\\ea60';
-	}
-	:host([icon='plus']):before {
-		content: '\\ea60';
-	}
-	:host([icon='gist-new']):before {
-		content: '\\ea60';
-	}
-	:host([icon='repo-create']):before {
-		content: '\\ea60';
-	}
-	:host([icon='lightbulb']):before {
-		content: '\\ea61';
-	}
-	:host([icon='light-bulb']):before {
-		content: '\\ea61';
-	}
-	:host([icon='repo']):before {
-		content: '\\ea62';
-	}
-	:host([icon='repo-delete']):before {
-		content: '\\ea62';
-	}
-	:host([icon='gist-fork']):before {
-		content: '\\ea63';
-	}
-	:host([icon='repo-forked']):before {
-		content: '\\ea63';
-	}
-	:host([icon='git-pull-request']):before {
-		content: '\\ea64';
-	}
-	:host([icon='git-pull-request-abandoned']):before {
-		content: '\\ea64';
-	}
-	:host([icon='record-keys']):before {
-		content: '\\ea65';
-	}
-	:host([icon='keyboard']):before {
-		content: '\\ea65';
-	}
-	:host([icon='tag']):before {
-		content: '\\ea66';
-	}
-	:host([icon='tag-add']):before {
-		content: '\\ea66';
-	}
-	:host([icon='tag-remove']):before {
-		content: '\\ea66';
-	}
-	:host([icon='person']):before {
-		content: '\\ea67';
-	}
-	:host([icon='person-follow']):before {
-		content: '\\ea67';
-	}
-	:host([icon='person-outline']):before {
-		content: '\\ea67';
-	}
-	:host([icon='person-filled']):before {
-		content: '\\ea67';
-	}
-	:host([icon='git-branch']):before {
-		content: '\\ea68';
-	}
-	:host([icon='git-branch-create']):before {
-		content: '\\ea68';
-	}
-	:host([icon='git-branch-delete']):before {
-		content: '\\ea68';
-	}
-	:host([icon='source-control']):before {
-		content: '\\ea68';
-	}
-	:host([icon='mirror']):before {
-		content: '\\ea69';
-	}
-	:host([icon='mirror-public']):before {
-		content: '\\ea69';
-	}
-	:host([icon='star']):before {
-		content: '\\ea6a';
-	}
-	:host([icon='star-add']):before {
-		content: '\\ea6a';
-	}
-	:host([icon='star-delete']):before {
-		content: '\\ea6a';
-	}
-	:host([icon='star-empty']):before {
-		content: '\\ea6a';
-	}
-	:host([icon='comment']):before {
-		content: '\\ea6b';
-	}
-	:host([icon='comment-add']):before {
-		content: '\\ea6b';
-	}
-	:host([icon='alert']):before {
-		content: '\\ea6c';
-	}
-	:host([icon='warning']):before {
-		content: '\\ea6c';
-	}
-	:host([icon='search']):before {
-		content: '\\ea6d';
-	}
-	:host([icon='search-save']):before {
-		content: '\\ea6d';
-	}
-	:host([icon='log-out']):before {
-		content: '\\ea6e';
-	}
-	:host([icon='sign-out']):before {
-		content: '\\ea6e';
-	}
-	:host([icon='log-in']):before {
-		content: '\\ea6f';
-	}
-	:host([icon='sign-in']):before {
-		content: '\\ea6f';
-	}
-	:host([icon='eye']):before {
-		content: '\\ea70';
-	}
-	:host([icon='eye-unwatch']):before {
-		content: '\\ea70';
-	}
-	:host([icon='eye-watch']):before {
-		content: '\\ea70';
-	}
-	:host([icon='circle-filled']):before {
-		content: '\\ea71';
-	}
-	:host([icon='primitive-dot']):before {
-		content: '\\ea71';
-	}
-	:host([icon='close-dirty']):before {
-		content: '\\ea71';
-	}
-	:host([icon='debug-breakpoint']):before {
-		content: '\\ea71';
-	}
-	:host([icon='debug-breakpoint-disabled']):before {
-		content: '\\ea71';
-	}
-	:host([icon='debug-hint']):before {
-		content: '\\ea71';
-	}
-	:host([icon='primitive-square']):before {
-		content: '\\ea72';
-	}
-	:host([icon='edit']):before {
-		content: '\\ea73';
-	}
-	:host([icon='pencil']):before {
-		content: '\\ea73';
-	}
-	:host([icon='info']):before {
-		content: '\\ea74';
-	}
-	:host([icon='issue-opened']):before {
-		content: '\\ea74';
-	}
-	:host([icon='gist-private']):before {
-		content: '\\ea75';
-	}
-	:host([icon='git-fork-private']):before {
-		content: '\\ea75';
-	}
-	:host([icon='lock']):before {
-		content: '\\ea75';
-	}
-	:host([icon='mirror-private']):before {
-		content: '\\ea75';
-	}
-	:host([icon='close']):before {
-		content: '\\ea76';
-	}
-	:host([icon='remove-close']):before {
-		content: '\\ea76';
-	}
-	:host([icon='x']):before {
-		content: '\\ea76';
-	}
-	:host([icon='repo-sync']):before {
-		content: '\\ea77';
-	}
-	:host([icon='sync']):before {
-		content: '\\ea77';
-	}
-	:host([icon='clone']):before {
-		content: '\\ea78';
-	}
-	:host([icon='desktop-download']):before {
-		content: '\\ea78';
-	}
-	:host([icon='beaker']):before {
-		content: '\\ea79';
-	}
-	:host([icon='microscope']):before {
-		content: '\\ea79';
-	}
-	:host([icon='vm']):before {
-		content: '\\ea7a';
-	}
-	:host([icon='device-desktop']):before {
-		content: '\\ea7a';
-	}
-	:host([icon='file']):before {
-		content: '\\ea7b';
-	}
-	:host([icon='file-text']):before {
-		content: '\\ea7b';
-	}
-	:host([icon='more']):before {
-		content: '\\ea7c';
-	}
-	:host([icon='ellipsis']):before {
-		content: '\\ea7c';
-	}
-	:host([icon='kebab-horizontal']):before {
-		content: '\\ea7c';
-	}
-	:host([icon='mail-reply']):before {
-		content: '\\ea7d';
-	}
-	:host([icon='reply']):before {
-		content: '\\ea7d';
-	}
-	:host([icon='organization']):before {
-		content: '\\ea7e';
-	}
-	:host([icon='organization-filled']):before {
-		content: '\\ea7e';
-	}
-	:host([icon='organization-outline']):before {
-		content: '\\ea7e';
-	}
-	:host([icon='new-file']):before {
-		content: '\\ea7f';
-	}
-	:host([icon='file-add']):before {
-		content: '\\ea7f';
-	}
-	:host([icon='new-folder']):before {
-		content: '\\ea80';
-	}
-	:host([icon='file-directory-create']):before {
-		content: '\\ea80';
-	}
-	:host([icon='trash']):before {
-		content: '\\ea81';
-	}
-	:host([icon='trashcan']):before {
-		content: '\\ea81';
-	}
-	:host([icon='history']):before {
-		content: '\\ea82';
-	}
-	:host([icon='clock']):before {
-		content: '\\ea82';
-	}
-	:host([icon='folder']):before {
-		content: '\\ea83';
-	}
-	:host([icon='file-directory']):before {
-		content: '\\ea83';
-	}
-	:host([icon='symbol-folder']):before {
-		content: '\\ea83';
-	}
-	:host([icon='logo-github']):before {
-		content: '\\ea84';
-	}
-	:host([icon='mark-github']):before {
-		content: '\\ea84';
-	}
-	:host([icon='github']):before {
-		content: '\\ea84';
-	}
-	:host([icon='terminal']):before {
-		content: '\\ea85';
-	}
-	:host([icon='console']):before {
-		content: '\\ea85';
-	}
-	:host([icon='repl']):before {
-		content: '\\ea85';
-	}
-	:host([icon='zap']):before {
-		content: '\\ea86';
-	}
-	:host([icon='symbol-event']):before {
-		content: '\\ea86';
-	}
-	:host([icon='error']):before {
-		content: '\\ea87';
-	}
-	:host([icon='stop']):before {
-		content: '\\ea87';
-	}
-	:host([icon='variable']):before {
-		content: '\\ea88';
-	}
-	:host([icon='symbol-variable']):before {
-		content: '\\ea88';
-	}
-	:host([icon='array']):before {
-		content: '\\ea8a';
-	}
-	:host([icon='symbol-array']):before {
-		content: '\\ea8a';
-	}
-	:host([icon='symbol-module']):before {
-		content: '\\ea8b';
-	}
-	:host([icon='symbol-package']):before {
-		content: '\\ea8b';
-	}
-	:host([icon='symbol-namespace']):before {
-		content: '\\ea8b';
-	}
-	:host([icon='symbol-object']):before {
-		content: '\\ea8b';
-	}
-	:host([icon='symbol-method']):before {
-		content: '\\ea8c';
-	}
-	:host([icon='symbol-function']):before {
-		content: '\\ea8c';
-	}
-	:host([icon='symbol-constructor']):before {
-		content: '\\ea8c';
-	}
-	:host([icon='symbol-boolean']):before {
-		content: '\\ea8f';
-	}
-	:host([icon='symbol-null']):before {
-		content: '\\ea8f';
-	}
-	:host([icon='symbol-numeric']):before {
-		content: '\\ea90';
-	}
-	:host([icon='symbol-number']):before {
-		content: '\\ea90';
-	}
-	:host([icon='symbol-structure']):before {
-		content: '\\ea91';
-	}
-	:host([icon='symbol-struct']):before {
-		content: '\\ea91';
-	}
-	:host([icon='symbol-parameter']):before {
-		content: '\\ea92';
-	}
-	:host([icon='symbol-type-parameter']):before {
-		content: '\\ea92';
-	}
-	:host([icon='symbol-key']):before {
-		content: '\\ea93';
-	}
-	:host([icon='symbol-text']):before {
-		content: '\\ea93';
-	}
-	:host([icon='symbol-reference']):before {
-		content: '\\ea94';
-	}
-	:host([icon='go-to-file']):before {
-		content: '\\ea94';
-	}
-	:host([icon='symbol-enum']):before {
-		content: '\\ea95';
-	}
-	:host([icon='symbol-value']):before {
-		content: '\\ea95';
-	}
-	:host([icon='symbol-ruler']):before {
-		content: '\\ea96';
-	}
-	:host([icon='symbol-unit']):before {
-		content: '\\ea96';
-	}
-	:host([icon='activate-breakpoints']):before {
-		content: '\\ea97';
-	}
-	:host([icon='archive']):before {
-		content: '\\ea98';
-	}
-	:host([icon='arrow-both']):before {
-		content: '\\ea99';
-	}
-	:host([icon='arrow-down']):before {
-		content: '\\ea9a';
-	}
-	:host([icon='arrow-left']):before {
-		content: '\\ea9b';
-	}
-	:host([icon='arrow-right']):before {
-		content: '\\ea9c';
-	}
-	:host([icon='arrow-small-down']):before {
-		content: '\\ea9d';
-	}
-	:host([icon='arrow-small-left']):before {
-		content: '\\ea9e';
-	}
-	:host([icon='arrow-small-right']):before {
-		content: '\\ea9f';
-	}
-	:host([icon='arrow-small-up']):before {
-		content: '\\eaa0';
-	}
-	:host([icon='arrow-up']):before {
-		content: '\\eaa1';
-	}
-	:host([icon='bell']):before {
-		content: '\\eaa2';
-	}
-	:host([icon='bold']):before {
-		content: '\\eaa3';
-	}
-	:host([icon='book']):before {
-		content: '\\eaa4';
-	}
-	:host([icon='bookmark']):before {
-		content: '\\eaa5';
-	}
-	:host([icon='debug-breakpoint-conditional-unverified']):before {
-		content: '\\eaa6';
-	}
-	:host([icon='debug-breakpoint-conditional']):before {
-		content: '\\eaa7';
-	}
-	:host([icon='debug-breakpoint-conditional-disabled']):before {
-		content: '\\eaa7';
-	}
-	:host([icon='debug-breakpoint-data-unverified']):before {
-		content: '\\eaa8';
-	}
-	:host([icon='debug-breakpoint-data']):before {
-		content: '\\eaa9';
-	}
-	:host([icon='debug-breakpoint-data-disabled']):before {
-		content: '\\eaa9';
-	}
-	:host([icon='debug-breakpoint-log-unverified']):before {
-		content: '\\eaaa';
-	}
-	:host([icon='debug-breakpoint-log']):before {
-		content: '\\eaab';
-	}
-	:host([icon='debug-breakpoint-log-disabled']):before {
-		content: '\\eaab';
-	}
-	:host([icon='briefcase']):before {
-		content: '\\eaac';
-	}
-	:host([icon='broadcast']):before {
-		content: '\\eaad';
-	}
-	:host([icon='browser']):before {
-		content: '\\eaae';
-	}
-	:host([icon='bug']):before {
-		content: '\\eaaf';
-	}
-	:host([icon='calendar']):before {
-		content: '\\eab0';
-	}
-	:host([icon='case-sensitive']):before {
-		content: '\\eab1';
-	}
-	:host([icon='check']):before {
-		content: '\\eab2';
-	}
-	:host([icon='checklist']):before {
-		content: '\\eab3';
-	}
-	:host([icon='chevron-down']):before {
-		content: '\\eab4';
-	}
-	:host([icon='chevron-left']):before {
-		content: '\\eab5';
-	}
-	:host([icon='chevron-right']):before {
-		content: '\\eab6';
-	}
-	:host([icon='chevron-up']):before {
-		content: '\\eab7';
-	}
-	:host([icon='chrome-close']):before {
-		content: '\\eab8';
-	}
-	:host([icon='chrome-maximize']):before {
-		content: '\\eab9';
-	}
-	:host([icon='chrome-minimize']):before {
-		content: '\\eaba';
-	}
-	:host([icon='chrome-restore']):before {
-		content: '\\eabb';
-	}
-	:host([icon='circle-outline']):before {
-		content: '\\eabc';
-	}
-	:host([icon='debug-breakpoint-unverified']):before {
-		content: '\\eabc';
-	}
-	:host([icon='circle-slash']):before {
-		content: '\\eabd';
-	}
-	:host([icon='circuit-board']):before {
-		content: '\\eabe';
-	}
-	:host([icon='clear-all']):before {
-		content: '\\eabf';
-	}
-	:host([icon='clippy']):before {
-		content: '\\eac0';
-	}
-	:host([icon='close-all']):before {
-		content: '\\eac1';
-	}
-	:host([icon='cloud-download']):before {
-		content: '\\eac2';
-	}
-	:host([icon='cloud-upload']):before {
-		content: '\\eac3';
-	}
-	:host([icon='code']):before {
-		content: '\\eac4';
-	}
-	:host([icon='collapse-all']):before {
-		content: '\\eac5';
-	}
-	:host([icon='color-mode']):before {
-		content: '\\eac6';
-	}
-	:host([icon='comment-discussion']):before {
-		content: '\\eac7';
-	}
-	:host([icon='credit-card']):before {
-		content: '\\eac9';
-	}
-	:host([icon='dash']):before {
-		content: '\\eacc';
-	}
-	:host([icon='dashboard']):before {
-		content: '\\eacd';
-	}
-	:host([icon='database']):before {
-		content: '\\eace';
-	}
-	:host([icon='debug-continue']):before {
-		content: '\\eacf';
-	}
-	:host([icon='debug-disconnect']):before {
-		content: '\\ead0';
-	}
-	:host([icon='debug-pause']):before {
-		content: '\\ead1';
-	}
-	:host([icon='debug-restart']):before {
-		content: '\\ead2';
-	}
-	:host([icon='debug-start']):before {
-		content: '\\ead3';
-	}
-	:host([icon='debug-step-into']):before {
-		content: '\\ead4';
-	}
-	:host([icon='debug-step-out']):before {
-		content: '\\ead5';
-	}
-	:host([icon='debug-step-over']):before {
-		content: '\\ead6';
-	}
-	:host([icon='debug-stop']):before {
-		content: '\\ead7';
-	}
-	:host([icon='debug']):before {
-		content: '\\ead8';
-	}
-	:host([icon='device-camera-video']):before {
-		content: '\\ead9';
-	}
-	:host([icon='device-camera']):before {
-		content: '\\eada';
-	}
-	:host([icon='device-mobile']):before {
-		content: '\\eadb';
-	}
-	:host([icon='diff-added']):before {
-		content: '\\eadc';
-	}
-	:host([icon='diff-ignored']):before {
-		content: '\\eadd';
-	}
-	:host([icon='diff-modified']):before {
-		content: '\\eade';
-	}
-	:host([icon='diff-removed']):before {
-		content: '\\eadf';
-	}
-	:host([icon='diff-renamed']):before {
-		content: '\\eae0';
-	}
-	:host([icon='diff']):before {
-		content: '\\eae1';
-	}
-	:host([icon='discard']):before {
-		content: '\\eae2';
-	}
-	:host([icon='editor-layout']):before {
-		content: '\\eae3';
-	}
-	:host([icon='empty-window']):before {
-		content: '\\eae4';
-	}
-	:host([icon='exclude']):before {
-		content: '\\eae5';
-	}
-	:host([icon='extensions']):before {
-		content: '\\eae6';
-	}
-	:host([icon='eye-closed']):before {
-		content: '\\eae7';
-	}
-	:host([icon='file-binary']):before {
-		content: '\\eae8';
-	}
-	:host([icon='file-code']):before {
-		content: '\\eae9';
-	}
-	:host([icon='file-media']):before {
-		content: '\\eaea';
-	}
-	:host([icon='file-pdf']):before {
-		content: '\\eaeb';
-	}
-	:host([icon='file-submodule']):before {
-		content: '\\eaec';
-	}
-	:host([icon='file-symlink-directory']):before {
-		content: '\\eaed';
-	}
-	:host([icon='file-symlink-file']):before {
-		content: '\\eaee';
-	}
-	:host([icon='file-zip']):before {
-		content: '\\eaef';
-	}
-	:host([icon='files']):before {
-		content: '\\eaf0';
-	}
-	:host([icon='filter']):before {
-		content: '\\eaf1';
-	}
-	:host([icon='flame']):before {
-		content: '\\eaf2';
-	}
-	:host([icon='fold-down']):before {
-		content: '\\eaf3';
-	}
-	:host([icon='fold-up']):before {
-		content: '\\eaf4';
-	}
-	:host([icon='fold']):before {
-		content: '\\eaf5';
-	}
-	:host([icon='folder-active']):before {
-		content: '\\eaf6';
-	}
-	:host([icon='folder-opened']):before {
-		content: '\\eaf7';
-	}
-	:host([icon='gear']):before {
-		content: '\\eaf8';
-	}
-	:host([icon='gift']):before {
-		content: '\\eaf9';
-	}
-	:host([icon='gist-secret']):before {
-		content: '\\eafa';
-	}
-	:host([icon='gist']):before {
-		content: '\\eafb';
-	}
-	:host([icon='git-commit']):before {
-		content: '\\eafc';
-	}
-	:host([icon='git-compare']):before {
-		content: '\\eafd';
-	}
-	:host([icon='compare-changes']):before {
-		content: '\\eafd';
-	}
-	:host([icon='git-merge']):before {
-		content: '\\eafe';
-	}
-	:host([icon='github-action']):before {
-		content: '\\eaff';
-	}
-	:host([icon='github-alt']):before {
-		content: '\\eb00';
-	}
-	:host([icon='globe']):before {
-		content: '\\eb01';
-	}
-	:host([icon='grabber']):before {
-		content: '\\eb02';
-	}
-	:host([icon='graph']):before {
-		content: '\\eb03';
-	}
-	:host([icon='gripper']):before {
-		content: '\\eb04';
-	}
-	:host([icon='heart']):before {
-		content: '\\eb05';
-	}
-	:host([icon='home']):before {
-		content: '\\eb06';
-	}
-	:host([icon='horizontal-rule']):before {
-		content: '\\eb07';
-	}
-	:host([icon='hubot']):before {
-		content: '\\eb08';
-	}
-	:host([icon='inbox']):before {
-		content: '\\eb09';
-	}
-	:host([icon='issue-reopened']):before {
-		content: '\\eb0b';
-	}
-	:host([icon='issues']):before {
-		content: '\\eb0c';
-	}
-	:host([icon='italic']):before {
-		content: '\\eb0d';
-	}
-	:host([icon='jersey']):before {
-		content: '\\eb0e';
-	}
-	:host([icon='json']):before {
-		content: '\\eb0f';
-	}
-	:host([icon='kebab-vertical']):before {
-		content: '\\eb10';
-	}
-	:host([icon='key']):before {
-		content: '\\eb11';
-	}
-	:host([icon='law']):before {
-		content: '\\eb12';
-	}
-	:host([icon='lightbulb-autofix']):before {
-		content: '\\eb13';
-	}
-	:host([icon='link-external']):before {
-		content: '\\eb14';
-	}
-	:host([icon='link']):before {
-		content: '\\eb15';
-	}
-	:host([icon='list-ordered']):before {
-		content: '\\eb16';
-	}
-	:host([icon='list-unordered']):before {
-		content: '\\eb17';
-	}
-	:host([icon='live-share']):before {
-		content: '\\eb18';
-	}
-	:host([icon='loading']):before {
-		content: '\\eb19';
-	}
-	:host([icon='location']):before {
-		content: '\\eb1a';
-	}
-	:host([icon='mail-read']):before {
-		content: '\\eb1b';
-	}
-	:host([icon='mail']):before {
-		content: '\\eb1c';
-	}
-	:host([icon='markdown']):before {
-		content: '\\eb1d';
-	}
-	:host([icon='megaphone']):before {
-		content: '\\eb1e';
-	}
-	:host([icon='mention']):before {
-		content: '\\eb1f';
-	}
-	:host([icon='milestone']):before {
-		content: '\\eb20';
-	}
-	:host([icon='mortar-board']):before {
-		content: '\\eb21';
-	}
-	:host([icon='move']):before {
-		content: '\\eb22';
-	}
-	:host([icon='multiple-windows']):before {
-		content: '\\eb23';
-	}
-	:host([icon='mute']):before {
-		content: '\\eb24';
-	}
-	:host([icon='no-newline']):before {
-		content: '\\eb25';
-	}
-	:host([icon='note']):before {
-		content: '\\eb26';
-	}
-	:host([icon='octoface']):before {
-		content: '\\eb27';
-	}
-	:host([icon='open-preview']):before {
-		content: '\\eb28';
-	}
-	:host([icon='package']):before {
-		content: '\\eb29';
-	}
-	:host([icon='paintcan']):before {
-		content: '\\eb2a';
-	}
-	:host([icon='pin']):before {
-		content: '\\eb2b';
-	}
-	:host([icon='play']):before {
-		content: '\\eb2c';
-	}
-	:host([icon='run']):before {
-		content: '\\eb2c';
-	}
-	:host([icon='plug']):before {
-		content: '\\eb2d';
-	}
-	:host([icon='preserve-case']):before {
-		content: '\\eb2e';
-	}
-	:host([icon='preview']):before {
-		content: '\\eb2f';
-	}
-	:host([icon='project']):before {
-		content: '\\eb30';
-	}
-	:host([icon='pulse']):before {
-		content: '\\eb31';
-	}
-	:host([icon='question']):before {
-		content: '\\eb32';
-	}
-	:host([icon='quote']):before {
-		content: '\\eb33';
-	}
-	:host([icon='radio-tower']):before {
-		content: '\\eb34';
-	}
-	:host([icon='reactions']):before {
-		content: '\\eb35';
-	}
-	:host([icon='references']):before {
-		content: '\\eb36';
-	}
-	:host([icon='refresh']):before {
-		content: '\\eb37';
-	}
-	:host([icon='regex']):before {
-		content: '\\eb38';
-	}
-	:host([icon='remote-explorer']):before {
-		content: '\\eb39';
-	}
-	:host([icon='remote']):before {
-		content: '\\eb3a';
-	}
-	:host([icon='remove']):before {
-		content: '\\eb3b';
-	}
-	:host([icon='replace-all']):before {
-		content: '\\eb3c';
-	}
-	:host([icon='replace']):before {
-		content: '\\eb3d';
-	}
-	:host([icon='repo-clone']):before {
-		content: '\\eb3e';
-	}
-	:host([icon='repo-force-push']):before {
-		content: '\\eb3f';
-	}
-	:host([icon='repo-pull']):before {
-		content: '\\eb40';
-	}
-	:host([icon='repo-push']):before {
-		content: '\\eb41';
-	}
-	:host([icon='report']):before {
-		content: '\\eb42';
-	}
-	:host([icon='request-changes']):before {
-		content: '\\eb43';
-	}
-	:host([icon='rocket']):before {
-		content: '\\eb44';
-	}
-	:host([icon='root-folder-opened']):before {
-		content: '\\eb45';
-	}
-	:host([icon='root-folder']):before {
-		content: '\\eb46';
-	}
-	:host([icon='rss']):before {
-		content: '\\eb47';
-	}
-	:host([icon='ruby']):before {
-		content: '\\eb48';
-	}
-	:host([icon='save-all']):before {
-		content: '\\eb49';
-	}
-	:host([icon='save-as']):before {
-		content: '\\eb4a';
-	}
-	:host([icon='save']):before {
-		content: '\\eb4b';
-	}
-	:host([icon='screen-full']):before {
-		content: '\\eb4c';
-	}
-	:host([icon='screen-normal']):before {
-		content: '\\eb4d';
-	}
-	:host([icon='search-stop']):before {
-		content: '\\eb4e';
-	}
-	:host([icon='server']):before {
-		content: '\\eb50';
-	}
-	:host([icon='settings-gear']):before {
-		content: '\\eb51';
-	}
-	:host([icon='settings']):before {
-		content: '\\eb52';
-	}
-	:host([icon='shield']):before {
-		content: '\\eb53';
-	}
-	:host([icon='smiley']):before {
-		content: '\\eb54';
-	}
-	:host([icon='sort-precedence']):before {
-		content: '\\eb55';
-	}
-	:host([icon='split-horizontal']):before {
-		content: '\\eb56';
-	}
-	:host([icon='split-vertical']):before {
-		content: '\\eb57';
-	}
-	:host([icon='squirrel']):before {
-		content: '\\eb58';
-	}
-	:host([icon='star-full']):before {
-		content: '\\eb59';
-	}
-	:host([icon='star-half']):before {
-		content: '\\eb5a';
-	}
-	:host([icon='symbol-class']):before {
-		content: '\\eb5b';
-	}
-	:host([icon='symbol-color']):before {
-		content: '\\eb5c';
-	}
-	:host([icon='symbol-constant']):before {
-		content: '\\eb5d';
-	}
-	:host([icon='symbol-enum-member']):before {
-		content: '\\eb5e';
-	}
-	:host([icon='symbol-field']):before {
-		content: '\\eb5f';
-	}
-	:host([icon='symbol-file']):before {
-		content: '\\eb60';
-	}
-	:host([icon='symbol-interface']):before {
-		content: '\\eb61';
-	}
-	:host([icon='symbol-keyword']):before {
-		content: '\\eb62';
-	}
-	:host([icon='symbol-misc']):before {
-		content: '\\eb63';
-	}
-	:host([icon='symbol-operator']):before {
-		content: '\\eb64';
-	}
-	:host([icon='symbol-property']):before {
-		content: '\\eb65';
-	}
-	:host([icon='wrench']):before {
-		content: '\\eb65';
-	}
-	:host([icon='wrench-subaction']):before {
-		content: '\\eb65';
-	}
-	:host([icon='symbol-snippet']):before {
-		content: '\\eb66';
-	}
-	:host([icon='tasklist']):before {
-		content: '\\eb67';
-	}
-	:host([icon='telescope']):before {
-		content: '\\eb68';
-	}
-	:host([icon='text-size']):before {
-		content: '\\eb69';
-	}
-	:host([icon='three-bars']):before {
-		content: '\\eb6a';
-	}
-	:host([icon='thumbsdown']):before {
-		content: '\\eb6b';
-	}
-	:host([icon='thumbsup']):before {
-		content: '\\eb6c';
-	}
-	:host([icon='tools']):before {
-		content: '\\eb6d';
-	}
-	:host([icon='triangle-down']):before {
-		content: '\\eb6e';
-	}
-	:host([icon='triangle-left']):before {
-		content: '\\eb6f';
-	}
-	:host([icon='triangle-right']):before {
-		content: '\\eb70';
-	}
-	:host([icon='triangle-up']):before {
-		content: '\\eb71';
-	}
-	:host([icon='twitter']):before {
-		content: '\\eb72';
-	}
-	:host([icon='unfold']):before {
-		content: '\\eb73';
-	}
-	:host([icon='unlock']):before {
-		content: '\\eb74';
-	}
-	:host([icon='unmute']):before {
-		content: '\\eb75';
-	}
-	:host([icon='unverified']):before {
-		content: '\\eb76';
-	}
-	:host([icon='verified']):before {
-		content: '\\eb77';
-	}
-	:host([icon='versions']):before {
-		content: '\\eb78';
-	}
-	:host([icon='vm-active']):before {
-		content: '\\eb79';
-	}
-	:host([icon='vm-outline']):before {
-		content: '\\eb7a';
-	}
-	:host([icon='vm-running']):before {
-		content: '\\eb7b';
-	}
-	:host([icon='watch']):before {
-		content: '\\eb7c';
-	}
-	:host([icon='whitespace']):before {
-		content: '\\eb7d';
-	}
-	:host([icon='whole-word']):before {
-		content: '\\eb7e';
-	}
-	:host([icon='window']):before {
-		content: '\\eb7f';
-	}
-	:host([icon='word-wrap']):before {
-		content: '\\eb80';
-	}
-	:host([icon='zoom-in']):before {
-		content: '\\eb81';
-	}
-	:host([icon='zoom-out']):before {
-		content: '\\eb82';
-	}
-	:host([icon='list-filter']):before {
-		content: '\\eb83';
-	}
-	:host([icon='list-flat']):before {
-		content: '\\eb84';
-	}
-	:host([icon='list-selection']):before {
-		content: '\\eb85';
-	}
-	:host([icon='selection']):before {
-		content: '\\eb85';
-	}
-	:host([icon='list-tree']):before {
-		content: '\\eb86';
-	}
-	:host([icon='debug-breakpoint-function-unverified']):before {
-		content: '\\eb87';
-	}
-	:host([icon='debug-breakpoint-function']):before {
-		content: '\\eb88';
-	}
-	:host([icon='debug-breakpoint-function-disabled']):before {
-		content: '\\eb88';
-	}
-	:host([icon='debug-stackframe-active']):before {
-		content: '\\eb89';
-	}
-	:host([icon='debug-stackframe-dot']):before {
-		content: '\\eb8a';
-	}
-	:host([icon='debug-stackframe']):before {
-		content: '\\eb8b';
-	}
-	:host([icon='debug-stackframe-focused']):before {
-		content: '\\eb8b';
-	}
-	:host([icon='debug-breakpoint-unsupported']):before {
-		content: '\\eb8c';
-	}
-	:host([icon='symbol-string']):before {
-		content: '\\eb8d';
-	}
-	:host([icon='debug-reverse-continue']):before {
-		content: '\\eb8e';
-	}
-	:host([icon='debug-step-back']):before {
-		content: '\\eb8f';
-	}
-	:host([icon='debug-restart-frame']):before {
-		content: '\\eb90';
-	}
-	:host([icon='debug-alt']):before {
-		content: '\\eb91';
-	}
-	:host([icon='call-incoming']):before {
-		content: '\\eb92';
-	}
-	:host([icon='call-outgoing']):before {
-		content: '\\eb93';
-	}
-	:host([icon='menu']):before {
-		content: '\\eb94';
-	}
-	:host([icon='expand-all']):before {
-		content: '\\eb95';
-	}
-	:host([icon='feedback']):before {
-		content: '\\eb96';
-	}
-	:host([icon='group-by-ref-type']):before {
-		content: '\\eb97';
-	}
-	:host([icon='ungroup-by-ref-type']):before {
-		content: '\\eb98';
-	}
-	:host([icon='account']):before {
-		content: '\\eb99';
-	}
-	:host([icon='bell-dot']):before {
-		content: '\\eb9a';
-	}
-	:host([icon='debug-console']):before {
-		content: '\\eb9b';
-	}
-	:host([icon='library']):before {
-		content: '\\eb9c';
-	}
-	:host([icon='output']):before {
-		content: '\\eb9d';
-	}
-	:host([icon='run-all']):before {
-		content: '\\eb9e';
-	}
-	:host([icon='sync-ignored']):before {
-		content: '\\eb9f';
-	}
-	:host([icon='pinned']):before {
-		content: '\\eba0';
-	}
-	:host([icon='github-inverted']):before {
-		content: '\\eba1';
-	}
-	:host([icon='server-process']):before {
-		content: '\\eba2';
-	}
-	:host([icon='server-environment']):before {
-		content: '\\eba3';
-	}
-	:host([icon='pass']):before {
-		content: '\\eba4';
-	}
-	:host([icon='issue-closed']):before {
-		content: '\\eba4';
-	}
-	:host([icon='stop-circle']):before {
-		content: '\\eba5';
-	}
-	:host([icon='play-circle']):before {
-		content: '\\eba6';
-	}
-	:host([icon='record']):before {
-		content: '\\eba7';
-	}
-	:host([icon='debug-alt-small']):before {
-		content: '\\eba8';
-	}
-	:host([icon='vm-connect']):before {
-		content: '\\eba9';
-	}
-	:host([icon='cloud']):before {
-		content: '\\ebaa';
-	}
-	:host([icon='merge']):before {
-		content: '\\ebab';
-	}
-	:host([icon='export']):before {
-		content: '\\ebac';
-	}
-	:host([icon='graph-left']):before {
-		content: '\\ebad';
-	}
-	:host([icon='magnet']):before {
-		content: '\\ebae';
-	}
-	:host([icon='notebook']):before {
-		content: '\\ebaf';
-	}
-	:host([icon='redo']):before {
-		content: '\\ebb0';
-	}
-	:host([icon='check-all']):before {
-		content: '\\ebb1';
-	}
-	:host([icon='pinned-dirty']):before {
-		content: '\\ebb2';
-	}
-	:host([icon='pass-filled']):before {
-		content: '\\ebb3';
-	}
-	:host([icon='circle-large-filled']):before {
-		content: '\\ebb4';
-	}
-	:host([icon='circle-large-outline']):before {
-		content: '\\ebb5';
-	}
-	:host([icon='combine']):before {
-		content: '\\ebb6';
-	}
-	:host([icon='gather']):before {
-		content: '\\ebb6';
-	}
-	:host([icon='table']):before {
-		content: '\\ebb7';
-	}
-	:host([icon='variable-group']):before {
-		content: '\\ebb8';
-	}
-	:host([icon='type-hierarchy']):before {
-		content: '\\ebb9';
-	}
-	:host([icon='type-hierarchy-sub']):before {
-		content: '\\ebba';
-	}
-	:host([icon='type-hierarchy-super']):before {
-		content: '\\ebbb';
-	}
-	:host([icon='git-pull-request-create']):before {
-		content: '\\ebbc';
-	}
-	:host([icon='run-above']):before {
-		content: '\\ebbd';
-	}
-	:host([icon='run-below']):before {
-		content: '\\ebbe';
-	}
-	:host([icon='notebook-template']):before {
-		content: '\\ebbf';
-	}
-	:host([icon='debug-rerun']):before {
-		content: '\\ebc0';
-	}
-	:host([icon='workspace-trusted']):before {
-		content: '\\ebc1';
-	}
-	:host([icon='workspace-untrusted']):before {
-		content: '\\ebc2';
-	}
-	:host([icon='workspace-unknown']):before {
-		content: '\\ebc3';
-	}
-	:host([icon='terminal-cmd']):before {
-		content: '\\ebc4';
-	}
-	:host([icon='terminal-debian']):before {
-		content: '\\ebc5';
-	}
-	:host([icon='terminal-linux']):before {
-		content: '\\ebc6';
-	}
-	:host([icon='terminal-powershell']):before {
-		content: '\\ebc7';
-	}
-	:host([icon='terminal-tmux']):before {
-		content: '\\ebc8';
-	}
-	:host([icon='terminal-ubuntu']):before {
-		content: '\\ebc9';
-	}
-	:host([icon='terminal-bash']):before {
-		content: '\\ebca';
-	}
-	:host([icon='arrow-swap']):before {
-		content: '\\ebcb';
-	}
-	:host([icon='copy']):before {
-		content: '\\ebcc';
-	}
-	:host([icon='person-add']):before {
-		content: '\\ebcd';
-	}
-	:host([icon='filter-filled']):before {
-		content: '\\ebce';
-	}
-	:host([icon='wand']):before {
-		content: '\\ebcf';
-	}
-	:host([icon='debug-line-by-line']):before {
-		content: '\\ebd0';
-	}
-	:host([icon='inspect']):before {
-		content: '\\ebd1';
-	}
-	:host([icon='layers']):before {
-		content: '\\ebd2';
-	}
-	:host([icon='layers-dot']):before {
-		content: '\\ebd3';
-	}
-	:host([icon='layers-active']):before {
-		content: '\\ebd4';
-	}
-	:host([icon='compass']):before {
-		content: '\\ebd5';
-	}
-	:host([icon='compass-dot']):before {
-		content: '\\ebd6';
-	}
-	:host([icon='compass-active']):before {
-		content: '\\ebd7';
-	}
-	:host([icon='azure']):before {
-		content: '\\ebd8';
-	}
-	:host([icon='issue-draft']):before {
-		content: '\\ebd9';
-	}
-	:host([icon='git-pull-request-closed']):before {
-		content: '\\ebda';
-	}
-	:host([icon='git-pull-request-draft']):before {
-		content: '\\ebdb';
-	}
-	:host([icon='debug-all']):before {
-		content: '\\ebdc';
-	}
-	:host([icon='debug-coverage']):before {
-		content: '\\ebdd';
-	}
-	:host([icon='run-errors']):before {
-		content: '\\ebde';
-	}
-	:host([icon='folder-library']):before {
-		content: '\\ebdf';
-	}
-	:host([icon='debug-continue-small']):before {
-		content: '\\ebe0';
-	}
-	:host([icon='beaker-stop']):before {
-		content: '\\ebe1';
-	}
-	:host([icon='graph-line']):before {
-		content: '\\ebe2';
-	}
-	:host([icon='graph-scatter']):before {
-		content: '\\ebe3';
-	}
-	:host([icon='pie-chart']):before {
-		content: '\\ebe4';
-	}
-	:host([icon='bracket']):before {
-		content: '\\eb0f';
-	}
-	:host([icon='bracket-dot']):before {
-		content: '\\ebe5';
-	}
-	:host([icon='bracket-error']):before {
-		content: '\\ebe6';
-	}
-	:host([icon='lock-small']):before {
-		content: '\\ebe7';
-	}
-	:host([icon='azure-devops']):before {
-		content: '\\ebe8';
-	}
-	:host([icon='verified-filled']):before {
-		content: '\\ebe9';
-	}
-	:host([icon='newline']):before {
-		content: '\\ebea';
-	}
-	:host([icon='layout']):before {
-		content: '\\ebeb';
-	}
-	:host([icon='layout-activitybar-left']):before {
-		content: '\\ebec';
-	}
-	:host([icon='layout-activitybar-right']):before {
-		content: '\\ebed';
-	}
-	:host([icon='layout-panel-left']):before {
-		content: '\\ebee';
-	}
-	:host([icon='layout-panel-center']):before {
-		content: '\\ebef';
-	}
-	:host([icon='layout-panel-justify']):before {
-		content: '\\ebf0';
-	}
-	:host([icon='layout-panel-right']):before {
-		content: '\\ebf1';
-	}
-	:host([icon='layout-panel']):before {
-		content: '\\ebf2';
-	}
-	:host([icon='layout-sidebar-left']):before {
-		content: '\\ebf3';
-	}
-	:host([icon='layout-sidebar-right']):before {
-		content: '\\ebf4';
-	}
-	:host([icon='layout-statusbar']):before {
-		content: '\\ebf5';
-	}
-	:host([icon='layout-menubar']):before {
-		content: '\\ebf6';
-	}
-	:host([icon='layout-centered']):before {
-		content: '\\ebf7';
-	}
-	:host([icon='target']):before {
-		content: '\\ebf8';
-	}
-	:host([icon^='gl-']) {
-		font-family: 'glicons';
-	}
-	:host([icon='gl-pinned-filled']):before {
-		content: '\\f11c';
-		/* TODO: see relative positioning needed in every use-case */
-		position: relative;
-		left: 1px;
-	}
-	:host([icon='gl-graph']):before {
-		content: '\\f102';
-	}
-	:host([icon='gl-list-auto']):before {
-		content: '\\f11a';
-	}
-	:host([icon='gl-clock']):before {
-		content: '\\f11d';
-	}
-	:host([icon='gl-worktrees-view']):before {
-		content: '\\f112';
-	}
-	:host([icon='gl-switch']):before {
-		content: '\\f118';
-	}
+		:host([icon='add']):before {
+			content: '\\ea60';
+		}
+		:host([icon='plus']):before {
+			content: '\\ea60';
+		}
+		:host([icon='gist-new']):before {
+			content: '\\ea60';
+		}
+		:host([icon='repo-create']):before {
+			content: '\\ea60';
+		}
+		:host([icon='lightbulb']):before {
+			content: '\\ea61';
+		}
+		:host([icon='light-bulb']):before {
+			content: '\\ea61';
+		}
+		:host([icon='repo']):before {
+			content: '\\ea62';
+		}
+		:host([icon='repo-delete']):before {
+			content: '\\ea62';
+		}
+		:host([icon='gist-fork']):before {
+			content: '\\ea63';
+		}
+		:host([icon='repo-forked']):before {
+			content: '\\ea63';
+		}
+		:host([icon='git-pull-request']):before {
+			content: '\\ea64';
+		}
+		:host([icon='git-pull-request-abandoned']):before {
+			content: '\\ea64';
+		}
+		:host([icon='record-keys']):before {
+			content: '\\ea65';
+		}
+		:host([icon='keyboard']):before {
+			content: '\\ea65';
+		}
+		:host([icon='tag']):before {
+			content: '\\ea66';
+		}
+		:host([icon='tag-add']):before {
+			content: '\\ea66';
+		}
+		:host([icon='tag-remove']):before {
+			content: '\\ea66';
+		}
+		:host([icon='person']):before {
+			content: '\\ea67';
+		}
+		:host([icon='person-follow']):before {
+			content: '\\ea67';
+		}
+		:host([icon='person-outline']):before {
+			content: '\\ea67';
+		}
+		:host([icon='person-filled']):before {
+			content: '\\ea67';
+		}
+		:host([icon='git-branch']):before {
+			content: '\\ea68';
+		}
+		:host([icon='git-branch-create']):before {
+			content: '\\ea68';
+		}
+		:host([icon='git-branch-delete']):before {
+			content: '\\ea68';
+		}
+		:host([icon='source-control']):before {
+			content: '\\ea68';
+		}
+		:host([icon='mirror']):before {
+			content: '\\ea69';
+		}
+		:host([icon='mirror-public']):before {
+			content: '\\ea69';
+		}
+		:host([icon='star']):before {
+			content: '\\ea6a';
+		}
+		:host([icon='star-add']):before {
+			content: '\\ea6a';
+		}
+		:host([icon='star-delete']):before {
+			content: '\\ea6a';
+		}
+		:host([icon='star-empty']):before {
+			content: '\\ea6a';
+		}
+		:host([icon='comment']):before {
+			content: '\\ea6b';
+		}
+		:host([icon='comment-add']):before {
+			content: '\\ea6b';
+		}
+		:host([icon='alert']):before {
+			content: '\\ea6c';
+		}
+		:host([icon='warning']):before {
+			content: '\\ea6c';
+		}
+		:host([icon='search']):before {
+			content: '\\ea6d';
+		}
+		:host([icon='search-save']):before {
+			content: '\\ea6d';
+		}
+		:host([icon='log-out']):before {
+			content: '\\ea6e';
+		}
+		:host([icon='sign-out']):before {
+			content: '\\ea6e';
+		}
+		:host([icon='log-in']):before {
+			content: '\\ea6f';
+		}
+		:host([icon='sign-in']):before {
+			content: '\\ea6f';
+		}
+		:host([icon='eye']):before {
+			content: '\\ea70';
+		}
+		:host([icon='eye-unwatch']):before {
+			content: '\\ea70';
+		}
+		:host([icon='eye-watch']):before {
+			content: '\\ea70';
+		}
+		:host([icon='circle-filled']):before {
+			content: '\\ea71';
+		}
+		:host([icon='primitive-dot']):before {
+			content: '\\ea71';
+		}
+		:host([icon='close-dirty']):before {
+			content: '\\ea71';
+		}
+		:host([icon='debug-breakpoint']):before {
+			content: '\\ea71';
+		}
+		:host([icon='debug-breakpoint-disabled']):before {
+			content: '\\ea71';
+		}
+		:host([icon='debug-hint']):before {
+			content: '\\ea71';
+		}
+		:host([icon='primitive-square']):before {
+			content: '\\ea72';
+		}
+		:host([icon='edit']):before {
+			content: '\\ea73';
+		}
+		:host([icon='pencil']):before {
+			content: '\\ea73';
+		}
+		:host([icon='info']):before {
+			content: '\\ea74';
+		}
+		:host([icon='issue-opened']):before {
+			content: '\\ea74';
+		}
+		:host([icon='gist-private']):before {
+			content: '\\ea75';
+		}
+		:host([icon='git-fork-private']):before {
+			content: '\\ea75';
+		}
+		:host([icon='lock']):before {
+			content: '\\ea75';
+		}
+		:host([icon='mirror-private']):before {
+			content: '\\ea75';
+		}
+		:host([icon='close']):before {
+			content: '\\ea76';
+		}
+		:host([icon='remove-close']):before {
+			content: '\\ea76';
+		}
+		:host([icon='x']):before {
+			content: '\\ea76';
+		}
+		:host([icon='repo-sync']):before {
+			content: '\\ea77';
+		}
+		:host([icon='sync']):before {
+			content: '\\ea77';
+		}
+		:host([icon='clone']):before {
+			content: '\\ea78';
+		}
+		:host([icon='desktop-download']):before {
+			content: '\\ea78';
+		}
+		:host([icon='beaker']):before {
+			content: '\\ea79';
+		}
+		:host([icon='microscope']):before {
+			content: '\\ea79';
+		}
+		:host([icon='vm']):before {
+			content: '\\ea7a';
+		}
+		:host([icon='device-desktop']):before {
+			content: '\\ea7a';
+		}
+		:host([icon='file']):before {
+			content: '\\ea7b';
+		}
+		:host([icon='file-text']):before {
+			content: '\\ea7b';
+		}
+		:host([icon='more']):before {
+			content: '\\ea7c';
+		}
+		:host([icon='ellipsis']):before {
+			content: '\\ea7c';
+		}
+		:host([icon='kebab-horizontal']):before {
+			content: '\\ea7c';
+		}
+		:host([icon='mail-reply']):before {
+			content: '\\ea7d';
+		}
+		:host([icon='reply']):before {
+			content: '\\ea7d';
+		}
+		:host([icon='organization']):before {
+			content: '\\ea7e';
+		}
+		:host([icon='organization-filled']):before {
+			content: '\\ea7e';
+		}
+		:host([icon='organization-outline']):before {
+			content: '\\ea7e';
+		}
+		:host([icon='new-file']):before {
+			content: '\\ea7f';
+		}
+		:host([icon='file-add']):before {
+			content: '\\ea7f';
+		}
+		:host([icon='new-folder']):before {
+			content: '\\ea80';
+		}
+		:host([icon='file-directory-create']):before {
+			content: '\\ea80';
+		}
+		:host([icon='trash']):before {
+			content: '\\ea81';
+		}
+		:host([icon='trashcan']):before {
+			content: '\\ea81';
+		}
+		:host([icon='history']):before {
+			content: '\\ea82';
+		}
+		:host([icon='clock']):before {
+			content: '\\ea82';
+		}
+		:host([icon='folder']):before {
+			content: '\\ea83';
+		}
+		:host([icon='file-directory']):before {
+			content: '\\ea83';
+		}
+		:host([icon='symbol-folder']):before {
+			content: '\\ea83';
+		}
+		:host([icon='logo-github']):before {
+			content: '\\ea84';
+		}
+		:host([icon='mark-github']):before {
+			content: '\\ea84';
+		}
+		:host([icon='github']):before {
+			content: '\\ea84';
+		}
+		:host([icon='terminal']):before {
+			content: '\\ea85';
+		}
+		:host([icon='console']):before {
+			content: '\\ea85';
+		}
+		:host([icon='repl']):before {
+			content: '\\ea85';
+		}
+		:host([icon='zap']):before {
+			content: '\\ea86';
+		}
+		:host([icon='symbol-event']):before {
+			content: '\\ea86';
+		}
+		:host([icon='error']):before {
+			content: '\\ea87';
+		}
+		:host([icon='stop']):before {
+			content: '\\ea87';
+		}
+		:host([icon='variable']):before {
+			content: '\\ea88';
+		}
+		:host([icon='symbol-variable']):before {
+			content: '\\ea88';
+		}
+		:host([icon='array']):before {
+			content: '\\ea8a';
+		}
+		:host([icon='symbol-array']):before {
+			content: '\\ea8a';
+		}
+		:host([icon='symbol-module']):before {
+			content: '\\ea8b';
+		}
+		:host([icon='symbol-package']):before {
+			content: '\\ea8b';
+		}
+		:host([icon='symbol-namespace']):before {
+			content: '\\ea8b';
+		}
+		:host([icon='symbol-object']):before {
+			content: '\\ea8b';
+		}
+		:host([icon='symbol-method']):before {
+			content: '\\ea8c';
+		}
+		:host([icon='symbol-function']):before {
+			content: '\\ea8c';
+		}
+		:host([icon='symbol-constructor']):before {
+			content: '\\ea8c';
+		}
+		:host([icon='symbol-boolean']):before {
+			content: '\\ea8f';
+		}
+		:host([icon='symbol-null']):before {
+			content: '\\ea8f';
+		}
+		:host([icon='symbol-numeric']):before {
+			content: '\\ea90';
+		}
+		:host([icon='symbol-number']):before {
+			content: '\\ea90';
+		}
+		:host([icon='symbol-structure']):before {
+			content: '\\ea91';
+		}
+		:host([icon='symbol-struct']):before {
+			content: '\\ea91';
+		}
+		:host([icon='symbol-parameter']):before {
+			content: '\\ea92';
+		}
+		:host([icon='symbol-type-parameter']):before {
+			content: '\\ea92';
+		}
+		:host([icon='symbol-key']):before {
+			content: '\\ea93';
+		}
+		:host([icon='symbol-text']):before {
+			content: '\\ea93';
+		}
+		:host([icon='symbol-reference']):before {
+			content: '\\ea94';
+		}
+		:host([icon='go-to-file']):before {
+			content: '\\ea94';
+		}
+		:host([icon='symbol-enum']):before {
+			content: '\\ea95';
+		}
+		:host([icon='symbol-value']):before {
+			content: '\\ea95';
+		}
+		:host([icon='symbol-ruler']):before {
+			content: '\\ea96';
+		}
+		:host([icon='symbol-unit']):before {
+			content: '\\ea96';
+		}
+		:host([icon='activate-breakpoints']):before {
+			content: '\\ea97';
+		}
+		:host([icon='archive']):before {
+			content: '\\ea98';
+		}
+		:host([icon='arrow-both']):before {
+			content: '\\ea99';
+		}
+		:host([icon='arrow-down']):before {
+			content: '\\ea9a';
+		}
+		:host([icon='arrow-left']):before {
+			content: '\\ea9b';
+		}
+		:host([icon='arrow-right']):before {
+			content: '\\ea9c';
+		}
+		:host([icon='arrow-small-down']):before {
+			content: '\\ea9d';
+		}
+		:host([icon='arrow-small-left']):before {
+			content: '\\ea9e';
+		}
+		:host([icon='arrow-small-right']):before {
+			content: '\\ea9f';
+		}
+		:host([icon='arrow-small-up']):before {
+			content: '\\eaa0';
+		}
+		:host([icon='arrow-up']):before {
+			content: '\\eaa1';
+		}
+		:host([icon='bell']):before {
+			content: '\\eaa2';
+		}
+		:host([icon='bold']):before {
+			content: '\\eaa3';
+		}
+		:host([icon='book']):before {
+			content: '\\eaa4';
+		}
+		:host([icon='bookmark']):before {
+			content: '\\eaa5';
+		}
+		:host([icon='debug-breakpoint-conditional-unverified']):before {
+			content: '\\eaa6';
+		}
+		:host([icon='debug-breakpoint-conditional']):before {
+			content: '\\eaa7';
+		}
+		:host([icon='debug-breakpoint-conditional-disabled']):before {
+			content: '\\eaa7';
+		}
+		:host([icon='debug-breakpoint-data-unverified']):before {
+			content: '\\eaa8';
+		}
+		:host([icon='debug-breakpoint-data']):before {
+			content: '\\eaa9';
+		}
+		:host([icon='debug-breakpoint-data-disabled']):before {
+			content: '\\eaa9';
+		}
+		:host([icon='debug-breakpoint-log-unverified']):before {
+			content: '\\eaaa';
+		}
+		:host([icon='debug-breakpoint-log']):before {
+			content: '\\eaab';
+		}
+		:host([icon='debug-breakpoint-log-disabled']):before {
+			content: '\\eaab';
+		}
+		:host([icon='briefcase']):before {
+			content: '\\eaac';
+		}
+		:host([icon='broadcast']):before {
+			content: '\\eaad';
+		}
+		:host([icon='browser']):before {
+			content: '\\eaae';
+		}
+		:host([icon='bug']):before {
+			content: '\\eaaf';
+		}
+		:host([icon='calendar']):before {
+			content: '\\eab0';
+		}
+		:host([icon='case-sensitive']):before {
+			content: '\\eab1';
+		}
+		:host([icon='check']):before {
+			content: '\\eab2';
+		}
+		:host([icon='checklist']):before {
+			content: '\\eab3';
+		}
+		:host([icon='chevron-down']):before {
+			content: '\\eab4';
+		}
+		:host([icon='chevron-left']):before {
+			content: '\\eab5';
+		}
+		:host([icon='chevron-right']):before {
+			content: '\\eab6';
+		}
+		:host([icon='chevron-up']):before {
+			content: '\\eab7';
+		}
+		:host([icon='chrome-close']):before {
+			content: '\\eab8';
+		}
+		:host([icon='chrome-maximize']):before {
+			content: '\\eab9';
+		}
+		:host([icon='chrome-minimize']):before {
+			content: '\\eaba';
+		}
+		:host([icon='chrome-restore']):before {
+			content: '\\eabb';
+		}
+		:host([icon='circle-outline']):before {
+			content: '\\eabc';
+		}
+		:host([icon='debug-breakpoint-unverified']):before {
+			content: '\\eabc';
+		}
+		:host([icon='circle-slash']):before {
+			content: '\\eabd';
+		}
+		:host([icon='circuit-board']):before {
+			content: '\\eabe';
+		}
+		:host([icon='clear-all']):before {
+			content: '\\eabf';
+		}
+		:host([icon='clippy']):before {
+			content: '\\eac0';
+		}
+		:host([icon='close-all']):before {
+			content: '\\eac1';
+		}
+		:host([icon='cloud-download']):before {
+			content: '\\eac2';
+		}
+		:host([icon='cloud-upload']):before {
+			content: '\\eac3';
+		}
+		:host([icon='code']):before {
+			content: '\\eac4';
+		}
+		:host([icon='collapse-all']):before {
+			content: '\\eac5';
+		}
+		:host([icon='color-mode']):before {
+			content: '\\eac6';
+		}
+		:host([icon='comment-discussion']):before {
+			content: '\\eac7';
+		}
+		:host([icon='credit-card']):before {
+			content: '\\eac9';
+		}
+		:host([icon='dash']):before {
+			content: '\\eacc';
+		}
+		:host([icon='dashboard']):before {
+			content: '\\eacd';
+		}
+		:host([icon='database']):before {
+			content: '\\eace';
+		}
+		:host([icon='debug-continue']):before {
+			content: '\\eacf';
+		}
+		:host([icon='debug-disconnect']):before {
+			content: '\\ead0';
+		}
+		:host([icon='debug-pause']):before {
+			content: '\\ead1';
+		}
+		:host([icon='debug-restart']):before {
+			content: '\\ead2';
+		}
+		:host([icon='debug-start']):before {
+			content: '\\ead3';
+		}
+		:host([icon='debug-step-into']):before {
+			content: '\\ead4';
+		}
+		:host([icon='debug-step-out']):before {
+			content: '\\ead5';
+		}
+		:host([icon='debug-step-over']):before {
+			content: '\\ead6';
+		}
+		:host([icon='debug-stop']):before {
+			content: '\\ead7';
+		}
+		:host([icon='debug']):before {
+			content: '\\ead8';
+		}
+		:host([icon='device-camera-video']):before {
+			content: '\\ead9';
+		}
+		:host([icon='device-camera']):before {
+			content: '\\eada';
+		}
+		:host([icon='device-mobile']):before {
+			content: '\\eadb';
+		}
+		:host([icon='diff-added']):before {
+			content: '\\eadc';
+		}
+		:host([icon='diff-ignored']):before {
+			content: '\\eadd';
+		}
+		:host([icon='diff-modified']):before {
+			content: '\\eade';
+		}
+		:host([icon='diff-removed']):before {
+			content: '\\eadf';
+		}
+		:host([icon='diff-renamed']):before {
+			content: '\\eae0';
+		}
+		:host([icon='diff']):before {
+			content: '\\eae1';
+		}
+		:host([icon='discard']):before {
+			content: '\\eae2';
+		}
+		:host([icon='editor-layout']):before {
+			content: '\\eae3';
+		}
+		:host([icon='empty-window']):before {
+			content: '\\eae4';
+		}
+		:host([icon='exclude']):before {
+			content: '\\eae5';
+		}
+		:host([icon='extensions']):before {
+			content: '\\eae6';
+		}
+		:host([icon='eye-closed']):before {
+			content: '\\eae7';
+		}
+		:host([icon='file-binary']):before {
+			content: '\\eae8';
+		}
+		:host([icon='file-code']):before {
+			content: '\\eae9';
+		}
+		:host([icon='file-media']):before {
+			content: '\\eaea';
+		}
+		:host([icon='file-pdf']):before {
+			content: '\\eaeb';
+		}
+		:host([icon='file-submodule']):before {
+			content: '\\eaec';
+		}
+		:host([icon='file-symlink-directory']):before {
+			content: '\\eaed';
+		}
+		:host([icon='file-symlink-file']):before {
+			content: '\\eaee';
+		}
+		:host([icon='file-zip']):before {
+			content: '\\eaef';
+		}
+		:host([icon='files']):before {
+			content: '\\eaf0';
+		}
+		:host([icon='filter']):before {
+			content: '\\eaf1';
+		}
+		:host([icon='flame']):before {
+			content: '\\eaf2';
+		}
+		:host([icon='fold-down']):before {
+			content: '\\eaf3';
+		}
+		:host([icon='fold-up']):before {
+			content: '\\eaf4';
+		}
+		:host([icon='fold']):before {
+			content: '\\eaf5';
+		}
+		:host([icon='folder-active']):before {
+			content: '\\eaf6';
+		}
+		:host([icon='folder-opened']):before {
+			content: '\\eaf7';
+		}
+		:host([icon='gear']):before {
+			content: '\\eaf8';
+		}
+		:host([icon='gift']):before {
+			content: '\\eaf9';
+		}
+		:host([icon='gist-secret']):before {
+			content: '\\eafa';
+		}
+		:host([icon='gist']):before {
+			content: '\\eafb';
+		}
+		:host([icon='git-commit']):before {
+			content: '\\eafc';
+		}
+		:host([icon='git-compare']):before {
+			content: '\\eafd';
+		}
+		:host([icon='compare-changes']):before {
+			content: '\\eafd';
+		}
+		:host([icon='git-merge']):before {
+			content: '\\eafe';
+		}
+		:host([icon='github-action']):before {
+			content: '\\eaff';
+		}
+		:host([icon='github-alt']):before {
+			content: '\\eb00';
+		}
+		:host([icon='globe']):before {
+			content: '\\eb01';
+		}
+		:host([icon='grabber']):before {
+			content: '\\eb02';
+		}
+		:host([icon='graph']):before {
+			content: '\\eb03';
+		}
+		:host([icon='gripper']):before {
+			content: '\\eb04';
+		}
+		:host([icon='heart']):before {
+			content: '\\eb05';
+		}
+		:host([icon='home']):before {
+			content: '\\eb06';
+		}
+		:host([icon='horizontal-rule']):before {
+			content: '\\eb07';
+		}
+		:host([icon='hubot']):before {
+			content: '\\eb08';
+		}
+		:host([icon='inbox']):before {
+			content: '\\eb09';
+		}
+		:host([icon='issue-reopened']):before {
+			content: '\\eb0b';
+		}
+		:host([icon='issues']):before {
+			content: '\\eb0c';
+		}
+		:host([icon='italic']):before {
+			content: '\\eb0d';
+		}
+		:host([icon='jersey']):before {
+			content: '\\eb0e';
+		}
+		:host([icon='json']):before {
+			content: '\\eb0f';
+		}
+		:host([icon='kebab-vertical']):before {
+			content: '\\eb10';
+		}
+		:host([icon='key']):before {
+			content: '\\eb11';
+		}
+		:host([icon='law']):before {
+			content: '\\eb12';
+		}
+		:host([icon='lightbulb-autofix']):before {
+			content: '\\eb13';
+		}
+		:host([icon='link-external']):before {
+			content: '\\eb14';
+		}
+		:host([icon='link']):before {
+			content: '\\eb15';
+		}
+		:host([icon='list-ordered']):before {
+			content: '\\eb16';
+		}
+		:host([icon='list-unordered']):before {
+			content: '\\eb17';
+		}
+		:host([icon='live-share']):before {
+			content: '\\eb18';
+		}
+		:host([icon='loading']):before {
+			content: '\\eb19';
+		}
+		:host([icon='location']):before {
+			content: '\\eb1a';
+		}
+		:host([icon='mail-read']):before {
+			content: '\\eb1b';
+		}
+		:host([icon='mail']):before {
+			content: '\\eb1c';
+		}
+		:host([icon='markdown']):before {
+			content: '\\eb1d';
+		}
+		:host([icon='megaphone']):before {
+			content: '\\eb1e';
+		}
+		:host([icon='mention']):before {
+			content: '\\eb1f';
+		}
+		:host([icon='milestone']):before {
+			content: '\\eb20';
+		}
+		:host([icon='mortar-board']):before {
+			content: '\\eb21';
+		}
+		:host([icon='move']):before {
+			content: '\\eb22';
+		}
+		:host([icon='multiple-windows']):before {
+			content: '\\eb23';
+		}
+		:host([icon='mute']):before {
+			content: '\\eb24';
+		}
+		:host([icon='no-newline']):before {
+			content: '\\eb25';
+		}
+		:host([icon='note']):before {
+			content: '\\eb26';
+		}
+		:host([icon='octoface']):before {
+			content: '\\eb27';
+		}
+		:host([icon='open-preview']):before {
+			content: '\\eb28';
+		}
+		:host([icon='package']):before {
+			content: '\\eb29';
+		}
+		:host([icon='paintcan']):before {
+			content: '\\eb2a';
+		}
+		:host([icon='pin']):before {
+			content: '\\eb2b';
+		}
+		:host([icon='play']):before {
+			content: '\\eb2c';
+		}
+		:host([icon='run']):before {
+			content: '\\eb2c';
+		}
+		:host([icon='plug']):before {
+			content: '\\eb2d';
+		}
+		:host([icon='preserve-case']):before {
+			content: '\\eb2e';
+		}
+		:host([icon='preview']):before {
+			content: '\\eb2f';
+		}
+		:host([icon='project']):before {
+			content: '\\eb30';
+		}
+		:host([icon='pulse']):before {
+			content: '\\eb31';
+		}
+		:host([icon='question']):before {
+			content: '\\eb32';
+		}
+		:host([icon='quote']):before {
+			content: '\\eb33';
+		}
+		:host([icon='radio-tower']):before {
+			content: '\\eb34';
+		}
+		:host([icon='reactions']):before {
+			content: '\\eb35';
+		}
+		:host([icon='references']):before {
+			content: '\\eb36';
+		}
+		:host([icon='refresh']):before {
+			content: '\\eb37';
+		}
+		:host([icon='regex']):before {
+			content: '\\eb38';
+		}
+		:host([icon='remote-explorer']):before {
+			content: '\\eb39';
+		}
+		:host([icon='remote']):before {
+			content: '\\eb3a';
+		}
+		:host([icon='remove']):before {
+			content: '\\eb3b';
+		}
+		:host([icon='replace-all']):before {
+			content: '\\eb3c';
+		}
+		:host([icon='replace']):before {
+			content: '\\eb3d';
+		}
+		:host([icon='repo-clone']):before {
+			content: '\\eb3e';
+		}
+		:host([icon='repo-force-push']):before {
+			content: '\\eb3f';
+		}
+		:host([icon='repo-pull']):before {
+			content: '\\eb40';
+		}
+		:host([icon='repo-push']):before {
+			content: '\\eb41';
+		}
+		:host([icon='report']):before {
+			content: '\\eb42';
+		}
+		:host([icon='request-changes']):before {
+			content: '\\eb43';
+		}
+		:host([icon='rocket']):before {
+			content: '\\eb44';
+		}
+		:host([icon='root-folder-opened']):before {
+			content: '\\eb45';
+		}
+		:host([icon='root-folder']):before {
+			content: '\\eb46';
+		}
+		:host([icon='rss']):before {
+			content: '\\eb47';
+		}
+		:host([icon='ruby']):before {
+			content: '\\eb48';
+		}
+		:host([icon='save-all']):before {
+			content: '\\eb49';
+		}
+		:host([icon='save-as']):before {
+			content: '\\eb4a';
+		}
+		:host([icon='save']):before {
+			content: '\\eb4b';
+		}
+		:host([icon='screen-full']):before {
+			content: '\\eb4c';
+		}
+		:host([icon='screen-normal']):before {
+			content: '\\eb4d';
+		}
+		:host([icon='search-stop']):before {
+			content: '\\eb4e';
+		}
+		:host([icon='server']):before {
+			content: '\\eb50';
+		}
+		:host([icon='settings-gear']):before {
+			content: '\\eb51';
+		}
+		:host([icon='settings']):before {
+			content: '\\eb52';
+		}
+		:host([icon='shield']):before {
+			content: '\\eb53';
+		}
+		:host([icon='smiley']):before {
+			content: '\\eb54';
+		}
+		:host([icon='sort-precedence']):before {
+			content: '\\eb55';
+		}
+		:host([icon='split-horizontal']):before {
+			content: '\\eb56';
+		}
+		:host([icon='split-vertical']):before {
+			content: '\\eb57';
+		}
+		:host([icon='squirrel']):before {
+			content: '\\eb58';
+		}
+		:host([icon='star-full']):before {
+			content: '\\eb59';
+		}
+		:host([icon='star-half']):before {
+			content: '\\eb5a';
+		}
+		:host([icon='symbol-class']):before {
+			content: '\\eb5b';
+		}
+		:host([icon='symbol-color']):before {
+			content: '\\eb5c';
+		}
+		:host([icon='symbol-constant']):before {
+			content: '\\eb5d';
+		}
+		:host([icon='symbol-enum-member']):before {
+			content: '\\eb5e';
+		}
+		:host([icon='symbol-field']):before {
+			content: '\\eb5f';
+		}
+		:host([icon='symbol-file']):before {
+			content: '\\eb60';
+		}
+		:host([icon='symbol-interface']):before {
+			content: '\\eb61';
+		}
+		:host([icon='symbol-keyword']):before {
+			content: '\\eb62';
+		}
+		:host([icon='symbol-misc']):before {
+			content: '\\eb63';
+		}
+		:host([icon='symbol-operator']):before {
+			content: '\\eb64';
+		}
+		:host([icon='symbol-property']):before {
+			content: '\\eb65';
+		}
+		:host([icon='wrench']):before {
+			content: '\\eb65';
+		}
+		:host([icon='wrench-subaction']):before {
+			content: '\\eb65';
+		}
+		:host([icon='symbol-snippet']):before {
+			content: '\\eb66';
+		}
+		:host([icon='tasklist']):before {
+			content: '\\eb67';
+		}
+		:host([icon='telescope']):before {
+			content: '\\eb68';
+		}
+		:host([icon='text-size']):before {
+			content: '\\eb69';
+		}
+		:host([icon='three-bars']):before {
+			content: '\\eb6a';
+		}
+		:host([icon='thumbsdown']):before {
+			content: '\\eb6b';
+		}
+		:host([icon='thumbsup']):before {
+			content: '\\eb6c';
+		}
+		:host([icon='tools']):before {
+			content: '\\eb6d';
+		}
+		:host([icon='triangle-down']):before {
+			content: '\\eb6e';
+		}
+		:host([icon='triangle-left']):before {
+			content: '\\eb6f';
+		}
+		:host([icon='triangle-right']):before {
+			content: '\\eb70';
+		}
+		:host([icon='triangle-up']):before {
+			content: '\\eb71';
+		}
+		:host([icon='twitter']):before {
+			content: '\\eb72';
+		}
+		:host([icon='unfold']):before {
+			content: '\\eb73';
+		}
+		:host([icon='unlock']):before {
+			content: '\\eb74';
+		}
+		:host([icon='unmute']):before {
+			content: '\\eb75';
+		}
+		:host([icon='unverified']):before {
+			content: '\\eb76';
+		}
+		:host([icon='verified']):before {
+			content: '\\eb77';
+		}
+		:host([icon='versions']):before {
+			content: '\\eb78';
+		}
+		:host([icon='vm-active']):before {
+			content: '\\eb79';
+		}
+		:host([icon='vm-outline']):before {
+			content: '\\eb7a';
+		}
+		:host([icon='vm-running']):before {
+			content: '\\eb7b';
+		}
+		:host([icon='watch']):before {
+			content: '\\eb7c';
+		}
+		:host([icon='whitespace']):before {
+			content: '\\eb7d';
+		}
+		:host([icon='whole-word']):before {
+			content: '\\eb7e';
+		}
+		:host([icon='window']):before {
+			content: '\\eb7f';
+		}
+		:host([icon='word-wrap']):before {
+			content: '\\eb80';
+		}
+		:host([icon='zoom-in']):before {
+			content: '\\eb81';
+		}
+		:host([icon='zoom-out']):before {
+			content: '\\eb82';
+		}
+		:host([icon='list-filter']):before {
+			content: '\\eb83';
+		}
+		:host([icon='list-flat']):before {
+			content: '\\eb84';
+		}
+		:host([icon='list-selection']):before {
+			content: '\\eb85';
+		}
+		:host([icon='selection']):before {
+			content: '\\eb85';
+		}
+		:host([icon='list-tree']):before {
+			content: '\\eb86';
+		}
+		:host([icon='debug-breakpoint-function-unverified']):before {
+			content: '\\eb87';
+		}
+		:host([icon='debug-breakpoint-function']):before {
+			content: '\\eb88';
+		}
+		:host([icon='debug-breakpoint-function-disabled']):before {
+			content: '\\eb88';
+		}
+		:host([icon='debug-stackframe-active']):before {
+			content: '\\eb89';
+		}
+		:host([icon='debug-stackframe-dot']):before {
+			content: '\\eb8a';
+		}
+		:host([icon='debug-stackframe']):before {
+			content: '\\eb8b';
+		}
+		:host([icon='debug-stackframe-focused']):before {
+			content: '\\eb8b';
+		}
+		:host([icon='debug-breakpoint-unsupported']):before {
+			content: '\\eb8c';
+		}
+		:host([icon='symbol-string']):before {
+			content: '\\eb8d';
+		}
+		:host([icon='debug-reverse-continue']):before {
+			content: '\\eb8e';
+		}
+		:host([icon='debug-step-back']):before {
+			content: '\\eb8f';
+		}
+		:host([icon='debug-restart-frame']):before {
+			content: '\\eb90';
+		}
+		:host([icon='debug-alt']):before {
+			content: '\\eb91';
+		}
+		:host([icon='call-incoming']):before {
+			content: '\\eb92';
+		}
+		:host([icon='call-outgoing']):before {
+			content: '\\eb93';
+		}
+		:host([icon='menu']):before {
+			content: '\\eb94';
+		}
+		:host([icon='expand-all']):before {
+			content: '\\eb95';
+		}
+		:host([icon='feedback']):before {
+			content: '\\eb96';
+		}
+		:host([icon='group-by-ref-type']):before {
+			content: '\\eb97';
+		}
+		:host([icon='ungroup-by-ref-type']):before {
+			content: '\\eb98';
+		}
+		:host([icon='account']):before {
+			content: '\\eb99';
+		}
+		:host([icon='bell-dot']):before {
+			content: '\\eb9a';
+		}
+		:host([icon='debug-console']):before {
+			content: '\\eb9b';
+		}
+		:host([icon='library']):before {
+			content: '\\eb9c';
+		}
+		:host([icon='output']):before {
+			content: '\\eb9d';
+		}
+		:host([icon='run-all']):before {
+			content: '\\eb9e';
+		}
+		:host([icon='sync-ignored']):before {
+			content: '\\eb9f';
+		}
+		:host([icon='pinned']):before {
+			content: '\\eba0';
+		}
+		:host([icon='github-inverted']):before {
+			content: '\\eba1';
+		}
+		:host([icon='server-process']):before {
+			content: '\\eba2';
+		}
+		:host([icon='server-environment']):before {
+			content: '\\eba3';
+		}
+		:host([icon='pass']):before {
+			content: '\\eba4';
+		}
+		:host([icon='issue-closed']):before {
+			content: '\\eba4';
+		}
+		:host([icon='stop-circle']):before {
+			content: '\\eba5';
+		}
+		:host([icon='play-circle']):before {
+			content: '\\eba6';
+		}
+		:host([icon='record']):before {
+			content: '\\eba7';
+		}
+		:host([icon='debug-alt-small']):before {
+			content: '\\eba8';
+		}
+		:host([icon='vm-connect']):before {
+			content: '\\eba9';
+		}
+		:host([icon='cloud']):before {
+			content: '\\ebaa';
+		}
+		:host([icon='merge']):before {
+			content: '\\ebab';
+		}
+		:host([icon='export']):before {
+			content: '\\ebac';
+		}
+		:host([icon='graph-left']):before {
+			content: '\\ebad';
+		}
+		:host([icon='magnet']):before {
+			content: '\\ebae';
+		}
+		:host([icon='notebook']):before {
+			content: '\\ebaf';
+		}
+		:host([icon='redo']):before {
+			content: '\\ebb0';
+		}
+		:host([icon='check-all']):before {
+			content: '\\ebb1';
+		}
+		:host([icon='pinned-dirty']):before {
+			content: '\\ebb2';
+		}
+		:host([icon='pass-filled']):before {
+			content: '\\ebb3';
+		}
+		:host([icon='circle-large-filled']):before {
+			content: '\\ebb4';
+		}
+		:host([icon='circle-large-outline']):before {
+			content: '\\ebb5';
+		}
+		:host([icon='combine']):before {
+			content: '\\ebb6';
+		}
+		:host([icon='gather']):before {
+			content: '\\ebb6';
+		}
+		:host([icon='table']):before {
+			content: '\\ebb7';
+		}
+		:host([icon='variable-group']):before {
+			content: '\\ebb8';
+		}
+		:host([icon='type-hierarchy']):before {
+			content: '\\ebb9';
+		}
+		:host([icon='type-hierarchy-sub']):before {
+			content: '\\ebba';
+		}
+		:host([icon='type-hierarchy-super']):before {
+			content: '\\ebbb';
+		}
+		:host([icon='git-pull-request-create']):before {
+			content: '\\ebbc';
+		}
+		:host([icon='run-above']):before {
+			content: '\\ebbd';
+		}
+		:host([icon='run-below']):before {
+			content: '\\ebbe';
+		}
+		:host([icon='notebook-template']):before {
+			content: '\\ebbf';
+		}
+		:host([icon='debug-rerun']):before {
+			content: '\\ebc0';
+		}
+		:host([icon='workspace-trusted']):before {
+			content: '\\ebc1';
+		}
+		:host([icon='workspace-untrusted']):before {
+			content: '\\ebc2';
+		}
+		:host([icon='workspace-unknown']):before {
+			content: '\\ebc3';
+		}
+		:host([icon='terminal-cmd']):before {
+			content: '\\ebc4';
+		}
+		:host([icon='terminal-debian']):before {
+			content: '\\ebc5';
+		}
+		:host([icon='terminal-linux']):before {
+			content: '\\ebc6';
+		}
+		:host([icon='terminal-powershell']):before {
+			content: '\\ebc7';
+		}
+		:host([icon='terminal-tmux']):before {
+			content: '\\ebc8';
+		}
+		:host([icon='terminal-ubuntu']):before {
+			content: '\\ebc9';
+		}
+		:host([icon='terminal-bash']):before {
+			content: '\\ebca';
+		}
+		:host([icon='arrow-swap']):before {
+			content: '\\ebcb';
+		}
+		:host([icon='copy']):before {
+			content: '\\ebcc';
+		}
+		:host([icon='person-add']):before {
+			content: '\\ebcd';
+		}
+		:host([icon='filter-filled']):before {
+			content: '\\ebce';
+		}
+		:host([icon='wand']):before {
+			content: '\\ebcf';
+		}
+		:host([icon='debug-line-by-line']):before {
+			content: '\\ebd0';
+		}
+		:host([icon='inspect']):before {
+			content: '\\ebd1';
+		}
+		:host([icon='layers']):before {
+			content: '\\ebd2';
+		}
+		:host([icon='layers-dot']):before {
+			content: '\\ebd3';
+		}
+		:host([icon='layers-active']):before {
+			content: '\\ebd4';
+		}
+		:host([icon='compass']):before {
+			content: '\\ebd5';
+		}
+		:host([icon='compass-dot']):before {
+			content: '\\ebd6';
+		}
+		:host([icon='compass-active']):before {
+			content: '\\ebd7';
+		}
+		:host([icon='azure']):before {
+			content: '\\ebd8';
+		}
+		:host([icon='issue-draft']):before {
+			content: '\\ebd9';
+		}
+		:host([icon='git-pull-request-closed']):before {
+			content: '\\ebda';
+		}
+		:host([icon='git-pull-request-draft']):before {
+			content: '\\ebdb';
+		}
+		:host([icon='debug-all']):before {
+			content: '\\ebdc';
+		}
+		:host([icon='debug-coverage']):before {
+			content: '\\ebdd';
+		}
+		:host([icon='run-errors']):before {
+			content: '\\ebde';
+		}
+		:host([icon='folder-library']):before {
+			content: '\\ebdf';
+		}
+		:host([icon='debug-continue-small']):before {
+			content: '\\ebe0';
+		}
+		:host([icon='beaker-stop']):before {
+			content: '\\ebe1';
+		}
+		:host([icon='graph-line']):before {
+			content: '\\ebe2';
+		}
+		:host([icon='graph-scatter']):before {
+			content: '\\ebe3';
+		}
+		:host([icon='pie-chart']):before {
+			content: '\\ebe4';
+		}
+		:host([icon='bracket']):before {
+			content: '\\eb0f';
+		}
+		:host([icon='bracket-dot']):before {
+			content: '\\ebe5';
+		}
+		:host([icon='bracket-error']):before {
+			content: '\\ebe6';
+		}
+		:host([icon='lock-small']):before {
+			content: '\\ebe7';
+		}
+		:host([icon='azure-devops']):before {
+			content: '\\ebe8';
+		}
+		:host([icon='verified-filled']):before {
+			content: '\\ebe9';
+		}
+		:host([icon='newline']):before {
+			content: '\\ebea';
+		}
+		:host([icon='layout']):before {
+			content: '\\ebeb';
+		}
+		:host([icon='layout-activitybar-left']):before {
+			content: '\\ebec';
+		}
+		:host([icon='layout-activitybar-right']):before {
+			content: '\\ebed';
+		}
+		:host([icon='layout-panel-left']):before {
+			content: '\\ebee';
+		}
+		:host([icon='layout-panel-center']):before {
+			content: '\\ebef';
+		}
+		:host([icon='layout-panel-justify']):before {
+			content: '\\ebf0';
+		}
+		:host([icon='layout-panel-right']):before {
+			content: '\\ebf1';
+		}
+		:host([icon='layout-panel']):before {
+			content: '\\ebf2';
+		}
+		:host([icon='layout-sidebar-left']):before {
+			content: '\\ebf3';
+		}
+		:host([icon='layout-sidebar-right']):before {
+			content: '\\ebf4';
+		}
+		:host([icon='layout-statusbar']):before {
+			content: '\\ebf5';
+		}
+		:host([icon='layout-menubar']):before {
+			content: '\\ebf6';
+		}
+		:host([icon='layout-centered']):before {
+			content: '\\ebf7';
+		}
+		:host([icon='target']):before {
+			content: '\\ebf8';
+		}
 
-	@keyframes codicon-spin {
-		100% {
-			transform: rotate(360deg);
+		:host([icon^='gl-']) {
+			font-family: 'glicons';
+		}
+		:host([icon='gl-commit-horizontal']):before {
+			content: '\\f101';
+		}
+		:host([icon='gl-graph']):before {
+			content: '\\f102';
+		}
+		:host([icon='gl-next-commit']):before {
+			content: '\\f103';
+		}
+		:host([icon='gl-prev-commit-menu']):before {
+			content: '\\f104';
+		}
+		:host([icon='gl-prev-commit']):before {
+			content: '\\f105';
+		}
+		:host([icon='gl-compare-ref-working']):before {
+			content: '\\f106';
+		}
+		:host([icon='gl-branches-view']):before {
+			content: '\\f107';
+		}
+		:host([icon='gl-commit-view']):before {
+			content: '\\f108';
+		}
+		:host([icon='gl-commits-view']):before {
+			content: '\\f109';
+		}
+		:host([icon='gl-compare-view']):before {
+			content: '\\f10a';
+		}
+		:host([icon='gl-contributors-view']):before {
+			content: '\\f10b';
+		}
+		:host([icon='gl-history-view']):before {
+			content: '\\f10c';
+		}
+		:host([icon='gl-remotes-view']):before {
+			content: '\\f10d';
+		}
+		:host([icon='gl-repositories-view']):before {
+			content: '\\f10e';
+		}
+		:host([icon='gl-search-view']):before {
+			content: '\\f10f';
+		}
+		:host([icon='gl-stashes-view']):before {
+			content: '\\f110';
+		}
+		:host([icon='gl-tags-view']):before {
+			content: '\\f111';
+		}
+		:host([icon='gl-worktrees-view']):before {
+			content: '\\f112';
+		}
+		:host([icon='gl-gitlens']):before {
+			content: '\\f113';
+		}
+		:host([icon='gl-stash-pop']):before {
+			content: '\\f114';
+		}
+		:host([icon='gl-stash-save']):before {
+			content: '\\f115';
+		}
+		:host([icon='gl-unplug']):before {
+			content: '\\f116';
+		}
+		:host([icon='gl-open-revision']):before {
+			content: '\\f117';
+		}
+		:host([icon='gl-switch']):before {
+			content: '\\f118';
+		}
+		:host([icon='gl-expand']):before {
+			content: '\\f119';
+		}
+		:host([icon='gl-list-auto']):before {
+			content: '\\f11a';
+		}
+		:host([icon='gl-arrow-up-force']):before {
+			content: '\\f11b';
+		}
+		:host([icon='gl-pinned-filled']):before {
+			content: '\\f11c';
+			/* TODO: see relative positioning needed in every use-case */
+			position: relative;
+			left: 1px;
+		}
+		:host([icon='gl-clock']):before {
+			content: '\\f11d';
+		}
+		:host([icon='gl-provider-azdo']):before {
+			content: '\\f11e';
+		}
+		:host([icon='gl-provider-bitbucket']):before {
+			content: '\\f11f';
+		}
+		:host([icon='gl-provider-gerrit']):before {
+			content: '\\f120';
+		}
+		:host([icon='gl-provider-gitea']):before {
+			content: '\\f121';
+		}
+		:host([icon='gl-provider-github']):before {
+			content: '\\f122';
+		}
+		:host([icon='gl-provider-gitlab']):before {
+			content: '\\f123';
+		}
+		:host([icon='gl-gitlens-inspect']):before {
+			content: '\\f124';
 		}
-	}
 
-	:host([modifier='spin']) {
-		/* Use steps to throttle FPS to reduce CPU usage */
-		animation: codicon-spin 1.5s steps(30) infinite;
-	}
-	:host([icon='loading'][modifier='spin']) {
-		/* Use steps to throttle FPS to reduce CPU usage */
-		animation: codicon-spin 1.5s steps(30) infinite;
+		@keyframes codicon-spin {
+			100% {
+				transform: rotate(360deg);
+			}
+		}
 
-		/* custom speed & easing for loading icon */
-		animation-duration: 1s !important;
-		animation-timing-function: cubic-bezier(0.53, 0.21, 0.29, 0.67) !important;
-	}
-`;
+		:host([modifier='spin']) {
+			/* Use steps to throttle FPS to reduce CPU usage */
+			animation: codicon-spin 1.5s steps(30) infinite;
+		}
+		:host([icon='loading'][modifier='spin']) {
+			/* Use steps to throttle FPS to reduce CPU usage */
+			animation: codicon-spin 1.5s steps(30) infinite;
 
-@customElement({ name: 'code-icon', styles: styles })
-export class CodeIcon extends FASTElement {
-	@attr
+			/* custom speed & easing for loading icon */
+			animation-duration: 1s !important;
+			animation-timing-function: cubic-bezier(0.53, 0.21, 0.29, 0.67) !important;
+		}
+	`;
+	@property()
 	icon = '';
 
-	@attr
+	@property()
 	modifier = '';
 
-	@attr
+	@property({ type: Number })
 	size = 16;
-	sizeChanged() {
-		this.style.setProperty('--code-icon-size', `${this.size}px`);
+
+	override updated(changedProperties: Map<string, unknown>) {
+		if (changedProperties.has('size')) {
+			this.style.setProperty('--code-icon-size', `${this.size}px`);
+		}
+		super.update(changedProperties);
 	}
 }
diff --git a/src/webviews/apps/shared/components/styles/lit/a11y.css.ts b/src/webviews/apps/shared/components/styles/lit/a11y.css.ts
new file mode 100644
index 0000000..5f2ead3
--- /dev/null
+++ b/src/webviews/apps/shared/components/styles/lit/a11y.css.ts
@@ -0,0 +1,19 @@
+import { css } from 'lit';
+
+export const srOnly = css`
+	.sr-only,
+	.sr-only-focusable:not(:active):not(:focus) {
+		clip: rect(0 0 0 0);
+		clip-path: inset(50%);
+		width: 1px;
+		height: 1px;
+		overflow: hidden;
+		position: absolute;
+		white-space: nowrap;
+	}
+`;
+
+export const focusOutline = css`
+	outline: 1px solid var(--color-focus-border);
+	outline-offset: -1px;
+`;
diff --git a/src/webviews/apps/shared/components/styles/lit/base.css.ts b/src/webviews/apps/shared/components/styles/lit/base.css.ts
new file mode 100644
index 0000000..28aeaaa
--- /dev/null
+++ b/src/webviews/apps/shared/components/styles/lit/base.css.ts
@@ -0,0 +1,15 @@
+import { css } from 'lit';
+
+export const elementBase = css`
+	:host {
+		box-sizing: border-box;
+	}
+	:host *,
+	:host *::before,
+	:host *::after {
+		box-sizing: inherit;
+	}
+	[hidden] {
+		display: none !important;
+	}
+`;
diff --git a/src/webviews/apps/shared/styles/properties.scss b/src/webviews/apps/shared/styles/properties.scss
new file mode 100644
index 0000000..b4bdc21
--- /dev/null
+++ b/src/webviews/apps/shared/styles/properties.scss
@@ -0,0 +1,17 @@
+:root {
+	--gitlens-gutter-width: 20px;
+	--gk-action-radius: 0.2rem;
+	--gk-card-radius: 0.4rem;
+}
+
+.vscode-high-contrast,
+.vscode-dark {
+	--gk-card-background: var(--color-background--lighten-05);
+	--gk-card-hover-background: var(--color-background--lighten-075);
+}
+
+.vscode-high-contrast-light,
+.vscode-light {
+	--gk-card-background: var(--color-background--darken-05);
+	--gk-card-hover-background: var(--color-background--darken-075);
+}