diff --git a/docs/source/api/composer.rst b/docs/source/api/composer.rst
index a969d4ff91455f0fda51813aab93e23c4b0b7098..667b0de60f9564e98de46b562e0fcc0afe7cf2a1 100644
--- a/docs/source/api/composer.rst
+++ b/docs/source/api/composer.rst
@@ -1,6 +1,6 @@
-***************************************
-Composer API (`pystencilssfg.composer`)
-***************************************
+*****************************************
+Composer API (``pystencilssfg.composer``)
+*****************************************
 
 .. autoclass:: pystencilssfg.composer.SfgComposer
     :members:
diff --git a/docs/source/api/lang.rst b/docs/source/api/lang.rst
index efc69d98c3b278a3fa34b5164a35f58f76c6e2d5..c83317e506549eb9ca9d86bc71765d196306ef09 100644
--- a/docs/source/api/lang.rst
+++ b/docs/source/api/lang.rst
@@ -9,8 +9,20 @@ Expressions
 .. automodule:: pystencilssfg.lang.expressions
     :members:
 
-C++ Standard Library (`pystencilssfg.lang.cpp`)
------------------------------------------------
+Header Files
+------------
+
+.. automodule:: pystencilssfg.lang.headers
+    :members:
+
+Data Types
+----------
+
+.. automodule:: pystencilssfg.lang.types
+    :members:
+
+C++ Standard Library (``pystencilssfg.lang.cpp``)
+-------------------------------------------------
 
 Quick Access
 ^^^^^^^^^^^^
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 40d5a0fbccc11bddd40d0da96a3dc883b64cdc6e..4bdf700da8e949023ddc1a56fd44d915a9f842db 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -65,12 +65,15 @@ html_theme_options = {
 
 intersphinx_mapping = {
     "python": ("https://docs.python.org/3.8", None),
-    "numpy": ("https://docs.scipy.org/doc/numpy/", None),
-    "matplotlib": ("https://matplotlib.org/", None),
+    "numpy": ("https://numpy.org/doc/stable/", None),
     "sympy": ("https://docs.sympy.org/latest/", None),
     "pystencils": ("https://da15siwa.pages.i10git.cs.fau.de/dev-docs/pystencils-nbackend/", None),
 }
 
+#   References
+
+#   Treat `single-quoted` code blocks as references to any
+default_role = "any"
 
 #   Autodoc options
 
diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py
index c48410c0619482dcbe44de21742727e1b27ade8e..90146e596123eedc73eea5f813964f7593b6f43f 100644
--- a/src/pystencilssfg/composer/basic_composer.py
+++ b/src/pystencilssfg/composer/basic_composer.py
@@ -286,7 +286,7 @@ class SfgBasicComposer(SfgIComposer):
 
         When using `call`, the given kernel will simply be called as a function.
         To invoke a GPU kernel on a specified launch grid, use `cuda_invoke`
-        or the interfaces of `pystencilssfg.extensions.sycl` instead.
+        or the interfaces of ``pystencilssfg.extensions.sycl`` instead.
 
         Args:
             kernel_handle: Handle to a kernel previously added to some kernel namespace.
@@ -300,6 +300,7 @@ class SfgBasicComposer(SfgIComposer):
         threads_per_block: ExprLike,
         stream: ExprLike | None,
     ):
+        """Dispatch a CUDA kernel to the device."""
         num_blocks_str = str(num_blocks)
         tpb_str = str(threads_per_block)
         stream_str = str(stream) if stream is not None else None
