From a5374d0163b0c9ce22ec24fef812d53a1f5beb5d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 26 Jul 2026 09:36:51 +0000 Subject: [PATCH] feat(home): link hero carousel screenshots to their blog posts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The flow-detail/flow-takeover and share-sheet slides each have a full writeup already (answer-calls-with-a-call-flow, share-a-call-recording). Wraps the shot and its label in a link to that post — localized per locale — when the carousel data supplies one, so the hero drives real traffic instead of just describing the feature. Optional and additive: shots without an href render exactly as before. --- src/components/HeroCarousel.astro | 77 +++++++++++++++++++++++-------- src/pages/de/index.astro | 3 ++ src/pages/es/index.astro | 3 ++ src/pages/fr/index.astro | 3 ++ src/pages/index.astro | 3 ++ src/pages/it/index.astro | 3 ++ src/pages/ja/index.astro | 3 ++ src/pages/ko/index.astro | 3 ++ src/pages/zh-hant/index.astro | 3 ++ src/pages/zh/index.astro | 3 ++ 10 files changed, 84 insertions(+), 20 deletions(-) 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) => ( - {shot.alt} - )) + shots.map((shot, i) => { + const img = ( + {shot.alt} + ); + 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/', }, ];