Components
Team
Two forms for the same information. The strip shows on the landing page that there are people behind the technology; the grid on the Über uns page shows which people.
Team strip
Horizontally scrolling, black-and-white avatars, bounded by a hairline above and below. It runs the full page width, not inside the container. Four cells fill 1440 exactly, which is how the mockup draws it; below 960 px they hold their 15 rem floor and the strip scrolls.
-
Simon Deussen
Founder
-
Daniel Tremer
CEO & Managing Partner
-
Vorname Nachname
Data Engineer
-
Vorname Nachname
AI Specialist
<div class="cf-team-strip" tabindex="0" role="region" aria-labelledby="team"> <ul class="cf-team-strip__list" role="list"> <li class="cf-team-strip__item"> <img class="cf-team-strip__avatar" src="…" alt="" width="640" height="800" loading="lazy" decoding="async"> <div> <p class="cf-person__name">Simon Deussen</p> <p class="cf-person__role">Founder</p> </div> </li> </ul> </div>
Anatomy
| Part | Element | What it does |
|---|---|---|
.cf-team-strip | div | The scroll box. Carries tabindex="0", role="region" and aria-labelledby, and draws the hairline above and below. Focus ring comes from base.css, which rings any [tabindex]. |
.cf-team-strip__list | ul | The list itself, and the column track. One column per person at minmax(15rem, 1fr). |
.cf-team-strip__item | li | One person. Snap point, and the divider on its right. |
.cf-team-strip__avatar | img | 56 px round, grayscale. The box is fixed, so the file is sized to it: a 144 px square, which is 3 x the box and the largest a screen can use. width/height carry that intrinsic size, loading="lazy" because the strip is last on the page. |
tabindex="0" makes the box a tab stop and
arrow-scrollable; role="region" plus a name from the section heading
says what the reader has landed in. It is the same contract
.cf-table__scroll already carries.
The
role="region" has to sit on a wrapper rather than on the
<ul>, because a role replaces the element's own — a labelled
region would have cost the list its count.
aria-roledescription="carousel", a slide group per
item, previous and next buttons and a rotation switch. Nothing here rotates. A list
that is wider than the screen is a list, and it gets list markup — which is also
what the APG recommends for this case.
Team grid
For the Über uns page: colour portraits at 4 : 5 in a fully ruled field, three to a row
at the reference width. Under the name and role, a hairline and one sentence on what the
person works on. Cells are equal size regardless of how long the role title is, and
subgrid holds all four lines on shared baselines across a row — including
that hairline, which the six texts would otherwise draw at six different heights.
-
Simon Deussen
Founder & Managing Partner
Simon founded control-f and runs it as Managing Partner and Lead Data Architect. A B.Sc. in media informatics at the Hochschule der Medien Stuttgart, with a bachelor thesis written at Daimler TSS on converting screen designs into HTML and CSS with deep learning, was followed by three years at inovex, first as a machine learning engineer and then, alongside a master's in autonomous systems at the Hochschule Bonn-Rhein-Sieg, in data management and analytics. That is the ground control-f is built on: turning disordered company data into decisions that can be trusted, predictive maintenance that catches plant and machine failures before they happen, and data pipelines that still run two years after handover. Pragmatic solutions rather than AI that stays in the slide deck.
-
Daniel Tremer
Managing Partner
Daniel joined control-f as Managing Partner, bringing over a decade of experience in data science and machine learning to the company's work with industrial enterprise clients.
-
Piet Brömmel
Data Engineer
Piet has a background in machine learning and data engineering. He holds a master's in computer science from TU Dortmund and previously worked as a data scientist at Fraunhofer, working with robots and computer vision. His interests span software development, LLMs and everything around them, algorithmic art, and hiking.
-
Henry Beiker
Data Engineer
Henry brings software development and AI testing to control-f's data engineering work. A B.Sc. and then a master's in computer science at the Humboldt-Universität zu Berlin ran alongside three and a half years of development work. At Howto Health that has meant leading software and data engineering projects, APIs for data processing and integration, and an in-house task planning tool built against requirements taken straight from clients. In a research team at Fraunhofer FOKUS it has meant a simulation environment in Unreal Engine for testing object detection models, a test framework for autonomous robots on train tracks, and the evaluation workflows around both. That is the same question the master's thesis takes up, improving object detection by simulating the scenarios that provoke false negatives. The stack is Python, SQL and JavaScript with Django, FastAPI and Flask, React in front and PostgreSQL underneath.
-
Robin Marzucca
Data Engineer
Robin brings a background in theoretical particle physics to control-f's data engineering work.
-
Marie Ernø-Møller
Data Engineer
Marie brings a background in theoretical physics to control-f's data engineering work. An MSc in quantum physics from the University of Copenhagen, with a thesis on double-copy amplitudes and their applications in general relativity, led to gravitational-wave research at Humboldt-Universität zu Berlin, where quantum field theory and effective field theory methods were applied to black hole mergers. That research training now sits alongside a deliberate move into machine learning and full-stack engineering: an MLOps bootcamp, containerised data pipelines built with Airflow, MLflow, Grafana and Prometheus, backend work in FastAPI and PostgreSQL, and a self-built mobile application whose emphasis is relational schema design and time-series metrics.
<ul class="cf-team-grid" role="list"> <li class="cf-team-grid__item"> <img class="cf-team-grid__photo" src="…" alt="" width="640" height="800" loading="lazy" decoding="async"> <p class="cf-person__name">Simon Deussen</p> <p class="cf-person__role">Founder</p> <p class="cf-person__focus">Gründung und fachliche Richtung: …</p> </li> </ul>
No scroll box here: the field wraps rather than overflowing, so there is nothing to
reach past. The cell count is what moves — see the note on the track minimum in
components.css.
Rules
| Aspect | Strip | Grid |
|---|---|---|
| Image | round, b/w, 56 px | rectangular 4 : 5, colour |
| Cell | 120 px tall — --space-8 around the 56 px portrait, --space-6 between it and the name | 15% all round, so the portrait is 70 % of the cell at every column count |
| Name | Geist SemiBold 16 px | Geist SemiBold 16 px |
| Role | Geist Mono Medium 11 px, uppercase, --text-secondary | |
| Focus | — | Geist 14 px over a --border-default hairline. One sentence on what the person works on; the strip has no room for a third register |
| Frame | top/bottom plus a divider on the right | fully ruled grid |
| Markup | <ul role="list"> of <li> — a team is a countable set of people, and the count is worth announcing | |
| Keyboard | one tab stop on the scroll box, then arrow keys | no tab stop — nothing scrolls |
| Loading | loading="lazy", decoding="async", and width/height for the intrinsic ratio — both forms sit near the bottom of their page | |
| Order | founders and management first, then alphabetical | |
alt="" on portraits is deliberate. The name sits right
next to the image in text — an alt would only duplicate it. A photo that
stands alone, without an accompanying name, gets a descriptive alternative text.
assets/source/mockups/ueber-uns.jpg, the team
block there is full-bleed with 294 px cells that run past the right edge — 4.9 of them
fit a 1440 frame, so the fifth is cut, exactly the way the landing-page strip is drawn.
The implementation renders it as a contained field that wraps instead. The wrapping
grid is the better answer for a ten-person page and it is what ships today, but it is
an improvement over the material rather than the material, and no decision has been
recorded for it. A designer settles which one the page keeps.
What could be taken from the plate without settling that question is the proportion, and it now has been. In the mockup the portrait is inset 48 px from the cell's top and both sides — 205 px of photo in a 294 px cell, 70 %. That 70 % is the decision; 48 px is only what it came to at the designer's cell width. So the inset is written as the ratio —
padding: 15%, resolved against the
grid area — and the portrait is 70.0 % of the cell at every column count the field
reaches, from the 426.3 px cell of the 1440 frame down to the 332.8 px cell of a 375 px
phone. It was previously a fixed --space-8, which landed 69.5 % at the one
cell width the grid then had and would land 85.0 % at today's — next door to the 84.5 %
the 16 px inline inset used to draw, a portrait with no cell left around it.
The cell is now wider than the mockup's rather than narrower. The track minimum used to be pinned low to keep all six people on one row at 1280, which is what held the cell at 213 px and made the mockup's 294 unreachable. Three columns and two rows lifts it to 426.3. The rule the old minimum was chosen for — a ruled field only looks right when the column count divides the six — is kept: this minimum produces 3, 2 and 1 and never the ragged 4 or 5.
Do
- Shoot everyone in the same setting — one session, one light.
- Keep role titles short, and consistently in one language.
- Remove people who have left promptly.
- Name the strip's scroll box after the section heading it sits under.
Don't
- No placeholder avatars among real portraits.
- No mixed treatments — either all b/w or all colour.
- No LinkedIn icons in the cell; contact goes through the contact page.
- Never ship the strip without its scroll box — a bare
.cf-team-strip__listhides everyone past the fold from a keyboard.