www.trr379.de/layouts/index.html
jennikrz 39d66fe593 Move homepage content from template/i18n to _index.md frontmatter
Hardcoded panel texts and venn labels are now stored as structured
frontmatter in content/_index.md and content/_index.de.md, enabling
metadata-backend-driven content updates without template changes.

i18n files now contain only UI labels, not page content.
Animation coupling between template IDs and JS triggers is documented
inline in layouts/index.html.

Also: remove explicit body padding override that was making homepage
nav inconsistent with the rest of the site.
2026-05-22 05:43:37 +00:00

192 lines
9.4 KiB
HTML

{{ define "main" }}
{{/* ═════════════════════════════════════════════════════════════════
TRR379 HOMEPAGE TEMPLATE
─────────────────────────────────────────────────────────────────
CONTENT vs. UI STRINGS — where to edit what:
--------------------------------------------
• Page content (hero titles, panel texts, research-area labels)
lives in `content/_index.md` and `content/_index.de.md` frontmatter.
These files are intended to be auto-populated from the metadata
backend (forgejo actions, see q04 workflow).
• Generic UI labels ("Objectives", "all news", "see all projects")
live in `i18n/en.yaml` and `i18n/de.yaml`.
ANIMATION COUPLING — important caveat:
--------------------------------------
This template's structure is tightly coupled to scroll animations
defined in `static/js/trr379-home.js`. The following element IDs
are referenced by the JS and MUST exist for animations to work:
#hero, #heroText, #heroFigure
#middleWrapper
#fig2Wrap, #fig4Wrap
#rdocPanel, #multiPanel, #adolPanel ← exactly 3 panels expected
#researchAreas
#vennFigure, #vennConnectors, #vennFooter
#vennLabelA, #vennLabelB, #vennLabelC, #vennLabelZ
#scrollProgress
The 3-panel middle section is hardcoded by design — each panel
triggers a specific animation:
• #rdocPanel → triggers Figure2 draw-in
• #multiPanel → triggers Figure2-to-Figure4 fly transition + Figure4 draw
• #adolPanel → triggers Figure4 grey-arrow reveal
To ADD A NEW PANEL with associated animation:
1. Add the panel entry to `content/_index.md` frontmatter under `panels:`
2. Add a new <div class="text-panel" id="..."> block in this template
3. In `static/js/trr379-home.js`, add a new ScrollTrigger for the panel
(see sections 3, 4 for examples of how Figure2 and Figure4 panels
are wired up). The generic pin/dwell logic in section 7 will
automatically include any element with class `.text-panel`.
To REMOVE OR REORDER PANELS:
Both the template and JS need to be updated together. The JS
animation timing assumes 3 panels in the order rdoc → multi → adol.
══════════════════════════════════════════════════════════════════ */}}
{{/* ── CSS einbinden ── */}}
<link rel="stylesheet" href="/css/trr379-home.css">
{{/* ── GSAP (lokal) + Animation Code ── */}}
<script defer src="/js/gsap.min.js"></script>
<script defer src="/js/ScrollTrigger.min.js"></script>
<script defer src="/js/trr379-home.js"></script>
<div class="scroll-progress" id="scrollProgress"></div>
{{/* ── HERO SECTION — content from frontmatter (hero.title, hero.subtitle) ── */}}
<section class="hero" id="hero">
<div class="hero-inner">
<div class="hero-text" id="heroText">
<h1 class="hero-title">{{ .Params.hero.title | safeHTML }}</h1>
<p class="hero-subtitle">{{ .Params.hero.subtitle | safeHTML }}</p>
</div>
<div class="hero-figure" id="heroFigure"></div>
</div>
</section>
{{/* ── MIDDLE WRAPPER — 3 scroll-pinned panels, see header comment ──
Each panel reads its content from `.Params.panels.<id>` in frontmatter.
IDs are hardcoded because the animation references them. */}}
<div class="middle-wrapper" id="middleWrapper">
<div class="middle-figure-col">
<div class="fig-stack">
<div id="fig2Wrap"></div>
<div id="fig4Wrap"></div>
</div>
</div>
<div class="middle-text-col">
{{/* Panel 1: RDoC — triggers Figure2 draw */}}
{{ with .Params.panels.rdoc }}
<div class="text-panel" id="rdocPanel">
<div class="content-text">
{{ with .label_key }}<p class="section-label green">{{ i18n . }}</p>{{ end }}
<h2 class="section-title">{{ .title }}</h2>
<p class="section-text">{{ .text | safeHTML }}</p>
</div>
</div>
{{ end }}
{{/* Panel 2: Multilevel — triggers Figure2-to-Figure4 transition */}}
{{ with .Params.panels.multilevel }}
<div class="text-panel" id="multiPanel">
<div class="content-text">
<h2 class="section-title">{{ .title }}</h2>
<p class="section-text">{{ .text | safeHTML }}</p>
<a href="/topics/" style="display:inline-block;margin-top:1rem;color:var(--green-light);font-weight:600;text-decoration:none;">→ {{ i18n "all_research_topics" }}</a>
</div>
</div>
{{ end }}
{{/* Panel 3: Adolescence — triggers Figure4 grey-arrow reveal */}}
{{ with .Params.panels.adolescence }}
<div class="text-panel" id="adolPanel">
<div class="content-text">
<h2 class="section-title">{{ .title }}</h2>
<p class="section-text">{{ .text | safeHTML }}</p>
</div>
</div>
{{ end }}
</div>
</div>
{{/* ── VENN SECTION — research areas from frontmatter ──
Labels A/B/C/Z are read from `.Params.research_areas` array,
but their POSITIONS in the venn diagram are CSS-defined
(.venn-label-a, -b, -c, -z) and matched to area IDs ("a", "b", "c", "z"). */}}
<section class="venn-section" id="researchAreas">
<div class="venn-container">
<div class="venn-footer" id="vennFooter">
<h2 class="section-title" style="text-align:center">{{ i18n "research_areas" }}</h2>
<p style="text-align:center;color:#555;font-size:1rem;">
<a href="/projects" style="color:inherit;text-decoration:none;border-bottom:1px solid rgba(255,255,255,0.3);">{{ i18n "see_all_projects" }} &nbsp;</a>
</p>
</div>
<div class="venn-figure-wrap">
<div class="venn-figure" id="vennFigure"></div>
<div class="venn-labels">
<svg id="vennConnectors" viewBox="0 0 900 620" preserveAspectRatio="xMidYMid meet" style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;opacity:0;">
<line x1="155" y1="100" x2="320" y2="240" stroke="#ef9052" stroke-width="1.2"/>
<line x1="735" y1="155" x2="590" y2="155" stroke="#0a8f37" stroke-width="1.2"/>
<line x1="735" y1="400" x2="590" y2="380" stroke="#9c1916" stroke-width="1.2"/>
<line x1="175" y1="460" x2="370" y2="390" stroke="#b0b0b0" stroke-width="1.2"/>
</svg>
{{ range .Params.research_areas }}
<div class="venn-label venn-label-{{ .id }}" id="vennLabel{{ .id | upper }}">
<span class="venn-label-title" style="color:{{ .color }}">{{ .title }}</span>
<span class="venn-label-desc">{{ .desc | safeHTML }}</span>
</div>
{{ end }}
</div>
</div>
</div>
</section>
{{/* ── Latest News ── */}}
{{ $news := (site.GetPage "/news").Pages.ByDate.Reverse | first 6 }}
{{ if $news }}
<section class="home-news">
<div class="home-news-inner">
<div class="home-news-header">
<h2 class="home-news-title">{{ i18n "latest_news" }}</h2>
<a href="/news/" class="home-news-more">{{ i18n "all_news" }} →</a>
</div>
<div class="home-news-grid">
{{ range $news }}
{{ $thumb := .Resources.GetMatch "feature*" }}
{{ if not $thumb }}{{ $thumb = .Resources.GetMatch "thumbnail*" }}{{ end }}
<a class="home-news-card" href="{{ .Permalink }}">
{{ with $thumb }}
<div class="home-news-img">
<img src="{{ (.Fill "600x400 Center").RelPermalink }}" alt="">
</div>
{{ end }}
<div class="home-news-body">
<span class="home-news-date">{{ .Date.Format "2 Jan 2006" }}</span>
<h3 class="home-news-card-title">{{ .Title }}</h3>
<p class="home-news-excerpt">{{ .Summary | truncate 100 }}</p>
</div>
</a>
{{ end }}
</div>
</div>
</section>
{{ end }}
{{/* ── Optional intro markdown content from _index.md body ── */}}
{{ if .Content }}
<section class="trr-intro">
<div class="trr-intro-inner">
{{ .Content }}
</div>
</section>
{{ end }}
{{ end }}