diff --git a/src/pystencilssfg/lang/cpp/std_mdspan.py b/src/pystencilssfg/lang/cpp/std_mdspan.py
index 7c3fd3598cb59ff1157c63619eba092b40cc6654..4f7616011339d6640412305493f064972c3f081f 100644
--- a/src/pystencilssfg/lang/cpp/std_mdspan.py
+++ b/src/pystencilssfg/lang/cpp/std_mdspan.py
@@ -17,17 +17,61 @@ from ...lang import SrcField, IFieldExtraction, cpptype, Ref, HeaderFile
 class StdMdspan(SrcField):
     """Represents an `std::mdspan` instance.
 
-    **On Standard Library Adoption**
+    The `std::mdspan <https://en.cppreference.com/w/cpp/container/mdspan>`_
+    provides non-owning views into contiguous or strided n-dimensional arrays.
+    It has been added to the C++ STL with the C++23 standard.
+    As such, it is a natural data structure to target with pystencils kernels.
 
-    Since `std::mdspan` is not yet widely adopted
+    **Concerning Headers and Namespaces**
+
+    Since ``std::mdspan`` is not yet widely adopted
     (libc++ ships it as of LLVM 18, but GCC libstdc++ does not include it yet),
     you might have to manually include an implementation in your project
-    (you can get a reference implementation [here](https://github.com/kokkos/mdspan)).
+    (you can get a reference implementation at https://github.com/kokkos/mdspan).
     However, when working with a non-standard mdspan implementation,
     the path to its the header and the namespace it is defined in will likely be different.
 
-    To tell pystencils-sfg which headers to include and which namespace to use for `mdspan`,
-    use `StdMdspan.configure`.
+    To tell pystencils-sfg which headers to include and which namespace to use for ``mdspan``,
+    use `StdMdspan.configure`;
+    for instance, adding this call before creating any ``mdspan`` objects will
+    set their namespace to `std::experimental`, and require ``<experimental/mdspan>`` to be imported:
+
+    >>> from pystencilssfg.lang.cpp import std
+    >>> std.mdspan.configure("std::experimental", "<experimental/mdspan>")
+
+    **Creation from pystencils fields**
+
+    Using `from_field`, ``mdspan`` objects can be created directly from `Field <pystencils.Field>` instances.
+    The `extents`_ and `layout_policy`_ of the ``mdspan`` type will be inferred from the field.
+    Each fixed entry in the field's shape will become a fixed entry of the ``mdspan``'s extents.
+    The field's memory layout will be mapped onto a predefined ``LayoutPolicy`` according to this table:
+
+    +------------------------+--------------------------+
+    | pystencils Layout Name | ``mdspan`` Layout Policy |
+    +========================+==========================+
+    | ``"fzyx"``             | `std::layout_left`_      |
+    | ``"soa"``              |                          |
+    | ``"f"``                |                          |
+    | ``"reverse_numpy"``    |                          |
+    +------------------------+--------------------------+
+    | ``"c"``                | `std::layout_right`_     |
+    | ``"numpy"``            |                          |
+    +------------------------+--------------------------+
+    | ``"zyxf"``             | `std::layout_stride`_    |
+    | ``"aos"``              |                          |
+    +------------------------+--------------------------+
+
+    The structure-of-arrays (or ZYXF) layout has no equivalent layout policy in the C++ standard,
+    so it can only be mapped onto ``layout_stride``, which models user-defined strides.
+
+    .. _extents: https://en.cppreference.com/w/cpp/container/mdspan/extents
+    .. _layout_policy: https://en.cppreference.com/w/cpp/named_req/LayoutMappingPolicy
+    .. _std::layout_left: https://en.cppreference.com/w/cpp/container/mdspan/layout_left
+    .. _std::layout_right: https://en.cppreference.com/w/cpp/container/mdspan/layout_right
+    .. _std::layout_stride: https://en.cppreference.com/w/cpp/container/mdspan/layout_stride
+
+    Args:
+        T: Element type of the mdspan
     """
 
     dynamic_extent = "std::dynamic_extent"
@@ -37,7 +81,7 @@ class StdMdspan(SrcField):
 
     @classmethod
     def configure(cls, namespace: str = "std", header: str | HeaderFile = "<mdspan>"):
-        """Configure the namespace and header `mdspan` is defined in."""
+        """Configure the namespace and header ``std::mdspan`` is defined in."""
         cls._namespace = namespace
         cls._template = cpptype(
             f"{namespace}::mdspan< {{T}}, {{extents}}, {{layout_policy}} >", header
@@ -47,14 +91,14 @@ class StdMdspan(SrcField):
         self,
         T: UserTypeSpec,
         extents: tuple[int | str, ...],
-        extents_type: PsType = PsUnsignedIntegerType(64),
+        extents_type: UserTypeSpec = PsUnsignedIntegerType(64),
         layout_policy: str | None = None,
         ref: bool = False,
         const: bool = False,
     ):
         T = create_type(T)
 
