
Week 1: Web Design & Project Management
Table of Contents
The first week we were introduced to version management, and best practices for doing projects under sharp time constraints. Our tasks included building a personal website for documentation.
This Week’s Tasks
- Get familiar with git.
- Build a personal website and deploy it using the Fab Academy GitLab.
- Write something about yourself.
- Propose a potential final project.
Git and General Setup
"git" can mean anything, depending on your mood.
- random three-letter combination that is pronounceable, and not
actually used by any common UNIX command. The fact that it is a
mispronounciation of "get" may or may not be relevant.
- stupid. contemptible and despicable. simple. Take your pick from the
dictionary of slang.
- "global information tracker": you're in a good mood, and it actually
works for you. Angels sing, and a light suddenly fills the room.
- "goddamn idiotic truckload of sh*t": when it breaks
Ladies and Gentlemen, welcome to Fab Academy 2025!
The above quote is taken from the README.md of git as per its initial commit in April 2005. The commit has the melodious title Initial revision of “git”, the information manager from hell. Git itself is a software, used for decentralized version control. There are many different ways how to use git. For a deeper look, you can check the book GitMagic or the git documentation. Git also introduces some new terminology I will use here too. A glossary of that is found at the gitglossary.
During Fab Academy, there is one project per developing person, namely the personal documentation website of every student. This student is adding, editing, and removing files from their project. The simplest workflow is therefore to just commit to the main branch every time at the local repository and then push the changes to the global repository. Maybe I will use branches for checking out versions I would like to have fast access to later on. For this configuration, one will get along using the following commands:
# initially cloning the repository
# which is already set up automatically
# on sign-in to the Fab Academy course
git clone
# add the changes in selected files to
# the staging area, i.e. the set of
# changes that is to be added to
# the version history on the next commit
git add <filename(s)>
# tell git to add all changes in the
# staging area to the version history
# of the local repository
git commit -m <commit message>
# update the remote git repository at
# the GitLab host to be up to date
# with your local repository
git push [-u origin main]
I did not need to install git, since it was already available at my machine (I use arch, btw). For the Fab Academy repository, I generated a new SSH key pair. The key is of type ED25519. ED25519 is a signature scheme that does the same cryptographic operations as RSA, but on different mathematical structures, which allows the key to be of shorter length compared to an RSA key while both keys ensure the same level of security:
ssh-keygen -t ed25519
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAuKIqWhmepJhKC7ER67oDIX5fP6+gntQzo06hCqoYs6 jakob@t480
For text editing, I use VSCodium with a Vim extension. For typing, I use Neo as a keyboard layout. Thanks to an ergonomic arrangement of the letters, typing feels very very pleasant. There even are multiple layers, such as for special characters=><{}+%~
or for γρεεκ λεττερσ and they are arranged in a way that typing them does not require painfully acrobatic keyboard stunts. Being able to type blindly with that layout allows me to take notes in realtime while listening a conversation or a talk.
Building a Personal Website
Choosing a Static Site Generator
For Fab Academy, what is needed is a simple website, where you can add your weekly documentation and which, as a bonus, looks somehow appealing. The easiest way for that would be to just use the proposed template or to build a website with simple HTML and CSS. So you could write a week_01.html
file, add some layout, maybe styling. You might end up with a decent-looking website. Then, for the following week, you would just copy our week_01.html
, since it contains our carefully-designed HTML file structure, rename it to week_02.html
and continue the second week’s report… Now, what happens if you would like to change e.g. a textwidth in our week_**.html
-pages you defined earlier? You would then have to go through all the week_**.html
files and change them by hand.
What if you could save our content for every week in a simple markdown file and have an HTML template separately where the text of the weekly reports is just put into to generate a new week_**.html
file for each week? This is what static site generators do. There are numerous of these. Well-known are MkDocs, Hugo, and Sphinx. When using a static site generator, you can choose a theme, which basically is a set of HTML and CSS files (maybe something more, but that is not too critical) that define how your website will look. The content of these websites is then given by you in the form of text files (e.g. in .md
format).
I checked MkDocs and Hugo. There was no preference since both do the same thing. It was about what features the generated sites would have. I looked at some interesting themes for both generators to see what was closest to what I wanted. The features that I would have liked to have were as follows:
- possibility to add personal information and picture to the home page of the website
- possibility to have a listing of the weekly projects with a title image for every project, similar to brunos website
- quick navigation (e.g. by having a side menu or a beneficial layout of the site)
- syntax highlighting
- the website not being bloated with scripts and animations
- responsiveness (would be nice, but it was not a must)
- possibility to look at 3D objects inside the browser
- Our instructor told me that we can easily add this feature later on, so I did not gave this too much weight.
- aesthetic style or the possibility to add that yourself
- I imagined a simple, yet somehow interesting, maybe brutalist style to give it some personal touch (or as a friend of mine likes to say “for the website’s aesthetic to be in-character”).
- possibility to have an intuitive structure being presented in an easily understandable way (yes, with some themes this is difficult)
Another difficulty was that the website should at the same time work as technical documentation and as a personal portfolio. It was necessary for me to think a bit about how to present that as a website. However, I think the following structure (which is similar to that of the proposed template) is quite fitting for that.
"Home" with personal info
├── Assignments (listing the assignments comprehensively)
│ ├── Assignment week 1
│ ├── ...
│ └── Assignment week n
├── Final Project
└── About
I checked the following themes:




