# nees – Bausteine

Nachschlagewerk für wiederkehrende Anordnungen auf der Seite. Zweck: Du nennst
den Kurznamen, ich weiß ohne Rückfrage, was zu bauen ist.

Alle Maße stammen aus den Layout-PDFs und gelten bei **1920pt Seitenbreite**.
Im SCSS stehen sie als `clamp()`, damit sie mitskalieren.

---

## So kannst du es mir sagen

> „Ein **Kennzahlen-Band** mit fünf Werten."
> „**Karten** wie in Abschnitt 2, aber vier statt drei."
> „Die **Kopfzeile** über den Slider, Aktionslink zu /karriere."
> „Das Ganze als **Halbbild**, Bild links."

Für eine Abweichung reicht der Zusatz — „mit Kontur", „ohne Aktionslink",
„Spalten 8/4 statt gleich". Sagst du nichts, nehme ich die Werte aus dem PDF.

---

## 1 Halbbild (Hero)

**Wofür:** Bildschirmfüllender Einstieg. Text links, Bild bis zur Mitte rechts.

| | |
|---|---|
| CType | `textpic` |
| `frame_class` | `half` |
| `frame_layout` | `h-100` — nur damit wird es bildschirmhoch |
| `imageorient` | `25` = Bild rechts, `26` = Bild links |
| SCSS | `.frame-half` in `Page/_frames.scss` und `Components/_hero.scss` |

```json
{"CType":"textpic","frame_class":"half","frame_layout":"h-100",
 "header_layout":1,"subheader_class":"highlight",
 "frame_options":"switch-headline,border-headline",
 "imageorient":25,"imagecols":1,"space_before_class":""}
```

**Bilder:** erstes = großes Bild, zweites = rundes Portrait unten links.
Alle Bilder eines Elements liegen in **einer** `.gallery-row`.

**Maße:** weiße Fläche 920 von 1920 (47.9 %), Textrand 121, H1 90pt,
Subline 30pt grau, Knöpfe 80 hoch mit 31 Abstand, Portrait 137.6 rund.

---

## 2 Karten mit Kontur

**Wofür:** Drei bis vier gleichrangige Punkte auf dunklem Grund, nummeriert.

| | |
|---|---|
| CType | `card_group`, FlexForm `columns` = 3 |
| `frame_class` | `dark` |
| Kinder | `tx_bootstrappackage_card_group_item`, Feld `tt_content` = uid |
| Nummer | CSS-Counter, **nicht** pflegen — ergibt sich aus der Reihenfolge |
| SCSS | `.frame-dark .card-group-element` in `Components/_numbered-list.scss` |

```json
{"CType":"card_group","frame_class":"dark","header_layout":2,
 "subheader_class":"highlight",
 "frame_options":"switch-headline,border-headline",
 "pi_flexform":{"align":"left","columns":"3"}}
```

**Maße:** Karte 523 x 343, Radius 6px, Kontur rgba(weiß,.3), Lücke 54,
Innenabstand 69/40/79, Titel 35pt, Text 30pt.

> Nur nehmen, wenn alle Spalten **gleich** breit sein sollen. Sobald die
> Breiten variieren: Container, siehe 5.

---

## 3 Abschnittskopf mit Aktionslink

**Wofür:** Highlight, Trenner, Überschrift links — Aktionslink rechts auf
Höhe des Trenners.

| | |
|---|---|
| CType | `text` (oder `ce_columns2`, siehe 5) |
| `frame_class` | `kopfzeile` |
| Aktionslink | im `bodytext` als `<p class="nees-kopfzeile-aktion">` |
| SCSS | `.frame-kopfzeile` in `Components/_reference.scss` |

```json
{"CType":"text","frame_class":"kopfzeile","header_layout":2,
 "subheader_class":"highlight",
 "frame_options":"switch-headline,border-headline",
 "bodytext":"<p class=\"nees-kopfzeile-aktion\"><a class=\"nees-link\" href=\"t3://page?uid=24\">Alle Projekte</a></p>"}
```

