Product Requirements Document · solcom · 2026-05-03

Vacancy-Detail-Canvas-Template-Overhaul nach Figma „Projektdetails"

TL;DR — Die Vacancy-Detail-Page (node.vacancy.full) erhält eine 3-Section-Canvas-Topologie: Hero mit neuer card-meta-list-SDC (5 Meta-Rows, je Icon+Label+Field-Ref) in der 33%-Spalte und Job-Titel + Apply-Button in der 66%-Spalte, Body-Section, Apply-CTA-Section. Zwei neue SDCs im byte_theme: card-meta-list (Bubble-Frame-Container) und meta-row (Mikro-SDC). Stack: Twig-SDC + Canvas-Config-YAML. Cross-Sell, Sticky-Bar, Background-Lights: Out-of-Scope.

Status: accepted · Figma: 1019-78888 · Verwandter PRD: Personio-Vacancy-Integration

Problem Statement

Aus Sicht der Recruiting-/Marketing-Verantwortlichen:

Recruiting: fehlender Brand-Auftritt auf Vacancy-Detail-Pages node.vacancy.full

„Wenn jemand auf solcom.de eine offene Stelle anklickt — z. B. /karriere/leiterin-it-infrastruktur-security-mwd — bekommt sie eine sehr schlichte Seite mit einem Titel, einem Block Body-Text und einem Apply-Button. Das wirkt nicht wie eine SOLCOM-Stellenanzeige im Brand-Auftritt — es wirkt wie ein Standard-Drupal-Node-Render. Das Figma-Design ‚Projektdetails' zeigt klar, wie wir uns Job-/Projekt-Detail-Pages vorstellen: links eine prominente Meta-Card mit den Eckdaten (Stellentyp, Einsatzort, Arbeitszeit, Erfahrungslevel, Stellen-Nr.), rechts groß der Titel und ein Apply-Call-to-Action — das ganze auf dem markigen Dark-Blue-Background mit den signature Lime-Lights."

Site-Builder: fehlende wiederverwendbare Canvas-Komponenten config/sync

„Aktuell rendert die Detail-Page das field_body als ein einzelner HTML-Block. Wenn wir Seitenelemente flexibler komponieren wollen (z. B. Meta-Card nicht nur über Vacancy-Bundle, sondern später auch für einen Freelancer-Projekt-Bundle), brauchen wir wiederverwendbare Canvas-Komponenten, keine Hard-Coded-Twig- Templates pro Bundle."

Theme-Developer: Topologie-Entscheidung für Mikro-Komponenten byte_theme/components

„Wir haben das bubble-card-frame-Pattern (ADR-0005) und die Card-Familie (ADR-0009) bereits etabliert. Eine neue Meta-Card sollte sich in diese Familie einreihen, ohne den Familien-Vertrag zu brechen — also als Slot-Container, nicht als monolithische Heading/Bullets-Prop-SDC. Mikro-Komponenten für Icon+Label+Value-Zeilen sind im Repo bisher nicht vorhanden — die Topologie muss bewusst gewählt werden."

Solution

Zwei neue SDCs im byte_theme: card-meta-list als Bubble-Frame-Container (4. Card-Familienmitglied) und meta-row als Mikro-SDC mit Props icon, label, value. Der Canvas-Content-Template-Tree für vacancy.full enthält 5× meta-row als Slot-Children, jede mit eigenem 1:1-Field-Ref. Phosphor-Icon-Wiederverwendung über bestehenden icon-SDC.

Aus Sicht der Recruiting-Verantwortlichen nach der Umsetzung: Jede freigeschaltete Vacancy zeigt automatisch den Hero-Bereich (Meta-Card links, Job-Titel + Apply-Button rechts), Body-Text und finalen Apply-CTA — keine manuelle Pflege pro Stelle.

Architekturell: Zwei neue SDCs in web/themes/custom/byte_theme/components/ (card-meta-list/, meta-row/), je mit *.component.yml + *.twig. Canvas-Registrierung via canvas.component.sdc.byte_theme.*.yml. Das bestehende Content-Template canvas.content_template.node.vacancy.full.yml wird umstrukturiert auf 3 Sections + Breadcrumb + 5 Meta-Rows.

