diff --git a/Cargo.lock b/Cargo.lock
index 413bd28abe0376ec51a64b099de1f14fe4b124e2..81eb682a27d7abb30b25fca3f1db9f7fd5c62c2c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13390,11 +13390,14 @@ dependencies = [
  "pallet-example-single-block-migrations",
  "pallet-examples",
  "pallet-multisig",
+ "pallet-nfts",
+ "pallet-preimage",
  "pallet-proxy",
  "pallet-referenda",
  "pallet-scheduler",
  "pallet-timestamp",
  "pallet-transaction-payment",
+ "pallet-uniques",
  "pallet-utility",
  "parity-scale-codec",
  "sc-cli",
diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml
index 434202ed69365549b4e6ddf0c1b7a4d9c1e303c5..3b8f45d7756e935f66ec2b9ab46dd975386a355f 100644
--- a/docs/sdk/Cargo.toml
+++ b/docs/sdk/Cargo.toml
@@ -66,6 +66,7 @@ pallet-aura = { path = "../../substrate/frame/aura", default-features = false }
 pallet-timestamp = { path = "../../substrate/frame/timestamp" }
 pallet-balances = { path = "../../substrate/frame/balances" }
 pallet-assets = { path = "../../substrate/frame/assets" }
+pallet-preimage = { path = "../../substrate/frame/preimage" }
 pallet-transaction-payment = { path = "../../substrate/frame/transaction-payment" }
 pallet-utility = { path = "../../substrate/frame/utility" }
 pallet-multisig = { path = "../../substrate/frame/multisig" }
@@ -73,6 +74,8 @@ pallet-proxy = { path = "../../substrate/frame/proxy" }
 pallet-authorship = { path = "../../substrate/frame/authorship" }
 pallet-collective = { path = "../../substrate/frame/collective" }
 pallet-democracy = { path = "../../substrate/frame/democracy" }
+pallet-uniques = { path = "../../substrate/frame/uniques" }
+pallet-nfts = { path = "../../substrate/frame/nfts" }
 pallet-scheduler = { path = "../../substrate/frame/scheduler" }
 
 # Primitives
diff --git a/docs/sdk/src/reference_docs/frame_currency.rs b/docs/sdk/src/reference_docs/frame_currency.rs
deleted file mode 100644
index 6987d51aec824d370fb4706ae7d5b942a2667a64..0000000000000000000000000000000000000000
--- a/docs/sdk/src/reference_docs/frame_currency.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//! FRAME Currency Abstractions and Traits
-//!
-//! Notes:
-//!
-//! - History, `Currency` trait.
-//! - `Hold` and `Freeze` with diagram.
-//! - `HoldReason` and `FreezeReason`
-//! 	- This footgun: <https://github.com/paritytech/polkadot-sdk/pull/1900#discussion_r1363783609>
diff --git a/docs/sdk/src/reference_docs/frame_pallet_coupling.rs b/docs/sdk/src/reference_docs/frame_pallet_coupling.rs
index cca7f9feb3f40ca9f933e9e89ed8739fa2a79b45..be464bbbf8359c77fa549ab80bcb0008244488f9 100644
--- a/docs/sdk/src/reference_docs/frame_pallet_coupling.rs
+++ b/docs/sdk/src/reference_docs/frame_pallet_coupling.rs
@@ -143,7 +143,7 @@
 //! For example, all pallets in `polkadot-sdk` that needed to work with currencies could have been
 //! tightly coupled with [`pallet_balances`]. But, `polkadot-sdk` also provides [`pallet_assets`]
 //! (and more implementations by the community), therefore all pallets use traits to loosely couple
-//! with balances or assets pallet. More on this in [`crate::reference_docs::frame_currency`].
+//! with balances or assets pallet. More on this in [`crate::reference_docs::frame_tokens`].
 //!
 //! ## Further References
 //!
diff --git a/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs b/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs
index cbbf611f9dc4afd9866eb4786599294fdfda69a3..f9a69b892a3152854cdf7b5f97d003e500f64f07 100644
--- a/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs
+++ b/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs
@@ -131,7 +131,6 @@
 //!
 //! TODO: Link to multi block migration example/s once PR is merged (<https://github.com/paritytech/polkadot-sdk/pull/2119>).
 //!
-//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion
 //! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade
 //! [`StorageVersion`]: frame_support::traits::StorageVersion
 //! [`set_code`]: frame_system::Call::set_code
diff --git a/docs/sdk/src/reference_docs/frame_tokens.rs b/docs/sdk/src/reference_docs/frame_tokens.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c9d34e2091d897918123b4d0e374bf39a292f207
--- /dev/null
+++ b/docs/sdk/src/reference_docs/frame_tokens.rs
@@ -0,0 +1,131 @@
+// This file is part of polkadot-sdk.
+//
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! # FRAME Tokens
+//!
+//! This reference doc serves as a high-level overview of the token-related logic in FRAME, and
+//! how to properly apply it to your use case.
+//!
+//! On completion of reading this doc, you should have a good understanding of:
+//! - The distinction between token traits and trait implementations in FRAME, and why this
+//!   distinction is helpful
+//! - Token-related traits avaliable in FRAME
+//! - Token-related trait implementations in FRAME
+//! - How to choose the right trait or trait implementation for your use case
+//! - Where to go next
+//!
+//! ## Getting Started
+//!
+//! The most ubiquitous way to add a token to a FRAME runtime is [`pallet_balances`]. Read
+//! more about pallets [here](crate::polkadot_sdk::frame_runtime#pallets).
+//!
+//! You may then write custom pallets that interact with [`pallet_balances`]. The fastest way to
+//! get started with that is by
+//! [tightly coupling](crate::reference_docs::frame_pallet_coupling#tight-coupling-pallets) your
+//! custom pallet to [`pallet_balances`].
+//!
+//! However, to keep pallets flexible and modular, it is often prefered to
+//! [loosely couple](crate::reference_docs::frame_pallet_coupling#loosely--coupling-pallets).
+//!
+//! To achieve loose coupling,
+//! we separate token logic into traits and trait implementations.
+//!
+//! ## Traits and Trait Implementations
+//!
+//! Broadly speaking, token logic in FRAME can be divided into two categories: traits and
+//! trait implementations.
+//!
+//! **Traits** define common interfaces that types of tokens should implement. For example, the
+//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) trait specifies an interface
+//! for *inspecting* token state such as the total issuance of the token, the balance of individual
+//! accounts, etc.
+//!
+//! **Trait implementations** are concrete implementations of these traits. For example, one of the
+//! many traits [`pallet_balances`] implements is
+//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`)*. It provides the concrete way
+//! of inspecting the total issuance, balance of accounts, etc. There can be many implementations of
+//! the same traits.
+//!
+//! The distinction between traits and trait implementations is helpful because it allows pallets
+//! and other logic to be generic over their dependencies, avoiding tight coupling.
+//!
+//! To illustrate this with an example let's consider [`pallet_preimage`]. This pallet takes a
+//! deposit in exchange for storing a preimage for later use. A naive implementation of the
+//! pallet may use [`pallet_balances`] in a tightly coupled manner, directly calling methods
+//! on the pallet to reserve and unreserve deposits. This approach works well,
+//! until someone has a use case requiring that an asset from a different pallet such as
+//! [`pallet_assets`] is used for the deposit. Rather than tightly couple [`pallet_preimage`] to
+//! [`pallet_balances`], [`pallet_assets`], and every other token-handling pallet a user
+//! could possibly specify, [`pallet_preimage`] does not specify a concrete pallet as a dependency
+//! but instead accepts any dependency which implements the
+//! [`currency::ReservableCurrency`](`frame_support::traits::tokens::currency::ReservableCurrency`)
+//! trait, namely via its [`Config::Currency`](`pallet_preimage::pallet::Config::Currency`)
+//! associated type. This allows [`pallet_preimage`] to support any arbitrary pallet implementing
+//! this trait, without needing any knowledge of what those pallets may be or requiring changes to
+//! support new pallets which may be written in the future.
+//!
+//! Read more about coupling, and the benefits of loose coupling
+//! [here](crate::reference_docs::frame_pallet_coupling).
+//!
+//! ##### *Rust Advanced Tip
+//!
+//! The knowledge that [`pallet_balances`] implements
+//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) is not some arcane knowledge
+//! that you have to know by heart or memorize. One can simply look at the list of the implementors
+//! of any trait in the Rust Doc to find all implementors (e.g.
+//! <https://paritytech.github.io/polkadot-sdk/master/frame/traits/tokens/fungible/trait.Mutate.html#implementors>),
+//! or use the `rust-analyzer` `Implementations` action.
+//!
+//! ## Fungible Token Traits in FRAME
+//!
+//! The [`fungible`](`frame_support::traits::fungible`) crate contains the latest set of FRAME
+//! fungible token traits, and is recommended to use for all new logic requiring a fungible token.
+//! See the crate documentation for more info about these fungible traits.
+//!
+//! [`fungibles`](`frame_support::traits::fungibles`) provides very similar functionality to
+//! [`fungible`](`frame_support::traits::fungible`), except it supports managing multiple tokens.
+//!
+//! You may notice the trait [`Currency`](`frame_support::traits::Currency`) with similar
+//! functionality is also used in the codebase, however this trait is deprecated and existing logic
+//! is in the process of being migrated to [`fungible`](`frame_support::traits::fungible`) ([tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226)).
+//!
+//! ## Fungible Token Trait Implementations in FRAME
+//!
+//! [`pallet_balances`] implements [`fungible`](`frame_support::traits::fungible`), and is the most
+//! commonly used fungible implementation in FRAME. Most of the time, it's used for managing the
+//! native token of the blockchain network it's used in.
+//!
+//! [`pallet_assets`] implements [`fungibles`](`frame_support::traits::fungibles`), and is another
+//! popular fungible token implementation. It supports the creation and management of multiple
+//! assets in a single crate, making it a good choice when a network requires more assets in
+//! addition to its native token.
+//!
+//! ## Non-Fungible Tokens in FRAME
+//!
+//! [`pallet_nfts`] is recommended to use for all NFT use cases in FRAME.
+//! See the crate documentation for more info about this pallet.
+//!
+//! [`pallet_uniques`] is deprecated and should not be used.
+//!
+//!
+//! # What Next?
+//!
+//! - If you are interested in implementing a single fungible token, continue reading the
+//!   [`fungible`](`frame_support::traits::fungible`) and [`pallet_balances`] docs.
+//! - If you are interested in implementing a set of fungible tokens, continue reading the
+//!   [`fungibles`](`frame_support::traits::fungibles`) trait and [`pallet_assets`] docs.
+//! - If you are interested in implementing an NFT, continue reading the [`pallet_nfts`] docs.
diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs
index a0d8d05b44926c4b2ca9259d0709a8a7dee2fb76..145df8844f26e5b58d737a4290035e3886bf63fe 100644
--- a/docs/sdk/src/reference_docs/mod.rs
+++ b/docs/sdk/src/reference_docs/mod.rs
@@ -65,9 +65,6 @@ pub mod metadata;
 /// Learn about how frame-system handles `account-ids`, nonces, consumers and providers.
 pub mod frame_system_accounts;
 
-/// Learn about the currency-related abstractions provided in FRAME.
-pub mod frame_currency;
-
 /// Advice for configuring your development environment for Substrate development.
 pub mod development_environment_advice;
 
@@ -75,6 +72,9 @@ pub mod development_environment_advice;
 // TODO: @shawntabrizi @ggwpez https://github.com/paritytech/polkadot-sdk-docs/issues/50
 pub mod frame_benchmarking_weight;
 
+/// Learn about the token-related logic in FRAME and how to apply it to your use case.
+pub mod frame_tokens;
+
 /// Learn about chain specification file and the genesis state of the blockchain.
 // TODO: @michalkucharczyk https://github.com/paritytech/polkadot-sdk-docs/issues/51
 pub mod chain_spec_genesis;
diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs
index c5468e4237df1fd5d936ef9cca2f96336758241f..e5fe2a3d1fd3965b31563480e45eb99fecfd05b7 100644
--- a/substrate/frame/assets/src/lib.rs
+++ b/substrate/frame/assets/src/lib.rs
@@ -17,7 +17,16 @@
 
 //! # Assets Pallet
 //!
-//! A simple, secure module for dealing with fungible assets.
+//! A simple, secure module for dealing with sets of assets implementing
+//! [`fungible`](frame_support::traits::fungible) traits, via
+//! [`fungibles`](frame_support::traits::fungibles) traits.
+//!
+//! The pallet makes heavy use of concepts such as Holds and Freezes from the
+//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs
+//! as a prerequisite to understanding this pallet.
+//!
+//! See the [`frame_tokens`] reference docs for more information about the place of the
+//! Assets pallet in FRAME.
 //!
 //! ## Overview
 //!
@@ -133,6 +142,8 @@
 //!
 //! * [`System`](../frame_system/index.html)
 //! * [`Support`](../frame_support/index.html)
+//!
+//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
 
 // This recursion limit is needed because we have too many benchmarks and benchmarking will fail if
 // we add more without this limit.
diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs
index 80278752207dee2f54972b60fb2062e6e69ace0e..685b12499ac0ffb2a27d3f861232ab3dc09bf08f 100644
--- a/substrate/frame/balances/src/lib.rs
+++ b/substrate/frame/balances/src/lib.rs
@@ -17,11 +17,15 @@
 
 //! # Balances Pallet
 //!
-//! The Balances pallet provides functionality for handling accounts and balances.
+//! The Balances pallet provides functionality for handling accounts and balances for a single
+//! token.
 //!
-//! - [`Config`]
-//! - [`Call`]
-//! - [`Pallet`]
+//! It makes heavy use of concepts such as Holds and Freezes from the
+//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs
+//! as a prerequisite to understanding this pallet.
+//!
+//! Also see the [`frame_tokens`] reference docs for higher level information regarding the
+//! place of this palet in FRAME.
 //!
 //! ## Overview
 //!
@@ -38,42 +42,30 @@
 //!
 //! ### Terminology
 //!
-//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This
-//!   prevents "dust accounts" from filling storage. When the free plus the reserved balance (i.e.
-//!   the total balance) fall below this, then the account is said to be dead; and it loses its
-//!   functionality as well as any prior history and all information on it is removed from the
-//!   chain's state. No account should ever have a total balance that is strictly between 0 and the
-//!   existential deposit (exclusive). If this ever happens, it indicates either a bug in this
-//!   pallet or an erroneous raw mutation of storage.
-//!
-//! - **Total Issuance:** The total number of units in existence in a system.
-//!
 //! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after
-//!   its total balance has become zero (or, strictly speaking, less than the Existential Deposit).
-//!
-//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only
-//!   balance that matters for most operations.
+//!   its total balance has become less than the Existential Deposit.
 //!
-//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended.
-//!   Reserved balance can still be slashed, but only after all the free balance has been slashed.
-//!
-//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite
-//!   accounting (i.e. a difference between total issuance and account balances). Functions that
-//! result in an imbalance will return an object of the `Imbalance` trait that can be managed within
-//! your runtime logic. (If an imbalance is simply dropped, it should automatically maintain any
-//! book-keeping such as total issuance.)
+//! ### Implementations
 //!
-//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block
-//!   number. Multiple locks always operate over the same funds, so they "overlay" rather than
-//! "stack".
+//! The Balances pallet provides implementations for the following [`fungible`] traits. If these
+//! traits provide the functionality that you need, then you should avoid tight coupling with the
+//! Balances pallet.
 //!
-//! ### Implementations
+//! - [`fungible::Inspect`]
+//! - [`fungible::Mutate`]
+//! - [`fungible::Unbalanced`]
+//! - [`fungible::Balanced`]
+//! - [`fungible::BalancedHold`]
+//! - [`fungible::InspectHold`]
+//! - [`fungible::MutateHold`]
+//! - [`fungible::InspectFreeze`]
+//! - [`fungible::MutateFreeze`]
+//! - [`fungible::Imbalance`]
 //!
-//! The Balances pallet provides implementations for the following traits. If these traits provide
-//! the functionality that you need, then you can avoid coupling with the Balances pallet.
+//! It also implements the following [`Currency`] related traits, however they are deprecated and
+//! will eventually be removed.
 //!
-//! - [`Currency`]: Functions for dealing with a
-//! fungible assets system.
+//! - [`Currency`]: Functions for dealing with a fungible assets system.
 //! - [`ReservableCurrency`]
 //! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency):
 //! Functions for dealing with assets that can be reserved from an account.
@@ -83,14 +75,6 @@
 //! imbalances between total issuance in the system and account balances. Must be used when a
 //! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee).
 //!
-//! ## Interface
-//!
-//! ### Dispatchable Functions
-//!
-//! - `transfer_allow_death` - Transfer some liquid free balance to another account.
-//! - `force_set_balance` - Set the balances of a given account. The origin of this call must be
-//!   root.
-//!
 //! ## Usage
 //!
 //! The following examples show how to use the Balances pallet in your custom pallet.
@@ -151,8 +135,11 @@
 //! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`.
 //! * Existential Deposit is set to a value greater than zero.
 //!
-//! Note, you may find the Balances pallet still functions with an ED of zero in some circumstances,
-//! however this is not a configuration which is generally supported, nor will it be.
+//! Note, you may find the Balances pallet still functions with an ED of zero when the
+//! `insecure_zero_ed` cargo feature is enabled. However this is not a configuration which is
+//! generally supported, nor will it be.
+//!
+//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
 
 #![cfg_attr(not(feature = "std"), no_std)]
 mod benchmarking;
@@ -308,10 +295,14 @@ pub mod pallet {
 
 		/// The maximum number of locks that should exist on an account.
 		/// Not strictly enforced, but used for weight estimation.
+		///
+		/// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/`
 		#[pallet::constant]
 		type MaxLocks: Get<u32>;
 
 		/// The maximum number of named reserves that can exist on an account.
+		///
+		/// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/`
 		#[pallet::constant]
 		type MaxReserves: Get<u32>;
 
@@ -455,6 +446,8 @@ pub mod pallet {
 
 	/// Any liquidity locks on some account balances.
 	/// NOTE: Should only be accessed when setting, changing and freeing a lock.
+	///
+	/// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/`
 	#[pallet::storage]
 	#[pallet::getter(fn locks)]
 	pub type Locks<T: Config<I>, I: 'static = ()> = StorageMap<
@@ -466,6 +459,8 @@ pub mod pallet {
 	>;
 
 	/// Named reserves on some account balances.
+	///
+	/// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/`
 	#[pallet::storage]
 	#[pallet::getter(fn reserves)]
 	pub type Reserves<T: Config<I>, I: 'static = ()> = StorageMap<
diff --git a/substrate/frame/support/src/traits/tokens/currency.rs b/substrate/frame/support/src/traits/tokens/currency.rs
index 282e7f6447330fd0ebdee3a107edc3faca4024a9..b3db4c98001d900522b33c6a25e3e9b9119c3ea5 100644
--- a/substrate/frame/support/src/traits/tokens/currency.rs
+++ b/substrate/frame/support/src/traits/tokens/currency.rs
@@ -16,6 +16,9 @@
 // limitations under the License.
 
 //! The Currency trait and associated types.
+//!
+//! Note Currency and related traits are deprecated, instead
+//! [`fungible`](frame_support::traits::fungible) traits should be used.
 
 use super::{
 	imbalance::{Imbalance, SignedImbalance},
diff --git a/substrate/frame/support/src/traits/tokens/fungible/freeze.rs b/substrate/frame/support/src/traits/tokens/fungible/freeze.rs
index 8b542ee4c6060e143ee58902a38e39cca38b109b..96efbc6ab89e154a57d88d75c65ab8c330af41eb 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/freeze.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/freeze.rs
@@ -16,6 +16,9 @@
 // limitations under the License.
 
 //! The traits for putting freezes within a single fungible token class.
+//!
+//! See the [`crate::traits::fungible`] doc for more information about fungible traits
+//! including the place of the Freezes in FRAME.
 
 use scale_info::TypeInfo;
 use sp_arithmetic::{
@@ -35,7 +38,7 @@ pub trait Inspect<AccountId>: super::Inspect<AccountId> {
 	/// An identifier for a freeze.
 	type Id: codec::Encode + TypeInfo + 'static;
 
-	/// Amount of funds held in reserve by `who` for the given `id`.
+	/// Amount of funds frozen in reserve by `who` for the given `id`.
 	fn balance_frozen(id: &Self::Id, who: &AccountId) -> Self::Balance;
 
 	/// The amount of the balance which can become frozen. Defaults to `total_balance()`.
@@ -45,11 +48,11 @@ pub trait Inspect<AccountId>: super::Inspect<AccountId> {
 
 	/// Returns `true` if it's possible to introduce a freeze for the given `id` onto the
 	/// account of `who`. This will be true as long as the implementor supports as many
-	/// concurrent freeze locks as there are possible values of `id`.
+	/// concurrent freezes as there are possible values of `id`.
 	fn can_freeze(id: &Self::Id, who: &AccountId) -> bool;
 }
 
-/// Trait for introducing, altering and removing locks to freeze an account's funds so they never
+/// Trait for introducing, altering and removing freezes for an account for its funds never
 /// go below a set minimum.
 pub trait Mutate<AccountId>: Inspect<AccountId> {
 	/// Prevent actions which would reduce the balance of the account of `who` below the given
@@ -66,16 +69,16 @@ pub trait Mutate<AccountId>: Inspect<AccountId> {
 	/// counteract any pre-existing freezes in place for `who` under the `id`. Also unlike
 	/// `set_freeze`, in the case that `amount` is zero, this is no-op and never fails.
 	///
-	/// Note that more funds can be locked than the total balance, if desired.
+	/// Note that more funds can be frozen than the total balance, if desired.
 	fn extend_freeze(id: &Self::Id, who: &AccountId, amount: Self::Balance) -> DispatchResult;
 
-	/// Remove an existing lock.
+	/// Remove an existing freeze.
 	fn thaw(id: &Self::Id, who: &AccountId) -> DispatchResult;
 
 	/// Attempt to alter the amount frozen under the given `id` to `amount`.
 	///
 	/// Fail if the account of `who` has fewer freezable funds than `amount`, unless `fortitude` is
-	/// `Fortitude::Force`.
+	/// [`Fortitude::Force`].
 	fn set_frozen(
 		id: &Self::Id,
 		who: &AccountId,
@@ -91,7 +94,7 @@ pub trait Mutate<AccountId>: Inspect<AccountId> {
 	/// the amount frozen under `id`. Do nothing otherwise.
 	///
 	/// Fail if the account of `who` has fewer freezable funds than `amount`, unless `fortitude` is
-	/// `Fortitude::Force`.
+	/// [`Fortitude::Force`].
 	fn ensure_frozen(
 		id: &Self::Id,
 		who: &AccountId,
diff --git a/substrate/frame/support/src/traits/tokens/fungible/hold.rs b/substrate/frame/support/src/traits/tokens/fungible/hold.rs
index 6da652d2998dfc18dd7da5754da7faf22abab839..28ece25c91d427146354e3ad91257e01cd9c4cb5 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/hold.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/hold.rs
@@ -16,6 +16,9 @@
 // limitations under the License.
 
 //! The traits for putting holds within a single fungible token class.
+//!
+//! See the [`crate::traits::fungible`] doc for more information about fungible traits
+//! including the place of the Holds in FRAME.
 
 use crate::{
 	ensure,
@@ -214,8 +217,8 @@ pub trait Mutate<AccountId>:
 	///
 	/// The actual amount released is returned with `Ok`.
 	///
-	/// If `precision` is `BestEffort`, then the amount actually unreserved and returned as the
-	/// inner value of `Ok` may be smaller than the `amount` passed.
+	/// If `precision` is [`Precision::BestEffort`], then the amount actually unreserved and
+	/// returned as the inner value of `Ok` may be smaller than the `amount` passed.
 	///
 	/// NOTE! The inner of the `Ok` result variant returns the *actual* amount released. This is the
 	/// opposite of the `ReservableCurrency::unreserve()` result, which gives the amount not able
diff --git a/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs b/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs
index 0e25102197007e7ce3f38eef7417425f09dbcd2f..020dffe28c85b7a0f1bb213173342e4dd9e907d7 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs
@@ -17,6 +17,8 @@
 
 //! The imbalance type and its associates, which handles keeps everything adding up properly with
 //! unbalanced operations.
+//!
+//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
 
 use super::{super::Imbalance as ImbalanceT, Balanced, *};
 use crate::traits::{
diff --git a/substrate/frame/support/src/traits/tokens/fungible/item_of.rs b/substrate/frame/support/src/traits/tokens/fungible/item_of.rs
index 37749d396009d8a11629d3c1f94c6ce5efbe6f21..5374cc52bab72a25270606e89f97a6f035f3a704 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/item_of.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/item_of.rs
@@ -16,6 +16,11 @@
 // limitations under the License.
 
 //! Adapter to use `fungibles::*` implementations as `fungible::*`.
+//!
+//! This allows for a `fungibles` asset, e.g. from the `pallet_assets` pallet, to be used when a
+//! `fungible` asset is expected.
+//!
+//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
 
 use super::*;
 use crate::traits::{
diff --git a/substrate/frame/support/src/traits/tokens/fungible/mod.rs b/substrate/frame/support/src/traits/tokens/fungible/mod.rs
index ba4a2e5e21a2c9f5115ca6331e85df0fea58bb74..4a0cda2dbc7b7a8ae20dedae071cbf726a31a0fc 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/mod.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/mod.rs
@@ -17,26 +17,135 @@
 
 //! The traits for dealing with a single fungible token class and any associated types.
 //!
-//! ### User-implememted traits
-//! - `Inspect`: Regular balance inspector functions.
-//! - `Unbalanced`: Low-level balance mutating functions. Does not guarantee proper book-keeping and
-//!   so should not be called into directly from application code. Other traits depend on this and
-//!   provide default implementations based on it.
-//! - `UnbalancedHold`: Low-level balance mutating functions for balances placed on hold. Does not
+//! Also see the [`frame_tokens`] reference docs for more information about the place of
+//! `fungible` traits in Substrate.
+//!
+//! # Avaliable Traits
+//! - [`Inspect`]: Regular balance inspector functions.
+//! - [`Unbalanced`]: Low-level balance mutating functions. Does not guarantee proper book-keeping
+//!   and so should not be called into directly from application code. Other traits depend on this
+//!   and provide default implementations based on it.
+//! - [`UnbalancedHold`]: Low-level balance mutating functions for balances placed on hold. Does not
 //!   guarantee proper book-keeping and so should not be called into directly from application code.
 //!   Other traits depend on this and provide default implementations based on it.
-//! - `Mutate`: Regular balance mutator functions. Pre-implemented using `Unbalanced`, though the
-//!   `done_*` functions should likely be reimplemented in case you want to do something following
-//!   the operation such as emit events.
-//! - `InspectHold`: Inspector functions for balances on hold.
-//! - `MutateHold`: Mutator functions for balances on hold. Mostly pre-implemented using
-//!   `UnbalancedHold`.
-//! - `InspectFreeze`: Inspector functions for frozen balance.
-//! - `MutateFreeze`: Mutator functions for frozen balance.
-//! - `Balanced`: One-sided mutator functions for regular balances, which return imbalance objects
+//! - [`Mutate`]: Regular balance mutator functions. Pre-implemented using [`Unbalanced`], though
+//!   the `done_*` functions should likely be reimplemented in case you want to do something
+//!   following the operation such as emit events.
+//! - [`InspectHold`]: Inspector functions for balances on hold.
+//! - [`MutateHold`]: Mutator functions for balances on hold. Mostly pre-implemented using
+//!   [`UnbalancedHold`].
+//! - [`InspectFreeze`]: Inspector functions for frozen balance.
+//! - [`MutateFreeze`]: Mutator functions for frozen balance.
+//! - [`Balanced`]: One-sided mutator functions for regular balances, which return imbalance objects
 //!   which guarantee eventual book-keeping. May be useful for some sophisticated operations where
 //!   funds must be removed from an account before it is known precisely what should be done with
 //!   them.
+//!
+//! ## Terminology
+//!
+//! - **Total Issuance**: The total number of units in existence in a system.
+//!
+//! - **Total Balance**: The sum of an account's free and held balances.
+//!
+//! - **Free Balance**: A portion of an account's total balance that is not held. Note this is
+//!   distinct from the Spendable Balance, which represents how much Balance the user can actually
+//!   transfer.
+//!
+//! - **Held Balance**: Held balance still belongs to the account holder, but is suspended. It can
+//!   be slashed, but only after all the free balance has been slashed.
+//!
+//!   Multiple holds stack rather than overlay. This means that if an account has
+//!   3 holds for 100 units, the account can spend its funds for any reason down to 300 units, at
+//!   which point the holds will start to come into play.
+//!
+//! - **Frozen Balance**: A freeze on a specified amount of an account's free balance until a
+//!   specified block number.
+//!
+//!   Multiple freezes always operate over the same funds, so they "overlay" rather than
+//!   "stack". This means that if an account has 3 freezes for 100 units, the account can spend its
+//!   funds for any reason down to 100 units, at which point the freezes will start to come into
+//!   play.
+//!
+//! - **Minimum Balance (a.k.a. Existential Deposit, a.k.a. ED)**: The minimum balance required to
+//!   create or keep an account open. This is to prevent "dust accounts" from filling storage. When
+//!   the free plus the held balance (i.e. the total balance) falls below this, then the account is
+//!   said to be dead. It loses its functionality as well as any prior history and all information
+//!   on it is removed from the chain's state. No account should ever have a total balance that is
+//!   strictly between 0 and the existential deposit (exclusive). If this ever happens, it indicates
+//!   either a bug in the implementation of this trait or an erroneous raw mutation of storage.
+//!
+//! - **Untouchable Balance**: The part of a user's free balance they cannot spend, due to ED or
+//!   Freeze(s).
+//!
+//! - **Spendable Balance**: The part of a user's free balance they can actually transfer, after
+//!   accounting for Holds and Freezes.
+//!
+//! - **Imbalance**: A condition when some funds were credited or debited without equal and opposite
+//!   accounting (i.e. a difference between total issuance and account balances). Functions that
+//!   result in an imbalance will return an object of the [`imbalance::Credit`] or
+//!   [`imbalance::Debt`] traits that can be managed within your runtime logic.
+//!
+//!   If an imbalance is simply dropped, it should automatically maintain any book-keeping such as
+//!   total issuance.
+//!
+//! ## Visualising Balance Components Together 💫
+//!
+//! ```ignore
+//! |__total__________________________________|
+//! |__on_hold__|_____________free____________|
+//! |__________frozen___________|
+//! |__on_hold__|__ed__|
+//!             |__untouchable__|__spendable__|
+//! ```
+//!
+//! ## Holds and Freezes
+//!
+//! Both holds and freezes are used to prevent an account from using some of its balance.
+//!
+//! The primary distinction between the two are that:
+//! - Holds are cumulative (do not overlap) and are distinct from the free balance
+//! - Freezes are not cumulative, and can overlap with each other or with holds
+//!
+//! ```ignore
+//! |__total_____________________________|
+//! |__hold_a__|__hold_b__|_____free_____|
+//! |__on_hold____________|     // <- the sum of all holds
+//! |__freeze_a_______________|
+//! |__freeze_b____|
+//! |__freeze_c________|
+//! |__frozen_________________| // <- the max of all freezes
+//! ```
+//!
+//! Holds are designed to be infallibly slashed, meaning that any logic using a `Freeze`
+//! must handle the possibility of the frozen amount being reduced, potentially to zero. A
+//! permissionless function should be provided in order to allow bookkeeping to be updated in this
+//! instance. E.g. some balance is frozen when it is used for voting, one could use held balance for
+//! voting, but nothing prevents this frozen balance from being reduced if the overlapping hold is
+//! slashed.
+//!
+//! Every Hold and Freeze is accompanied by a unique `Reason`, making it clear for each instance
+//! what the originating pallet and purpose is. These reasons are amalgomated into a single enum
+//! `RuntimeHoldReason` and `RuntimeFreezeReason` respectively, when the runtime is compiled.
+//!
+//! Note that `Hold` and `Freeze` reasons should remain in your runtime for as long as storage
+//! could exist in your runtime with those reasons, otherwise your runtime state could become
+//! undecodable.
+//!
+//! ### Should I use a Hold or Freeze?
+//!
+//! If you require a balance to be infaillibly slashed, then you should use Holds.
+//!
+//! If you require setting a minimum account balance amount, then you should use a Freezes. Note
+//! Freezes do not carry the same guarantees as Holds. Although the account cannot voluntarily
+//! reduce their balance below the largest freeze, if Holds on the account are slashed then the
+//! balance could drop below the freeze amount.
+//!
+//! ## Sets of Tokens
+//!
+//! For managing sets of tokens, see the [`fungibles`](`frame_support::traits::fungibles`) trait
+//! which is a wrapper around this trait but supporting multiple asset instances.
+//!
+//! [`frame_tokens`]: ../../../../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
 
 pub mod conformance_tests;
 pub mod freeze;
diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs
index 0157b08bd137b2813236f34e193799cf8267b88a..4ed31dcf9fb1f099ebc576ae981d289613775b60 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! `Inspect` and `Mutate` traits for working with regular balances.
+//!
+//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
 
 use crate::{
 	ensure,
diff --git a/substrate/frame/support/src/traits/tokens/fungible/union_of.rs b/substrate/frame/support/src/traits/tokens/fungible/union_of.rs
index 33711d7a16cc6e7fe40eb619f5b4aba4703163df..575b771a614480147d5afe878dc71652d278bb67 100644
--- a/substrate/frame/support/src/traits/tokens/fungible/union_of.rs
+++ b/substrate/frame/support/src/traits/tokens/fungible/union_of.rs
@@ -17,6 +17,8 @@
 
 //! Types to combine some `fungible::*` and `fungibles::*` implementations into one union
 //! `fungibles::*` implementation.
+//!
+//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
 
 use codec::{Decode, Encode, MaxEncodedLen};
 use frame_support::traits::{
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/approvals.rs b/substrate/frame/support/src/traits/tokens/fungibles/approvals.rs
index 7a80279b01981420840811e550c92c106a682bef..09e3d20756a2fbb3e1dd8c08b17b38c44f82c28c 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/approvals.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/approvals.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! Inspect and Mutate traits for Asset approvals
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use crate::dispatch::DispatchResult;
 pub trait Inspect<AccountId>: super::Inspect<AccountId> {
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/enumerable.rs b/substrate/frame/support/src/traits/tokens/fungibles/enumerable.rs
index 08bb784a7dbf63fd39c51f0468cfe42cbcb16248..81dbb93b0b8d63fafcbd80ab64ad3aec53c40bab 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/enumerable.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/enumerable.rs
@@ -15,6 +15,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//! Contains an interface for enumerating assets in existence or owned by a given account.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
+
 /// Interface for enumerating assets in existence or owned by a given account.
 pub trait Inspect<AccountId>: super::Inspect<AccountId> {
 	type AssetsIterator;
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/freeze.rs b/substrate/frame/support/src/traits/tokens/fungibles/freeze.rs
index b07d20d6c41ce48c3f4face0ea4a213a3023f5e3..244f700589945d97d1d5ed2abc8326bded127d73 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/freeze.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/freeze.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! The traits for putting freezes within a single fungible token class.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use crate::{ensure, traits::tokens::Fortitude};
 use scale_info::TypeInfo;
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/hold.rs b/substrate/frame/support/src/traits/tokens/fungibles/hold.rs
index 1efd1594213c1a80eeccdd4fdf0c9f01c812794c..ef3fef7a300d96b5c741983fd0b19297b44f541c 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/hold.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/hold.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! The traits for putting holds within a single fungible token class.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use crate::{
 	ensure,
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs b/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs
index 54c1e900b6e3664b6fbf3470e41d17eaae37e635..bb0d83721a481e11f80f1ae9fa75292528f7c8a0 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs
@@ -17,6 +17,8 @@
 
 //! The imbalance type and its associates, which handles keeps everything adding up properly with
 //! unbalanced operations.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use super::*;
 use crate::traits::{
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/lifetime.rs b/substrate/frame/support/src/traits/tokens/fungibles/lifetime.rs
index 0e195a52318b7ddb34aef57e3d8742cd36952e06..49f6c846ccdd54adeceb668bb10a8cb2ca11281f 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/lifetime.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/lifetime.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! Traits for creating and destroying assets.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use sp_runtime::{DispatchError, DispatchResult};
 
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/metadata.rs b/substrate/frame/support/src/traits/tokens/fungibles/metadata.rs
index ab310119e58467da21dc9f68c84ad8dd173e8f43..ab722426dadf6fa759340ac12609e58c1139ff02 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/metadata.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/metadata.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! Inspect and Mutate traits for Asset metadata
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use crate::dispatch::DispatchResult;
 use sp_std::vec::Vec;
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/mod.rs b/substrate/frame/support/src/traits/tokens/fungibles/mod.rs
index 1db0706ba4fde4c3b53dbcdd5ea850a37752b1e9..2122fdeaed3f28b937fa16a2230fa0f9a56d869a 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/mod.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/mod.rs
@@ -15,7 +15,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! The traits for sets of fungible tokens and any associated types.
+//! The traits for *sets* of [`fungible`](`frame_support::traits::fungible`) tokens and any
+//! associated types.
+//!
+//! Individual tokens in the `fungibles` set may be used when a `fungible` trait is expected using
+//! [`crate::traits::tokens::fungible::ItemOf`].
+//!
+//! Also see the [`frame_tokens`] reference docs for more information about the place of
+//! `fungible` traits in Substrate.
+//!
+//! [`frame_tokens`]: ../../../../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
 
 pub mod approvals;
 mod enumerable;
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/regular.rs b/substrate/frame/support/src/traits/tokens/fungibles/regular.rs
index 8cc97802da66e5fa192a3720cfc6381c8930818f..b30e0ae3a2a3657c1a2685fa413ff120803ae187 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/regular.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/regular.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! `Inspect` and `Mutate` traits for working with regular balances.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use sp_std::marker::PhantomData;
 
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/roles.rs b/substrate/frame/support/src/traits/tokens/fungibles/roles.rs
index 5cd1228afbce72542aae333759968d5ddee6fac3..4f95ad8368c2c555e1a07f1f1b8b9ede7cf574cb 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/roles.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/roles.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! Inspect traits for Asset roles
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 pub trait Inspect<AccountId>: super::Inspect<AccountId> {
 	// Get owner for an AssetId.
diff --git a/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs b/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs
index 9d2a783df2a4af0c593c784d4c4d794b0311c392..c8a1ec37e78184f36342acefd65dd1815792b257 100644
--- a/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs
+++ b/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs
@@ -16,6 +16,8 @@
 // limitations under the License.
 
 //! Type to combine two `fungibles::*` implementations into one union `fungibles::*` implementation.
+//!
+//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
 
 use frame_support::traits::{
 	tokens::{