diff --git a/reference/reference.md b/reference/reference.md
new file mode 100644
index 00000000..04af6c95
--- /dev/null
+++ b/reference/reference.md
@@ -0,0 +1,207 @@
+
+/ [home](/README.md)
+
+# Reference
+
+## Introduction
+
+YOMM2 is a library that implements open multi-methods for C++17. The semantics
+of methods are strongly influenced by the [Open Multi-Methods for
+C++](https://www.stroustrup.com/multimethods.pdf) paper by Peter Pirkelbauer,
+Yuriy Solodkyy, and Bjarne Stroustrup.
+
+This implementation diverges from the paper on the following points:
+* A "base-method" is called a "method declaration" in YOMM2, and an "overrider"
+ is called a "method definition". This is because
+* YOMM2 has a mechanism (`next`) to call the next most specialised method.
+* The paper allows only references for virtual parameters. YOMM2 also allows
+ pointers and smart pointers.
+* YOMM2 does not support repeated inheritance. Multiple and virtual inheritance
+ are supported.
+* Method definitions are hidden. It is possible to access definitions while
+ bypassing method dispatch, but this requires the definitions to be placed in a
+ method container; see [the documentation](method_container.md) of
+ `method_container`.
+
+## Concepts
+
+A *method* is a function that has one or more virtual parameters, and a
+collection of method definitions.
+
+A *method definition* is a function attached to a single method. The type of the
+parameters corresponding to the virtual parameters in the method must be
+compatible with the method's parameter type. The other parameters must have the
+same type as in the method. The return type of the definition must be compatible
+with the return type of the method.
+
+A *virtual parameter* is a parameter that is taken into account when the method
+is called.
+
+A *virtual argument* is an argument in a method call that corresponds to a
+virtual parameter in the method declaration. The method uses the *dynamic* type
+of the virtual arguments to select which definition to execute. The rules for
+selecting the definition are the same as for overload resolution: use the most
+specialised definition, from the set of applicable definitions. However, note
+that the selection happens at runtime.
+
+## API Overview
+
+The library is normally used via the _keyword interface_, provided by the
+`` header. It attempts to present open methods as a
+language feature. It consists of a collection of macros, which are, of course,
+global, but so are keywords. The [virtual_](/reference/virtual_.md) template, used to specify
+virtual parameters, is also aliases in the global namespace.
+
+The library can also be used through the _core interface_, which is almost
+entirely free of macros. The primary use of this interface is to support
+templatized classes, methods and definitions - something that macros are
+incapable of. See [the templates tutorial](tutorials/templates_tutorial.md) for
+more details and examples.
+
+## Exceptions
+
+YOMM2 is exception agnostic. The library does not throw nor catches exceptions,
+but it is exception safe. Errors are reported via an indirect call to a handler
+function, which can be set with [set_error_handler](/reference/set_error_handler.md). A handler may throw
+exceptions.
+
+## Headers
+
+### ``
+
+This header provides the _keyword interface_. Since version 1.3.0, this is the
+recommended main header for normal usage of the library. It is used in most
+examples and tutorials. The header makes it look like the library's features are
+part of the language:
+
+* It includes ``.
+* It includes ``, thus making the lowercase macros
+ (`declare_method`, etc) available.
+* It contains a `using ::yorel::yomm2::virtual_` directive.
+
+### ``
+
+This header provides the _core interface_, in the `yorel::yomm2` namespace.
+Since version 1.3.0, the key mechanisms are documented; thus, it possible to use
+the library without resorting on the macros. See the [API
+tutorial](../tutorials/api.md) for an introduction to the main features of
+`core`.
+
+The main constructs are:
+
+* [method](/reference/method.md), a class template that contains:
+ * a static function object [fn](method.md#fn), to call the method
+ * nested class templates [add_function](method.md#add_function) and
+ [add_definition](method.md#add_definition), to add definitions to a method
+ * [next_type](method.md#next_type) and [use_next](method.md#use_next), to call
+ the next most specialised method
+* [use_classes](/reference/use_classes.md), a class template, provides the class and inheritance information.
+* [update_methods](/reference/update_methods.md), a function that calculates the method dispatch tables, using
+ the method, definition, and class information.
+
+The header itself does not define any macros, except for its include guard
+(`YOREL_YOMM2_CORE_INCLUDED`).
+
+The header consumes two macros:
+* `NDEBUG`: if defined, no checks are performed during method calls. This
+ delivers a performance close to normal virtual function calls.
+* `YOMM2_ENABLE_TRACE`: enables tracing. This feature is not documented at the
+ moment.
+* `YOMM2_SHARED`: if defined, the library runtime is in a shared library or DLL.
+
+The header defines the following macros:
+* an include guard (`YOREL_YOMM2_CORE_INCLUDED`).
+* *iff* `YOMM2_SHARED` is defined, a `yOMM2_API` macro, for internal use.
+
+### ``
+
+This header defines two macros: `YOMM2_GENSYM`, which generates a new obfuscated
+symbol each time that is is expanded; and `YOMM2_SYMBOL(seed)`, which generates
+an obfuscated symbol (the same symbol for the same value of `seed`).
+
+These macros are useful when using the core interface, which requires
+instantiating static objects to register classes, methods, and definitions; and
+for defining the "key" type for the [method](/reference/method.md) template.
+
+### ``
+
+This header defines *experimental* meta-programming constructs intended to
+facilitate the creation of templatized method and methods definitions. See the
+[template tutorial](../tutorials/templates_tutorial.md) for examples.
+
+### ``
+
+This header defines the upper-case versions of the macros (`YOMM2_DECLARE` etc).
+
+### ``
+
+This header defines the lower-case versions of the macros (`declare_method`
+etc).
+
+### ``
+
+This was the recommended header before version 1.3.0. Includes
+`` and ``.
+
+## Libraries
+
+40488
+99424
+~58K
+
+## Index
+
+| name | type | purpose |
+| -------------------------------- | ----------------- | ------------------------------------------------------------------------ |
+| [class_declaration](/reference/class_declaration.md) | class template | declares a class and its bases |
+| [declare_method](/reference/declare_method.md) | macro | declares a method |
+| [declare_static_method](/reference/declare_static_method.md) | macro | declares a static method inside a class |
+| [define_method](/reference/define_method.md) | macro | adds a definition to a method |
+| [define_method_inline](/reference/define_method_inline.md) | macro | adds an definition to a method in a container, and make it inline |
+| [error_handler_type](/reference/set_error_handler.md) | type | handler function |
+| [error_type](/reference/set_error_handler.md) | variant | object passed to error handler |
+| [friend_method](/reference/friend_method.md) | macro | makes a method in a container, or the entire container, a friend |
+| [hash_search_error](/reference/set_error_handler.md) | class | failure to find a hash function for registered classes |
+| [make_virtual_shared](/reference/virtual_ptr.md) | function template | creates an object and return a `virtual_shared_ptr` |
+| [method](/reference/method.md) | class template | implements a method |
+| [method_call_error](/reference/method_call_error.md) | class | information about a failed method call |
+| [method_call_error_handler](/reference/method_call_error.md) | type | type of a function called when a method call fails |
+| [method_container](/reference/method_container.md) | macro | declares a method definition container |
+| [method_definition](/reference/method_definition.md) | macro | retrieves a definition from a container |
+| [register_class](/reference/register_class.md) | macro | registers a class and its bases (deprecated) |
+| [register_classes](/reference/use_classes.md) | macro | registers classes and their inheritance relationships |
+| [resolution_error](/reference/set_error_handler.md) | class | method call does not resolve to exactly one definition |
+| [set_error_handler](/reference/set_error_handler.md) | function | sets the function called for all errors |
+| [set_method_call_error_handler](/reference/method_call_error.md) | function | sets function to call when a method call fails |
+| [unknown_class_error](/reference/set_error_handler.md) | class | class used in method declaration, definition, or call was not registered |
+| [update](/reference/update.md) | function | sets up dispatch tables |
+| [update_methods](/reference/update_methods.md) | function | sets up dispatch tables (deprecated, requires linking with library) |
+| [use_classes](/reference/use_classes.md) | class template | registers classes and their inheritance relationships |
+| [virtual_](/reference/virtual_.md) | class template | marks a method parameter as virtual |
+| [virtual_ptr](/reference/virtual_ptr.md) | class template | fat pointer for optimal method dispatch |
+| [virtual_shared_ptr](/reference/virtual_ptr.md) | class template | `virtual_ptr` using a `std::shared_ptr` |
+| [YOMM2_CLASS](/reference/register_class.md) | macro | same as `register_class` (deprecated) |
+| [YOMM2_CLASSES](/reference/use_classes.md) | macro | same as `register_classes` |
+| [YOMM2_DECLARE](/reference/declare_method.md) | macro | same as `declare_method` |
+| [YOMM2_DECLARE_METHOD_CONTAINER](/reference/method_container.md) | macro | same as `method_container` |
+| [YOMM2_DEFINE](/reference/define_method.md) | macro | same as `define_method` |
+| [YOMM2_DEFINE_INLINE](/reference/define_method_inline.md) | macro | same as `define_method_inline` |
+| [YOMM2_DEFINITION](/reference/method_definition.md) | macro | same as `method_definition` |
+| [YOMM2_FRIEND](/reference/friend_method.md) | macro | same as `friend_method` |
+| [YOMM2_GENSYM](/reference/YOMM2_GENSYM.md) | macro | generates a unique symbol |
+| [YOMM2_STATIC_DECLARE](/reference/declare_static_method.md) | macro | declares a static method inside a class |
+| [YOMM2_SYMBOL](/reference/YOMM2_SYMBOL.md) | macro | generates an obfuscated symbol |
+
+
+
+### *Experimental* template helpers
+
+| name | type | purpose |
+| ----------------- | -------------- | ---------------------------------------------------------------- |
+| [apply_product](/reference/apply_product.md) | meta-function | apply templates to the n-fold Cartesian product of `types` lists |
+| [not_defined](/reference/not_defined.md) | meta-function | tell [use_definitions](/reference/use_definitions.md) to discard a definition |
+| [product](/reference/product.md) | meta-function | form n-fold Cartesian product of `types` lists |
+| [template_](/reference/template_.md) | class template | wrap a template in a type |
+| [templates](/reference/templates.md) | class template | wrap templates in a `types` list |
+| [types](/reference/types.md) | class template | sequence of types |
+| [use_definitions](/reference/use_definitions.md) | class template | add batch of definitions from a generic container to methods |