diff --git a/docs/plans/2026-05-21-praxis-visual-parity-2.md b/docs/plans/2026-05-21-praxis-visual-parity-2.md new file mode 100644 index 0000000..6831251 --- /dev/null +++ b/docs/plans/2026-05-21-praxis-visual-parity-2.md @@ -0,0 +1,238 @@ +# Visual Parity Pass 2 — Implementation Plan + +**Goal:** Restore the missing team carousel on `/team/`, fix carousel image distortion, clean up markdown / autoescape glitches in `doctors.md` and navbar — closing the regressions reported after Phase 1.5 deploy. + +**Architecture:** New `team_carousel.html` macro + `section.html` dispatch by `page.extra.layout`; rewrite `content/team/employees.md` to carry slides as front-matter data; spot fixes in `doctors.md` and `navbar.html`. + +**Tech Stack:** Zola 0.22, Tera, Bootstrap 3 (carousel JS already wired in `base.html`), Font Awesome (icons already loaded). + +--- + +## Task 1: Rewrite `content/team/employees.md` with carousel front matter + +**Files:** +- Modify: `content/team/employees.md` (full rewrite) + +Replace the entire file with TOML front matter holding the five slides and an empty body: + +```toml ++++ +title = "Unser Praxis-Team" +weight = 20 + +[extra] +anchor = "employees" +layout = "carousel" + +[[extra.slides]] +name = "Frau Berscheidt" +image = "Berscheidt.jpg" +description = "Medizinische Fachangestellte, Diabetes-Assistentin" + +[[extra.slides]] +name = "Frau Bolz" +image = "Bolz.jpg" +description = "Medizinische Fachangestellte" + +[[extra.slides]] +name = "Frau Frohne" +image = "Frohne.jpg" +description = "Medizinische Fachangestellte" + +[[extra.slides]] +name = "Frau Merhof" +image = "Merhof.jpg" +description = "Medizinische Fachangestellte" + +[[extra.slides]] +name = "Frau Rodrigues" +image = "Rodrigues.jpg" +description = "Medizinische Fachangestellte" ++++ +``` + +Commit: +``` +fix(team): convert employees.md to carousel front-matter data +``` + +## Task 2: Create `templates/macros/team_carousel.html` + +**Files:** +- Create: `templates/macros/team_carousel.html` + +```html +{% macro team_carousel(title, anchor, slides) %} +
+
+
+ {%- if anchor %} +
+

{{ title }}

+
+ {%- else %} +

{{ title }}

+ {%- endif %} + +
+
+ +
+ +
+
+{% endmacro %} +``` + +Commit: +``` +feat(templates): add team_carousel macro mirroring live employees block +``` + +## Task 3: Wire macro into `templates/section.html` + +**Files:** +- Modify: `templates/section.html` + +Add the macro import alongside the others, and branch on `page.extra.layout` in the child-page loop: + +```html +{% extends "base.html" %} +{% import "macros/section_title.html" as st %} +{% import "macros/page_title.html" as pt %} +{% import "macros/team_carousel.html" as tc %} + +{% block content %} + +{{ pt::page_title(title=section.title) }} + +{% if section.content %} +
+
+
{{ section.content | safe }}
+
+
+{% endif %} + +{% for page in section.pages %} + {% if page.extra.layout == "carousel" %} + {{ tc::team_carousel( + title=page.title, + anchor=page.extra.anchor | default(value=page.slug), + slides=page.extra.slides) }} + {% else %} +
+ {{ st::section_title(title=page.title, anchor=page.extra.anchor | default(value=page.slug)) }} +
+
+ {{ page.content | safe }} +
+
+
+ {% endif %} +{% endfor %} + +{% endblock %} +``` + +Commit: +``` +feat(templates): dispatch section pages by extra.layout for carousel support +``` + +## Task 4: Fix `
` headings in `content/team/doctors.md` + +**Files:** +- Modify: `content/team/doctors.md` + +Replace every `#####X` (no space) with `##### X` (with space) — exactly six lines: +- `#####Qualifikation` → `##### Qualifikation` (3×) +- `#####Tätigkeitsschwerpunkte` → `##### Tätigkeitsschwerpunkte` (2×) +- `#####Tätigkeitsschwerpunkt` → `##### Tätigkeitsschwerpunkt` (1×) +- `#####Interessenschwerpunkt` → `##### Interessenschwerpunkt` (1×) + +(Total occurrences: 6 — verified via `grep -c '^#####[^ ]' content/team/doctors.md`.) + +## Task 5: Fix `` closing tags in `content/team/doctors.md` + +**Files:** +- Modify: `content/team/doctors.md` + +Each doctor block has a schedule table with two `…` mismatches in +its first row. Replace `` with `` — six total occurrences. + +Combine commits 4+5: +``` +fix(content): proper md headings and td closing tags in doctors.md +``` + +## Task 6: Strip base_url from nav permalinks in `templates/partials/navbar.html` + +**Files:** +- Modify: `templates/partials/navbar.html` + +For each `` (two top-level loops, plus the +mobile menu list further down): +- Old: `href="{{ sub.permalink }}"` (etc.) +- New: `href="{{ sub.permalink | replace(from=config.base_url, to='') | safe }}"` + +Same treatment for `cpage.permalink` inside the dropdown. + +Commit: +``` +fix(navbar): render nav hrefs as relative paths to match live markup +``` + +## Task 7: Build, deploy, verify + +- [ ] Run `zola build` from project root. Expect zero warnings/errors. +- [ ] Read `public/team/index.html` and confirm: + - One `
` containing `id="employeesSlider"`. + - Exactly five `
` blocks (first with `active`). + - Each item has `

