Skip to content

Commit c426fb0

Browse files
authored
Merge pull request #413 from labstack/kapa-ask-ai
feat(docs): themed 'Ask AI' header pill (kapa.ai)
2 parents bd0f4b9 + 12ab4ca commit c426fb0

8 files changed

Lines changed: 61 additions & 175 deletions

File tree

site/astro.config.mjs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ export default defineConfig({
3131
lastUpdated: true,
3232
// Echo "E" cube mark; .ico kept as legacy fallback, apple-touch-icon added in head.
3333
favicon: '/favicon.svg',
34-
// Keep Starlight's built-in Pagefind ⌘K search; add Ask Echo + DocActions via overrides.
34+
// Keep Starlight's built-in Pagefind ⌘K search; Search override adds the
35+
// empty-state launchpad. "Ask AI" is the kapa.ai widget (see head).
3536
components: {
3637
Footer: './src/components/Footer.astro',
37-
PageTitle: './src/components/PageTitle.astro',
3838
Search: './src/components/Search.astro',
3939
},
4040
head: [
@@ -45,6 +45,30 @@ export default defineConfig({
4545
content:
4646
"window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-H19TMZLQFN',{anonymize_ip:true});",
4747
},
48+
// kapa.ai "Ask AI" widget — real answers from the indexed Echo docs.
49+
// We hide kapa's default floating launcher and open the modal from our
50+
// own "Ask AI" pill in the header (see Search.astro) so the trigger
51+
// matches the Terminal chrome instead of kapa's stock button.
52+
{
53+
tag: 'script',
54+
attrs: {
55+
async: true,
56+
src: 'https://widget.kapa.ai/kapa-widget.bundle.js',
57+
'data-website-id': '3ff47090-a571-4c4a-bec0-c0a377028db5',
58+
'data-project-name': 'Echo',
59+
// Modal header title (defaults to "Echo Docs AI" from the project name).
60+
'data-modal-title': 'Ask AI',
61+
'data-project-color': '#00afd1',
62+
// Modal header logo — the same sparkle as the "Ask AI" header pill
63+
// (not the Echo cube). The floating launcher that also used this is hidden.
64+
'data-project-logo': '/ask-ai.svg',
65+
// Sync the widget's light/dark with the site (we set data-theme on <html>).
66+
'data-color-scheme-selector': "[data-theme='dark']",
67+
// Hide the stock floating button; kapa wires clicks on our header pill.
68+
'data-button-hide': 'true',
69+
'data-modal-override-open-selector': '#echo-ask-ai',
70+
},
71+
},
4872
// Dark-first: default new visitors to dark unless they've chosen otherwise.
4973
{
5074
tag: 'script',

site/public/ask-ai.svg

Lines changed: 1 addition & 0 deletions
Loading

site/src/components/AskEcho.astro

Lines changed: 0 additions & 110 deletions
This file was deleted.

site/src/components/DocActions.astro

Lines changed: 0 additions & 8 deletions
This file was deleted.

site/src/components/Footer.astro

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
---
22
import Default from '@astrojs/starlight/components/Footer.astro';
3-
import AskEcho from './AskEcho.astro';
43
54
const year = new Date().getFullYear();
65
---
76
<Default><slot /></Default>
8-
<AskEcho />
97
<footer class="echo-docfoot">
108
<span{year} LabStack LLC. Released under the MIT License.</span>
119
<div class="echo-social">

site/src/components/PageTitle.astro

Lines changed: 0 additions & 6 deletions
This file was deleted.

site/src/components/Search.astro

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
---
22
import Default from '@astrojs/starlight/components/Search.astro';
33
---
4-
<Default />
4+
<div class="echo-search-row">
5+
<Default />
6+
{/* Opens the kapa.ai modal — wired via data-modal-override-open-selector in astro.config. */}
7+
<button id="echo-ask-ai" class="echo-ask-ai" type="button" aria-label="Ask AI about Echo">
8+
<i class="ph ph-sparkle" aria-hidden="true"></i>
9+
<span class="echo-ask-ai__label">Ask AI</span>
10+
</button>
11+
</div>
512

613
<script>
714
// Command-palette empty state: inject quick links + a shortcut footer into the

site/src/styles/terminal.css

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,32 @@
8787
/* search box (chrome) */
8888
site-search button { border-radius: 8px !important; }
8989

90+
/* "Ask AI" pill — opens the kapa.ai modal (Search.astro + astro.config). Sits
91+
beside the search box and mirrors its chrome (40px, dark, 8px radius) so the
92+
two read as one control group. Cyan sparkle marks it as the AI entrypoint. */
93+
.echo-search-row { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
94+
/* site-search is display:contents, so size its actual trigger button: let it grow
95+
to fill the row (capped at Starlight's 352px max-width, restoring its old size). */
96+
.echo-search-row site-search button { flex: 1 1 auto; }
97+
.echo-ask-ai {
98+
display: inline-flex; align-items: center; gap: 7px; flex: none;
99+
height: 40px; padding: 0 14px; cursor: pointer; white-space: nowrap;
100+
border: 1px solid var(--sl-color-gray-5); border-radius: 8px;
101+
background: var(--sl-color-black); color: var(--sl-color-text);
102+
font-family: var(--sl-font-mono); font-size: 0.8125rem; font-weight: 500; line-height: 1;
103+
transition: border-color .15s, background .15s, color .15s;
104+
}
105+
.echo-ask-ai i { font-size: 1rem; color: var(--echo-cyan-text); transition: color .15s; }
106+
.echo-ask-ai:hover, .echo-ask-ai:focus-visible {
107+
border-color: var(--echo-cyan); background: var(--echo-soft);
108+
color: var(--sl-color-white); outline: none;
109+
}
110+
/* Tight headers (mobile): drop the label, keep the sparkle as an icon button. */
111+
@media (max-width: 50rem) {
112+
.echo-ask-ai { padding: 0 11px; }
113+
.echo-ask-ai__label { display: none; }
114+
}
115+
90116
/* Empty search modal: a command-palette launchpad (quick links + shortcut
91117
footer) injected by Search.astro, shown only before a query exists. Pagefind
92118
marks the results drawer .pagefind-ui__hidden when empty. */
@@ -154,52 +180,6 @@ site-search button { border-radius: 8px !important; }
154180
.expressive-code .copy button:hover { background: color-mix(in srgb, var(--echo-cyan) 16%, transparent); }
155181
.expressive-code .copy button:hover::after { background-color: var(--echo-cyan-2) !important; } /* icon glyph */
156182

157-
/* ---------- Doc action toolbar ---------- */
158-
.doc-actions { display: flex; flex-wrap: wrap; gap: 7px; margin: 4px 0 4px; }
159-
.doc-act {
160-
display: inline-flex; align-items: center; gap: 6px; font-family: var(--sl-font-mono);
161-
font-size: 0.72rem; color: var(--sl-color-gray-3); border: 1px solid var(--sl-color-hairline-light);
162-
background: var(--sl-color-bg-sidebar); border-radius: 7px; padding: 5px 11px; cursor: pointer;
163-
line-height: 1; text-decoration: none; transition: all .15s;
164-
}
165-
.doc-act:hover { color: var(--sl-color-white); border-color: var(--echo-cyan); text-decoration: none; }
166-
.doc-act .ph { font-size: 14px; }
167-
.doc-act--primary { background: var(--echo-soft); border-color: transparent; color: var(--echo-cyan-text); }
168-
169-
/* ---------- Ask Echo (island) ---------- */
170-
.ask-fab {
171-
position: fixed; right: 22px; bottom: 22px; z-index: 999; display: inline-flex; align-items: center; gap: 8px;
172-
background: var(--sl-color-bg-sidebar); border: 1px solid var(--sl-color-hairline-light); color: var(--sl-color-white);
173-
border-radius: 30px; padding: 9px 16px; font-family: var(--sl-font-mono); font-size: 0.78rem; cursor: pointer;
174-
box-shadow: 0 14px 34px -12px rgba(0,0,0,.7);
175-
}
176-
.ask-fab:hover { border-color: var(--echo-cyan); }
177-
.ask-fab .ph { color: var(--echo-cyan-text); font-size: 16px; }
178-
.ask-fab kbd { background: var(--sl-color-hairline); border: 1px solid var(--sl-color-hairline-light); border-radius: 5px; padding: 1px 6px; font-size: 0.7rem; color: var(--sl-color-gray-4); }
179-
.ask-overlay { position: fixed; inset: 0; z-index: 1000; background: rgba(6,5,5,.66); backdrop-filter: blur(6px); display: flex; align-items: flex-start; justify-content: center; padding-top: 11vh; }
180-
.ask-overlay[hidden] { display: none; }
181-
.ask-fab[hidden] { display: none; }
182-
.ask-palette { width: min(660px, 92vw); background: var(--sl-color-bg-sidebar); border: 1px solid var(--sl-color-hairline-light); border-radius: 16px; overflow: hidden; box-shadow: 0 40px 120px -30px rgba(0,0,0,.9); font-family: var(--sl-font-mono); }
183-
.ask-top { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--sl-color-hairline); }
184-
.ask-top .ph { color: var(--echo-cyan-text); font-size: 19px; }
185-
.ask-input { flex: 1; background: none; border: 0; outline: none; color: var(--sl-color-white); font-size: 15px; font-family: var(--sl-font-mono); }
186-
.ask-input::placeholder { color: var(--sl-color-gray-4); }
187-
.ask-esc { font-size: 0.7rem; color: var(--sl-color-gray-4); border: 1px solid var(--sl-color-hairline-light); border-radius: 6px; padding: 3px 7px; }
188-
.ask-body { max-height: 54vh; overflow-y: auto; padding: 12px 16px 16px; }
189-
.ask-s { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; padding: 10px 11px; border: 0; background: none; border-radius: 8px; color: var(--sl-color-gray-3); font-size: 13px; cursor: pointer; font-family: var(--sl-font-mono); }
190-
.ask-s:hover { background: var(--sl-color-hairline); color: var(--sl-color-white); }
191-
.ask-s .ph { font-size: 17px; color: var(--echo-cyan-text); }
192-
.ask-badge { display: inline-flex; align-items: center; gap: 8px; font-size: 0.7rem; color: var(--echo-cyan-text); background: var(--echo-soft); border-radius: 20px; padding: 4px 11px; margin-bottom: 13px; }
193-
.ask-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--echo-cyan); animation: askb 1.2s infinite; }
194-
@keyframes askb { 50% { opacity: .3; } }
195-
.ask-answer { font-size: 13.5px; line-height: 1.7; color: var(--sl-color-text); }
196-
.ask-answer strong { color: var(--sl-color-white); }
197-
.ask-answer pre { margin: 12px 0; background: #0a0908; border: 1px solid var(--sl-color-hairline); border-radius: 9px; padding: 14px 16px; overflow-x: auto; font-size: 12.5px; }
198-
.ask-cursor { display: inline-block; width: 7px; height: 15px; background: var(--echo-cyan); vertical-align: -2px; animation: askb .9s infinite; }
199-
.ask-sources { margin-top: 16px; border-top: 1px solid var(--sl-color-hairline); padding-top: 12px; }
200-
.ask-sources h5 { font-size: 0.62rem; text-transform: uppercase; letter-spacing: .1em; color: var(--sl-color-gray-4); margin-bottom: 8px; }
201-
.ask-src { display: flex; gap: 9px; padding: 6px 8px; border-radius: 7px; color: var(--sl-color-gray-3); font-size: 12.5px; }
202-
.ask-n { font-size: 0.7rem; color: var(--echo-cyan-text); border: 1px solid var(--sl-color-hairline-light); border-radius: 5px; padding: 1px 6px; }
203183

204184
/* ---------- Homepage ---------- */
205185
.hero { padding-block: 3rem 1rem; }

0 commit comments

Comments
 (0)