Connect Way Tabs
Three integration option cards act as tabs: the selected card gets an accent border and its arrow turns, the command box below fades to match, and it copies in one click. Good for docs entry points and install guides.
Taken from the page template Qishu Agent Tool Platform Home. Use it on its own, or combine it with the other components from the same template to rebuild the full page.
Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds Connect Way Tabs to your project in your colors.
Where to use it
Site headers, tab switches, segmented controls, side navigation and footers.
Install
With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.
Code
Source for Connect Way Tabs. Motion uses only transform and opacity and respects the Reduce motion setting.
<div class="x-qcw"><section class="qs-connect" id="connect"><div class="qs-wrap qs-connect__in"><h2 class="qs-h2 qs-h2--l">三种接法,<br class="qs-br-m">同一个余额。</h2><div class="qs-ways" role="tablist"><button class="qs-way is-on" type="button" role="tab" aria-selected="true" data-qs-way="0"><span class="qs-way__h"><b>Skill</b><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6-6 6"/></svg></span><span class="qs-way__d">在对话里贴一行</span></button><button class="qs-way" type="button" role="tab" aria-selected="false" data-qs-way="1"><span class="qs-way__h"><b>MCP</b><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6-6 6"/></svg></span><span class="qs-way__d">添加远程服务地址</span></button><button class="qs-way" type="button" role="tab" aria-selected="false" data-qs-way="2"><span class="qs-way__h"><b>CLI</b><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6-6 6"/></svg></span><span class="qs-way__d">在终端里安装运行</span></button></div><div class="qs-panes"><div class="qs-pane is-on" data-qs-pane="0"><div class="qs-cmd qs-cmd--dark"><span class="qs-cmd__p">$</span><code>接入 https://example.com/skill.md</code><button class="qs-cmd__btn" type="button" aria-label="复制" data-qs-copy="接入 https://example.com/skill.md"><span class="i-copy"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></span><span class="i-ok"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span></button></div></div><div class="qs-pane" data-qs-pane="1"><div class="qs-cmd qs-cmd--dark"><span class="qs-cmd__p">$</span><code>mcp add qishu https://example.com/mcp</code><button class="qs-cmd__btn" type="button" aria-label="复制" data-qs-copy="mcp add qishu https://example.com/mcp"><span class="i-copy"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></span><span class="i-ok"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span></button></div></div><div class="qs-pane" data-qs-pane="2"><div class="qs-cmd qs-cmd--dark"><span class="qs-cmd__p">$</span><code>qishu connect --skill example.com/skill.md</code><button class="qs-cmd__btn" type="button" aria-label="复制" data-qs-copy="qishu connect --skill example.com/skill.md"><span class="i-copy"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></span><span class="i-ok"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span></button></div></div></div></div></section></div>
.x-qcw{--acc:#0016D7;--ink:#1c1c1e;--mut:#6e6e73;--line:#ececee;--soft:#fafafa;
--sans:"Inter","PingFang SC","Hiragino Sans GB","Noto Sans CJK SC","Microsoft YaHei",system-ui,sans-serif;
--mono:ui-monospace,"SFMono-Regular","JetBrains Mono",Menlo,Consolas,"DejaVu Sans Mono",monospace;
font-family:var(--sans);color:var(--ink);-webkit-font-smoothing:antialiased;line-height:1.5;width:100%;box-sizing:border-box;text-align:left}.x-qcw *,.x-qcw *::before,.x-qcw *::after{box-sizing:border-box;margin:0;padding:0}.x-qcw a{color:inherit;text-decoration:none}.x-qcw button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}.x-qcw .qs-wrap{max-width:1100px;margin:0 auto;padding:0 24px}.x-qcw .qs-h2{font-size:clamp(30px,4.4vw,52px);font-weight:800;letter-spacing:-.035em;line-height:1.08;text-align:center}.x-qcw .qs-mark{display:inline-grid;grid-template-columns:repeat(2,6px);gap:2px;transform:rotate(45deg);margin:0 2px}.x-qcw .qs-mark i{width:6px;height:6px;border-radius:1.5px;background:currentColor;display:block}.x-qcw .qs-mark i:nth-child(4){opacity:.35}.x-qcw .qs-cmd{display:flex;align-items:center;gap:12px;width:100%;max-width:560px;margin:0 auto;padding:12px 12px 12px 18px;border-radius:10px;font-family:var(--mono);font-size:14px;text-align:left}.x-qcw .qs-cmd code{flex:1;font-family:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.x-qcw .qs-cmd--dark{background:#141416;color:#f2f2f2;box-shadow:0 18px 40px -16px rgba(0,0,0,.45)}.x-qcw .qs-cmd--dark .qs-cmd__p{color:#7c7c84}.x-qcw .qs-cmd--light{background:#fff;color:#1c1c1e;box-shadow:0 18px 40px -14px rgba(0,0,30,.45)}.x-qcw .qs-cmd--light .qs-cmd__p{color:#9a9aa2}.x-qcw .qs-cmd__btn{position:relative;flex:none;width:30px;height:30px;border-radius:7px;background:var(--acc);color:#fff;display:grid;place-items:center;transition:transform .2s}.x-qcw .qs-cmd__btn:hover{transform:scale(1.06)}.x-qcw .qs-cmd__btn:active{transform:scale(.94)}.x-qcw .qs-cmd__btn span{grid-area:1/1;display:grid;transition:opacity .2s,transform .2s}.x-qcw .qs-cmd__btn .i-ok{opacity:0;transform:scale(.6)}.x-qcw .qs-cmd__btn.is-done .i-ok{opacity:1;transform:none}.x-qcw .qs-cmd__btn.is-done .i-copy{opacity:0;transform:scale(.6)}@media (prefers-reduced-motion:reduce){.x-qcw .qs-cmd__btn,.x-qcw .qs-cmd__btn span{transition:none}}.x-qcw .qs-connect{background:var(--soft) radial-gradient(#dcdce3 1px,transparent 1.3px) 0 0/18px 18px;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:104px 0}.x-qcw .qs-connect__in{max-width:1000px}.x-qcw .qs-h2--l{text-align:left}.x-qcw .qs-br-m{display:none}.x-qcw .qs-ways{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:44px}.x-qcw .qs-way{text-align:left;background:#fff;border:1px solid var(--line);border-radius:8px;padding:24px;display:flex;flex-direction:column;gap:8px;transition:border-color .2s,box-shadow .2s,transform .2s}.x-qcw .qs-way:hover{transform:translateY(-2px);box-shadow:0 12px 28px -16px rgba(0,0,40,.25)}.x-qcw .qs-way.is-on{border-color:var(--acc);box-shadow:0 0 0 1px var(--acc)}.x-qcw .qs-way__h{display:flex;justify-content:space-between;align-items:center}.x-qcw .qs-way__h b{font-size:19px;font-weight:700}.x-qcw .qs-way__h svg{width:16px;height:16px;color:#8a8a90;transition:transform .2s}.x-qcw .qs-way.is-on .qs-way__h svg{transform:rotate(90deg);color:var(--acc)}.x-qcw .qs-way__d{font-size:14px;color:var(--mut)}.x-qcw .qs-panes{position:relative;margin-top:20px;min-height:56px}.x-qcw .qs-pane{position:absolute;inset:0 0 auto 0;opacity:0;transform:translateY(6px);pointer-events:none;transition:opacity .3s,transform .3s}.x-qcw .qs-pane.is-on{position:relative;opacity:1;transform:none;pointer-events:auto}.x-qcw .qs-pane .qs-cmd{max-width:none}@media (max-width:760px){.x-qcw .qs-connect{padding:80px 0}.x-qcw .qs-ways{grid-template-columns:1fr}.x-qcw .qs-br-m{display:inline}}@media (prefers-reduced-motion:reduce){.x-qcw .qs-way,.x-qcw .qs-pane,.x-qcw .qs-way__h svg{transition:none}}.x-qcw .qs-connect{padding:96px 0;border:0;min-height:min(860px,96vh);display:flex;flex-direction:column;justify-content:center;}
(root) => {
const el = (root.classList && root.classList.contains('x-qcw')) ? root : (root.querySelector('.x-qcw') || root);
const offs = [];
const ways = [...el.querySelectorAll('[data-qs-way]')], panes = [...el.querySelectorAll('[data-qs-pane]')];
ways.forEach((w) => {
const on = () => {
const k = w.getAttribute('data-qs-way');
ways.forEach((x) => { const a = x === w; x.classList.toggle('is-on', a); x.setAttribute('aria-selected', a ? 'true' : 'false'); });
panes.forEach((p) => p.classList.toggle('is-on', p.getAttribute('data-qs-pane') === k));
};
w.addEventListener('click', on); offs.push(() => w.removeEventListener('click', on));
});
…