`. + - No `

#####…

` literals in the doctors section. + - No `` substrings. +- [ ] Read `public/index.html` and confirm nav `
` (no `/`). +- [ ] `rsync -avz --delete public/ mycelium:~/public/praxis/`. +- [ ] `curl -sI https://preview.praxis-am-lienhardplatz.de/team` → expect `HTTP/2 200`. +- [ ] Final commit on the deploy step: + +``` +chore(deploy): visual parity pass 2 — team carousel restored, markup cleaned +``` + +- [ ] `git push origin main`. + +--- + +## Self-review checklist (before exec) + +- [x] Every spec finding has a corresponding task. +- [x] No placeholders / TBDs. +- [x] Type consistency: `slides` list, `slide.image`, `slide.name`, `slide.description` are + the same names in employees.md, the macro, and the spec. +- [x] Images path: `static/images/team/.jpg` → served at `/images/team/.jpg`. +- [x] Bootstrap-3 carousel auto-init (`data-ride="carousel"`) — no extra JS needed. +- [x] Footer + base.html unchanged. diff --git a/docs/specs/2026-05-21-praxis-visual-parity-2-design.md b/docs/specs/2026-05-21-praxis-visual-parity-2-design.md new file mode 100644 index 0000000..0e782e5 --- /dev/null +++ b/docs/specs/2026-05-21-praxis-visual-parity-2-design.md @@ -0,0 +1,157 @@ +# Visual Parity Pass 2 — Design Spec + +**Date:** 2026-05-21 +**Phase:** 1.6 (regression follow-up to Phase 1.5) +**Status:** approved (auto-mode, in-session execution) + +## Goal + +Close the remaining visual gaps reported by the editor after Phase 1.5 deploy: +the team carousel that was silently dropped during the Grav→Zola content port, +the image-size distortion on the employee block, and a small set of markdown +parsing / template autoescape glitches. + +## Non-Goals + +- No Phase 2 modernization (typography, mobile, accessibility) — still 1:1 parity. +- No CSS edits — the live theme CSS is the contract; we change markup to match it. +- No production cutover. Staging only. + +## Reference + +- Live source-of-truth (read-only): `/home/brummel/dev/praxis/orig/` +- Current Zola build output: `/home/brummel/dev/praxis/public/` +- Phase 1.5 spec: `docs/specs/2026-05-20-praxis-visual-parity-design.md` +- Phase 1.5 plan: `docs/plans/2026-05-20-praxis-visual-parity.md` + +## Findings + +### 1. Team carousel missing on `/team/` + +Live (`orig/user/themes/praxis/templates/modular/employees.html.twig`) renders a +Bootstrap-3 carousel: `
` → `
` with one `.item` per slide +(blockquote / ul / li-img + li.name + p.description), plus `.left/.right +carousel-control` anchors. Source data is a `slides` list in the +`employees.md` front matter. CSS rules in +`orig/user/themes/praxis/css/_style.css:1838–1846` force `img { width:160px; +height:200px }` for items inside `#employeesSlider .carousel-inner`. + +Current Zola output for `/team/` `employees` section is just sequential +`` blocks with `name` paragraphs — +the carousel container, controls, and item wrapping are entirely missing. + +### 2. Image-size distortion (carousel slot only) + +`templates/macros/image.html` resizes with `op="fit_width"`. For 311×400 +originals at `width=200`, that produces 200×257 — the wrong aspect for the +160×200 CSS slot. The live site avoids this by serving the raw image and +letting CSS pin it to 160×200. Doctor portraits (400×400) and services +thumbnails (600×400) are visually fine; the bug is isolated to the carousel +images. + +### 3. `
` headings not parsed in `content/team/doctors.md` + +Markdown source has `#####Qualifikation` with no space after the hashes. +Grav's markdown parser was tolerant; pulldown-cmark (Zola) is not — output is +`

#####Qualifikation

`. Six occurrences across three doctor blocks. + +### 4. `` closing tag mismatch in doctors.md tables + +`…` pairs in the three doctor schedule tables (six total). Browsers +recover, but the markup is wrong and inconsistent with the live (which uses +`…` everywhere). + +### 5. Nav-link URLs HTML-entity-encoded + +`templates/partials/navbar.html` renders `{{ sub.permalink }}` and +`{{ cpage.permalink }}` without `| safe`. Tera autoescape converts the +slashes to `/`. Functional but markup-ugly and not parity. Live uses +relative paths (`/services/`). + +## Architecture + +### New: `templates/macros/team_carousel.html` + +Renders a `
` block: +- Reuses the section-title structure from `section_title.html` (or inlines it + identically — anchor optional). +- Renders `