The MkDocs themes were appealing because of the side menu. However, I did not find out how to use syntax highlighting with them. It seemed to be possible with the material theme, but I did not want to use that, as I thought it was unlikely I could adjust its style to fit my idea. Additionally, the MkDocs terminal theme displayed headings of different levels in the same font size, which is a no-go for a website that wants to appear well-structured. The Hugo “Binario” theme looked good, but I did not know if it was possible to add text to the title page. It also lacked a side menu, but following the documentation, I found that it was possible to add a table of contents and breadcrumbs to it. It also supported syntax highlighting. For the “Hugo Classic” theme, I would have had to adjust the theme to add title pictures for the assignment list, but I did not know how easy this would have been to achieve. At the end, I thought it was more probable that I could implement a proper start page in the Hugo “Binario” theme than to add nice pictures on list pages in the other theme. So, I decided to download it and try it out.
Trying Binario
At first, I cloned the website that was prepared for us by the Fab Academy team.
git clone git@gitlab.fabcloud.org:academany/fabacademy/2025/labs/ilmenau/students/jakob-lerch.git
public/
folder, which contained the prepared website, outside the repository and saved it as a reference for later. Then, I created a new directory website/
for the Hugo website and added the theme to it as themes/binario/
by cloning Binario’s repository. Actually, I added the Hugo theme as a git submodule, which was basically a repository inside a repository. Whenever the theme’s repository got updated by its maintainers, I could easily download the changes. However, I thought this was not necessary, since I planned to change the theme anyway, so it would diverge from the upstream version. To have some content present, I copied the example content (i.e. the config.toml
and the content/
directory) of the Binario theme from binario/exampleSite/
.The repository now looked like this:
# created with command `tree -L 3`
.
├── README.md
├── students.md
└── website
├── config.toml
├── content
│ ├── about.md
│ └── post
└── themes
└── binario
website/
and checked how it looked by running a local Hugo server:
hugo server

exampleSite
running on a local webserver.As you can see, there were no changes so far, since I just copied the example site. This was the exact same thing I did when creating the screenshots above.
What I noticed was that at the website’s root, there was a list of some subpages at the site. The first and most important thing I wanted to check was if it was possible to have text present right above this list. This text space, I wanted to use for adding personal information. Having that at the root of the website, I thought, was important. This was the first thing people would see when visiting the website, and since it was also a personal portfolio I might use in a professional context later on, not just technical documentation, it seemed crucial. How to do this? Basically, I would need to edit the content of the index.html
file. Without looking at the theme’s source code, usually in Hugo, this is done by adding an _index.md
with the corresponding content to the root of content/
. I could create this file manually, but instead, I used the command
hugo content/_index.md
website/
. This created _index.md
and also added the necessary front matter to it. I also added some content and a title. The file now looked like this:
---
title: "Some Title I Added"
date: "2025-01-25T23:41:24+01:00"
---
I am content.

Indeed, Hugo added the body of
_index.md
, but not the title, so there was no heading to see. This could be changed by just adding a markdown heading:
---
title: "Some Title I Added"
date: "2025-01-25T23:41:24+01:00"
---
# This Title Makes [Almost] Anything
I am content.