Goals (V1)

  1. Zwei neue SDCs card-meta-list und meta-row in web/themes/custom/byte_theme/components/ mit gültigem *.component.yml, *.twig; npm run format + npm run build laufen ohne Fehler.
  2. Beide SDCs sind über canvas.component.sdc.byte_theme.card-meta-list.yml und canvas.component.sdc.byte_theme.meta-row.yml als Canvas-Komponenten registriert; nach drush cim sichtbar im Canvas-Editor unter „Add component".
  3. Das Content-Template canvas.content_template.node.vacancy.full.yml ist umstrukturiert auf:
    • Breadcrumb-Block (unverändert)
    • Section 1 — Hero (columns: 33-66, background: primary, padding_block: 64, mobile_columns: 1): Spalte 1 — 1× card-meta-list mit 5× meta-row; Spalte 2 — 1× heading (Job-Titel, level 1, heading-responsive-4xl) + 1× cta (Apply-Button)
    • Section 2 — Body (columns: 100): 1× text mit Field-Ref auf field_body.processed
    • Section 3 — Apply-CTA: unverändert übernommen
  4. Die 5 Meta-Rows sind hart vorverdrahtet: briefcase/Stellentyp, map-pin/Einsatzort, clock/Arbeitszeit, graduation-cap/Erfahrungslevel, identification-card/Stellen-Nr.
  5. Auf einer existierenden Vacancy-Node (z. B. /karriere/leiterin-it-infrastruktur-security-mwd) ist das neue Layout sichtbar; Visual-Verify gegen Figma-Frame 1019-78888.
  6. Brand-Compliance via solcom-brand-reviewer und SDC-Compliance via drupal-twig-sdc-reviewer: keine P0/P1-Findings.

User Stories

Recruiting / Marketing

  1. Als Recruiting-Verantwortliche möchte ich, dass jede freigeschaltete Vacancy automatisch mit dem neuen Hero-Layout erscheint, damit ich keinen Content-Eingriff pro Stelle machen muss.
  2. Als Recruiting-Verantwortliche möchte ich, dass die Meta-Card die 5 Eckdaten der Stelle auf einen Blick zeigt, damit Bewerbende den Job-Fit schnell einschätzen können.
  3. Als Recruiting-Verantwortliche möchte ich, dass die Apply-Buttons direkt auf field_apply_url zeigen, damit Bewerbende ohne Umwege den Bewerbungsflow starten.
  4. Als Recruiting-Verantwortliche möchte ich, dass field_body als zusammenhängender Lese-Block zwischen Hero und finalem CTA steht, damit die etablierte Content-Pflege nicht bricht.

Bewerbende (End-User)

  1. Als Bewerber:in möchte ich, dass die Vacancy-Page mit Job-Titel und Eckdaten beginnt, damit ich in 3 Sekunden weiß, ob die Stelle für mich relevant ist.
  2. Als Bewerber:in möchte ich, dass die Stellen-Eckdaten visuell konsistent als Icon-Liste präsentiert werden, damit ich schnell scannen kann.
  3. Als Bewerber:in möchte ich einen prominenten Apply-Button im Hero sehen, damit ich nicht erst durch den Body scrollen muss, um mich zu bewerben.

Drupal Site-Builder

  1. Als Drupal Site-Builder möchte ich card-meta-list und meta-row im Canvas- Component-Browser finden, damit ich sie auch auf anderen Pages wiederverwenden kann.
  2. Als Drupal Site-Builder möchte ich, dass die Schema-description von card-meta-list klar erklärt, wie sie sich von card-bubble-profile-no-button unterscheidet, damit ich nicht versehentlich die falsche Komponente nutze.
  3. Als Drupal Site-Builder möchte ich, dass meta-row-Instances einen sinnvollen Default-Inhalt haben, damit eine neue Komponente im Canvas-Editor sofort etwas zeigt.

Theme-Developer

  1. Als Theme-Developer möchte ich, dass meta-row den bestehenden icon-SDC via Twig-Include nutzt, damit Icon-Logik nicht doppelt gepflegt wird.
  2. Als Theme-Developer möchte ich, dass card-meta-list den bestehenden bubble-card-frame (Variant profile-2-2-no-cta) einhängt, damit die Notch-Geometrie konsistent bleibt.
  3. Als Theme-Developer möchte ich, dass meta-row.icon als freier String modelliert ist (mit examples-Liste), nicht als hardcoded Enum.
  4. Als Theme-Developer möchte ich, dass beide SDCs den npm run format + npm run build Workflow ohne Anpassung des bestehenden Theme-Builds durchlaufen.

