Files
svemagie 48b6d920c4 merge: upstream theme updates (54 commits)
Key changes merged from svemagie/blog-eleventy-indiekit:

- feat: /updated.xml feed for recently edited posts
- feat: sitemap.xml generation in eleventy.after hook
- feat: excludePostTypes filter for homepage section config
- feat: view mode toggle (repo/type) for changelog page
- feat: replyTargets config for platform-to-syndicator mapping
- feat: syndication badge + linked timestamp on owner replies
- perf: memoize aiPosts/aiStats/hash filters; batch unfurl pre-fetch
- perf: clear eleventy-img in-memory cache between builds (OOM fix)
- perf: memory profiler (logMemory) at build phases
- perf: OG batch tracking (totalGenerated/batch counters)
- fix: h-entry u-url absolute for IndieNews compatibility
- fix: webmention platform detection in build-time templates
- fix: deduplicate interactions via interactionKey
- fix: reply form syndication via replyTargets (not hardcoded platforms)
- fix: remove skeleton loader CSS (CLS fix)
- fix: avatar dimensions 96→128 to match CSS classes
- css: remove unused skeleton loader rules

Local customisations preserved:
- Gitea-based data files (githubActivity, githubRepos, githubStarred)
- Funkwhale cover image cache copy in eleventy.after
- URL fallback arrays in funkwhale/lastfm data fetchers
- CONFIGURABLE cache durations (FUNKWHALE_FETCH_CACHE_DURATION etc.)
- OG_CACHE_DIR naming (not cacheDir)
- Our ogSlug format (plain slug, not date-prefixed)
- Gruvbox design tokens (link colours, selection colours)
- Unfurl manifest optimisation (skip re-fetching known URLs)
- CLAUDE.md, README.md, .github/workflows (ours)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 14:41:09 +02:00

78 lines
3.3 KiB
Plaintext

{#
Hero Section - author intro with avatar, name, title, bio
Rendered by homepage-builder when hero is enabled
#}
{% set heroConfig = homepageConfig.hero or {} %}
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
{% set authorName = id.name if (id.name is defined) else site.author.name %}
{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
{% set siteDescription = id.description if (id.description is defined) else site.description %}
{% set socialLinks = id.social if (id.social is defined) else site.social %}
{% set authorUrl = id.url if (id.url is defined and id.url) else (site.author.url or site.url) %}
<section class="h-card mb-8 sm:mb-12">
{# Hidden u-photo for reliable microformat parsing (some parsers struggle with img inside links) #}
{% if authorAvatar %}
<data class="u-photo hidden" value="{{ authorAvatar }}"></data>
{% endif %}
<div class="flex flex-col sm:flex-row gap-6 sm:gap-8 items-start">
{# Avatar #}
{% if heroConfig.showAvatar != false %}
<a href="{{ authorUrl }}" class="flex-shrink-0" rel="me" tabindex="-1" aria-hidden="true">
<img
src="{{ authorAvatar }}"
alt="{{ authorName }}"
width="128"
height="128"
class="w-24 h-24 sm:w-32 sm:h-32 rounded-full object-cover shadow-lg"
loading="eager"
>
</a>
{% endif %}
{# Introduction #}
<div class="flex-1 min-w-0">
<h1 class="text-2xl sm:text-3xl md:text-4xl font-bold text-surface-900 dark:text-surface-100 mb-2">
<a href="{{ authorUrl }}" class="p-name u-url u-uid hover:text-accent-700 dark:hover:text-accent-300" rel="me">{{ authorName }}</a>
</h1>
{% if authorTitle %}
<p class="p-job-title text-lg sm:text-xl text-accent-700 dark:text-accent-300 mb-3 sm:mb-4">
{{ authorTitle }}
</p>
{% endif %}
{% if authorBio %}
<p class="p-note text-base sm:text-lg text-surface-700 dark:text-surface-300 mb-4">
{{ authorBio }}
</p>
{% endif %}
{% if siteDescription %}
<p class="text-base sm:text-lg text-surface-700 dark:text-surface-300 mb-4 sm:mb-6">
{{ siteDescription }}
<a href="/about/" class="text-accent-700 dark:text-accent-300 hover:underline font-medium">Read more &rarr;</a>
</p>
{% endif %}
{# Social Links #}
{% from "components/social-icon.njk" import socialIcon, socialIconColorClass %}
{% if heroConfig.showSocial != false and socialLinks %}
<div class="flex flex-wrap gap-3">
{% for link in socialLinks %}
<a
href="{{ link.url }}"
rel="{{ link.rel }} noopener"
class="inline-flex items-center gap-2 px-3 py-2 text-sm text-surface-700 dark:text-surface-300 bg-surface-100 dark:bg-surface-800 rounded-lg hover:bg-surface-200 dark:hover:bg-surface-700 transition-colors"
target="_blank"
>
<span class="{{ socialIconColorClass(link.icon) }}">{{ socialIcon(link.icon, "w-5 h-5") }}</span>
<span class="text-sm font-medium">{{ link.name }}</span>
</a>
{% endfor %}
</div>
{% endif %}
</div>
</div>
</section>