diff --git a/src/lib/components/elements/contract.svelte b/src/lib/components/elements/contract.svelte
index 49f6ccb5..940e8161 100644
--- a/src/lib/components/elements/contract.svelte
+++ b/src/lib/components/elements/contract.svelte
@@ -10,16 +10,20 @@
 		children?: Snippet;
 		name?: Name | string;
 		action?: Name | string;
+		struct?: Name;
 		class?: string;
 	}
 
-	let { name, action, children, ...props }: Props = $props();
+	let { name, action, struct, children, ...props }: Props = $props();
 
 	let href = $derived.by(() => {
 		const base = `/${network}/contract/${String(name)}`;
 		if (action) {
 			return base + `/actions/${action}`;
 		}
+		if (struct) {
+			return base + `/structs/${struct}`;
+		}
 		return base;
 	});
 </script>
diff --git a/src/routes/[network]/(explorer)/contract/[contract]/+layout.svelte b/src/routes/[network]/(explorer)/contract/[contract]/+layout.svelte
index eb3a9d98..6787c2b5 100644
--- a/src/routes/[network]/(explorer)/contract/[contract]/+layout.svelte
+++ b/src/routes/[network]/(explorer)/contract/[contract]/+layout.svelte
@@ -43,6 +43,6 @@
 <!-- 	{/if} -->
 <!-- </Stack> -->
 
-<PillGroup {options} class="mb-6" />
+<PillGroup {options} />
 
 {@render children()}
diff --git a/src/routes/[network]/(explorer)/contract/[contract]/actions/+page.svelte b/src/routes/[network]/(explorer)/contract/[contract]/actions/+page.svelte
index e37c7791..e88e060d 100644
--- a/src/routes/[network]/(explorer)/contract/[contract]/actions/+page.svelte
+++ b/src/routes/[network]/(explorer)/contract/[contract]/actions/+page.svelte
@@ -1,13 +1,15 @@
 <script lang="ts">
 	import Stack from '$lib/components/layout/stack.svelte';
+	import Action from './action.svelte';
 
 	const { data } = $props();
 </script>
 
 <Stack>
-	{#each data.abi.actions as action}
-		<a href="/{data.network}/contract/{data.contract}/actions/{action.name}">
-			{action.name}
-		</a>
-	{/each}
+	<p>The actions for this contract with their input parameters and potential response data.</p>
+	<ul class="grid grid-cols-[auto_1fr] gap-2 overflow-x-auto">
+		{#each data.abi.actions as action}
+			<Action abi={data.abi} contract={data.contract} network={data.network} {action} />
+		{/each}
+	</ul>
 </Stack>
diff --git a/src/routes/[network]/(explorer)/contract/[contract]/actions/action.svelte b/src/routes/[network]/(explorer)/contract/[contract]/actions/action.svelte
new file mode 100644
index 00000000..50b5de97
--- /dev/null
+++ b/src/routes/[network]/(explorer)/contract/[contract]/actions/action.svelte
@@ -0,0 +1,121 @@
+<script lang="ts">
+	import Key from '$lib/components/elements/key.svelte';
+	import CopyButton from '$lib/components/button/copy.svelte';
+	import * as m from '$lib/paraglide/messages';
+	import Code from '$lib/components/code.svelte';
+	import type { UnicoveContext } from '$lib/state/client.svelte';
+	import { getContext } from 'svelte';
+	import Contract from '$lib/components/elements/contract.svelte';
+
+	const context = getContext<UnicoveContext>('state');
+
+	interface Props {}
+	let { abi, action, contract, network, ...props }: Props = $props();
+
+	const ricardian = $derived.by(() => {
+		try {
+			console.log(action.ricardian_contract);
+		} catch (e) {
+			console.error(e);
+		}
+		return {
+			summary: 'Error parsing Ricardian contract'
+		};
+	});
+	const struct = $derived(abi.structs.find((s) => s.name === action.type));
+	const response = $derived.by(() => {
+		const resultType = abi.action_results.find((s) => s.name === action.name);
+		if (resultType) {
+			const resultStruct = abi.structs.find((s) => s.name === resultType.result_type);
+			if (resultStruct) {
+				return resultStruct.fields;
+			}
+			const resultArray = abi.structs.find((s) => s.name === parseType(resultType.result_type));
+			if (resultArray) {
+				return [
+					{
+						name: resultType.result_type,
+						type: resultArray.name
+					}
+				];
+			}
+			return resultType;
+		}
+		return undefined;
+	});
+
+	function parseType(type: string) {
+		// Remove suffix syntax (e.g. [], ?, !, $)
+		return type.replace(/\[|\]|\?|\!|\$/g, '');
+	}
+</script>
+
+<li class="relative col-span-full grid grid-cols-subgrid bg-shark-950">
+	<dl
+		class="z-20 col-span-full space-y-1 rounded-t-lg bg-mineShaft-950 px-4 py-3 md:col-span-1 md:rounded-l-lg"
+	>
+		<div>
+			<div class="text-lg font-bold">Action</div>
+			<dd class="font-semibold">
+				<Contract name={contract} action={action.name}>
+					{action.name}
+				</Contract>
+			</dd>
+		</div>
+	</dl>
+
+	<div class="rounded-b-lg bg-mineShaft-950/50 px-4 py-3 md:rounded-r-lg">
+		<div class="grid grid-cols-2 gap-4">
+			<div>
+				<div class="text-lg font-bold">Parameters</div>
+				{#each struct.fields as field}
+					{@const fieldType = abi.structs.find((s) => s.name === parseType(field.type))}
+					<div>
+						<span class="text-white">
+							{field.name}
+						</span>
+						<span class="text-muted">
+							{#if fieldType}
+								<Contract name={contract} struct={fieldType.name}>
+									{field.type}
+								</Contract>
+							{:else}
+								{field.type}
+							{/if}
+						</span>
+					</div>
+				{:else}
+					<span class="text-muted"> No action parameters. </span>
+				{/each}
+				{#if context.settings.data.debugMode}
+					<Code>{JSON.stringify(struct, null, 2)}</Code>
+				{/if}
+			</div>
+			<div>
+				<div class="text-lg font-bold">Response Data</div>
+				{#each response as field}
+					{@const fieldType = abi.structs.find((s) => s.name === parseType(field.type))}
+					<div>
+						<span class="text-white">
+							{field.name}
+						</span>
+						<span class="text-muted">
+							{#if fieldType}
+								<Contract name={contract} struct={fieldType.name}>
+									{field.type}
+								</Contract>
+							{:else}
+								{field.type}
+							{/if}
+						</span>
+					</div>
+				{:else}
+					<p>No response data.</p>
+				{/each}
+				{#if context.settings.data.debugMode}
+					<Code>{JSON.stringify(response, null, 2)}</Code>
+				{/if}
+			</div>
+		</div>
+	</div>
+</li>