**Maße:** Link 70 unter der Oberkante der Highlight-Zeile, rechtsbündig am
Seitenrand 1799.

---

## 4 Referenzkacheln

**Wofür:** Zwei Projektbilder nebeneinander, darunter Titel, Jahr und Leistung.

| | |
|---|---|
| CType | `shortcut`, Feld `records` |
| `frame_class` | `referenzen` |
| Quelle | Ordner **pid 23**, 263 `mask_referenz`-Datensätze |
| SCSS | `.frame-referenzen` in `Components/_reference.scss` |

```json
{"CType":"shortcut","frame_class":"referenzen",
 "records":"tt_content_1325,tt_content_1369"}
```

**Gerendert** wird mit dem Template der Referenz selbst:

```
.referenz > .referenz-inner > .image-outer + .overlay
          > .name > .referenz-titel + .referenz-jahr + .referenz-leistung
```

Das Overlay gehört zur Referenzenseite und wird hier ausgeblendet.
Felder je Referenz: `header`, `tx_mask_jahr`, `tx_mask_leistung`, `image`.

**Maße:** Bild 798 x 453, Radius 6px, Lücke 83, Jahr bei 50 % der
Kachelbreite, Titel 35pt, Leistung 30pt grau.

---

## 5 Container – mehrspaltig mit freien Breiten

**Wofür:** Immer, wenn Spalten **unterschiedlich** breit sein sollen oder die
Aufteilung später änderbar bleiben soll.

| | |
|---|---|
| CType | `ce_columns2`, `ce_columns3`, `ce_columns4` |
| Kinder | `tx_container_parent` = uid, `colPos` = **101, 102, 103, 104** |
| Breite je Spalte | `columns.N.width`: `equal`, `1`–`12`, `auto`, `none` |
| Umschaltpunkt | `columns.breakpoint`: `none`, `sm`, `md`, `lg`, `xl` |
| Eigene Klassen | `row.class`, `columns.N.class` |

Daraus entsteht die Klasse: `col` + `-{breakpoint}` + `-{width}`.
`width 3` + `breakpoint md` ergibt `col-md-3`, `equal` ergibt `col-md`.

Das XML trägt zwei Sheets: `sGeneral` für Breiten und Umschaltpunkt,
`sCustom` für die Klassen.

> **Container im Backend anlegen.** Über den MCP schlägt es fehl:
> `container_elements` ruft im DataHandler den `FormDataCompiler` auf, der
> einen Backend-Request braucht. Kinder einhängen und Felder setzen geht
> danach über den MCP.

**Gestaltung an `.ce-col` hängen**, nicht an `col-md-3` — dann bleibt das
SCSS unabhängig von der Einstellung. Nachgemessen: bei vier Spalten ergeben
`col-md-3` und `col-md` dieselben 416pt.

Bootstraps `.row` zieht sich über negative Ränder aus dem Raster. Soll der
Inhalt bündig am Seitenrand stehen: `--bs-gutter-x: 0`.

---

## 6 Kennzahlen-Band

**Wofür:** Vier Werte auf dunklem Grund, jeder mit `#1` bis `#4` in Orange.

| | |
|---|---|
| CType | `ce_columns4` (Container, siehe 5) |
| `frame_class` | `kennzahlen` |
| Je Spalte | ein `text`-Element: Überschrift = Zahl, Fließtext = Label |
| Marke | CSS-Counter auf `.ce-col::before` |
| SCSS | `.frame-kennzahlen` in `Components/_stats.scss` |

```json
{"CType":"text","tx_container_parent":1754,"colPos":101,
 "header":"30+","header_layout":3,"bodytext":"<p>Jahre Erfahrung</p>"}
```

