Control-F GmbH · Version 1.0 · 2026
Design System
The web implementation of Brand Design Review 2. Colour, typography, grid, shape language and every component of the new Landing Page and Über uns page — as tokens, CSS classes and copy-paste markup.
The idea in four sentences
Control-F should look like a technical drawing, not like an agency website. The site stands on CF-Grau, not on white — a data space, not a sheet of paper. Everything is drawn with 1 px contours and constructed in 2:1 isometry; corners are square, never rounded. Lime is light — not a surface, and not ink: it marks the one place where something happens, and nothing else.
Foundations
Components
<details>, works without JS.
Blog Grid
The subdivision grid as an editorial layout, with a timeline axis.
Subdivision Field
The same grid with its hierarchy handed to the reader. Point at a cell and it takes the half.
Search & Results
The surface the company is named after. Every answer in contour, and the light waiting on the page you land on.
Vacancy
One open position on a hairline, with the four facts every candidate asks for. The search result's drawing, declared once.
Pagination
The section header read backwards: rule on top, counter left, controls right.
Error & Empty State
404, 410, 500 and the filter that matched nothing — one block, and a ruled list of ways out.
Arrival & Progress
Content on its way, drawn as itself one rung down the presence ladder — and the rail that climbs back up.
Scroll Cue
A label, a hairline and the keep-reading chevron, for the one hero that ends in air. Three passes of ink, and then it stops.
Article & Prose
The reading page: index, byline, and running text set by element.
Table
Ruled rows, nothing vertical, tabular figures. A scroll box you can reach with a keyboard.
Team
A strip for the landing page, a grid for Über uns.
Forms
Underlined fields, mono labels, no boxes.
Footer
Black, isometric logo object, one CTA.
Consent
The banner and the settings dialog, built for TDDDG § 25.
Patterns
200, not an error — the typo kept in the field, the corrected term one press from the six results.
Blog article
Header → index + prose → tail → related → footer.
Karriere page
Header → why here + the frame → the register of openings → what an application needs and what it doesn't → footer.
Stellenanzeige
One opening, one URL: breadcrumb → task + the fifth and sixth fact → requirements → apply → the other three. The page the JobPosting markup is allowed to sit on.
Karriere — 0 Stellen
The same route between two openings: the zero where the four stands, the register's empty block carrying the page's one lime action, and the sections that never read the list unchanged.
Kontakt page
Header → form + contact list → what happens next → footer.
Kontakt — Bestätigung
Where the form's 303 lands: what arrived and when, what happens next, and the phone for what cannot wait. noindex.
Bewerbung page
The application form: header → CV, cover letter and one trace of the applicant's work, with three file fields → procedure → footer. Answered by the same Worker as Kontakt.
Bewerbung — Bestätigung
Where the application form's 303 lands: what happens next, and what becomes of the documents that were just uploaded. noindex.
Datenschutz page
The address the consent banner sends people to. Header → index + twelve sections → the entry inventory at #cookies → footer.
Impressum page
The provider identification § 5 DDG asks for, as a list of named facts rather than a block of prose.
404 page
The error, the object with one unit missing, and four ways out. Site furniture unchanged.
scripts/build-i18n.py builds each page from the German
pattern beside it and replaces only the words, from
i18n/en.json. Markup, classes, comments, ids and the page-local
<style> and <script> come through byte for byte, so a
specimen and its translation are the same specimen — which is the point: an edition
hand-written a second time would be a generation behind by lunchtime, with five
routines editing the landing pattern hourly. Do not edit a page under
en/; edit the German page or the catalogue and rebuild. The reader's way
between the two is the EN / DE plate at the top right of the
bar — Navigation.
Reference
Including it
Three stylesheets, in this order. docs.css is not one of them — that is this documentation only.
<link rel="stylesheet" href="/design-system/assets/css/tokens.css"> <link rel="stylesheet" href="/design-system/assets/css/base.css"> <link rel="stylesheet" href="/design-system/assets/css/components.css">
And two scripts. Both ship, both are dependency-free and neither creates any markup of its own — the page is still HTML and CSS, and each file only decides when something already in it is shown. This list used to be empty, which is how a page built from the system arrived with a menu button that did nothing.
<!-- in the <head>: it writes the attribute that folds the nav, and it has to be there before the first paint --> <script src="/design-system/assets/js/cf-nav.js"></script> <!-- at the foot of the body --> <script src="/design-system/assets/js/cf-consent.js"></script>
cf-nav.js is the menu disclosure on the
phone layout; cf-consent.js is the consent banner
and its settings dialog, which the site cannot legally do without. Three more —
cf-icons.js, cf-stream.js and cf-sight.js — are
optional and additive; the README says what each one adds and what is lost by leaving
it out.
Open before launch
- Licence Publica Sans. Until then
--font-displayfalls back to Geist — the site works but loses its headline signature. - Self-host Geist and Geist Mono.
.woff2intoassets/fonts/. No Google Fonts CDN — GDPR. - Return the right status code.
patterns/404.htmlmust be served with404, and the four retired topic pages with301s to their new homes. A dead address answering200 OKis a soft 404.