Designer / Brand-Pflege

  1. Als Brand-Verantwortliche möchte ich, dass die Meta-Card visuell der Figma-Vorlage „Projektdetails" entspricht (Bubble-Frame, Lime-Akzent, ScalaSans Bold-Label + Regular-Wert, Phosphor-Icons), damit der Brand-Auftritt konsistent ist.
  2. Als Brand-Verantwortliche möchte ich, dass keine hardcoded Hex-Werte oder oklch()-Literale eingeführt werden — Brand-Tokens aus theme.brand.css müssen verwendet werden.

Operations / Deployment

  1. Als Deployment-Verantwortliche möchte ich, dass alle neuen Canvas-Configs in config/sync/ versionierbar sind und über drush cim reproduzierbar deployt werden können.
  2. Als Deployment-Verantwortliche möchte ich, dass die component_version-Hashes in den neuen canvas.component.sdc.*.yml-Files deterministisch sind und keine bestehenden Component-Configs invalidieren.

Implementation Decisions

Komponenten-Topologie — Option A gewählt ADR-0013

Vier abgewogene Optionen:

  • A — Container-SDC card-meta-list + Mikro-SDC meta-row (gewählt)
  • A* — Nur meta-row + CSS-Modifier auf card-bubble-profile-no-button (verworfen: schlechtere Self-Service-Eignung außerhalb Vacancy; Modifier-Setzung erfordert Dev-Eingriff)
  • B — Monolithische card-meta-list mit items[]-Prop (verworfen: Canvas-Field-Binding kann kein dynamisches items[] aus N Field-Refs synthetisieren)
  • C — section-SDC + 5× text-SDC ohne Bubble-Frame (verworfen: verfehlt das Visual)
  • D — card-SDC um Variant meta-list erweitern (verworfen: würde Card-Familien-Vertrag aus ADR-0009 brechen)

Customer-Lens-Validierung hat Option A mit zwei Schärfungen bestätigt: (1) card-meta-list.component.yml description muss explizit gegen card-bubble-profile-no-button abgrenzen; (2) meta-row.icon als freier String mit examples-Liste, nicht als hardcoded Enum.

Modul-/SDC-Schichtung byte_theme/components

Neues SDC card-meta-list im byte_theme:

  • Group: Card · Props: keine Pflicht-Props (Container-Pattern) · Slots: main_slot
  • Twig: hängt bubble-card-frame mit Variant profile-2-2-no-cta als Hintergrund-Layer ein, rendert main_slot-Inhalt darüber
  • Description: explizit abgrenzend gegen card-bubble-profile-no-button (spezialisierter Container für strukturierte Icon-Label-Value-Listen)

Neues SDC meta-row im byte_theme:

  • Group: Base · Props: icon (string, freier Phosphor-Name, examples: briefcase/map-pin/clock/graduation-cap/identification-card), label (string), value (string) — alle required
  • Twig: includet byte_theme:icon mit Context-Isolation (only)

Beide SDCs werden über separate canvas.component.sdc.byte_theme.*.yml-Files in Canvas registriert (Schema-Pattern wie bestehende canvas.component.sdc.byte_theme.card.yml).

Content-Template-Tree für vacancy.full canvas.content_template…full.yml

Section-Topologie: 3 Sections + Breadcrumb. Hero-Section mit columns: 33-66 (Fallback auf 50-50 wenn nicht in allowed-values). mobile_columns: 1.

Slot-Children Hero-Spalte 1 (33%): 1× card-meta-list mit 5× meta-row als verschachtelte Slot-Children, je mit eigenem Field-Ref.

Slot-Children Hero-Spalte 2 (66%): 1× heading (Field-Ref auf entity:node:vacancy.title.value, level 1, heading-responsive-4xl) + 1× cta mit Apply-Button.

Body-Section: columns: 100, 1× text mit Field-Ref auf field_body.processed. Apply-CTA-Section: unverändert aus aktuellem Template.

Field-Mapping (Meta-Rows) entity:node:vacancy
Pos. Icon (Phosphor) Label Field-Ref
1 briefcase „Stellentyp" field_employment_typeentity.name
2 map-pin „Einsatzort" field_officeentity.name
3 clock „Arbeitszeit" field_scheduleentity.name
4 graduation-cap „Erfahrungslevel" field_seniorityentity.name
5 identification-card „Stellen-Nr." field_personio_idvalue

