diff --git a/App/main.cpp b/App/main.cpp
index 090eaa3d32af627157899cd606c4640966c6224b..3c84275eda5a28956809b3256652a6aaae180e3d 100644
--- a/App/main.cpp
+++ b/App/main.cpp
@@ -27,51 +27,63 @@
 #include <QMetaType>
 #include <QtGlobal>
 
+void custom_terminate_handler()
+{
+    try {
+        std::rethrow_exception(std::current_exception());
+    } catch (const std::exception& ex) {
+        std::cerr << "terminate called after throwing an instance of 'std::runtime_error'\n"
+                  << "what():" << std::endl;
+        std::cerr << ex.what() << std::endl;
+
+        int argc;
+        char* argv[1];
+        QApplication app(argc, argv); // needed to run QMessageBox
+        QMessageBox msgbox(QMessageBox::Critical, "BornAgain: fatal bug",
+                           QString("Sorry, you encountered a fatal bug.\n"
+                                   "The application will terminate.\n"
+                                   "Please note the following and inform the maintainers.\n\n")
+                               + ex.what() + "\n",
+                           QMessageBox::Ok, nullptr);
+        msgbox.exec();
+    }
+}
+
 int main(int argc, char* argv[])
 {
+    std::set_terminate(custom_terminate_handler);
+
     ApplicationOptions options(argc, argv);
 
     QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates));
     qRegisterMetaType<QVector<double>>("QVector<double>");
 
     int ret = -1;
-    try {
-        QApplication app(argc, argv);
-        app.setApplicationName("BornAgain");
-        app.setApplicationVersion(GUI::Base::Path::getBornAgainVersionString());
-        app.setOrganizationName("BornAgain");
+    QApplication app(argc, argv);
+    app.setApplicationName("BornAgain");
+    app.setApplicationVersion(GUI::Base::Path::getBornAgainVersionString());
+    app.setOrganizationName("BornAgain");
 #ifndef Q_OS_MAC
-        app.setWindowIcon(QIcon(":/images/BornAgain.ico"));
+    app.setWindowIcon(QIcon(":/images/BornAgain.ico"));
 #endif
 
-        ApplicationSettings applicationSettings;
+    ApplicationSettings applicationSettings;
 
-        auto style = applicationSettings.styleToUse();
-        applicationSettings.loadStyle(style);
+    auto style = applicationSettings.styleToUse();
+    applicationSettings.loadStyle(style);
 
-        QString dir = GUI::Base::Path::appDataFolder();
-        if (!QDir().exists(dir))
-            QDir().mkpath(dir);
+    QString dir = GUI::Base::Path::appDataFolder();
+    if (!QDir().exists(dir))
+        QDir().mkpath(dir);
 
-        MainWindow win;
-        GUI::Global::mainWindow = &win;
-        if (options.find("geometry"))
-            win.resize(options.mainWindowSize());
-        if (options.find("project-file"))
-            win.loadProject(options.projectFile());
-        win.show();
+    MainWindow win;
+    GUI::Global::mainWindow = &win;
+    if (options.find("geometry"))
+        win.resize(options.mainWindowSize());
+    if (options.find("project-file"))
+        win.loadProject(options.projectFile());
+    win.show();
 
-        ret = app.exec();
-    } catch (const std::exception& ex) {
-        QApplication app(argc, argv);
-        QMessageBox msgbox(QMessageBox::Critical, "BornAgain: fatal bug",
-                           QString("Sorry, you encountered a fatal bug.\n"
-                                   "The application will terminate.\n"
-                                   "Please note the following and inform the maintainers.\n\n")
-                               + ex.what() + "\n",
-                           QMessageBox::Ok, nullptr);
-        msgbox.exec();
-        return 1;
-    }
+    ret = app.exec();
     return ret;
 }
diff --git a/Doc/PhysRef/PhysRef.pdf b/Doc/PhysRef/PhysRef.pdf
index ce31bbda84a363d127f3db5e929fa1766327eb56..3770727d7e5e1694caae74a99ff9543dd579c35e 100644
Binary files a/Doc/PhysRef/PhysRef.pdf and b/Doc/PhysRef/PhysRef.pdf differ
diff --git a/Doc/PhysRef/PhysRef.tex b/Doc/PhysRef/PhysRef.tex
index 5f83b1773ce7f6e387dab646cfa8213312022169..c8f6abf81bafb818795082cacabb95585aa08cc4 100644
--- a/Doc/PhysRef/PhysRef.tex
+++ b/Doc/PhysRef/PhysRef.tex
@@ -51,7 +51,7 @@
 \include{Multilayers}
 \include{Roughness}
 \include{Polarized}
-\iffalse\include{Evanescent}\fi
+\include{Evanescent}
 \include{Detector}
 
 %\appendix %\addtocontents{toc}{\protect\setcounter{tocdepth}{1}}
diff --git a/Doc/PhysRef/Roughness.tex b/Doc/PhysRef/Roughness.tex
index 23c03d86d3c5760107a0dda6d4800b582e4180d2..77dfc7a88dc396827384a47cba1ec4e35ca7a024 100644
--- a/Doc/PhysRef/Roughness.tex
+++ b/Doc/PhysRef/Roughness.tex
@@ -211,10 +211,11 @@ This takes all credibility from \cref{EtNC} and \cref{EslpmNC}.
 \index{Roughness!effect on reflectivity|)}%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\iftodo
 \section{Scattering by a rough interface}\label{Sroughscatter}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+\iftodo
