diff --git a/pages/framework/card-sdk.mdx b/pages/framework/card-sdk.mdx
deleted file mode 100644
index 5163d27..0000000
--- a/pages/framework/card-sdk.mdx
+++ /dev/null
@@ -1,309 +0,0 @@
-# Card SDK
-
-The Card SDK provides the glue between the Javascript defined in the TokenScript project and the engine.
-It is essentially a 2-way message bus that allows the TokenScript developer to make requests to the engine and to receive updated data and other events emitted by the engine.
-It also allows the user to access various data including context data, environment variables & contract information.
-
-## Token Context Data
-
-As explained in the introduction to TokenScript attributes, Token Context data is made available through the card SDK.
-Our starter templates already handles the dataChange event which is used to provide initial and updated token context data to your card.
-
-If you want to register your own listener, you can do so by overwriting the following eventHandler
-
-```typescript
-tokenscript.tokens.dataChanged = async (oldTokens: any, updatedTokens: ITokenData, id: string) => {
-
-}
-```
-
-For our Svelte & React templates, the `updatedTokens.currentInstance` is automatically written to a global context variable that your UI can react to.
-
-## Environment Variables
-
-To access environment variables within your card, ensure that the variables is added into `ts:meta` as demonstrated [here](./tokenscript-syntax/xml).
-
-You can then access these variables via the `tokenscript.env` object:
-
-```typescript
-tokenscript.env.MY_ENV_VARIABLE
-```
-
-## Event handlers
-
-The engine include event handler infrastructure that allows the registration of multiple event listeners throughout your application.
-
-Currently, there is only one handler however more will be added in the future:
-
-- TRANSACTION_EVENT
-
-```typescript
-// Types
-interface TokenScriptEvents {
- TRANSACTION_EVENT: ITransactionStatus
-}
-
-// Usage
-tokenscript.on("TRANSACTION_EVENT", (data: ITransactionStatus) => {
- // Handle transaction event
-})
-```
-
-The TRANSACTION_EVENT can be used to react to transaction status even when the default action button is used to trigger the transaction.
-
-## Bundled libraries
-
-To reduce the size of built TokenScripts, some common libraries are bundled with the Card SDK.
-This allows the use of these libraries without explicitly installing them via NPM.
-
-Bundled libraries
-
-- Ethers.js ^v6.13 - available via the `ethers` global variable
-
-## Engine & UX actions
-
-### setProps
-
-One of the most important engine actions is `setProps`. It allows the user to define values that can be used as inputs to attributes & transactions:
-
-```typescript
-tokenscript.action.setProps({
- myAttribute: "123",
- myAttribute2: 456
-})
-```
-
-When invoking this method, the engine checks these values to see if they are `ts:user-entry` attributes.
-If they are not user entry values the engine checks if any of these values are a dependency for another attribute defined in the current scope.
-If so the engine will reload those attributes and return the updated data to the card via the `dataChanged` handler explained above.
-In this way, attribute values can be updated automatically based on an input that is set programmatically from within the card.
-
-Likewise, declarative transactions can reference these values as transactions arguments.
-
-Both attributes & transactions reference these values using the `local-ref` XML attribute:
-
-```xml
-
-
-
-
-
-```
-
-### show/hideLoader
-
-A self-explanatory method, this allows the user to show or hide the default card loaded provided the TokenScript viewer UI:
-
-`tokenscript.action.showLoader()` OR `tokenscript.action.hideLoader()`.
-
-### setActionButton
-
-The setActionButton method allows the developer to control the state of the default action button:
-
-```typescript
-// Type
-type setActionButton = (options: { show?: boolean, disable?: boolean, text?: string }) => void
-
-// Usage
-tokenscript.action.setActionButton({
- show: true, // Whether to show the button
- disable: false, // Whether to make the button disabled
- text: "Transfer Now" // The text of the button
-})
-```
-
-This allows the user to hide, disable or update the button text based on some conditions defined in Javascript.
-
-### executeTransaction
-
-`executeTransaction` is used to invoke declarative transactions programmatically as discussed in [TokenScript Transactions](./tokenscript-syntax/transactions).
-
-```typescript
-// Types
-interface TXOptions {
- txName?: string
-}
-
-interface ITransactionStatus {
- status: 'started'|'aborted'|'submitted'|'confirmed'|'completed',
- txNumber?: string,
- txLink?: string,
- txRecord?: any
-}
-
-interface ITransactionListener {
- (data: ITransactionStatus): void|Promise
-}
-
-type ExecuteTransaction = (optionsOrTxName?: string|TXOptions, listener?: ITransactionListener) => Promise
-
-// Usage
-
-// 1. Execute the default transaction (specified in `ts:card`)
-if (!await tokenscript.action.executeTransaction()){
- return; // User aborted transaction
-}
-// Do some post-transaction processing
-
-// 2. Execute a top-level named transaction, with some input values from Javascript
-tokenscript.action.setProps({
- secretCode: "1234"
-});
-if (!await tokenscript.action.executeTransaction("levelUp")){
- return; // User aborted transaction
-}
-
-// 3. Use a transaction progress listener
-await tokenscript.action.executeTransaction("levelUp", (txInfo) => {
- // Update UI based on transaction process
-});
-
-```
-
-Since the executeTransaction method is async, it can be used to chain together transactions and other off-chain processes.
-
-### showMessageToast
-
-This allows the developer to show message notifications using the toast notification system provided by TokenScript viewer.
-Along with the other UI specific methods, this helps keep the user-experience consistent across all TokenScript applications.
-
-```typescript
-// Type
-type ShowMessageToast = (type: 'success'|'info'|'warning'|'error', title: string, description: string) => void;
-
-// Usage
-tokenscript.action.showMessageToast("error", "An error occurred", "Detailed information about the error");
-```
-
-### showTransactionToast
-
-Like the previous method, this allows the user to show transaction specific notifications:
-
-```typescript
-// Type
-type ShowTransactionToast = (status: "submitted"|"confirmed", chain: number, txHash: string) => void;
-
-// Usage
-tokenscript.action.showTransactionToast('confirmed', 137, "0x05b9d22ce9ac87e399c18c488c3e02327945ffb4633890030789ea1f2f783e0b");
-```
-
-Note: This method only needs to be used when using the injected ethereum provider. If you are using declarative transactions, notifications are already taken care of by the engine.
-
-### closeCard
-
-This method simply closes the current card:
-
-```typescript
-tokenscript.action.closeCard();
-```
-
-### openCard
-
-You can also switch between cards using the `openCard` method.
-
-```typescript
-// Type
-type OpenCard = (name: string, originId?: string, tokenId?: string) => void;
-
-// Usage
-tokenscript.action.openCard({
- name: "myCardName",
- originId: "ReallyCoolToken", // This is the name of the origin contract as defined in the tokenscript.xml.
- tokenId: "1" // The tokenId we want to open the card for
-});
-```
-
-If originId or tokenId are not provided, the current token context is used to open the new card.
-
-## Ethereum methods
-
-### Signing
-
-You can request the user to sign a personal message like this:
-
-```typescript
-// Type
-type SignPersonal = (msgParams: {data: string|Uint8Array}, callback?: (error: any, data: string) => void) => void|Promise;
-
-// Usage
-const signature = await tokenscript.personal.sign({data: "My message"});
-```
-
-This method is async but can also take a callback as well.
-
-**Note: If you need typed data signing, use the Ethereum Provider**
-
-### getRpcUrls
-
-The `getRpcUrls` method provides an array of RPC URLs for the specified chain ID:
-
-```typescript
-// Type
-type GetRpcUrls = (chain: number) => string[];
-
-// Usage
-const rpcUrls = tokenscript.eth.getRpcUrls(137);
-````
-
-These URLs are configured and provided by the TokenScript Engine.
-
-### getRpcProvider
-
-Instead of requesting URLs and configuring the ethereum provider yourself, you can get an ethers.js provider directly:
-
-```typescript
-// Type
-type GetRpcProvider = (chain: number) => AbstractProvider; // ethers.AbstractProvider
-
-// Usage
-const provider = tokenscript.eth.getRpcProvider(137);
-```
-
-If more than one RPC URL is defined for the specified chain ethers.FallbackProvider is returned, otherwise ethers.JsonRpcProvider is returned.
-
-### getContractInfo
-
-It's often helpful to get contract information based on the name specified in the TokenScript XML.
-In this way there is no need to hard-code contract addresses and ABI JSON within your Javascript code.
-Instead, this config information can be specified within the `tokenscript-project.json` environment variables and made available via this API method.
-
-```typescript
-// Type
-type GetContractInfo = (name: string, chain?: number) => {chain: number, address: string, abi: any};
-
-// Usage
-const contractInfo = tokenscript.eth.getContractInfo("MyReallyCoolToken");
-```
-
-If the chain parameter isn't provided, the chain of the current token is used or the first chain specified within `ts:contract`.
-
-### getContractInstance
-
-Just like getContractInfo, we can get an ethers.Contract instance based on the name & chain provided.
-These contracts must have an ABI specified within `ts:contract` for the methods you want to execute.
-
-```typescript
-// Type
-type GetContractInstance = (name: string, chain?: number) => Contract; // ethers.Contract
-
-// Usage
-const contract = tokenscript.eth.getContractInstance("MyReallyCoolToken"); // ABI with getTokenPoints is defined in `ts:contract`
-const points = await contract.getTokenPoints(token.tokenId);
-```
-
-This is most helpful when we want to read contract data within a card, without the use of TokenScript attributes that are loaded when the card is open.
-
-## Ethereum provider
-
-To allow scenarios that are not supported by TokenScript's declarative transactions, the Card SDK provides an EIP-1193 proxy.
-This is the standard injected provider (`window.ethereum`) that you would be familiar with from integrating with Metamask and other browser extension wallets.
-
-To use this provider, it's recommended that you wrap it with Ethers.js BrowserProvider like so:
-```typescript
-const provider = new ethers.BrowserProvider(window.ethereum);
-
-// You can then get an ethers contract instance to interact with a contract
-const contract = new ethers.Contract(contractAddress, abi, provider);
-```
-
-**Note: When using the injected provider, you must take care of chain switching, transaction notifications & error handling yourself.**
\ No newline at end of file
diff --git a/pages/framework/card-sdk/_meta.json b/pages/framework/card-sdk/_meta.json
new file mode 100644
index 0000000..90a9aad
--- /dev/null
+++ b/pages/framework/card-sdk/_meta.json
@@ -0,0 +1,5 @@
+{
+ "introduction": "Introduction",
+ "engine-actions": "Engine & UI Actions",
+ "ethereum-methods": "Ethereum Methods"
+}
diff --git a/pages/framework/card-sdk/engine-actions.mdx b/pages/framework/card-sdk/engine-actions.mdx
new file mode 100644
index 0000000..2627ed5
--- /dev/null
+++ b/pages/framework/card-sdk/engine-actions.mdx
@@ -0,0 +1,154 @@
+## Engine & UX actions
+
+### setProps
+
+One of the most important engine actions is `setProps`. It allows the user to define values that can be used as inputs to attributes & transactions:
+
+```typescript
+tokenscript.action.setProps({
+ myAttribute: "123",
+ myAttribute2: 456
+})
+```
+
+When invoking this method, the engine checks these values to see if they are `ts:user-entry` attributes.
+If they are not user entry values the engine checks if any of these values are a dependency for another attribute defined in the current scope.
+If so the engine will reload those attributes and return the updated data to the card via the `dataChanged` handler explained above.
+In this way, attribute values can be updated automatically based on an input that is set programmatically from within the card.
+
+Likewise, declarative transactions can reference these values as transactions arguments.
+
+Both attributes & transactions reference these values using the `local-ref` XML attribute:
+
+```xml
+
+
+
+
+
+```
+
+### show/hideLoader
+
+A self-explanatory method, this allows the user to show or hide the default card loaded provided the TokenScript viewer UI:
+
+`tokenscript.action.showLoader()` OR `tokenscript.action.hideLoader()`.
+
+### setActionButton
+
+The setActionButton method allows the developer to control the state of the default action button:
+
+```typescript
+// Type
+type setActionButton = (options: { show?: boolean, disable?: boolean, text?: string }) => void
+
+// Usage
+tokenscript.action.setActionButton({
+ show: true, // Whether to show the button
+ disable: false, // Whether to make the button disabled
+ text: "Transfer Now" // The text of the button
+})
+```
+
+This allows the user to hide, disable or update the button text based on some conditions defined in Javascript.
+
+### executeTransaction
+
+`executeTransaction` is used to invoke declarative transactions programmatically as discussed in [TokenScript Transactions](./tokenscript-syntax/transactions).
+
+```typescript
+// Types
+interface TXOptions {
+ txName?: string
+}
+
+interface ITransactionStatus {
+ status: 'started'|'aborted'|'submitted'|'confirmed'|'completed',
+ txNumber?: string,
+ txLink?: string,
+ txRecord?: any
+}
+
+interface ITransactionListener {
+ (data: ITransactionStatus): void|Promise
+}
+
+type ExecuteTransaction = (optionsOrTxName?: string|TXOptions, listener?: ITransactionListener) => Promise
+
+// Usage
+
+// 1. Execute the default transaction (specified in `ts:card`)
+if (!await tokenscript.action.executeTransaction()){
+ return; // User aborted transaction
+}
+// Do some post-transaction processing
+
+// 2. Execute a top-level named transaction, with some input values from Javascript
+tokenscript.action.setProps({
+ secretCode: "1234"
+});
+if (!await tokenscript.action.executeTransaction("levelUp")){
+ return; // User aborted transaction
+}
+
+// 3. Use a transaction progress listener
+await tokenscript.action.executeTransaction("levelUp", (txInfo) => {
+ // Update UI based on transaction process
+});
+
+```
+
+Since the executeTransaction method is async, it can be used to chain together transactions and other off-chain processes.
+
+### showMessageToast
+
+This allows the developer to show message notifications using the toast notification system provided by TokenScript viewer.
+Along with the other UI specific methods, this helps keep the user-experience consistent across all TokenScript applications.
+
+```typescript
+// Type
+type ShowMessageToast = (type: 'success'|'info'|'warning'|'error', title: string, description: string) => void;
+
+// Usage
+tokenscript.action.showMessageToast("error", "An error occurred", "Detailed information about the error");
+```
+
+### showTransactionToast
+
+Like the previous method, this allows the user to show transaction specific notifications:
+
+```typescript
+// Type
+type ShowTransactionToast = (status: "submitted"|"confirmed", chain: number, txHash: string) => void;
+
+// Usage
+tokenscript.action.showTransactionToast('confirmed', 137, "0x05b9d22ce9ac87e399c18c488c3e02327945ffb4633890030789ea1f2f783e0b");
+```
+
+Note: This method only needs to be used when using the injected ethereum provider. If you are using declarative transactions, notifications are already taken care of by the engine.
+
+### closeCard
+
+This method simply closes the current card:
+
+```typescript
+tokenscript.action.closeCard();
+```
+
+### openCard
+
+You can also switch between cards using the `openCard` method.
+
+```typescript
+// Type
+type OpenCard = (name: string, originId?: string, tokenId?: string) => void;
+
+// Usage
+tokenscript.action.openCard({
+ name: "myCardName",
+ originId: "ReallyCoolToken", // This is the name of the origin contract as defined in the tokenscript.xml.
+ tokenId: "1" // The tokenId we want to open the card for
+});
+```
+
+If originId or tokenId are not provided, the current token context is used to open the new card.
diff --git a/pages/framework/card-sdk/ethereum-methods.mdx b/pages/framework/card-sdk/ethereum-methods.mdx
new file mode 100644
index 0000000..da1412d
--- /dev/null
+++ b/pages/framework/card-sdk/ethereum-methods.mdx
@@ -0,0 +1,92 @@
+## Ethereum methods
+
+### Signing
+
+You can request the user to sign a personal message like this:
+
+```typescript
+// Type
+type SignPersonal = (msgParams: {data: string|Uint8Array}, callback?: (error: any, data: string) => void) => void|Promise;
+
+// Usage
+const signature = await tokenscript.personal.sign({data: "My message"});
+```
+
+This method is async but can also take a callback as well.
+
+**Note: If you need typed data signing, use the Ethereum Provider**
+
+### getRpcUrls
+
+The `getRpcUrls` method provides an array of RPC URLs for the specified chain ID:
+
+```typescript
+// Type
+type GetRpcUrls = (chain: number) => string[];
+
+// Usage
+const rpcUrls = tokenscript.eth.getRpcUrls(137);
+````
+
+These URLs are configured and provided by the TokenScript Engine.
+
+### getRpcProvider
+
+Instead of requesting URLs and configuring the ethereum provider yourself, you can get an ethers.js provider directly:
+
+```typescript
+// Type
+type GetRpcProvider = (chain: number) => AbstractProvider; // ethers.AbstractProvider
+
+// Usage
+const provider = tokenscript.eth.getRpcProvider(137);
+```
+
+If more than one RPC URL is defined for the specified chain ethers.FallbackProvider is returned, otherwise ethers.JsonRpcProvider is returned.
+
+### getContractInfo
+
+It's often helpful to get contract information based on the name specified in the TokenScript XML.
+In this way there is no need to hard-code contract addresses and ABI JSON within your Javascript code.
+Instead, this config information can be specified within the `tokenscript-project.json` environment variables and made available via this API method.
+
+```typescript
+// Type
+type GetContractInfo = (name: string, chain?: number) => {chain: number, address: string, abi: any};
+
+// Usage
+const contractInfo = tokenscript.eth.getContractInfo("MyReallyCoolToken");
+```
+
+If the chain parameter isn't provided, the chain of the current token is used or the first chain specified within `ts:contract`.
+
+### getContractInstance
+
+Just like getContractInfo, we can get an ethers.Contract instance based on the name & chain provided.
+These contracts must have an ABI specified within `ts:contract` for the methods you want to execute.
+
+```typescript
+// Type
+type GetContractInstance = (name: string, chain?: number) => Contract; // ethers.Contract
+
+// Usage
+const contract = tokenscript.eth.getContractInstance("MyReallyCoolToken"); // ABI with getTokenPoints is defined in `ts:contract`
+const points = await contract.getTokenPoints(token.tokenId);
+```
+
+This is most helpful when we want to read contract data within a card, without the use of TokenScript attributes that are loaded when the card is open.
+
+## Ethereum provider
+
+To allow scenarios that are not supported by TokenScript's declarative transactions, the Card SDK provides an EIP-1193 proxy.
+This is the standard injected provider (`window.ethereum`) that you would be familiar with from integrating with Metamask and other browser extension wallets.
+
+To use this provider, it's recommended that you wrap it with Ethers.js BrowserProvider like so:
+```typescript
+const provider = new ethers.BrowserProvider(window.ethereum);
+
+// You can then get an ethers contract instance to interact with a contract
+const contract = new ethers.Contract(contractAddress, abi, provider);
+```
+
+**Note: When using the injected provider, you must take care of chain switching, transaction notifications & error handling yourself.**
\ No newline at end of file
diff --git a/pages/framework/card-sdk/introduction.mdx b/pages/framework/card-sdk/introduction.mdx
new file mode 100644
index 0000000..3ca3942
--- /dev/null
+++ b/pages/framework/card-sdk/introduction.mdx
@@ -0,0 +1,61 @@
+# Card SDK
+
+The Card SDK provides the glue between the Javascript defined in the TokenScript project and the engine.
+It is essentially a 2-way message bus that allows the TokenScript developer to make requests to the engine and to receive updated data and other events emitted by the engine.
+It also allows the user to access various data including context data, environment variables & contract information.
+
+## Token Context Data
+
+As explained in the introduction to TokenScript attributes, Token Context data is made available through the card SDK.
+Our starter templates already handles the dataChange event which is used to provide initial and updated token context data to your card.
+
+If you want to register your own listener, you can do so by overwriting the following eventHandler
+
+```typescript
+tokenscript.tokens.dataChanged = async (oldTokens: any, updatedTokens: ITokenData, id: string) => {
+
+}
+```
+
+For our Svelte & React templates, the `updatedTokens.currentInstance` is automatically written to a global context variable that your UI can react to.
+
+## Environment Variables
+
+To access environment variables within your card, ensure that the variables is added into `ts:meta` as demonstrated [here](./tokenscript-syntax/xml).
+
+You can then access these variables via the `tokenscript.env` object:
+
+```typescript
+tokenscript.env.MY_ENV_VARIABLE
+```
+
+## Event handlers
+
+The engine include event handler infrastructure that allows the registration of multiple event listeners throughout your application.
+
+Currently, there is only one handler however more will be added in the future:
+
+- TRANSACTION_EVENT
+
+```typescript
+// Types
+interface TokenScriptEvents {
+ TRANSACTION_EVENT: ITransactionStatus
+}
+
+// Usage
+tokenscript.on("TRANSACTION_EVENT", (data: ITransactionStatus) => {
+ // Handle transaction event
+})
+```
+
+The TRANSACTION_EVENT can be used to react to transaction status even when the default action button is used to trigger the transaction.
+
+## Bundled libraries
+
+To reduce the size of built TokenScripts, some common libraries are bundled with the Card SDK.
+This allows the use of these libraries without explicitly installing them via NPM.
+
+Bundled libraries
+
+- Ethers.js ^v6.13 - available via the `ethers` global variable