**Maße:** Bereich 553 hoch, `#N` 30pt orange, 26.7 Luft zur Zahl,
Zahl 90pt weiß, 15.1 Luft zum Label, Label 30pt weiß.

---

## Werte, die überall gelten

**Schriftgrößen.** Im PDF mehrfach belegt sind 90 / 45 / 35 / 30 bei 1920pt.
Der Kunde hat diese Werte am 26.08.2026 als XD-Werte bestätigt und ausdrücklich
freigestellt: verbindlich sind die **Verhältnisse**, nicht die Absolutwerte.

Umgesetzt ist deshalb dasselbe Verhältnis mit **Deckel bei 1512 statt 1920**:

| Rolle | im Web | im PDF | Verhältnis |
|---|---|---|---|
| H1 im Halbbild, große Zahlen, Referenztitel | **72px** | 90pt | 3.00 |
| Abschnittsüberschriften (H2) | **36px** | 45pt | 1.50 |
| Kartentitel, Kacheltitel (H3) | **28px** | 35pt | 1.17 |
| Fließtext, Highlight-Zeile, Aktionslinks | **24px** | 30pt | 1.00 |
| Knopfschrift | **22.4px** | 28pt | 0.93 |

Grund für den Deckel: Ein XD-Board wird fast nie 1:1 betrachtet — auf einem
1512er Schirm zeigt XD es bei rund 79 %. Im Browser ist ein CSS-Pixel dagegen
ein CSS-Pixel, gezeichnete 90 wirken dort rund ein Fünftel größer als im
Entwurf. Verbreitete Fensterbreiten liegen ohnehin bei 1280–1512.

**Die Skala steht vollständig in `_variables.scss`** — `$h1/$h2/$h3-font-size`
und `$body-font-size`, dazu `$highlight-font-size: $body-font-size`. In den
Komponenten steht keine Schriftgröße mehr einzeln. Wer die Skala verschieben
will, ändert vier Zeilen.

**Raster:** Seitenrand **121** links und rechts, Inhalt also 1678 breit.
Trägt `.frame-container-default`. In Containern **nicht** noch einmal, sonst
verdoppelt sich der Rand.

**Überschriften-System:** Highlight-Zeile orange in Versalien, darunter
orangener Trenner (77.5 breit, 4pt stark), darunter die Überschrift. Erzeugt
über `subheader_class = highlight` plus
`frame_options = switch-headline,border-headline`.

**Farben:** nur `#E05206`, `#FFFFFF`, `#141414`, `#58585A`. Alles andere über
`nees-mix()` oder als `rgba()` daraus.

**Radius:** 0 überall, **6px** an Knöpfen, Karten und Bildkacheln.

**Abstände im PDF sind Oberkante zu Oberkante.** Als `margin` gesetzt kommt
die Zeilenhöhe obendrauf — der Zwischenraum ist der PDF-Wert minus
Schriftgröße.

---

## Fallen, die schon zugeschnappt sind

| Falle | Abhilfe |
|---|---|
| SCSS an erfundenen Klassen | Erst das Markup ansehen, dann gestalten |
| `.textpic` ist Flexbox mit `gap: 40px` | Abstand über `gap`, nicht über `margin` |
| `.frame` bringt `padding: 42px 0` mit | Bei Vollbild `padding-block: 0` |
| `figure` bringt eigenes Polster mit | `margin: 0` |
| `space_before_class` kennt kein `none` | Der leere Wert erzeugt die Klasse |
| Container über MCP anlegen | Geht nicht, siehe 5 |
| Höhe an `frame_class` hängen | Gehört an `frame_layout` (`h-100`) |
| Eigener CType ohne FlexForm-Datenstruktur | bootstrap_package meldet `background_image_options` je CType an, sonst Exception im Backend |

**Echtes Jost läuft rund 9 % breiter als der Satz im PDF.** Zeilen brechen
dadurch früher. Lieber den Rand schmaler als die Schrift stauchen.