+
 \index{Roughness!scattering|(}%
 
 
diff --git a/Doc/PhysRef/Title.tex b/Doc/PhysRef/Title.tex
index 914d126fd2b1abf76cce6c19dd3bcf88acdf7f9f..55f7b208ae77e3533da9c536648930de2a134dd5 100644
--- a/Doc/PhysRef/Title.tex
+++ b/Doc/PhysRef/Title.tex
@@ -61,6 +61,11 @@ Black-board bold ($\WW{M}$) denotes $4\times4$ matrices.
 
 Layers are numbered from 0 to $N-1$ against the $z$ direction,
 as explained in~\cref{Fdefz}.
+\\[2ex]
+
+This is work in progress.
+Sections replaced by \ldots\ are not yet ready for publication.
+Contact us to discuss them privately.
 
 ~\vfill
 \noindent
@@ -69,7 +74,7 @@ as explained in~\cref{Fdefz}.
 Copyright:  &Forschungszentrum Jülich GmbH 2013--\the\year\\[2ex]
 License:    &Creative Commons CC-BY-SA\\[2ex]
 Editor:     &Joachim Wuttke\\[2ex]
-Authors:    &BornAgain developers, see git log\\
+Authors:    &BornAgain developers, see AUTHORS file and git log\\
             &Scientific Computing Group\\
             &at Heinz Maier-Leibnitz Zentrum (MLZ) Garching\\[2ex]
 Disclaimer: &Software and documentation are work in progress.\\
diff --git a/GUI/View/Import/Legacy1dDialog.cpp b/GUI/View/Import/Legacy1dDialog.cpp
index 6c977cbac7c14294a4b4220020f7f96f4c957c00..a57924e1d2e19541fab65856d80f84ba2a886c09 100644
--- a/GUI/View/Import/Legacy1dDialog.cpp
+++ b/GUI/View/Import/Legacy1dDialog.cpp
@@ -52,6 +52,7 @@ Legacy1dDialog::Legacy1dDialog()
 
     auto from_sR = new QLabel("from  column"); // this one can be made invisible
     gridLayout->addWidget(from_sR, 2, 2);
+    from_sR->setVisible(Msettings.col_sR != 0);
 
     auto sb_Q = new QSpinBox;
     gridLayout->addWidget(sb_Q, 0, 3);
@@ -67,14 +68,18 @@ Legacy1dDialog::Legacy1dDialog()
 
     auto sb_sR = new QSpinBox;
     gridLayout->addWidget(sb_sR, 2, 3);
+    sb_sR->setVisible(Msettings.col_sR != 0);
     sb_sR->setMinimum(1);
     sb_sR->setValue(Msettings.col_sR);
     connect(sb_sR, &QSpinBox::valueChanged, [&p = Msettings](int i) { p.col_sR = i; });
 
     connect(have_sR, &QCheckBox::stateChanged, [&p = Msettings, from_sR, sb_sR](int i) {
-        sb_sR->setValue(i ? p.col_R + 1 : 0);
         from_sR->setVisible(i != 0);
         sb_sR->setVisible(i != 0);
+        if (i == 0)
+            Msettings.col_sR = 0;
+        else
+            sb_sR->setValue(p.col_R + 1);
     });
 
     auto w21 = new QWidget;
diff --git a/Tests/Unit/Sample/FormFactorBasicTest.cpp b/Tests/Unit/Sample/FormFactorBasicTest.cpp
index 88593dcbc3913cbdbbb375f69581d7fa7a71da2d..fa354eb17148a8022d0f66aceadc68c71986df58 100644
--- a/Tests/Unit/Sample/FormFactorBasicTest.cpp
+++ b/Tests/Unit/Sample/FormFactorBasicTest.cpp
@@ -1,13 +1,15 @@
 #include "Base/Const/Units.h"
-#include <numbers>
-using std::numbers::pi;
 #include "Base/Types/Span.h"
 #include "Sample/HardParticle/HardParticles.h"
 #include "Sample/Scattering/Rotations.h"
 #include "Tests/GTestWrapper/google_test.h"
+#include <numbers>
+using std::numbers::pi;
 
 using namespace std::complex_literals;
 
+const double eps_span = 1e-40;
+
 void test_eps_q(const IFormFactor* p, C3 qdir, double eps)
 {
     C3 q = eps * qdir;
@@ -125,7 +127,7 @@ TEST(FormFactorBasicTest, Pyramid2)
     Pyramid2 particle(length, width, height, alpha);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -160,10 +162,10 @@ TEST(FormFactorBasicTest, Box)
     EXPECT_DOUBLE_EQ(volume, particle.volume());
 
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
-    EXPECT_EQ(0., particle.spanZ(new RotationZ(17 * Units::deg)).low());
+    EXPECT_NEAR(0., particle.spanZ(new RotationZ(17 * Units::deg)).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(new RotationZ(39 * Units::deg)).hig(), height * 1e-15);
 
     EXPECT_NEAR(-width / 2, particle.spanZ(new RotationX(90 * Units::deg)).low(), 1e-12);
@@ -188,7 +190,7 @@ TEST(FormFactorBasicTest, CantellatedCube)
     CantellatedCube particle(L, t);
     EXPECT_DOUBLE_EQ(particle.volume(), volume);
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(L, particle.spanZ(&rot).hig(), L * 1e-15);
 
     test_ff(&particle);
@@ -214,7 +216,7 @@ TEST(FormFactorBasicTest, Cone)
     Cone particle(radius, height, alpha);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -261,7 +263,7 @@ TEST(FormFactorBasicTest, CosineRippleBox)
     CosineRippleBox particle(length, width, height);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -287,7 +289,7 @@ TEST(FormFactorBasicTest, Bipyramid4)
     Bipyramid4 particle(length, height, height_ratio, alpha);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height * (1 + height_ratio), particle.spanZ(&rot).hig(),
                 height * (1 + height_ratio) * 1e-15);
 
@@ -310,7 +312,7 @@ TEST(FormFactorBasicTest, Cylinder)
     EXPECT_DOUBLE_EQ(volume, particle.volume());
 
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     RotationX rectX(90 * Units::deg);
@@ -358,7 +360,7 @@ TEST(FormFactorBasicTest, HorizontalCylinder)
     HorizontalCylinder particle_full(R, L);
     EXPECT_DOUBLE_EQ(full_volume, particle_full.volume());
 
-    EXPECT_EQ(0., particle_full.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle_full.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(2 * R, particle_full.spanZ(&rot).hig(), 2 * R * 1e-15);
 
     // truncated
@@ -372,7 +374,7 @@ TEST(FormFactorBasicTest, HorizontalCylinder)
     HorizontalCylinder particle_trunc(R, L, b, t);
     EXPECT_NEAR(trunc_volume, particle_trunc.volume(), 1e-7);
 
-    EXPECT_EQ(0., particle_trunc.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle_trunc.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(t - b, particle_trunc.spanZ(&rot).hig(), 1e-7);
 
     RotationX rot1((pi / 2));
@@ -400,7 +402,7 @@ TEST(FormFactorBasicTest, Dodecahedron)
     Dodecahedron particle(edge);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(2 * 1.11352 * edge, particle.spanZ(&rot).hig(), 1e-4);
     // height=2*inradius from web ressource
 
@@ -420,7 +422,7 @@ TEST(FormFactorBasicTest, EllipsoidalCylinder)
     EllipsoidalCylinder particle(radiusx, radiusy, height);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -461,7 +463,7 @@ TEST(FormFactorBasicTest, Spheroid)
     Spheroid particle(radius, height);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -497,7 +499,7 @@ TEST(FormFactorBasicTest, Icosahedron)
     Icosahedron particle(edge);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(2 * 0.755761 * edge, particle.spanZ(&rot).hig(), 1e-4);
     // height=2*inradius from web ressource
 
@@ -518,7 +520,7 @@ TEST(FormFactorBasicTest, PlatonicOctahedron)
     PlatonicOctahedron particle(edge);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(edge * sqrt(2.), particle.spanZ(&rot).hig(), 1e-4);
 
     test_ff(&particle);
@@ -538,7 +540,7 @@ TEST(FormFactorBasicTest, PlatonicTetrahedron)
     PlatonicTetrahedron particle(edge);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(edge * sqrt(2. / 3.), particle.spanZ(&rot).hig(), 1e-4);
 
     test_ff(&particle);
@@ -560,7 +562,7 @@ TEST(FormFactorBasicTest, Prism3)
     Prism3 particle(base_edge, height);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -582,7 +584,7 @@ TEST(FormFactorBasicTest, Prism6)
     Prism6 particle(base_edge, height);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -609,7 +611,7 @@ TEST(FormFactorBasicTest, Pyramid4)
     Pyramid4 particle(base_edge, height, alpha);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -635,7 +637,7 @@ TEST(FormFactorBasicTest, SawtoothRippleBox)
     SawtoothRippleBox particle(length, width, height, d);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     // test_ff( &particle ); WAITING: restore once radius returns the umkreis radius
@@ -657,7 +659,7 @@ TEST(FormFactorBasicTest, TruncatedCube)
     TruncatedCube particle(length, t);
     EXPECT_DOUBLE_EQ(particle.volume(), volume);
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(length, particle.spanZ(&rot).hig(), length * 1e-15);
 
     test_ff(&particle);
@@ -682,7 +684,7 @@ TEST(FormFactorBasicTest, TruncatedSphere)
     TruncatedSphere particle(radius, height, 0);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
@@ -706,7 +708,7 @@ TEST(FormFactorBasicTest, TruncatedSpheroid)
     TruncatedSpheroid particle(radius, height, flattening, 0);
     EXPECT_DOUBLE_EQ(volume, particle.volume());
     RotationZ rot(.42);
-    EXPECT_EQ(0., particle.spanZ(&rot).low());
+    EXPECT_NEAR(0., particle.spanZ(&rot).low(), eps_span);
     EXPECT_NEAR(height, particle.spanZ(&rot).hig(), height * 1e-15);
 
     test_ff(&particle);
diff --git a/hugo/content/_index.md b/hugo/content/_index.md
index 3dc49a7b0cba90efa5128986c781472925708d7a..d5b3ac4fe1a7eb74a72f6a4a5b81095f4710ff27 100644
--- a/hugo/content/_index.md
+++ b/hugo/content/_index.md
@@ -21,6 +21,7 @@ Some features of the software are not yet documented.
 Complementary information can be found in the
 
 * Reference Paper: [J. Appl. Cryst. 2020](http://journals.iucr.org/j/issues/2020/01/00/ge5067/ge5067.pdf)
+* [Physics Reference]({{% files-versioned %}}/BornAgain-PhysicsReference.pdf)
 
 Older course materials are at
 
diff --git a/hugo/content/installation/building/unix/_index.md b/hugo/content/installation/building/unix/_index.md
index 8ab69532b306bd963f6489e5d8094c26fbfbc3d0..3900a52436774db41bacdc2247d60f94140135e7 100644
--- a/hugo/content/installation/building/unix/_index.md
+++ b/hugo/content/installation/building/unix/_index.md
@@ -1,6 +1,6 @@
 +++
 title = "Unix"
-weight = 40
+weight = 30
 +++
 
 # Build BornAgain under Unix
diff --git a/hugo/content/installation/building/unix/build-and-install.md b/hugo/content/installation/building/unix/build-and-install.md
index 5ea90a163791693a3db608054dbad96d8893fe73..7fe100f72edd886a622e59886633510c0b9ba49d 100644
--- a/hugo/content/installation/building/unix/build-and-install.md
+++ b/hugo/content/installation/building/unix/build-and-install.md
@@ -18,108 +18,43 @@ it takes the following commands to build and install the software:
 
 ```bash
 $ cd <source_dir>
-$ mkdir build
+$ mkdir build # see note [1]
 $ cd build
-$ cmake [<options>] ..
-$ make -j4
+$ cmake [<options>] .. # see note [4]
+$ make -j4  # see note [2]
 $ ctest -j4
+$ make install # see note [3]
 ```
 
-The last step, which should be done *only* for linheinz and libformfactor:
-```bash
-$ sudo make install
-```
-
-These steps shall now be explained in more detail.
+##### Note [1]: Build directory
 
-#### Dedicated build directory
-
-```bash
-$ mkdir build
-$ cd build
-```
+The build process must take place "out of place", i.e. not directly in the source directory.
+Otherwise, location and name of the build directory are arbitrary.
+We nonetheless recommend to follow our convention,
+create a subdirectory under the source directory, and call it `build`.
 
-The build process must take place in a dedicated directory,
-for which we suggest the canonical name `build`, and which
-should be a subdirectory of the software's source directory.
+##### Note [2]: Make or Ninja
 
-#### CMake command for the build configuration
+With GNU Make, the option `-j<n>` indicates the number of processors to be used in parallel.
 
-```bash
-$ cmake -DCMAKE_INSTALL_PREFIX=<install_dir> ..
-```
+In our experience, the alternative build software `Ninja` is faster and therefore to be preferred.
+To use Ninja,
+  * install it (e.g. Debian package ninja-build)
+  * call `cmake` with option `-GNinja`
+  * replace calls of `make -j<n>` by `ninja`.
 
-This command checks your system for the presence of the third party
-libraries necessary for compilation. In the case of a complex system
-setup, with libraries of different versions scattered across multiple
-places (`/opt/local`, `/usr/local`, etc), you may want to help CMake in
-finding the correct library paths by running it with additional
-parameters:
+##### Note [3]: Install location
 
-```bash
-$ cmake -DCMAKE_PREFIX_PATH=/opt/local -DCMAKE_INSTALL_PREFIX=<install_dir> ..
-```
-
-{{< alert theme="info" >}}
-**Note for MacOS users**
-
-MacOS users who have installed third-party libraries using the
-MacPorts package manager have to use an additional key during the
-CMake configuration to specify the location of MacPort's libraries
-(e.g. `/opt/local`):
-```
-cmake -DCMAKE_PREFIX_PATH=/opt/local -DCMAKE_INSTALL_PREFIX=<install_dir> ..
-```
-
-
-**For Homebrew users**
-```
-cmake -DCMAKE_PREFIX_PATH=/usr/local -DCMAKE_INSTALL_PREFIX=<install_dir> ..
-```
-{{< /alert >}}
+The install directory can be specified by suppling the option
+`-DCMAKE_INSTALL_PREFIX=<install_dir>` to the `cmake` command.
+Depending on the choice of the installation directory,
+it may or may not be necessary to run the command `make install`
+(or `ninja install`) under `sudo`.
 
-{{< alert theme="info" >}}
-**Note for Python2 users**
-
-Use additional CMake key during configuration
-```
-cmake -DBORNAGAIN_USE_PYTHON3=OFF -DCMAKE_INSTALL_PREFIX=<install_dir> ..
-```
-{{< /alert >}}
-
-#### The compilation
-
-```bash
-$ make -j4
-```
-
-This command starts the compilation process with a maximum of 4
-parallel threads. Depending on your CPU, you can increase this
-parameter (`-j[N]`) to decrease the compilation time.
-
-#### Testing the build
-
-```bash
-$ ctest -j4
-...
-100% tests passed, 0 tests failed out of 61
-Total Test time (real) = 31.14 sec
-[100%] Build target check
-```
-
-Running the functional tests is an optional but recommended step. The
-command `ctest` will compile several additional tests and run them one
-by one. The option `-j[N]` uses up to `N` threads to run these tests
-in parallel. Every test contains the simulation of a typical sample
-and compares the result with a reference file. Having `100% tests
-passed` ensures that your local installation is correct.
-
-#### Installing linheinz and libformfactor
-
-```bash
-$ sudo make install
-```
+##### Note [4]: Other CMake options
 
-The last command copies the compiled software into the installation
-directory `<install_dir>`, which has been specified earlier on during
-the CMake configuration.
+Besides the `cmake` options already mentioned, you may need
+`-DCMAKE_PREFIX_PATH=<paths>`
+where `<paths>` is a semicolon-separated list of directories
+specifying directories that are searched by CMake for
+the libraries and auxiliary programs that are needed for building BornAgain.
diff --git a/hugo/content/installation/building/unix/third-party.md b/hugo/content/installation/building/unix/third-party.md
index 759eae2db5c41e35b9360a8a2230ade17d6a1e80..f0b29035adc4c3dbd706673612ed869cbcb62bfa 100644
--- a/hugo/content/installation/building/unix/third-party.md
+++ b/hugo/content/installation/building/unix/third-party.md
@@ -7,21 +7,29 @@ weight = 10
 
 Required software:
 
-* Compiler with full C++-17 support
-   * `gcc >= 8`
-   * `clang >= 7`
+* Compiler with basic C++-20 support (`gcc` or `clang`)
 * `cmake >= 3.14`
 * `gsl >= 1.15` (GNU scientific library)
-* `fftw3 >= 3.3.1`
-* `libtiff >= 4.0.2`
-* `libcerf >= 2.0` (complex error function, maintained by us)
+* `fftw3 >= 3.3.1` (fast Fourier transform)
+* `libtiff >= 4.0.2` (TIFF image loader)
+* `libcerf >= 2.0` (complex error function) [1]
 * `python3 >= 3.8`
-* `python3-dev python3-pip python3-numpy python3-matplotlib`
-* `python3-lmfit` (optional, for some fit scripts)
-* `boost >= 1.65` (see note below)
+* `python3-dev`
+* `python3-pip` (to be removed, https://jugit.fz-juelich.de/mlz/bornagain/-/issues/682)
+* `python3-numpy` [2]
+* `python3-matplotlib` [2]
+* `python3-lmfit` (optional, for some fit scripts) [2]
+* `boost >= 1.65` [3]
 * `Qt6`
 
-From libboost, we need the library components `iostreams` and `program_options`.
+[1] The library libcerf happens to be maintained by our own group.
+Nonetheless it is treated as an external dependency because packages
+are provided by all major Linux distributions (see https://pkgs.org).
+
+[2] Python modules may be installed either as Linux distribution
+packages or through the Python package manager `pip3`.
+
+[3] From libboost, we need the library components `iostreams` and `program_options`.
 Internally, the CMake command to find `boost::iostreams` may add a dependence
 on `boost::regex`. Furthermore, we need a number of header-only components,
 including `algorithm/string`, `bimap`, `geometry`, `numeric/interval`, `polymorphic_cast`.
@@ -49,111 +57,42 @@ Install required packages:
 ```
 $ sudo apt-get install build-essential git cmake \
   libgsl-dev libfftw3-dev libtiff5-dev \
-  python3 python3-dev python3-numpy python3-matplotlib python3-lmfit \
+  python3 python3-dev python3-pip python3-numpy python3-matplotlib python3-lmfit \
   libboost-dev libboost-iostreams-dev \
   libboost-program-options-dev libboost-regex-dev \
-  libcerf-dev qt6-base-dev
+  libcerf-dev qt6-base-dev qt6-svg-dev
 ```
 
+Note: Normally we should also depend on `libcerf-dev`,
+which however is presently outdated.
+Therefore Debian users should install libcerf from source,
+https://jugit.fz-juelich.de/mlz/libcerf.
+
 ### OpenSuse
 Install required packages:
 ```
 $ sudo zypper install gcc-c++ git-core cmake gsl-devel \
-  libboost_*-devel fftw3-devel python3-devel python3-numpy-devel \
-  python3-matplotlib python3-lmfit libtiff-devel \
+  libboost_*-devel fftw3-devel libcerf-devel libtiff-devel \
+  python3-devel python3-pip \
+  python3-numpy-devel python3-matplotlib python3-lmfit \
   libqt6-qtbase-devel libqt6-qttools-devel libqt6-qtsvg-devel
 ```
 
 ### MacOS
 
-MacOS comes with no package manager, but fortunately there are several
-free and well maintained package managers that significantly simplify
-the installation of third-party open-source software. Here, we provide
-recepies for <a href=https://brew.sh/>Homebrew</a> and <a
-href=https://www.macports.org/>MacPorts</a>.
+To install third-party dependencies on MacOS, we recommend using
+the package manager <a href=https://brew.sh/>Homebrew</a>:
 
-#### Homebrew
-
-Note: Homebrew installs all packages in <pre>/usr/local</pre>, while
-MacPorts prefers the <pre>/opt/local</pre> folder. Depending on your
-package manager selection, the corresponding path has to be specified
-explicitly during the BornAgain CMake configuration as explained in
-the [build instructions]({{% relref "installation/building/unix" %}}).
-
-Install Homebrew as explained <a href=https://brew.sh/>here</a> and
-then install all BornAgain dependencies by running the following
-commands:
 ```
-brew install git cmake fftw gsl python boost libtiff qt6
+brew install git cmake fftw gsl libcerf python boost libtiff qt6
 pip3 install matplotlib numpy
 ```
 
-Finally, add Qt to your path environment variable:
-```
-export PATH=/usr/local/opt/qt6/bin/:$PATH
-```
-
-#### Macports
-
-Install Macports by downloading and running the installer from <a
-href=https://www.macports.org/install.php>here</a>. Then install all
-BornAgain dependencies by running the following command:
-```
-sudo port install git cmake fftw-3 gsl py3-matplotlib py3-numpy\
- py3-lmfit tiff boost qt6-mac
-```
-
-#### Minimal Qt installation via command line
-
-The Qt framework with arbitrary components can be installed via command line.
-To perform a minimal installation, first download a Qt installer for the platform
-from the official website.
-
-Remember to set up a Qt account beforehand; this is required for
-any installation.
-
-Define the following variables:
-* Path to the downloaded Qt installer
-  ```
-  qt_installer='/path/to/Qt-installer'
-  ```
-* Root path for Qt installation
-  ```
-  qt_root='/Qt/installation/path'
-  ```
-* Qt credentials
-  ```
-  qt_email='myemail@some.org'
-  qt_passw='myPassWord'
-  ```
-
-For a minimal Qt installation (only the components for gcc 64bit), use
-```
-$qt_installer --root "$qt_root" --email "$qt_email" --pw "$qt_passw" \
-  --auto-answer telemetry-question=No,AssociateCommonFiletypes=No --accept-licenses \
-  --no-default-installations install qt.qt6.623.gcc_64
-```
-where `qt.qt6.623.gcc_64` is the name of the component to install.
-
-Note that during the installation some questions must be answered
-(e.g. with `Accept` or `Yes`).
+Homebrew installs all packages to `/usr/local`. Possibly,
+this path has to be passed to CMake using the argument `-DCMAKE_PREFIX_PATH`
+(see the [build instructions]({{% relref "installation/building/unix/build-and-install" %}})).
 
-For searching Qt components (e.g. search for Qt6 components `qt.qt6`), use
-```
-$qt_installer --email "$qt_email" --pw "$qt_passw" search qt.qt6
+Add Qt to your path environment variable:
 ```
-
-After the installation, under the Qt root directory one finds the
-detailed installation log, `InstallationLog.txt`,
-and Qt maintenance tool, `MaintenanceTool`.
-
-Qt maintenance tool can be used to remove or update components;
-e.g. for removing Qt Creator, use
-```
-$qt_root/MaintenanceTool remove qt.tools.qtcreator
+export PATH=/usr/local/opt/qt6/bin/:$PATH
 ```
-
-For further information, see the official guide to the Qt-installer
-command-line interface:
-* <https://doc.qt.io/qtinstallerframework/ifw-cli.html>
-* <https://doc.qt.io/qtinstallerframework/ifw-use-cases-cli.html>
diff --git a/hugo/content/installation/building/windows/index.md b/hugo/content/installation/building/windows/index.md
index b298101ff68ee1cbcf126ea8b160ce68972928d6..b9703c14b627498835a3bf02efd7a3230413eff3 100644
--- a/hugo/content/installation/building/windows/index.md
+++ b/hugo/content/installation/building/windows/index.md
@@ -1,6 +1,6 @@
 +++
 title = "Windows"
-weight = 10
+weight = 50
 +++
 
 ## Build under Windows
diff --git a/hugo/content/installation/install/linux.md b/hugo/content/installation/install/linux.md
new file mode 100644
index 0000000000000000000000000000000000000000..2306d21c7ef808958ca7145f0c18338fb139ff22
--- /dev/null
+++ b/hugo/content/installation/install/linux.md
@@ -0,0 +1,59 @@
++++
+title = "Linux"
+weight = 30
++++
+
+## Install on Linux
+
+#### Prequisite: Python
+
+As a prerequisite, Python must be installed.
+Check the version with `python3 --version`.
+Which versions are compatible with BornAgain
+can be inferred from the available installers at {{% files-versioned %}}/linux_x64.
+
+In the following, we assume that `python` is an alias for `python3`.
+
+#### Install BornAgain as Python-only package
+
+If the BornAgain GUI is not required as only Python scripting mode is to be used,
+then BornAgain can be installed as a Python package from the `pip` repository:
+```
+$ python -m pip install bornagain
+```
+
+#### Install BornAgain as a Debian package
+
+A BornAgain Debian/Ubuntu package (Python and GUI) is provided by external maintainers
+  at https://tracker.debian.org/pkg/bornagain.
+
+The only drawback is that versions may be lagging behind,
+in *unstable* by a couple of months, in *stable* by several years.
+
+#### Install using our installer
+
+A Linux installer for BornAgain (Python and GUI)
+can be downloaded from {{% files-versioned %}}/linux_x64.
+Choose the installer that fits your version of Python.
+
+The installer is self-extracting and does _not_ need root permission.
+
+We recommend installation to a dedicated directory (here `~/ba`):
+```
+$ chmod u+x {{% recommended-linuxinstaller %}} # permit execution
+$ {{% recommended-linuxinstaller %}} --help # show options
+$ ba_path='~/ba'
+$ mkdir $ba_path
+$ ./{{% recommended-linuxinstaller %}} --exclude-subdir --skip-license --prefix=$ba_path
+```
+Then the GUI can be executed:
+```
+$ cd $ba_path
+$ ./bin/bornagain
+```
+
+The GUI package was tested with the standard X11 window system.
+If you are using the alternative Wayland window system,
+please let us know about your experience.
+
+{{% children  %}}
diff --git a/hugo/content/installation/install/linux/index.md b/hugo/content/installation/install/linux/index.md
deleted file mode 100644
index ee843bb77a57ea140369a31bcffc5f8a0a90d21f..0000000000000000000000000000000000000000
--- a/hugo/content/installation/install/linux/index.md
+++ /dev/null
@@ -1,54 +0,0 @@
-+++
-title = "Linux"
-weight = 30
-+++
-
-## Install on Linux
-
-BornAgain Python package is available in PyPI repository.
-
-BornAgain GUI application is provided as 64-bit binary bundle. 
-
-### Install BornAgain Python package
-
-BornAgain Python package can be installed with `pip`:
-```
-$ python -m pip install bornagain
-```
-### Install BornAgain GUI application
-
-There are two ways to install BornAgain GUI on Linux:
-
-- using the Debian/Ubuntu package provided by external maintainers
-  at https://tracker.debian.org/pkg/bornagain
-- using the installer shell script described in the following.
-
-The BornAgain Linux installer can be downloaded from {{% url-releases %}}.
-Choose installer according to the version of Python, e.g. `{{% recommended-linuxinstaller %}}`.
-
-The installer is self-extracting and does _not_ need any root permissions.
-
-It can be used as follows
-(here, installation root path is chosen to be `~/ba`):
-```
-$ chmod +x {{% recommended-linuxinstaller %}}  # permit execution
-$ ba_path='~/ba'
-$ mkdir $ba_path  # make a deliberate installation path 
-$ ./{{% recommended-linuxinstaller %}} --exclude-subdir --skip-license --prefix=$ba_path
-```
-and then, the GUI can be executed:
-```
-$ cd $ba_path
-$ ./bin/bornagain
-```
-
-A description of available options can be displayed with
-```
-$ {{% recommended-linuxinstaller %}} --help
-```
-
-The GUI package was tested with the standard X11 window system.
-If you are using the alternative Wayland window system,
-please let us know about your experience.
-
-{{% children  %}}
diff --git a/hugo/content/installation/install/macos.md b/hugo/content/installation/install/macos.md
new file mode 100644
index 0000000000000000000000000000000000000000..f19982b349e8bb60e91ef77bf84c795af09dd464
--- /dev/null
+++ b/hugo/content/installation/install/macos.md
@@ -0,0 +1,49 @@
++++
+title = "MacOS"
+weight = 70
++++
+
+## Install on MacOS
+
+#### Prequisite: Python
+
+As a prerequisite, Python must be installed.
+
+Note that pre-installed Python on MacOS may be outdated.
+Check the installed version with `python3 --version`.
+Which versions are compatible with BornAgain
+can be inferred from the available installers at
+  * {{% files-versioned %}}/mac_arm or
+  * {{% files-versioned %}}/mac_x64.
+
+The official Python installers can be downloaded from https://www.python.org/downloads.
+
+Or use Homebrew:
+```
+$ brew install python3
+```
+
+In the following, we assume that `python` is an alias for `python3`.
+
+#### Install BornAgain as Python-only package
+
+If the BornAgain GUI is not required as only Python scripting mode is to be used,
+then BornAgain can be installed as a Python package from the `pip` repository:
+```
+$ python -m pip install bornagain
+```
+
+#### Install BornAgain GUI application
+
+A Linux installer for BornAgain (Python and GUI)
+can be downloaded from
+  * {{% files-versioned %}}/mac_arm or
+  * {{% files-versioned %}}/mac_x64.
+
+Choose the installer that fits your version of Python.
+
+After downloading the installer, double click `.dmg` file to mount it, accept the license agreement and then drag the BornAgain icon onto the Applications shortcut icon.
+
+{{< figscg src="/img/draw/installation_macdmg2.png" class="center">}}
+
+Depending on your system's security settings you might not be able to open BornAgain directly from the Launchpad. In this case, search Apple help pages for something like "Open a Mac app from an unidentified developer".
diff --git a/hugo/content/installation/install/macos/index.md b/hugo/content/installation/install/macos/index.md
deleted file mode 100644
index da5fcd8899e0565e2c84c54a5c031d3a7349328b..0000000000000000000000000000000000000000
--- a/hugo/content/installation/install/macos/index.md
+++ /dev/null
@@ -1,88 +0,0 @@
-+++
-title = "MacOS"
-weight = 20
-+++
-
-## Install on MacOS
-
-BornAgain GUI application for macOS is provided as 64-bit `.dmg` installer.
-
-BornAgain Python package is available in PyPI repository and can be installed with `pip`. This package is required for running scripts or importing them into the GUI application.
-
-To install and run BornAgain for the first time proceed with the following steps:
-
-- [Install Python](#install-python)
-- [Install BornAgain Python package](#install-bornagain-python-package)
-- [Install BornAgain GUI application](#install-bornagain-gui-application)
-
-
-### Install Python
- 
-{{< alert theme="info" >}}
-If Python is already installed and set up, this block can be skipped.
-{{< /alert >}}
-
-{{< alert theme="warning" >}}
-While Python comes pre-installed on macOS, it is always quite outdated and not recommended to use together with BornAgain libraries.
-{{< /alert >}}
-
-The installer for appropriate version of Python can be downloaded from https://www.python.org/downloads. 
-
-Choose Python version according to the compatibility table:
-
-BornAgain version | Supported Python versions
-------------------|---------------------------
-20.0              | 3.8 to 3.10
-
-
-Run the installer and follow the steps. 
-
-Ensure that `pip` package manager is checked for installation. Command 
-```
-$ python3 -m ensurepip
-```
-will install `pip` if it is missing.
-
-##### Alternative way
-
-If the system is already equipped with [Homebrew](http://brew.sh/) (recommended) or [MacPorts](http://www.macports.org/) package managers, Python can be installed from the terminal.
-
-For Homebrew users:
-```
-$ brew install python3
-```
-
-For MacPorts users (assuming Python version 3.9)
-```
-$ sudo port install python39
-$ sudo port select --set python3 python39
-```
-
-### Install BornAgain Python package
-
-{{< alert theme="info" >}}
-For using BornAgain as GUI application only, this block can be skipped.
-{{< /alert >}}
-
-BornAgain Python package in available in the public repository and can be installed with `pip`:
-```
-$ python3 -m pip install bornagain
-```
-
-### Install BornAgain GUI application
-
-{{< alert theme="info" >}}
-For using BornAgain in scripts only, this block can be skipped.
-{{< /alert >}}
-
-The BornAgain installer can be downloaded from {{% url-releases %}}.
-Its type must match the processor architecture, e.g.
-`{{% recommended-macinstaller-amd64 %}}` or
-`{{% recommended-macinstaller-arm %}}`.
-
-After downloading the installer, double click `.dmg` file to mount it, accept the license agreement and then drag the BornAgain icon onto the Applications shortcut icon.
-
-{{< figscg src="/img/draw/installation_macdmg2.png" class="center">}}
-
-Depending on your system's security settings you might not be able to open BornAgain directly from the Launchpad. In this case, search Apple help pages for something like "Open a Mac app from an unidentified developer".
-
diff --git a/hugo/content/installation/install/windows/_index.md b/hugo/content/installation/install/windows/_index.md
index cc41618ef7ea57d7af1da65e5f0896ac1f8ff6f0..541540ec94f492d659b7a83e05d886bafb3491d1 100644
--- a/hugo/content/installation/install/windows/_index.md
+++ b/hugo/content/installation/install/windows/_index.md
@@ -1,11 +1,11 @@
 +++
 title = "Windows"
-weight = 10
+weight = 50
 +++
 
 ## Install on Windows
 
-BornAgain GUI application for Windows is provided as 64-bit installer; it requires Python libraries to be installed on the system for being run. 
+BornAgain GUI application for Windows is provided as 64-bit installer; it requires Python libraries to be installed on the system for being run.
 
 BornAgain Python package is available in PyPI repository and can be installed with `pip`. This package is required for running scripts or importing them into the GUI application.
 
@@ -15,7 +15,7 @@ To install and run BornAgain for the first time proceed with the following steps
 - [Install BornAgain Python package](#install-bornagain-python-package)
 - [Install BornAgain GUI application](#install-bornagain-gui-application)
 - [Troubleshooting](#troubleshooting)
- 
+
 ### Install Python environment
 
 {{< alert theme="info" >}}
@@ -23,17 +23,17 @@ If Python environment is already installed and set up, this block can be skipped
 {{< /alert >}}
 
 Python environment is needed for running both GUI application and example scripts.
-The installer for appropriate version of Python can be downloaded from https://www.python.org/downloads. 
+The installer for appropriate version of Python can be downloaded from https://www.python.org/downloads.
 
 BornAgain supports Python versions from 3.8 to 3.11.
 
-Run the installer and follow the steps. 
+Run the installer and follow the steps.
 
 To use BornAgain GUI application, the installation directory should be added to the system `PATH`:
 
 {{< figscg src="add_to_PATH.png" class="center" width="450px">}}
 
-Ensure that `pip` package manager is checked for installation. Command 
+Ensure that `pip` package manager is checked for installation. Command
 ```
 $ python -m ensurepip
 ```
@@ -63,8 +63,8 @@ For using BornAgain in scripts only, this block can be skipped.
 {{< /alert >}}
 
 BornAgain installation package can be downloaded from
-{{% url-releases %}}.
-The installer should be chosen accordingly to the Python version installed on the 
+{{% files-versioned %}}.
+The installer should be chosen accordingly to the Python version installed on the
 destination machine, for example `{{% recommended-wininstaller %}}`.
 
 After downloading the installer,
diff --git a/hugo/hugo.toml b/hugo/hugo.toml
index 00e0a7fbd2dd7c60969ce09270e9ee5f93dd8395..c714fedffca42793fc869eab29057393d18ab955 100644
--- a/hugo/hugo.toml
+++ b/hugo/hugo.toml
@@ -19,7 +19,7 @@ PygmentsStyle = "vs"
   email = "contact@bornagainproject.org"
   url_home = "https://bornagainproject.org"
 
-  release_number = "20.2"
+  release_number = "21.0"
   # version name is either major_release_number or "git-main" (must agree with baseURL)
   version_name = "git-main"
 
diff --git a/hugo/layouts/shortcodes/files-versioned.html b/hugo/layouts/shortcodes/files-versioned.html
new file mode 100644
index 0000000000000000000000000000000000000000..7f69e19503ef4b8124fc063cf507390914c62bd7
--- /dev/null
+++ b/hugo/layouts/shortcodes/files-versioned.html
@@ -0,0 +1 @@
+https://bornagainproject.org/ext/files/{{.Site.Params.release_number}}{{- print "" -}}
diff --git a/hugo/layouts/shortcodes/url-releases.html b/hugo/layouts/shortcodes/url-releases.html
deleted file mode 100644
index 32a145e57bb34dc320c833f5165bfe6699976b51..0000000000000000000000000000000000000000
--- a/hugo/layouts/shortcodes/url-releases.html
+++ /dev/null
@@ -1 +0,0 @@
-https://bornagainproject.org/ext/files/latest{{- print "" -}}