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

PartElementWhat it does
.cf-team-stripdivThe 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__listulThe list itself, and the column track. One column per person at minmax(15rem, 1fr).
.cf-team-strip__itemliOne person. Snap point, and the divider on its right.
.cf-team-strip__avatarimg56 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.
The wrapper is not decoration. A scroll box with no focusable child cannot be scrolled by keyboard — the reader tabs straight past it and never sees the people it cut off. Measured on the landing page at 375 px the strip overflows by 585 px and at 768 px by 192 px, so that is two of the four widths this system is tested at. 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.
It is not a carousel. The APG carousel pattern is for content that rotates: it wants 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

AspectStripGrid
Imageround, b/w, 56 pxrectangular 4 : 5, colour
Cell120 px tall — --space-8 around the 56 px portrait, --space-6 between it and the name15% all round, so the portrait is 70 % of the cell at every column count
NameGeist SemiBold 16 pxGeist SemiBold 16 px
RoleGeist Mono Medium 11 px, uppercase, --text-secondary
FocusGeist 14 px over a --border-default hairline. One sentence on what the person works on; the strip has no room for a third register
Frametop/bottom plus a divider on the rightfully ruled grid
Markup<ul role="list"> of <li> — a team is a countable set of people, and the count is worth announcing
Keyboardone tab stop on the scroll box, then arrow keysno tab stop — nothing scrolls
Loadingloading="lazy", decoding="async", and width/height for the intrinsic ratio — both forms sit near the bottom of their page
Orderfounders 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.
Open against the source material: the Über uns mockup draws a strip, not a grid. Measured off 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__list hides everyone past the fold from a keyboard.