containing a title. At this point, it was very likely that Binario fulfilled the requirements, so I went on and customized the style.
Customizing The Theme
I thought of something raw, which is still capable of being shown in a professional context. I thought a good start for this was choosing a high-contrast colorscheme. Personally, I really like black and white. From my observation, using only black and white draws attention to the structural elements (edges, blobs, etc.), so you just naturally play around with them as a designer.

Following the documentation of Binario, you could just add customCSS = ["path/to/custom.css"]
to [Params]
in config.toml
and then write your custom styling in there. This styling did not substitute, but just overwrite existing rules, that is rules you did not touch in your custom.css
remain the unchanged. What was not documented was where this path to the custom stylesheet is relative too. I took a guess guided by prior experience from working with hugo and assumed the path customCSS
to be relative to website/themes/binario/static/
. I added customCSS = ["css/custom.css"]
according to the documentation, created the corresponding custom.css
, and filled it with the following content:
:root {
--color-bg: black;
}
body {
background-color: var(--color-bg);
}

Now, I wanted to change the grey elements in the foreground to be white. I checked what HTML elements those are corresponding with using the inspector tool in Firefox.

block
, so I added a CSS statement setting the background color of all elements of this class to white.
:root {
--color-bg: black;
--color-fg: white;
}
body {
background-color: var(--color-bg);
}
.block {
background-color: var(--color-fg);
}

block
. I did the same with the rest of the foreground elements. Afterwards, the CSS file looked like this:
:root {
--color-bg: black;
--color-fg: white;
}
body {
background-color: var(--color-bg);
}
.block,.header,.main-nav,.main-nav__btn-box,.main-nav__item {
background-color: var(--color-fg);
}
I then noticed that on hovering over the menu items (“About Hugo” etc.), the elements’ colors changed to be grey. How to change that? In CSS, you can specify properties of an element/class etc. different whether you hover over them, you clicking them etc. using the hover pseudo class. The considered item is of class main-nav__item
, clicking on that did not reveal any settings for something called .main-nav__item:hover
, but by accident, I inspected main-nav__item
, where the inspector showed a style specification for main-nav__item:hover
and linked to some file called bundle.css
, probably one of the CSS files that are part of Binario (I did not find it by quickly searching in Binario’s source though, but I wanted to focus on changing the theme, so did not go into depth here). I viewed the file in Firefox using the style editor and found the following two configurations:
.main-nav__item:hover {
background-color: #444;
}
.main-nav__link:hover {
text-decoration: none;
border-color: #666;
}
main-nav__link
and main-nav__item
are layered on top of each other at the website, so I thought why there is the need to specify the colors in the specific way. I changed the background color of the item
to blue and the one of the link
to red and found that the border color of the link
is probably used to shade the lower part of the menu element. I changed both colors to black.
.main-nav__item:hover {
background-color: var(--color-bg);
}
.main-nav__link:hover {
border-color: var(--color-bg);
}
bundle.css
file. I copied the relevant part into custom.css
and investigated it to understand how it works. Then, I removed the unnecessary statements and changed everything following my need. The outcome is clean CSS to overwrite just the necessary elements of the menu
/* Menu */
.main-nav__btn {
background-color: var(--color-fg);
border-left: 1px solid transparent;
}
.main-nav__item {
border-top: 1px solid transparent;
}
.main-nav__item:hover {
background-color: var(--color-bg);
}
.main-nav__item--active {
border-left: 4px solid var(--color-border);
}
.main-nav__item--active:hover {
background-color: transparent;
}
.main-nav__link {
border-left: 4px solid transparent;
}
.main-nav__link:hover {
border-color: var(--color-border);
}
.main-nav__list.main-nav__list--active {
background-color: var(--color-fg);
}
@media (min-width: 920px) {
.main-nav__item--active {
padding: .625rem .625rem .5rem;
border-bottom: 3px solid var(--color-border);
}
.main-nav__link {
border-bottom: 3px solid transparent;
}
}
--color-border
was newly defined in :root
. In addition, I noticed that I should add .main-nav-btn
to the “background-and-text-color” block:
.block,.header,.main-nav,.main-nav-btn,.main-nav__btn-box,.main-nav__item {
background-color: var(--color-fg);
color: var(--color-text-on-fg);
}