-        extents_type_str = extents_type.c_string()
+        extents_type_str = create_type(extents_type).c_string()
         extents_str = f"{self._namespace}::extents< {extents_type_str}, {', '.join(str(e) for e in extents)} >"
 
         layout_policy = (
@@ -97,23 +141,23 @@ class StdMdspan(SrcField):
     def from_field(
         cls,
         field: Field,
-        extents_type: PsType = PsUnsignedIntegerType(64),
+        extents_type: UserTypeSpec = PsUnsignedIntegerType(64),
+        layout_policy: str | None = None,
         ref: bool = False,
         const: bool = False,
     ):
         """Creates a `std::mdspan` instance for a given pystencils field."""
         from pystencils.field import layout_string_to_tuple
 
-        layout_policy: str
-
-        if field.layout == layout_string_to_tuple("fzyx", field.spatial_dimensions):
-            #   f is the rightmost extent, which is slowest with `layout_left`
-            layout_policy = f"{cls._namespace}::layout_left"
-        elif field.layout == layout_string_to_tuple("zyxf", field.spatial_dimensions):
-            #   f, as the rightmost extent, is the fastest
-            layout_policy = f"{cls._namespace}::layout_right"
-        else:
-            layout_policy = f"{cls._namespace}::layout_stride"
+        if layout_policy is None:
+            if field.layout == layout_string_to_tuple("fzyx", field.spatial_dimensions):
+                #   f is the rightmost extent, which is slowest with `layout_left`
+                layout_policy = f"{cls._namespace}::layout_left"
+            elif field.layout == layout_string_to_tuple("c", field.spatial_dimensions):
+                #   f, as the rightmost extent, is the fastest
+                layout_policy = f"{cls._namespace}::layout_right"
+            else:
+                layout_policy = f"{cls._namespace}::layout_stride"
 
         extents: list[str | int] = []
 
diff --git a/src/pystencilssfg/lang/expressions.py b/src/pystencilssfg/lang/expressions.py
index ccaf2d1bf3fe224e35be1508f13dfeb3251a84ee..53064bd13a201b0716545bf1e84677baa8df3be9 100644
--- a/src/pystencilssfg/lang/expressions.py
+++ b/src/pystencilssfg/lang/expressions.py
@@ -180,7 +180,7 @@ class AugExpr:
 
     - Calling `var <AugExpr.var>` on an unbound `AugExpr` turns it into a *variable* with the given name.
       This variable expression takes its set of required header files from the
-      `required_headers <PsType.required_headers>` field of the data type of the `AugExpr`.
+      `required_headers <pystencils.types.PsType.required_headers>` field of the data type of the `AugExpr`.
     - Using `bind <AugExpr.bind>`, an unbound `AugExpr` can be bound to an arbitrary string
       of code. The `bind` method mirrors the interface of `str.format` to combine sub-expressions
       and collect their dependencies.
@@ -206,6 +206,7 @@ class AugExpr:
         self._is_variable = False
 
     def var(self, name: str):
+        """Bind an unbound `AugExpr` instance as a new variable of given name."""
         v = SfgVar(name, self.get_dtype())
         expr = VarExpr(v)
         return self._bind(expr)
@@ -220,6 +221,7 @@ class AugExpr:
         return AugExpr().bind(fmt, *deps, **kwdeps)
 
     def bind(self, fmt: str | AugExpr, *deps, **kwdeps):
+        """Bind an unbound `AugExpr` instance to an expression."""
         if isinstance(fmt, AugExpr):
             if bool(deps) or bool(kwdeps):
                 raise ValueError(
@@ -342,7 +344,8 @@ def asvar(var: VarLike) -> SfgVar:
 
     Raises:
         ValueError: If given a non-variable `AugExpr`,
-            a `TypedSymbol` with a `DynamicType`,
+            a `TypedSymbol <pystencils.TypedSymbol>`
+            with a `DynamicType <pystencils.sympyextensions.typed_sympy.DynamicType>`,
             or any non-variable-like object.
     """
     match var: