From ed3a3306e346830223a954ffc9da774194949414 Mon Sep 17 00:00:00 2001
From: Jon Pither
Date: Thu, 7 May 2026 10:49:21 +0100
Subject: [PATCH 1/2] xt26: render speaker headshots inline in agenda
Each agenda subtitle line is parsed for the speaker name and matched
against speakers.json. Where there's a hit, a small circular avatar
renders next to the line, matching the juxt-bordered style of the
speaker grid above. Lines without a speaker entry (Nik Tkachev, Payal
Jain, panel TBA placeholders, plain non-speaker subtitles) fall through
gracefully - placeholder spacing keeps multi-speaker rows aligned.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
src/components/XT26Agenda.astro | 41 +++++++++++++++++++++++++++++----
1 file changed, 37 insertions(+), 4 deletions(-)
diff --git a/src/components/XT26Agenda.astro b/src/components/XT26Agenda.astro
index 61d7aac50..560fdb4a3 100644
--- a/src/components/XT26Agenda.astro
+++ b/src/components/XT26Agenda.astro
@@ -1,4 +1,11 @@
---
+import speakers from '../data/xt26/speakers.json'
+import AssetImage from '@components/AssetImage.astro'
+
+const speakerByName = Object.fromEntries(
+ speakers.map((s) => [s.name, s])
+)
+
const agenda = [
{
time: '08:30',
@@ -104,10 +111,23 @@ const agenda = [
isSpecialEvent: true
}
]
+
+const resolveLines = (subTitle) =>
+ (subTitle == null
+ ? []
+ : Array.isArray(subTitle)
+ ? subTitle
+ : [subTitle]
+ ).map((line) => {
+ const name = line.split('|')[0].trim()
+ return { line, speaker: speakerByName[name] }
+ })
---
{
agenda.map(({ time, title, subTitle, isSpecialEvent }, index) => {
+ const lines = resolveLines(subTitle)
+ const hasAnySpeaker = lines.some((l) => l.speaker)
const nextItem = index < agenda.length - 1 ? agenda[index + 1] : null
const isConsecutiveSpecialEvent = isSpecialEvent && nextItem?.isSpecialEvent
@@ -125,10 +145,23 @@ const agenda = [
{title}
- {subTitle &&
- (Array.isArray(subTitle) ? subTitle : [subTitle]).map((s) => (
-
{s}
- ))}
+ {lines.map(({ line, speaker }) => (
+
+ {hasAnySpeaker &&
+ (speaker?.image ? (
+
+ ) : (
+
+ ))}
+
{line}
+
+ ))}
From 5513d42dbd12939e72d2272d33c571045e3e5c4b Mon Sep 17 00:00:00 2001
From: Jon Pither
Date: Thu, 7 May 2026 10:57:28 +0100
Subject: [PATCH 2/2] xt26: fix AssetImage import path
The AssetImage component lives under @components/team/, not directly
under @components/. Tested locally with yarn build.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
src/components/XT26Agenda.astro | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/XT26Agenda.astro b/src/components/XT26Agenda.astro
index 560fdb4a3..2197bccaf 100644
--- a/src/components/XT26Agenda.astro
+++ b/src/components/XT26Agenda.astro
@@ -1,6 +1,6 @@
---
import speakers from '../data/xt26/speakers.json'
-import AssetImage from '@components/AssetImage.astro'
+import AssetImage from '@components/team/AssetImage.astro'
const speakerByName = Object.fromEntries(
speakers.map((s) => [s.name, s])