A next step was to change the accent color (which at this point was orange) to something else. The accent text color was defined in website/themes/binario/static/css/themes/dark-*.css
where the CSS file was chosen according to Binario’s colorTheme
paremeter in config.toml
. These CSS files only differ in what color they define for the different text elements. Their structure is the same. Let’s look at dark-blue.css
:
a {
color: #77baff;
}
blockquote {
border-color: #77baff;
}
mark {
background-color: #77baff;
}
.logo:hover {
color: #77baff;
}
.main-nav__btn {
fill: #77baff;
}
.toc {
color: #77baff;
}
.share__icon {
fill: #77baff;
stroke: #77baff;
}
custom.css
and changed all colors to be of the newly introduced --color-text-accent
, which I chose to be black.

Also, the link color was same as the accent color black which led to the links in the footer not being visible. Therefore, I introduced a variable --color-link
and changed the custom.css
accordingly. Also, when hovered over headings on list pages (they were links too), they turned white, making them unreadable. Fixing all these minor flaws and adding also some style elements to taste, such as underlines, hover effects etc. led to this section in the CSS file:
/* links */
a {
color: var(--color-link);
text-decoration: underline;
}
a:hover {
color: var(--color-link);
}
a.main-nav__link {
color: var(--color-text-on-fg);
text-decoration: none;
}
a.main-nav__link:hover {
color: var(--color-text-on-bg);
}
a.entry__title-link {
color: var(--color-text-on-fg);
text-decoration: none;
}
a.entry__title-link:hover {
text-decoration: underline;
}
body {
background-color: var(--color-bg);
font-family: serif;
}
After that, I played around with modifications of the logo link. I added a cross-out line, an overline, an underline, and a color change to the link color on hover.
/* logo magic */
.logo {
color: var(--color-text-accent);
text-decoration: line-through overline underline;
}
.logo:hover {
color: var(--color-link);
}

Now, I thought, syntax highlighting might be broken, but it still worked just fine:



config.toml
. So, I added this block as TOML to the config.toml
and set style = "rrt"
[markup]
[markup.highlight]
style = 'rrt'


code {
color: var(--color-text-on-bg) !important;
}
!important
I had to add to overwrite the style imposed by the enclosing div
of class entry__content
.
Follow-up changes included adding a shadow to images and changing the rendering of the image title to be the caption. This article helped with that. I added hanging indentation so that it would be easier to distinguish when a paragraph started and when one ended, making the text much easier to follow. Additionally, I discovered a scrollbar at the bottom of the page and made the overflow content of the entry__content
class hidden which removed the unwanted scrollbar. I applied a black background to links on hover, which made it better to see if one hovered or not, resulting in a nicer UI. Later, I changed the link color to the one you see now. Apart from that, I changed the order of posts in list pages to be “oldest first”, so that assignment notes for week one are on top. Furthermore, one could include making images enlarge when clicked, and adding a favicon for FabAcademy. However, these ideas will be an avenue for future work.
I like that this theme somehow blends raw minimalist style with old-fashioned looks (serif font, underlined links). It seems playful, yet screaming and can still be used as a professional portfolio. Some inspiration I took from the aesthetics of UBERMORGEN, an actionist artist collective from Vienna.
Adding Content
For adding content, I deleted the old content directory and checked if there are more settings in the config.toml
that could be useful for me. I changed it to be
baseURL = "https://fabacademy.org/2025/labs/ilmenau/students/jakob-lerch/"
title = "] jakob ["
languageCode = "en-us"
theme = "binario"
[Params]
description = "Website for documenting my Fab Academy"
columns = 2
customCSS = ["css/custom.css"]
copyright = "Jakob Lerch"
mainSections = ["assignments"]
dateFormat = "2005-12-31"
mainMenuAlignment = "left"
related = true
relatedMax = 5
hideNoPostsWarning = false
[Params.Entry]
meta = ["date", "categories", "tags"]
toc = true
tocOpen = true
[Params.Featured]
previewOnly = false # Show only preview featured image
[Params.Breadcrumb]
enable = true
homeText = "jakob"
After that, I added new content. I created a new week folder and added a featured picture (PNG for now, which would not be pushed like this). I also added a page for the final project. Each directory had an _index.md
file where metadata for this list page, as well as context, could be stored.
.
├── config.toml
├── content
│ ├── assignments
│ │ ├── _index.md
│ │ └── week-01
│ │ ├── featured.png
│ │ └── index.md
│ ├── final_project.md
│ ├── _index.md
│ └── notes
│ └── _index.md
├── public
└── themes
└── binario
In the preview of the weekly assignments, the content of week 1 was still very large.

