831 lines
20 KiB
Vue
831 lines
20 KiB
Vue
<script setup>
|
||
import { ref } from 'vue'
|
||
import { corpProfiles } from '../../data/corpProfiles'
|
||
|
||
const c = corpProfiles.tech
|
||
const stars = ref(48217)
|
||
const starred = ref(false)
|
||
function toggleStar() {
|
||
starred.value = !starred.value
|
||
stars.value += starred.value ? 1 : -1
|
||
}
|
||
const repos = [
|
||
{ name: 'qleap-runtime', desc: '端侧推理运行时,3 行代码部署模型', lang: 'C++', star: '21.4k', upd: 'yesterday' },
|
||
{ name: 'qleap-compiler', desc: '模型编译器,自动算子融合与量化', lang: 'Rust', star: '12.8k', upd: '3 days ago' },
|
||
{ name: 'awesome-edge-ai', desc: '端侧 AI 资源大全,社区共同维护', lang: 'Markdown', star: '9.6k', upd: 'last week' },
|
||
{ name: 'qleap-examples', desc: '40+ 场景示例:质检 / 座舱 / 无人机', lang: 'Python', star: '4.4k', upd: '2 weeks ago' },
|
||
]
|
||
const langColors = { 'C++': '#f34b7d', Rust: '#dea584', Markdown: '#3b6fb5', Python: '#3572a5' }
|
||
|
||
/* 产品 README 面板:仓库与 cases 一一对应 */
|
||
const rmIdx = ref(-1)
|
||
const rm = ref(null)
|
||
function openReadme(i) {
|
||
rmIdx.value = i
|
||
rm.value = c.cases[i]
|
||
}
|
||
function closeReadme() {
|
||
rmIdx.value = -1
|
||
rm.value = null
|
||
}
|
||
|
||
const starPath =
|
||
'M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z'
|
||
const repoPath =
|
||
'M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z'
|
||
|
||
/* 贡献热力图:确定性伪随机,26 周 × 7 天 */
|
||
const cells = Array.from({ length: 26 * 7 }, (_, i) => {
|
||
const v = (i * 2654435761 + 97) % 97
|
||
return v < 34 ? 0 : v < 58 ? 1 : v < 78 ? 2 : v < 90 ? 3 : 4
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div class="to">
|
||
<nav class="to-nav">
|
||
<b class="to-logo"></> qleap-oss</b>
|
||
<div class="to-menu">
|
||
<a href="#readme">README</a>
|
||
<a href="#repos">仓库</a>
|
||
</div>
|
||
<router-link to="/corp" class="to-back">cd ../合集</router-link>
|
||
</nav>
|
||
|
||
<header class="to-hero">
|
||
<div class="to-term">
|
||
<div class="to-term-bar"><i></i><i></i><i></i><span>bash — qleap</span></div>
|
||
<div class="to-term-body">
|
||
<p><span class="to-p">$</span> npm install @qleap/runtime</p>
|
||
<p class="to-dim">+ @qleap/runtime@3.2.0 · added 1 package in 2.4s</p>
|
||
<p><span class="to-p">$</span> qleap deploy ./model.onnx --target edge</p>
|
||
<p class="to-ok">✓ compiled for X1 · latency 8ms · power 3.2W</p>
|
||
<p><span class="to-p">$</span> <span class="to-cursor">▊</span></p>
|
||
</div>
|
||
</div>
|
||
<div class="to-hero-txt">
|
||
<h1>开源,是我们的<br />第二条产品线</h1>
|
||
<p>{{ c.name }}开源社区 · 让每台设备都跑得起 AI</p>
|
||
<button class="to-star" :class="{ on: starred }" @click="toggleStar">
|
||
<svg class="to-star-ic" viewBox="0 0 16 16" aria-hidden="true"><path :d="starPath" /></svg>
|
||
{{ starred ? 'Starred' : 'Star' }}
|
||
<b>{{ stars.toLocaleString() }}</b>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- README -->
|
||
<section id="readme" class="to-sec">
|
||
<h2 class="to-h2"># README.md</h2>
|
||
<div class="to-readme">
|
||
<div class="to-badges" aria-hidden="true">
|
||
<span class="to-badge"><i>build</i><em class="b-ok">passing</em></span>
|
||
<span class="to-badge"><i>coverage</i><em class="b-cov">94%</em></span>
|
||
<span class="to-badge"><i>license</i><em class="b-lic">MIT</em></span>
|
||
<span class="to-badge"><i>PRs</i><em class="b-prs">welcome</em></span>
|
||
</div>
|
||
<p class="to-md-h">## 为什么做开源</p>
|
||
<p class="to-dim">{{ c.desc }}</p>
|
||
<p class="to-md-h">## 我们提供什么</p>
|
||
<ul>
|
||
<li v-for="s in c.services" :key="s.name"><b>{{ s.name }}</b> — {{ s.desc }}</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 社区脉搏 -->
|
||
<section class="to-sec">
|
||
<h2 class="to-h2"># 社区脉搏</h2>
|
||
<div class="to-graph-wrap">
|
||
<div class="to-graph-days" aria-hidden="true"><span>Mon</span><span>Wed</span><span>Fri</span></div>
|
||
<div class="to-graph" aria-label="贡献热力图">
|
||
<i v-for="(l, i) in cells" :key="i" :data-l="l"></i>
|
||
</div>
|
||
</div>
|
||
<div class="to-graph-note">
|
||
<span>last 26 weeks · 3,842 contributions · 214 contributors · 平均合并耗时 26h</span>
|
||
<span class="to-legend" aria-hidden="true">Less <i data-l="0"></i><i data-l="1"></i><i data-l="2"></i><i data-l="3"></i><i data-l="4"></i> More</span>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 仓库 -->
|
||
<section id="repos" class="to-sec">
|
||
<h2 class="to-h2"># 热门仓库</h2>
|
||
<div class="to-repos">
|
||
<div v-for="(r, i) in repos" :key="r.name" class="to-repo" :style="{ '--i': i }" @click="openReadme(i)">
|
||
<b class="to-repo-name">
|
||
<svg class="to-repo-ic" viewBox="0 0 16 16" aria-hidden="true"><path :d="repoPath" /></svg>
|
||
{{ r.name }}
|
||
<em>Public</em>
|
||
</b>
|
||
<p>{{ r.desc }}</p>
|
||
<div class="to-repo-meta">
|
||
<span class="to-lang"><i :style="{ background: langColors[r.lang] }"></i>{{ r.lang }}</span>
|
||
<span class="to-repo-star"><svg viewBox="0 0 16 16" aria-hidden="true"><path :d="starPath" /></svg>{{ r.star }}</span>
|
||
<span>Updated {{ r.upd }}</span>
|
||
<span class="to-repo-more">$ cat README →</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 产品 README 面板 -->
|
||
<Transition name="to-cat">
|
||
<div v-if="rm" class="to-mask" @click.self="closeReadme">
|
||
<article class="to-panel">
|
||
<div class="to-panel-bar">
|
||
<span class="to-panel-path">{{ repos[rmIdx].name }} / <b>README.md</b></span>
|
||
<button class="to-panel-x" aria-label="关闭" @click="closeReadme">✕</button>
|
||
</div>
|
||
<div class="to-panel-body">
|
||
<p class="to-panel-h1"># {{ rm.name }}</p>
|
||
<div class="to-badges" aria-hidden="true">
|
||
<span class="to-badge"><i>type</i><em class="b-lic">{{ rm.tag }}</em></span>
|
||
<span class="to-badge"><i>build</i><em class="b-ok">passing</em></span>
|
||
<span class="to-badge"><i>PRs</i><em class="b-prs">welcome</em></span>
|
||
</div>
|
||
<img class="to-panel-img" :src="rm.image" :alt="rm.name" />
|
||
<p class="to-md-h">## 这是什么</p>
|
||
<p class="to-panel-story">{{ rm.story }}</p>
|
||
<p class="to-md-h">## Features</p>
|
||
<ul class="to-panel-feats">
|
||
<li v-for="h in rm.highlights" :key="h"><span class="to-p">-</span> {{ h }}</li>
|
||
</ul>
|
||
<p class="to-md-h">## Changelog</p>
|
||
<div class="to-panel-log">
|
||
<p v-for="t in rm.timeline" :key="t.at"><span class="to-panel-commit" aria-hidden="true">●</span><i>{{ t.at }}</i>{{ t.event }}</p>
|
||
</div>
|
||
<p class="to-md-h">## Benchmarks</p>
|
||
<div class="to-panel-mx">
|
||
<div v-for="m in rm.metrics" :key="m.label"><b>{{ m.value }}</b><span>{{ m.label }}</span></div>
|
||
</div>
|
||
<p class="to-panel-eof">// EOF · MIT License · star 一下再走呗 ⭐</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</Transition>
|
||
|
||
<section class="to-sec">
|
||
<div class="to-stats-term">
|
||
<p class="to-stats-cmd"><span class="to-p">$</span> qleap stats --org --human</p>
|
||
<div class="to-stats">
|
||
<div v-for="(s, i) in c.stats" :key="s.label" :style="{ '--i': i }"><b>{{ s.value }}</b><span>{{ s.label }}</span></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer class="to-footer">
|
||
<p class="to-dim">// {{ c.name }} {{ c.nameEn }} · {{ c.contacts.email }} · {{ c.contacts.addr }}</p>
|
||
<p class="to-links">
|
||
<router-link to="/corp">cd /corp 返回企业合集</router-link>
|
||
<router-link to="/">cd / 个人页面合集</router-link>
|
||
</p>
|
||
<p class="to-copy">© {{ c.founded }}–2026 · MIT License · 风格演示页,公司与仓库均为虚构</p>
|
||
</footer>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.to {
|
||
min-height: 100vh;
|
||
background: #0d1117;
|
||
color: #e6edf3;
|
||
font-family: Consolas, 'Courier New', monospace;
|
||
}
|
||
|
||
@keyframes to-fade {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(6px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: none;
|
||
}
|
||
}
|
||
|
||
.to-nav {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 40;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 22px;
|
||
padding: 13px clamp(16px, 5vw, 48px);
|
||
background: rgba(13, 17, 23, 0.95);
|
||
backdrop-filter: blur(6px);
|
||
border-bottom: 1px solid #30363d;
|
||
}
|
||
.to-logo {
|
||
font-size: 15px;
|
||
color: #3fb950;
|
||
}
|
||
.to-menu {
|
||
display: flex;
|
||
gap: 18px;
|
||
}
|
||
.to-menu a {
|
||
color: #8b949e;
|
||
text-decoration: none;
|
||
font-size: 13px;
|
||
}
|
||
.to-menu a:hover {
|
||
color: #58a6ff;
|
||
}
|
||
@media (max-width: 600px) {
|
||
.to-menu {
|
||
display: none;
|
||
}
|
||
}
|
||
.to-back {
|
||
margin-left: auto;
|
||
color: #0d1117;
|
||
background: #3fb950;
|
||
text-decoration: none;
|
||
font-size: 12.5px;
|
||
font-weight: 700;
|
||
padding: 6px 14px;
|
||
border-radius: 6px;
|
||
}
|
||
.to-back:hover {
|
||
background: #56d364;
|
||
}
|
||
|
||
.to-hero {
|
||
max-width: 1060px;
|
||
margin: 0 auto;
|
||
display: grid;
|
||
grid-template-columns: 1.1fr 0.9fr;
|
||
gap: 34px;
|
||
align-items: center;
|
||
padding: clamp(44px, 7vw, 80px) clamp(16px, 4vw, 26px) 56px;
|
||
}
|
||
.to-term {
|
||
background: #010409;
|
||
border: 1px solid #30363d;
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
|
||
animation: to-fade 0.6s 0.05s both;
|
||
}
|
||
.to-term-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 7px;
|
||
padding: 10px 14px;
|
||
background: #161b22;
|
||
border-bottom: 1px solid #30363d;
|
||
}
|
||
.to-term-bar i {
|
||
width: 11px;
|
||
height: 11px;
|
||
border-radius: 50%;
|
||
}
|
||
.to-term-bar i:nth-child(1) { background: #ff5f57; }
|
||
.to-term-bar i:nth-child(2) { background: #febc2e; }
|
||
.to-term-bar i:nth-child(3) { background: #28c840; }
|
||
.to-term-bar span {
|
||
margin-left: 8px;
|
||
font-size: 11px;
|
||
color: #8b949e;
|
||
}
|
||
.to-term-body {
|
||
padding: 18px 18px 22px;
|
||
font-size: 13px;
|
||
line-height: 2;
|
||
}
|
||
.to-term-body p {
|
||
margin: 0;
|
||
}
|
||
.to-p {
|
||
color: #3fb950;
|
||
margin-right: 8px;
|
||
}
|
||
.to-dim {
|
||
color: #8b949e;
|
||
}
|
||
.to-ok {
|
||
color: #3fb950;
|
||
}
|
||
.to-cursor {
|
||
animation: to-blink 1s step-end infinite;
|
||
}
|
||
@keyframes to-blink {
|
||
50% { opacity: 0; }
|
||
}
|
||
|
||
.to-hero-txt {
|
||
animation: to-fade 0.6s 0.15s both;
|
||
}
|
||
.to-hero-txt h1 {
|
||
margin: 0 0 14px;
|
||
font-size: clamp(28px, 4.6vw, 44px);
|
||
line-height: 1.25;
|
||
color: #e6edf3;
|
||
}
|
||
.to-hero-txt p {
|
||
margin: 0 0 24px;
|
||
font-size: 14px;
|
||
color: #8b949e;
|
||
}
|
||
.to-star {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
background: #21262d;
|
||
border: 1px solid #30363d;
|
||
color: #e6edf3;
|
||
font-family: inherit;
|
||
font-size: 14px;
|
||
padding: 10px 20px;
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
transition: all 0.18s ease;
|
||
}
|
||
.to-star:hover {
|
||
border-color: #8b949e;
|
||
}
|
||
.to-star.on {
|
||
color: #e3b341;
|
||
border-color: #e3b341;
|
||
}
|
||
.to-star-ic {
|
||
width: 16px;
|
||
height: 16px;
|
||
fill: none;
|
||
stroke: currentColor;
|
||
stroke-width: 1;
|
||
}
|
||
.to-star.on .to-star-ic {
|
||
fill: #e3b341;
|
||
stroke: #e3b341;
|
||
animation: to-pop 0.35s ease;
|
||
}
|
||
@keyframes to-pop {
|
||
40% {
|
||
transform: scale(1.4) rotate(-10deg);
|
||
}
|
||
}
|
||
.to-star b {
|
||
background: #30363d;
|
||
padding: 2px 10px;
|
||
border-radius: 99px;
|
||
font-size: 13px;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.to-sec {
|
||
max-width: 1060px;
|
||
margin: 0 auto 52px;
|
||
padding: 0 clamp(16px, 4vw, 26px);
|
||
}
|
||
.to-h2 {
|
||
font-size: 19px;
|
||
color: #58a6ff;
|
||
margin: 0 0 18px;
|
||
}
|
||
|
||
.to-readme {
|
||
background: #161b22;
|
||
border: 1px solid #30363d;
|
||
border-radius: 10px;
|
||
padding: 24px 26px;
|
||
font-size: 13.5px;
|
||
line-height: 2;
|
||
}
|
||
.to-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
margin-bottom: 18px;
|
||
}
|
||
.to-badge {
|
||
display: inline-flex;
|
||
font-size: 11px;
|
||
line-height: 1;
|
||
border-radius: 3px;
|
||
overflow: hidden;
|
||
}
|
||
.to-badge i {
|
||
font-style: normal;
|
||
background: #21262d;
|
||
color: #c9d1d9;
|
||
padding: 4.5px 7px;
|
||
}
|
||
.to-badge em {
|
||
font-style: normal;
|
||
font-weight: 700;
|
||
color: #0d1117;
|
||
padding: 4.5px 7px;
|
||
}
|
||
.to-badge .b-ok { background: #3fb950; }
|
||
.to-badge .b-cov { background: #58a6ff; }
|
||
.to-badge .b-lic { background: #d2a8ff; }
|
||
.to-badge .b-prs { background: #e3b341; }
|
||
.to-readme p {
|
||
margin: 0 0 8px;
|
||
}
|
||
.to-md-h {
|
||
color: #d2a8ff;
|
||
font-weight: 700;
|
||
border-bottom: 1px solid #21262d;
|
||
padding-bottom: 6px;
|
||
margin: 0 0 10px;
|
||
}
|
||
.to-readme .to-md-h + p {
|
||
margin-bottom: 18px;
|
||
}
|
||
.to-readme ul {
|
||
margin: 0;
|
||
padding-left: 22px;
|
||
color: #8b949e;
|
||
}
|
||
.to-readme li {
|
||
margin-bottom: 8px;
|
||
}
|
||
.to-readme li b {
|
||
font-weight: 400;
|
||
color: #79c0ff;
|
||
background: #21262d;
|
||
padding: 1px 7px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.to-graph-wrap {
|
||
display: flex;
|
||
gap: 8px;
|
||
padding: 14px;
|
||
border: 1px solid #30363d;
|
||
border-radius: 8px;
|
||
background: #0a0e14;
|
||
overflow-x: auto;
|
||
}
|
||
.to-graph-days {
|
||
display: grid;
|
||
grid-template-rows: repeat(7, 12px);
|
||
gap: 3px;
|
||
font-size: 9.5px;
|
||
color: #8b949e;
|
||
}
|
||
.to-graph-days span:nth-child(1) { grid-row: 2; }
|
||
.to-graph-days span:nth-child(2) { grid-row: 4; }
|
||
.to-graph-days span:nth-child(3) { grid-row: 6; }
|
||
.to-graph {
|
||
display: grid;
|
||
grid-template-rows: repeat(7, 12px);
|
||
grid-auto-flow: column;
|
||
grid-auto-columns: 12px;
|
||
gap: 3px;
|
||
}
|
||
.to-graph i {
|
||
border-radius: 2.5px;
|
||
background: #161b22;
|
||
transition: transform 0.12s ease, box-shadow 0.12s ease;
|
||
}
|
||
.to-graph i:hover {
|
||
transform: scale(1.3);
|
||
box-shadow: 0 0 0 1px rgba(230, 237, 243, 0.4);
|
||
}
|
||
.to-graph i[data-l='1'], .to-legend i[data-l='1'] { background: #0e4429; }
|
||
.to-graph i[data-l='2'], .to-legend i[data-l='2'] { background: #006d32; }
|
||
.to-graph i[data-l='3'], .to-legend i[data-l='3'] { background: #26a641; }
|
||
.to-graph i[data-l='4'], .to-legend i[data-l='4'] { background: #39d353; }
|
||
.to-graph-note {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
margin: 10px 2px 0;
|
||
font-size: 11.5px;
|
||
color: #8b949e;
|
||
}
|
||
.to-legend {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
}
|
||
.to-legend i {
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 2px;
|
||
background: #161b22;
|
||
}
|
||
|
||
/* 仓库:GitHub 列表行 */
|
||
.to-repos {
|
||
border: 1px solid #30363d;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
.to-repo {
|
||
padding: 16px 20px;
|
||
border-bottom: 1px solid #21262d;
|
||
transition: background 0.15s ease;
|
||
animation: to-fade 0.5s calc(var(--i) * 0.07s) both;
|
||
}
|
||
.to-repo:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.to-repo:hover {
|
||
background: #161b22;
|
||
}
|
||
.to-repo-name {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
color: #58a6ff;
|
||
font-size: 14.5px;
|
||
}
|
||
.to-repo:hover .to-repo-name {
|
||
text-decoration: underline;
|
||
}
|
||
.to-repo-ic {
|
||
width: 16px;
|
||
height: 16px;
|
||
fill: #8b949e;
|
||
flex: none;
|
||
}
|
||
.to-repo-name em {
|
||
font-style: normal;
|
||
font-size: 10.5px;
|
||
font-weight: 400;
|
||
color: #8b949e;
|
||
border: 1px solid #30363d;
|
||
border-radius: 999px;
|
||
padding: 1px 8px;
|
||
text-decoration: none;
|
||
}
|
||
.to-repo p {
|
||
margin: 8px 0 12px;
|
||
font-size: 12.5px;
|
||
line-height: 1.8;
|
||
color: #8b949e;
|
||
}
|
||
.to-repo-meta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16px;
|
||
font-size: 12px;
|
||
color: #8b949e;
|
||
}
|
||
.to-lang {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.to-lang i {
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 50%;
|
||
}
|
||
.to-repo-star {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.to-repo-star svg {
|
||
width: 13px;
|
||
height: 13px;
|
||
fill: currentColor;
|
||
}
|
||
|
||
/* 组织统计:终端输出 */
|
||
.to-stats-term {
|
||
background: #010409;
|
||
border: 1px solid #30363d;
|
||
border-radius: 10px;
|
||
padding: 16px 18px 18px;
|
||
}
|
||
.to-stats-cmd {
|
||
margin: 0 0 14px;
|
||
font-size: 13px;
|
||
}
|
||
.to-stats {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||
gap: 10px 0;
|
||
}
|
||
.to-stats > div {
|
||
border-left: 2px solid #21262d;
|
||
padding: 2px 16px;
|
||
animation: to-fade 0.5s calc(0.15s + var(--i) * 0.08s) both;
|
||
}
|
||
.to-stats b {
|
||
display: block;
|
||
font-size: clamp(20px, 3.4vw, 26px);
|
||
color: #3fb950;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.to-stats span {
|
||
font-size: 11.5px;
|
||
color: #8b949e;
|
||
}
|
||
.to-stats span::before {
|
||
content: '# ';
|
||
color: #484f58;
|
||
}
|
||
|
||
.to-footer {
|
||
border-top: 1px solid #30363d;
|
||
text-align: center;
|
||
padding: 28px 20px 40px;
|
||
font-size: 12.5px;
|
||
}
|
||
.to-footer p {
|
||
margin: 0 0 10px;
|
||
}
|
||
.to-links a {
|
||
color: #58a6ff;
|
||
text-decoration: none;
|
||
margin: 0 12px;
|
||
}
|
||
.to-links a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
.to-copy {
|
||
font-size: 11px;
|
||
color: #484f58;
|
||
}
|
||
|
||
@media (max-width: 820px) {
|
||
.to-hero {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
/* ---- 产品 README 面板 ---- */
|
||
.to-repo {
|
||
cursor: pointer;
|
||
}
|
||
.to-repo-more {
|
||
margin-left: auto;
|
||
color: #3fb950;
|
||
opacity: 0;
|
||
transition: opacity 0.2s ease;
|
||
}
|
||
.to-repo:hover .to-repo-more {
|
||
opacity: 1;
|
||
}
|
||
.to-mask {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 520;
|
||
display: grid;
|
||
place-items: center;
|
||
padding: 20px;
|
||
background: rgba(1, 4, 9, 0.8);
|
||
backdrop-filter: blur(4px);
|
||
}
|
||
.to-panel {
|
||
position: relative;
|
||
width: min(640px, 94vw);
|
||
max-height: 88vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background: #0d1117;
|
||
border: 1px solid #30363d;
|
||
border-radius: 10px;
|
||
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.7);
|
||
overflow: hidden;
|
||
}
|
||
.to-panel-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 10px;
|
||
padding: 10px 16px;
|
||
background: #161b22;
|
||
border-bottom: 1px solid #30363d;
|
||
}
|
||
.to-panel-path {
|
||
font-size: 12px;
|
||
color: #8b949e;
|
||
}
|
||
.to-panel-path b {
|
||
color: #58a6ff;
|
||
}
|
||
.to-panel-x {
|
||
width: 28px;
|
||
height: 28px;
|
||
border: 1px solid #30363d;
|
||
border-radius: 6px;
|
||
background: #0d1117;
|
||
color: #8b949e;
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
}
|
||
.to-panel-x:hover {
|
||
color: #e6edf3;
|
||
border-color: #8b949e;
|
||
}
|
||
.to-panel-body {
|
||
padding: 20px 24px 24px;
|
||
overflow-y: auto;
|
||
}
|
||
.to-panel-h1 {
|
||
margin: 0 0 10px;
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
color: #e6edf3;
|
||
border-bottom: 1px solid #30363d;
|
||
padding-bottom: 10px;
|
||
}
|
||
.to-panel-img {
|
||
display: block;
|
||
width: 100%;
|
||
aspect-ratio: 16 / 7;
|
||
object-fit: cover;
|
||
border-radius: 8px;
|
||
border: 1px solid #30363d;
|
||
margin: 12px 0 4px;
|
||
}
|
||
.to-panel-story {
|
||
margin: 0;
|
||
font-size: 13px;
|
||
line-height: 1.9;
|
||
color: #b6c2cf;
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||
}
|
||
.to-panel-feats {
|
||
margin: 0;
|
||
padding: 0;
|
||
list-style: none;
|
||
}
|
||
.to-panel-feats li {
|
||
padding: 3px 0;
|
||
font-size: 12.5px;
|
||
color: #b6c2cf;
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||
}
|
||
.to-panel-feats .to-p {
|
||
font-family: Consolas, monospace;
|
||
margin-right: 8px;
|
||
}
|
||
.to-panel-log p {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 10px;
|
||
margin: 0 0 6px;
|
||
font-size: 12.5px;
|
||
color: #b6c2cf;
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||
}
|
||
.to-panel-commit {
|
||
color: #3fb950;
|
||
font-size: 10px;
|
||
}
|
||
.to-panel-log i {
|
||
flex: 0 0 62px;
|
||
font-style: normal;
|
||
font-family: Consolas, monospace;
|
||
font-size: 11px;
|
||
color: #8b949e;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.to-panel-mx {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 10px;
|
||
margin-top: 4px;
|
||
}
|
||
.to-panel-mx > div {
|
||
background: #161b22;
|
||
border: 1px solid #30363d;
|
||
border-radius: 8px;
|
||
padding: 10px 8px;
|
||
text-align: center;
|
||
}
|
||
.to-panel-mx b {
|
||
display: block;
|
||
font-size: 17px;
|
||
color: #3fb950;
|
||
}
|
||
.to-panel-mx span {
|
||
font-size: 10.5px;
|
||
color: #8b949e;
|
||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||
}
|
||
.to-panel-eof {
|
||
margin: 16px 0 0;
|
||
font-size: 11px;
|
||
color: #484f58;
|
||
}
|
||
.to-cat-enter-active,
|
||
.to-cat-leave-active {
|
||
transition: opacity 0.22s ease;
|
||
}
|
||
.to-cat-enter-active .to-panel,
|
||
.to-cat-leave-active .to-panel {
|
||
transition: transform 0.26s cubic-bezier(0.25, 1.1, 0.4, 1);
|
||
}
|
||
.to-cat-enter-from,
|
||
.to-cat-leave-to {
|
||
opacity: 0;
|
||
}
|
||
.to-cat-enter-from .to-panel,
|
||
.to-cat-leave-to .to-panel {
|
||
transform: translateY(18px) scale(0.97);
|
||
}
|
||
</style>
|