Empty-State: Wenn ein Feld leer ist, rendert meta-row mit leerem value. Ob ein Empty-Hide-Mechanismus im MVP nötig ist, entscheidet Visual-Verify.

Icon-Strategie icon-SDC · Phosphor

MVP: Phosphor-Icon-Pack via existing icon-SDC (icon('phosphor', …)). Alle 5 gewählten Icons existieren im Phosphor-Pack.

Fallback bei Visual-Drift: Custom-SVG-Export aus Figma in web/themes/custom/byte_theme/icons/<name>.svg, Registrierung als zweites Icon-Pack. Eigener Issue/ADR.

ADR-Verankerung docs/adr/

Zwei ADRs dokumentieren die Topologie-Entscheidungen (vor dem Build geschrieben):

  1. ADR-0013 · card-meta-list-and-meta-row-topology — Begründet die 2-SDC-Topologie, dokumentiert rejected alternatives A*/B/C/D, Customer-Lens-Verdikt und die zwei Schärfungen.
  2. ADR-0014 · vacancy-full-canvas-template-overhaul — Begründet die 3-Section-Topologie, Field-Mapping und Out-of-Scope-Cuts.

Testing Decisions

Was macht einen guten Test:

Pflicht-Reviewer-Läufe nach Implementation:

  1. solcom-brand-reviewer — alle geänderten/neuen *.css, *.twig, *.svg im byte_theme.
  2. drupal-twig-sdc-reviewer — alle neuen *.twig und *.component.yml (13 byte_theme-Regeln).
  3. drupal-config-architecture-reviewer — neue canvas.component.sdc.byte_theme.*.yml und geänderte canvas.content_template.node.vacancy.full.yml.

P0/P1-Findings müssen vor dem Merge adressiert sein. P2/P3 darf in Folge-Issues laufen.

Out of Scope

Further Notes

Reihenfolge der Build-Schritte (Skill-orchestriert): Bevorzugt via /solcom-build-frontend-Slash-Command. Triage-Heuristik routet in greenfield.md-Sub-Workflow (neue SDCs) plus canvas-page.md-Sub-Workflow (Content-Template-Edit) — kombinierter Lauf:

  1. Greenfield-Sub-Lauf: Neue SDCs bauen (Phase 2 Spec via diesem PRD abgeschlossen → Phase 4 Build → Phase 5 Verify-Build → Phase 6 Review → Phase 7 Visual-Verify).
  2. Canvas-Page-Folge-Lauf: Content-Template umstrukturieren (Phase 4 Build → drush cim + drush cache:rebuild → Phase 6 Review → Phase 7 Visual-Verify auf /karriere/leiterin-it-infrastruktur-security-mwd).

Risiken / Offene Punkte:

FAQ

Warum nicht card-bubble-profile-no-button wiederverwenden statt neues SDC?
card-bubble-profile-no-button ist ein Slot-Container für freie Canvas-Komposition. card-meta-list ist spezialisiert auf strukturierte Icon-Label-Value-Listen und hat eine andere Schema-Description, damit Site-Builder nicht die falsche Komponente nutzen. Außerdem ermöglicht das neue SDC die explizite ADR-Verankerung (ADR-0013).
Warum freier String für meta-row.icon statt Enum?
Konsistenz zum bestehenden icon-SDC, das ebenfalls freie Strings akzeptiert. Ein hardcoded Enum würde jede Erweiterung (neue Phosphor-Icons) zu einem Schema-Change machen. Die examples-Liste im YAML gibt Site-Buildern trotzdem Orientierung.
Wie wird die Hero-Section auf Mobile gehandhabt?
mobile_columns: 1 stackt die zwei Spalten vertikal. Die Reihenfolge (Meta-Card vor oder nach Titel) wird in Phase 7 (Visual-Verify) entschieden — Template-Slot- Reihenfolge kann angepasst oder mit CSS-order-Override gesteuert werden.
Wann folgt Phase 2 (Cross-Sell, Sticky-Bar, Background-Lights)?
Keine fixierte Zeitplanung. Items sind in docs/tasks/todo.html als spätere Issues notiert. Pre-Requisite für Background-Lights ist ein separater Theme-Layer-ADR; für Cross-Sell ein vacancies_related-View.