diff --git a/src/components/HeroCarousel.astro b/src/components/HeroCarousel.astro
index 2c10376..1ced198 100644
--- a/src/components/HeroCarousel.astro
+++ b/src/components/HeroCarousel.astro
@@ -11,12 +11,17 @@
// at all — the dots still work.
//
// Reused by every locale homepage; only `imgCode` and the `shots` copy change.
+import { ArrowUpRight } from '@lucide/astro';
+
interface Shot {
scene: string;
alt: string;
/** Short feature name, shown above the caption. */
label: string;
caption: string;
+ /** Where this feature is covered in full — a blog post, most often. When set,
+ * the shot and its label both link there. */
+ href?: string;
}
interface Props {
@@ -47,23 +52,39 @@ const { imgCode, shots, interval = 4500 } = Astro.props;
style="aspect-ratio: 1200 / 872;"
>
{
- shots.map((shot, i) => (
-
- ))
+ shots.map((shot, i) => {
+ const img = (
+
+ );
+ const slideClasses = [
+ 'hc-slide absolute inset-0 transition-opacity duration-700 ease-in-out',
+ i === 0 ? 'opacity-100' : 'opacity-0',
+ ];
+ return shot.href ? (
+
+ {img}
+
+ ) : (
+
+ {img}
+
+ );
+ })
}
@@ -85,9 +106,20 @@ const { imgCode, shots, interval = 4500 } = Astro.props;
>
{/* 11px, not 10: `uppercase` does nothing for CJK labels, so they
lean on size alone to read as a label. */}
-
- {shot.label}
-
+ {shot.href ? (
+
+ {shot.label}
+
+
+ ) : (
+
+ {shot.label}
+
+ )}
{shot.caption}
))
@@ -201,12 +233,17 @@ const { imgCode, shots, interval = 4500 } = Astro.props;
// Only the current shot and caption are exposed — otherwise a screen
// reader reads every screenshot's alt text and every caption in a row.
+ // The CSS `pointer-events: none` on [aria-hidden] keeps hidden slides
+ // unclickable, but a keyboard user can still Tab to a hidden link, so
+ // its tabindex is toggled alongside aria-hidden.
for (const group of [slides, captions]) {
group.forEach((el, i) => {
const active = i === current;
el.classList.toggle('opacity-100', active);
el.classList.toggle('opacity-0', !active);
el.toggleAttribute('aria-hidden', !active);
+ const link = el.tagName === 'A' ? el : el.querySelector('a');
+ if (link) link.tabIndex = active ? 0 : -1;
});
}
diff --git a/src/pages/de/index.astro b/src/pages/de/index.astro
index 6a00405..845de6d 100644
--- a/src/pages/de/index.astro
+++ b/src/pages/de/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'Ein Anrufablauf in WaveKat Voice als Karte — Begrüßung, Prüfung der Öffnungszeiten, Klingeln an Ihrem Platz und Anrufbeantworter',
label: 'Anrufabläufe',
caption: 'Begrüßung, Öffnungszeiten, Ihr Platz klingelt, dann der Anrufbeantworter — als Karte.',
+ href: '/de/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice, während ein Anrufablauf eine Nachricht aufnimmt — mit Live-Transkript und einer Schaltfläche zum Übernehmen',
label: 'Nimmt für Sie ab',
caption: 'Der Ablauf geht ran — Sie lesen mit und übernehmen mitten in der Nachricht.',
+ href: '/de/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice teilt eine Anrufaufnahme — privat, auf Einladung oder für alle mit dem Link, mit maskierter Anruferkennung',
label: 'Aufgezeichnet und teilbar',
caption: 'Jeder Anruf wird aufgezeichnet und mitgeschrieben. Per Link teilen — Sie bestimmen, wer hört.',
+ href: '/de/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/es/index.astro b/src/pages/es/index.astro
index a9a4781..86a8286 100644
--- a/src/pages/es/index.astro
+++ b/src/pages/es/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'Un flujo de llamada de WaveKat Voice dibujado como un mapa: saludo, comprobación del horario, suena su equipo y buzón de voz',
label: 'Flujos de llamada',
caption: 'Saludo, su horario, suena su equipo y, si no, buzón de voz: dibujado como un mapa.',
+ href: '/es/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice mientras un flujo de llamada toma un mensaje, con la transcripción en vivo y un botón para contestar',
label: 'Contesta por usted',
caption: 'El flujo contesta: usted lee lo que dicen y toma la llamada a mitad del mensaje.',
+ href: '/es/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice compartiendo la grabación de una llamada: privado, por invitación o cualquiera con el enlace, con la identidad enmascarada',
label: 'Grabada y compartible',
caption: 'Cada llamada se graba y se escribe. Compártala con un enlace y decida quién la oye.',
+ href: '/es/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/fr/index.astro b/src/pages/fr/index.astro
index 44895e8..08eaf72 100644
--- a/src/pages/fr/index.astro
+++ b/src/pages/fr/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'Un flux d’appel WaveKat Voice dessiné comme une carte : accueil, vérification des horaires, sonnerie à votre poste et messagerie',
label: 'Flux d’appel',
caption: 'Accueil, vos horaires, votre poste sonne, puis la messagerie — dessiné comme une carte.',
+ href: '/fr/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice pendant qu’un flux d’appel prend un message, avec la transcription en direct et un bouton pour décrocher',
label: 'Décroche pour vous',
caption: 'Le flux décroche : vous lisez ce qui se dit et reprenez l’appel en plein message.',
+ href: '/fr/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice partage un enregistrement d’appel : privé, sur invitation ou toute personne ayant le lien, avec l’identité de l’appelant masquée',
label: 'Enregistré et partageable',
caption: 'Chaque appel est enregistré et retranscrit. Partagez-le par lien : vous choisissez qui l’écoute.',
+ href: '/fr/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 01f4d57..0af89d7 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -15,18 +15,21 @@ const heroShots = [
alt: 'A WaveKat Voice call flow drawn as a map — a greeting, a business-hours check, ringing your desk, and voicemail',
label: 'Call flows',
caption: 'A greeting, your opening hours, ring your desk, then voicemail — drawn as a map.',
+ href: '/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice while a call flow takes a message, showing the live transcript and a Pick up button to take the call over',
label: "Answers when you can't",
caption: 'It picks up for you — read what they say and take the call over mid-message.',
+ href: '/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice sharing a call recording, with private, specific-people and anyone-with-the-link options and the caller identity masked',
label: 'Recorded and shareable',
caption: 'Every call is recorded and written down. Send one by link, and choose who hears it.',
+ href: '/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/it/index.astro b/src/pages/it/index.astro
index a3fb1f0..3d5c639 100644
--- a/src/pages/it/index.astro
+++ b/src/pages/it/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'Un flusso di chiamata di WaveKat Voice disegnato come una mappa: saluto, controllo degli orari, squillo alla tua postazione e segreteria',
label: 'Flussi di chiamata',
caption: 'Saluto, i tuoi orari, squilla la tua postazione, poi la segreteria — come una mappa.',
+ href: '/it/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice mentre un flusso di chiamata prende un messaggio, con la trascrizione dal vivo e un pulsante per rispondere',
label: 'Risponde per te',
caption: 'Il flusso risponde: leggi quello che dicono e prendi la chiamata a metà messaggio.',
+ href: '/it/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice condivide la registrazione di una chiamata: privato, su invito o chiunque abbia il link, con l’identità del chiamante mascherata',
label: 'Registrata e condivisibile',
caption: 'Ogni chiamata è registrata e trascritta. Mandala con un link e decidi chi la ascolta.',
+ href: '/it/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/ja/index.astro b/src/pages/ja/index.astro
index 1bdbb68..04f1259 100644
--- a/src/pages/ja/index.astro
+++ b/src/pages/ja/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'WaveKat Voice の通話フロー図——挨拶、営業時間の判定、手元を鳴らす、最後に留守番メッセージ',
label: '通話フロー',
caption: '挨拶、営業時間、手元を鳴らす、そして留守番メッセージ——一枚の地図に。',
+ href: '/ja/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: '通話フローが伝言を預かっている WaveKat Voice——リアルタイム文字起こしと応答ボタン',
label: '手が離せないときに応答',
caption: '代わりに応答します——相手の話を読みながら、途中で代わることもできます。',
+ href: '/ja/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice の通話録音の共有——非公開・招待制・リンクを知っている全員から選べ、発信者情報は伏せられる',
label: '録音はリンクで共有',
caption: 'すべての通話を録音して文字に。リンクで送れて、誰が聞けるかも選べます。',
+ href: '/ja/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/ko/index.astro b/src/pages/ko/index.astro
index 46fa18e..55f4838 100644
--- a/src/pages/ko/index.astro
+++ b/src/pages/ko/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'WaveKat Voice의 통화 플로우 지도 — 인사말, 영업시간 확인, 내 자리 울리기, 마지막으로 음성 메시지',
label: '통화 플로우',
caption: '인사말, 영업시간, 내 자리 울리기, 그리고 음성 메시지 — 한 장의 지도로.',
+ href: '/ko/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: '통화 플로우가 메시지를 받는 동안의 WaveKat Voice — 실시간 전사와 받기 버튼',
label: '손이 빌 때까지 대신 받기',
caption: '대신 받아 줍니다 — 상대의 말을 읽으면서 도중에 넘겨받을 수 있습니다.',
+ href: '/ko/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice의 통화 녹음 공유 — 비공개·초대 전용·링크를 아는 누구나 중에서 고르고 발신자 정보는 가려집니다',
label: '녹음은 링크로 공유',
caption: '모든 통화가 녹음되고 글로 남습니다. 링크로 보내고, 누가 들을지 정하세요.',
+ href: '/ko/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/zh-hant/index.astro b/src/pages/zh-hant/index.astro
index a357083..60fa128 100644
--- a/src/pages/zh-hant/index.astro
+++ b/src/pages/zh-hant/index.astro
@@ -20,18 +20,21 @@ const heroShots = [
alt: 'WaveKat Voice 裡的通話流程圖——問候語、營業時間判斷、響你的桌面,最後是留言',
label: '通話流程',
caption: '問候語、營業時間、響你的桌面,再到留言——畫成一張流程圖。',
+ href: '/zh-hant/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice 的通話流程正在錄留言,旁邊是即時文字稿和一個接聽按鈕',
label: '你忙不過來時它來接',
caption: '它替你接聽——一邊看對方在說什麼,一邊隨時把電話接過來。',
+ href: '/zh-hant/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice 分享通話錄音——可選私密、僅限受邀者或任何人可開啟,並對來電者身分做遮蔽',
label: '錄音隨時可分享',
caption: '每通電話都錄音並寫成文字。用一條連結發出去,還能決定誰能聽。',
+ href: '/zh-hant/blog/share-a-call-recording/',
},
];
diff --git a/src/pages/zh/index.astro b/src/pages/zh/index.astro
index 0040d7b..654a022 100644
--- a/src/pages/zh/index.astro
+++ b/src/pages/zh/index.astro
@@ -19,18 +19,21 @@ const heroShots = [
alt: 'WaveKat Voice 里的来电流程图——问候语、营业时间判断、响你的桌面,最后是留言',
label: '来电流程',
caption: '问候语、营业时间、响你的桌面,再到留言——画成一张流程图。',
+ href: '/zh/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'flow-takeover',
alt: 'WaveKat Voice 的来电流程正在录留言,旁边是实时文字稿和一个接听按钮',
label: '你忙不过来时它来接',
caption: '它替你接听——一边看对方在说什么,一边随时把电话接过来。',
+ href: '/zh/blog/answer-calls-with-a-call-flow/',
},
{
scene: 'share-sheet',
alt: 'WaveKat Voice 分享通话录音——可选私密、仅限受邀者或任何人可打开,并对来电者身份做脱敏',
label: '录音随时可分享',
caption: '每通电话都录音并写成文字。用一条链接发出去,还能决定谁能听。',
+ href: '/zh/blog/share-a-call-recording/',
},
];