exampleSite/
and found that I had to add
<!--more-->

Afterwards, I added my notes from the weeks as pages, added the final project proposal, filled the about page with content, wrote some introductory text on the start page, and added a picture of my lovely pet Sisu. In case, the start page changed: it was a picture of an in-place printed snake.
Setting Up a GitLab CI Pipeline
Next, I wanted the Fab Academy GitLab to build and deploy my hugo page, so I did not need to do that myself anymore. As a result I would have had to push only the content files and GitLab would do the rest. This could be done with GitLab CI pipelines. A CI pipeline is defined in a .gitlab-ci.yml
file at the root of a git project. There already was an existing pipeline for the website that was prepared for us:
image: busybox
pages:
stage: deploy
script:
- echo "No commands to run, just upload the public folder to Pages."
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
#
# Before using this .gitlab-ci.yml:
#
# - This example uses the latest Docker image, but you might want to use the
# exact version to avoid any broken pipelines.
# All available Hugo versions are listed under https://gitlab.com/pages/hugo/container_registry.
# - Read about the difference between hugo and hugo_extended
# https://gitlab.com/pages/hugo/-/blob/main/README.md#hugo-vs-hugo_extended.
# - To change the theme, see
# https://gitlab.com/pages/hugo/-/blob/main/README.md#use-a-custom-theme.
#
image: registry.gitlab.com/pages/hugo/hugo_extended:latest
variables:E_URL: "github.com/theNewDynamic/gohugo-theme-ananke"
HUGO_ENV: production
THEME_URL: "github.com/theNewDynamic/gohugo-theme-ananke"
default:- apk add --no-cache go curl bash nodejs
before_script:od get -u $THEME_URL
- apk add --no-cache go curl bash nodejse PostCSS. See https://gohugo.i
- hugo mod get -u $THEME_URL
## Uncomment the following if you use PostCSS. See https://gohugo.io/hugo-pipes/postcss/
#- npm install postcss postcss-cli autoprefixer
test:
script:
- hugo
rules:
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH
pages:
script:
- hugo
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
image: registry.gitlab.com/pages/hugo/hugo_extended:latest
variables:
HUGO_ENV: production
default:
before_script:
- apk add --no-cache go curl bash nodejs
test:
script:
- hugo
rules:
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH
pages:
stage: deploy
script:
- cd website
- hugo
- mv public ../
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH

Documentation Workflow
During writing this report, I figured out a documentation scheme and wrote it down here. First, for myself to be able to check back on it in the following weeks and second, for peers to be able to check it as well.
Lessons Learned
- Documentation is not trivial, but if done cleverly, it can be super efficient. How to document your work with taking pictures
- using LLMs for forming text from bullet points and other stuff
- setting up image pipeline (syncthing, shotwell etc. using shotwell
Use of Language Models
During writing this report, I used the following prompts asking ChatGPT 4o mini to form text out of bullet points
Take the following bullet points and form prose text out of them. Do not add any additional information. Only use those words used in the bullet points and, additionally, those that are absolutely necessary to build grammatical sentences out of the bullet points. Formulate everything in past tense. Correct spelling mistakes:
<insert bullet points>
Take the following text at the bottom and return it unchanged. You may change it, but only if it is necessary so it meets the requirements listed below and do not change under any circumstances the content inside a <highlight ...> ... </highlight> code block where ... is a substitute for arbitrary text and do not remove any curly brackets and do not consider valid markdown syntax as an mistakes and do not add line breaks yourself:
Requirements listed below:
- The text is written from the perspective of "I".
- The text is in general written in past tense.
- The text is free of spelling and interpunctuation mistakes.
- The text is free of grammar mistakes.
Text at the bottom:
<insert text>