第二版更改

This commit is contained in:
2026-09-24 00:25:24 +08:00
parent 7548d2d913
commit 66fe52c0ef
26 changed files with 1162 additions and 1725 deletions
+25 -24
View File
@@ -1,6 +1,6 @@
# ΣDOCS · Simba Robotics
黑龙江大学 Simba 战队的文档站,基于 Astro 7 与 Starlight。首页复用 Simba 主站的黑红视觉、机器人实拍、Logo 和小组图标;文章页保留 Starlight 的侧栏、页内目录、搜索、浅色 / 深色主题与语言切换。
黑龙江大学 Simba 战队的文档站,基于 Astro 7 与 Starlight。首页与文章统一使用 Starlight 默认文档框架,保留侧栏、页内目录、搜索、代码复制、深浅主题与语言切换。
## 本地运行
@@ -12,46 +12,47 @@ npm run astro -- dev logs
npm run astro -- dev stop
```
中文首页:`http://localhost:4321/zh-cn/`,英文首页:`/en/`,根路径跳转到中文首页。
中文首页:`http://localhost:4321/zh-cn/`,英文首页:`/en/`。根路径跳转到中文首页。
生产构建使用 `npm run build`,产物在 `dist/`。`npm run preview` 可验证生产版本与 Pagefind 搜索;开发模式中的搜索由 Starlight 显示开发提示。正式部署时,在 `astro.config.mjs` 设置实际 `site` 域名,以生成 sitemap。
`npm run build` 生成 `dist/`,`npm run preview` 验证生产版本和 Pagefind 搜索。正式部署时,在 `astro.config.mjs` 设置实际 `site` 域名,以生成 sitemap。
## 从哪里修改
## 编写与维护
文档支持 `.md` 与 `.mdx`:普通文章可以直接使用 Markdown;需要组件时使用 MDX,在 frontmatter 后导入 Starlight 或项目内的 Astro 组件。可按内容使用卡片、步骤、标签页等任意组件,使用其他前端框架的组件前需安装对应的 Astro 集成。提示信息也可直接使用 `:::note` / `:::tip` / `:::caution` / `:::danger` 语法。
| 内容 | 文件 / 目录 |
| --- | --- |
| 首页布局与中英文文案 | `src/components/Home.astro` |
| 首页卡片、描述和链接 | `src/data/home.ts` |
| 首页样式 | `src/styles/home.css` |
| 文档主题与品牌 | `src/styles/custom.css`、`src/components/SiteTitle.astro` |
| 分类和顺序 | `astro.config.mjs`、页面 frontmatter 中的 `sidebar.order` |
| 中文 / 英文首页 | `src/content/docs/zh-cn/index.mdx`、`src/content/docs/en/index.mdx` |
| 分类和顺序 | `astro.config.mjs`、页面 frontmatter 的 `sidebar.order` |
| 全局字体、红色强调与深灰背景 | `src/styles/custom.css` |
| 入门与写作示例 | `src/content/docs/zh-cn/guides/` |
| 技术方向 | `src/content/docs/zh-cn/{mest,elct,vsag,pram}/` |
| 校内赛规则 | `src/content/docs/zh-cn/competition/` |
| 原始规则附件 | `public/downloads/rmic-2026-original-draft.md` |
新增 `.md` 或 `.mdx` 页面后,侧栏按目录自动生成。技术示例的页首有“示例内容”提示,替换为经过确认的内容后再调整该提示。原有视觉组导论保留,未改写。
各分类按目录自动生成。技术示例在页首标注,替换为经过确认的内容后再调整提示。原有视觉组导论正文保留。英文未翻译文章使用 Starlight 默认语言回退。
英文首页已提供,未翻译文章使用 Starlight 默认语言回退并显示提示。首页入口直达现有中文文章,避免空页面。
## 公式与 Mermaid
- 行内公式使用 `$…$`,独立公式使用 `$$…$$`(分行包裹)。`remark-math` 和 `rehype-katex` 在构建时渲染,KaTeX 的样式和字体随站点打包。
- 以上公式写法和 Mermaid 均支持 `.md` 与 `.mdx`,不需要逐页导入组件。
- 图表使用标准的 Mermaid 围栏代码块。`src/plugins/remark-mermaid.mjs` 保留源码,`src/scripts/mermaid.ts` 在有图表的页面按需加载 Mermaid 并渲染 SVG,随深浅主题切换重新绘制。宽图默认适应宽度,点击“放大查看”后可滚动阅读,无 JavaScript 或图表错误时仍可阅读源码。
- 除数学公式外,正文、导航、代码块、表单和图表文字均为无衬线字体。KaTeX 保留数学字体。
- `Head.astro` 仅增加图表渲染脚本,文档框架沿用 Starlight 默认实现。页眉 Logo 通过 Starlight 配置加载;搜索、导航、主题和语言切换保留原有行为。
写法和预览见 `src/content/docs/zh-cn/guides/contributing.mdx`。
## 校内赛规则
规则被整理为概览、赛前考核、开源审查、对抗赛、制作规范、裁判系统、待确认事项七章。使用 Starlight 提示栏、步骤、卡片、标签页、表格和自适应赛程示意。没有额外引入 Mermaid 客户端依赖;原始 Mermaid 源码保留在下载附件,网页以阶段示意与完整晋级关系表展示同一赛程。
手册按概览、赛前考核、开源审查、对抗赛、制作规范、裁判系统、待确认事项拆为七章。比赛流程使用原始附件的 Mermaid 源码,不另写 Astro 流程组件;数学表达使用原有美元符号公式语法。
`pending.md` 记录原稿缺失或有歧义的条款。正式发布前,应补齐报名入口、场地信息、同分规则、尺寸孔位图等,并同步各章节。所有页面当前标记为规则预览版;原始附件保持不变。
`pending.md` 记录原稿缺失或有歧义的条款。正式发布前应补齐报名入口、场地信息、同分规则、尺寸孔位图等,并同步各章节。原始下载附件保持不变。
## 主站素材
## 主站与仓库
素材于 2026-09-23 从 `https://simba-robotics.com` 复用并保存到 `public/simba/`,页面加载不依赖主站在线。素材属于战队原有资产,不因本次复用改变授权。
- [Simba 主站](https://simba-robotics.com)
- [文档仓库](https://git.simba-robotics.com/PRAM/simba_docs)
| 本地文件 | 主站来源路径 | 用途 |
| --- | --- | --- |
| `logo.svg` | `/logo.svg` | 品牌图标、favicon |
| `logo_with_char.webp` | `/logo_with_char.webp` | 页脚 Logo |
| `header.webp` | `/header.webp` | 首页机器人背景 |
| `mest.svg` | `/icons/mest.svg` | 机械架构入口 |
| `elct.svg` | `/icons/elct.svg` | 电传测控入口 |
| `vsag.svg` | `/icons/vsag.svg` | 视觉算法入口 |
| `pram.svg` | `/icons/pram.svg` | 宣传筹划入口 |
`public/simba/` 中的 Logo、图片与小组图标由主站复用。Logo 用于页眉与 favicon;此前用于展示首页的素材保留,供后续文章使用。来源为主站同名路径(小组图标来自 `/icons/`),下载日期 2026-09-23,授权不因复用而改变。
参考:[Astro 文档](https://docs.astro.build)、[Starlight 文档](https://starlight.astro.build)。
+24 -7
View File
@@ -1,9 +1,19 @@
// @ts-check
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import { unified } from '@astrojs/markdown-remark';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import remarkMermaid from './src/plugins/remark-mermaid.mjs';
export default defineConfig({
redirects: { '/': '/zh-cn/' },
markdown: {
processor: unified({
remarkPlugins: [remarkMath, remarkMermaid],
rehypePlugins: [rehypeKatex],
}),
},
integrations: [starlight({
title: 'ΣDOCS',
description: 'Simba Robotics / 黑龙江大学 602 创新实验室的工程知识库与校内赛手册。',
@@ -13,15 +23,22 @@ export default defineConfig({
en: { label: 'English', lang: 'en' },
},
favicon: '/simba/logo.svg',
customCss: ['./src/styles/custom.css'],
components: {
Header: './src/components/Header.astro',
Hero: './src/components/Hero.astro',
SiteTitle: './src/components/SiteTitle.astro',
Footer: './src/components/Footer.astro',
logo: { src: './public/simba/logo.svg', alt: 'Simba Robotics' },
customCss: ['katex/dist/katex.min.css', './src/styles/custom.css'],
components: { Head: './src/components/Head.astro' },
expressiveCode: {
styleOverrides: {
codeFontFamily: 'var(--sl-font)',
uiFontFamily: 'var(--sl-font)',
codeBackground: 'var(--sl-color-bg-nav)',
},
social: [{ icon: 'github', label: 'Simba Git · 文档仓库', href: 'https://git.simba-robotics.com/PRAM/simba_docs' }],
},
social: [
{ icon: 'external', label: 'Simba 战队主站', href: 'https://simba-robotics.com' },
{ icon: 'github', label: '文档仓库', href: 'https://git.simba-robotics.com/PRAM/simba_docs' },
],
sidebar: [
{ label: '文档首页', translations: { en: 'Documentation home' }, slug: 'index' },
{ label: '开始阅读', translations: { en: 'Start here' }, items: [{ autogenerate: { directory: 'guides' } }] },
{ label: '2026 校内赛 · RMIC', translations: { en: '2026 Campus Competition' }, items: [{ autogenerate: { directory: 'competition' } }] },
{ label: '机械架构 · MEST', translations: { en: 'Mechanical Engineering' }, items: [{ autogenerate: { directory: 'mest' } }] },
+638 -1251
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -10,10 +10,13 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/markdown-remark": "7.2.0",
"@astrojs/starlight": "^0.41.1",
"astro": "^7.0.2",
"sharp": "^0.34.5",
"starlight-ion-theme": "^2.4.0",
"starlight-theme-obsidian": "^0.4.1"
"katex": "^0.16.47",
"mermaid": "^12.0.0",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"sharp": "^0.34.5"
}
}
-4
View File
@@ -1,4 +0,0 @@
---
import DefaultFooter from '@astrojs/starlight/components/Footer.astro';
---
{!/^\/(?:zh-cn|en)\/?$/.test(Astro.url.pathname) && <DefaultFooter />}
+8
View File
@@ -0,0 +1,8 @@
---
import DefaultHead from '@astrojs/starlight/components/Head.astro';
---
<DefaultHead />
<script>
import '../scripts/mermaid';
</script>
-20
View File
@@ -1,20 +0,0 @@
---
import DefaultHeader from '@astrojs/starlight/components/Header.astro';
import Search from '@astrojs/starlight/components/Search.astro';
import LanguageSelect from '@astrojs/starlight/components/LanguageSelect.astro';
import SiteTitle from './SiteTitle.astro';
const home = /^\/(?:zh-cn|en)\/?$/.test(Astro.url.pathname);
const en = Astro.locals.starlightRoute.lang === 'en';
---
{home ? (
<div class="home-header">
<SiteTitle />
<nav aria-label={en ? 'Main navigation' : '主导航'}>
<a class="active" href={en ? '/en/' : '/zh-cn/'}><span>01</span> {en ? 'Home' : '首页'}</a>
<a href="#knowledge"><span>02</span> {en ? 'Knowledge' : '知识库'}</a>
<a href="/zh-cn/competition/"><span>03</span> {en ? 'RMIC 2026' : '校内赛'}</a>
<a href="https://simba-robotics.com"><span>↗</span> {en ? 'Main site' : '战队主站'}</a>
</nav>
<div class="home-tools"><Search /><LanguageSelect /></div>
</div>
) : <DefaultHeader />}
-6
View File
@@ -1,6 +0,0 @@
---
import DefaultHero from '@astrojs/starlight/components/Hero.astro';
import Home from './Home.astro';
const home = /^\/(?:zh-cn|en)\/?$/.test(Astro.url.pathname);
---
{home ? <Home /> : <DefaultHero />}
-73
View File
@@ -1,73 +0,0 @@
---
import { disciplines, reading } from '../data/home';
import '../styles/home.css';
const en = Astro.locals.starlightRoute.lang === 'en';
---
<div class="docs-home">
<section class="home-hero" aria-labelledby="_top">
<img class="hero-backdrop" src="/simba/header.webp" alt="" width="1600" height="1200" fetchpriority="high" />
<div class="hero-grid" aria-hidden="true"></div>
<div class="hero-shell">
<div class="eyebrow"><span>HLJU · 602 LAB</span><b>THE SIMBA KNOWLEDGE BASE</b></div>
<h1 id="_top" data-page-title><span>BUILD.</span><span class="outline">LEARN.</span><span>ITERATE<span class="red">.</span></span></h1>
<div class="hero-copy">
<h2>{en ? 'Every iteration deserves to be documented.' : '让每一次迭代,都有迹可循。'}</h2>
<p>{en ? 'Engineering notes, shared experience and competition guides from Simba Robotics.' : '从第一行代码到赛场上的每一次突破。'}<br />{en ? 'Build on what we learn. Make the next robot better.' : '这里是 Simba 战队的知识库,也是你的工程起点。'}</p>
</div>
<div class="hero-actions">
<a class="home-button primary" href={en ? '/en/guides/example/' : '/zh-cn/guides/getting-started/'}>{en ? 'Start reading' : '开始阅读'} <span aria-hidden="true">↗</span></a>
<a class="home-button" href="/zh-cn/competition/">{en ? '2026 RMIC guide · 中文' : '2026 校内赛手册'} <span aria-hidden="true">→</span></a>
</div>
<div class="image-caption" aria-hidden="true"><span class="signal"></span> SIMBA://ENGINEERING_IN_PROGRESS<br /><span>FIELD ARCHIVE / 602 LAB</span></div>
</div>
<div class="hero-bottom">
<div><strong>04</strong><span>{en ? 'DISCIPLINES' : '专业方向'}</span></div>
<div><strong>01</strong><span>{en ? 'SHARED KNOWLEDGE BASE' : '开放知识库'}</span></div>
<div class="hero-motto">BUILD · TEST · DOCUMENT · REPEAT</div>
<a href="#knowledge">{en ? 'EXPLORE THE DOCS' : '向下探索知识库'} <span aria-hidden="true">↓</span></a>
</div>
</section>
<div class="home-inner">
<a class="competition-notice" href="/zh-cn/competition/">
<span class="notice-tag">RMIC 2026</span>
<span class="notice-copy"><strong>{en ? 'Build your first competition robot.' : '你的第一台参赛机器人,从这里出发。'}</strong><span>{en ? 'Campus competition · Sep 23 – Nov 1 · Preview rules' : '黑龙江大学 RoboMaster 校内赛 · 09.23—11.01 · 规则预览版'}</span></span>
<span class="notice-link">{en ? 'Read the guide' : '查看参赛手册'} <b aria-hidden="true">↗</b></span>
</a>
<section class="knowledge-section" id="knowledge" aria-labelledby="knowledge-title">
<div class="section-eyebrow"><span>01</span> KNOWLEDGE BASE <i></i></div>
<div class="section-heading"><h2 id="knowledge-title">{en ? 'Find your next direction.' : '从热爱出发,向工程进阶。'}</h2><p>{en ? 'Four disciplines. One robot. A shared place to learn.' : '四个方向,一台机器人。'}<br />{en ? 'Chinese guides with clearly marked sample content.' : '把零散的经验,连接成可复用的知识。'}</p></div>
<div class="discipline-grid">
{disciplines.map((item, index) => (
<a class="discipline-card" href={item.href}>
<div class="card-top"><span>0{index + 1} / {item.code}</span><img src={'/simba/' + item.icon + '.svg'} width="42" height="42" alt="" loading="lazy" /></div>
<h3>{en ? item.en : item.title}</h3><p>{en ? item.enDescription : item.description}</p>
<div class="card-bottom"><span>{en ? item.code + ' / DOCS IN CHINESE' : item.tags}</span><b aria-hidden="true">↗</b></div>
</a>
))}
</div>
</section>
<section class="reading-section" aria-labelledby="reading-title">
<div class="section-eyebrow"><span>02</span> START EXPLORING <i></i></div>
<div class="section-heading"><h2 id="reading-title">{en ? 'A good place to begin.' : '不止于阅读,从动手开始。'}</h2><a class="text-link" href="/zh-cn/guides/getting-started/">{en ? 'Explore the guide' : '查看入门指南'} <span aria-hidden="true">↗</span></a></div>
<div class="reading-grid">
{reading.map((item, index) => (
<a class="reading-card" href={item.href}>
<span class="reading-index">0{index + 1} <b>{item.code}</b></span>
<h3>{en ? item.en : item.title}</h3><p>{en ? item.enDescription : item.description}</p>
<div><span>{en ? item.enLabel : item.label}</span><b aria-hidden="true">→</b></div>
</a>
))}
</div>
</section>
<section class="contribute-panel" aria-labelledby="contribute-title">
<div><span class="section-eyebrow">KNOWLEDGE IS BUILT TOGETHER.</span><h2 id="contribute-title">{en ? 'Your next discovery belongs here.' : '你踩过的坑,值得成为下一条路。'}</h2><p>{en ? 'A debugging note, a build log, or a better explanation. Start small.' : '一份调试记录、一次方案复盘、一段更清楚的解释。知识库的下一页,由你来写。'}</p></div>
<a class="home-button" href="/zh-cn/guides/contributing/">{en ? 'Contribute a document' : '参与文档共建'} <span aria-hidden="true">↗</span></a>
</section>
</div>
<div class="home-ticker" aria-hidden="true">SIMBA ROBOTICS <span>×</span> BUILD · TEST · ITERATE <span>×</span> MECHANICAL · CONTROL · VISION · OPERATIONS <span>×</span> KNOWLEDGE WITHOUT LIMITS</div>
<footer class="home-footer">
<div><img src="/simba/logo_with_char.webp" width="185" height="46" alt="Simba Robotics" loading="lazy" /><p>{en ? 'Heilongjiang University · 602 Innovation Lab' : '黑龙江大学 · 602 创新实验室'}<br />{en ? 'Build on experience. Pass it forward.' : '以工程实践,回应对机器人的热爱。'}</p></div>
<div class="footer-links"><a href="https://simba-robotics.com">{en ? 'Simba main site' : '战队主站'} ↗</a><a href="https://git.simba-robotics.com/PRAM/simba_docs">{en ? 'Source repository' : '文档仓库'} ↗</a><a href="/zh-cn/guides/contributing/">{en ? 'Contributing' : '贡献指南'} →</a></div>
<div class="footer-bottom"><span>© {new Date().getFullYear()} SIMBA ROBOTICS / ΣDOCS</span><span><i class="signal"></i> BUILD · SHARE · REPEAT</span><span>POWERED BY ASTRO & STARLIGHT</span></div>
</footer>
</div>
-8
View File
@@ -1,8 +0,0 @@
---
const { siteTitleHref } = Astro.locals.starlightRoute;
---
<a class="docs-brand" href={siteTitleHref} aria-label="ΣDOCS · 首页 / Home">
<span class="brand-icon"><img src="/simba/logo.svg" width="35" height="35" alt="" /></span>
<span class="brand-name" translate="no">ΣDOCS<small>SIMBA ROBOTICS</small></span>
</a>
-19
View File
@@ -1,19 +0,0 @@
---
const stages = [
{ number: '01', title: '16 → 8', format: '双败阶段 · BO3', detail: '首轮 → 胜者组 / 败者组两轮', result: '胜者组 4 队 + 败者组 4 队' },
{ number: '02', title: '8 → 4', format: '双败阶段 · BO3', detail: '胜者组 → 败者组两轮', result: '胜者组 2 队 + 败者组 2 队' },
{ number: '03', title: '四强 → 冠军', format: '单败阶段 · BO5', detail: '半决赛 → 冠军战 / 季军战', result: '决出冠军、亚军、季军、殿军' },
];
---
<figure class="tournament-flow" aria-label="对抗赛三个阶段示意,详细晋级关系见下表">
{stages.map(stage => <div><span>{stage.number} / {stage.format}</span><strong>{stage.title}</strong><p>{stage.detail}</p><small>{stage.result}</small></div>)}
</figure>
<style>
.tournament-flow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .8rem; margin: 1.5rem 0; }
.tournament-flow > div { border: 1px solid var(--sl-color-hairline); border-top: 3px solid var(--sl-color-accent); background: var(--sl-color-bg-sidebar); padding: 1rem; }
.tournament-flow span { font: .65rem var(--sl-font-mono); color: var(--sl-color-text-accent); }
.tournament-flow strong { display: block; font-size: 1.3rem; color: var(--sl-color-white); margin-top: .6rem; }
.tournament-flow p, .tournament-flow small { font-size: .7rem; margin-top: .6rem; display: block; }
@media (max-width: 650px) { .tournament-flow { grid-template-columns: 1fr; } }
</style>
+29 -5
View File
@@ -1,7 +1,31 @@
---
title: ΣDOCS · Simba Robotics Knowledge Base
description: Engineering notes, shared experience and campus competition guides from Simba Robotics at Heilongjiang University.
template: splash
hero:
title: BUILD. LEARN. ITERATE.
title: ΣDOCS Documentation
description: Technical guides, engineering notes, and campus competition rules from Simba Robotics.
---
import { CardGrid, LinkCard } from '@astrojs/starlight/components';
Welcome to **ΣDOCS**, the documentation site for Simba Robotics and the 602 Innovation Lab at Heilongjiang University.
[Simba main site](https://simba-robotics.com) · [Documentation repository](https://git.simba-robotics.com/PRAM/simba_docs)
## Start here
<CardGrid>
<LinkCard title="2026 campus competition" description="Schedule, assessments, robot specifications, and match rules." href="/en/competition/" />
<LinkCard title="Getting started" description="Choose a discipline and complete your first engineering task." href="/en/guides/getting-started/" />
<LinkCard title="Contribute to the docs" description="Examples of Markdown, components, math, and diagrams." href="/en/guides/contributing/" />
</CardGrid>
## Documentation
| Discipline | Guide |
| --- | --- |
| Mechanical engineering | [From sketch to assembly](/en/mest/getting-started/) |
| Electronics and control | [A first control development loop](/en/elct/getting-started/) |
| Vision and algorithms | [Introduction](/en/vsag/intro/) |
| Operations and media | [Documenting engineering work](/en/pram/getting-started/) |
:::note[Work in progress]
Technical guides currently use Chinese fallback content. New sample articles are marked, and the campus competition rules remain a preview pending organizer confirmation.
:::
+3 -3
View File
@@ -8,6 +8,7 @@ sidebar:
text: 预览版
variant: caution
---
import { CardGrid, LinkCard, Steps } from '@astrojs/starlight/components';
:::caution[规则预览版 · 尚未最终定稿]
@@ -77,12 +78,11 @@ import { CardGrid, LinkCard, Steps } from '@astrojs/starlight/components';
<LinkCard title="机器人制作规范" description="尺寸、能源、控制通信、发射机构与装甲安装。" href="/zh-cn/competition/robot-spec/" />
<LinkCard title="裁判系统" description="装甲板、图传、供电要求与押金规则。" href="/zh-cn/competition/referee-system/" />
<LinkCard title="对抗赛与奖项" description="单局判胜、淘汰流程、奖项评定与奖励。" href="/zh-cn/competition/matches/" />
<LinkCard title="待确认事项" description="集中查看原稿中的缺项、歧义及待补图示。" href="/zh-cn/competition/pending/" />
<LinkCard title="待确认事项" description="原稿中的缺项、歧义及待补图示。" href="/zh-cn/competition/pending/" />
</CardGrid>
## 原始附件
<a href="/downloads/rmic-2026-original-draft.md" download="比赛规则草稿.md">下载《比赛规则草稿》原始 Markdown</a>
[下载《比赛规则草稿》原始 Markdown](/downloads/rmic-2026-original-draft.md)
原始附件保持原文,便于与整理后的章节对照。原稿中的 Mermaid 赛程源码也包含在附件中。
@@ -4,8 +4,6 @@ description: 单局流程、训练安排、决赛晋级关系与奖项限制。
sidebar:
order: 4
---
import { Steps } from '@astrojs/starlight/components';
import TournamentFlow from '../../../../components/TournamentFlow.astro';
:::caution[预览版]
本章保留原稿的赛制与奖励表述。平局、同分、奖项名额及赛程执行细节尚待组委会确认。
@@ -13,8 +11,6 @@ import TournamentFlow from '../../../../components/TournamentFlow.astro';
## 单局比赛流程
<Steps>
1. **检录与安装裁判系统**
验证机器人符合[制作规范](/zh-cn/competition/robot-spec/),并安装[裁判系统](/zh-cn/competition/referee-system/)。
@@ -31,8 +27,6 @@ import TournamentFlow from '../../../../components/TournamentFlow.astro';
血量先减为 0 的一方落败;或在 **3 分钟比赛时间**耗尽后,血量较多的一方胜出。
</Steps>
:::note[准备时间与对抗时间分开计算]
三分钟准备后,再进行最多三分钟的单局对抗。原稿尚未说明双方同时归零或时间结束时血量相同的处理办法。
:::
@@ -60,22 +54,83 @@ import TournamentFlow from '../../../../components/TournamentFlow.astro';
### 晋级流程
<TournamentFlow />
```mermaid
flowchart TD
Note["比赛顺序说明:<br/>• 第一场前16队抽签编号1~16<br/>• 同一组内按编号从小到大依次两两比赛<br/>• 不同组按前文顺序进行<br/>• 每场编号小为红方,编号大为蓝方"]
下表将原稿的 Mermaid 流程图转为可直接查阅的晋级关系。**每一行是一轮比赛,不是一场单局。**
subgraph P1["第一阶段:16进8(双败淘汰,BO3)"]
R1["首轮 16进8<br/>16队 / 8场 BO3<br/>按编号:1v2, 3v4, ..., 15v16"]
W1["16进8胜者组<br/>8队 / 4场 BO3"]
L1_1["16进8败者组第一轮<br/>8队 / 4场 BO3"]
L1_2["16进8败者组第二轮<br/>8队 / 4场 BO3"]
end
| 轮次 | 队伍 / 场次 | 赛制 | 胜者去向 | 败者去向 |
| --- | --- | --- | --- | --- |
| 首轮 16 进 8 | 16 队 / 8 场,1v2、3v4…15v16 | BO3 | 8 队 → 16 进 8 胜者组 | 8 队 → 16 进 8 败者组第一轮 |
| 16 进 8 胜者组 | 8 队 / 4 场 | BO3 | 4 队 → 8 进 4 胜者组 | 4 队 → 16 进 8 败者组第二轮 |
| 16 进 8 败者组第一轮 | 8 队 / 4 场 | BO3 | 4 队 → 16 进 8 败者组第二轮 | 淘汰 |
| 16 进 8 败者组第二轮 | 8 队 / 4 场 | BO3 | 4 队 → 8 进 4 败者组第一轮 | 淘汰 |
| 8 进 4 胜者组 | 4 队 / 2 场 | BO3 | 2 队 → 半决赛 | 2 队 → 8 进 4 败者组第二轮 |
| 8 进 4 败者组第一轮 | 4 队 / 2 场 | BO3 | 2 队 → 8 进 4 败者组第二轮 | 淘汰 |
| 8 进 4 败者组第二轮 | 4 队 / 2 场 | BO3 | 2 队 → 半决赛 | 淘汰 |
| 半决赛 | 4 队 / 2 场 | BO5 | 2 队 → 冠军争夺战 | 2 队 → 季军争夺战 |
| 季军争夺战 | 2 队 / 1 场 | BO5 | 季军 | 殿军 |
| 冠军争夺战 | 2 队 / 1 场 | BO5 | 冠军 | 亚军 |
subgraph P2["第二阶段:8进4(双败淘汰,BO3)"]
W2["8进4胜者组<br/>4队 / 2场 BO3"]
L2_1["8进4败者组第一轮<br/>4队 / 2场 BO3"]
L2_2["8进4败者组第二轮<br/>4队 / 2场 BO3"]
end
subgraph P3["第三阶段:总决赛(单败淘汰,BO5)"]
SF["半决赛<br/>4队 / 2场 BO5"]
Bronze["季军争夺战<br/>1场 BO5"]
Final["冠军争夺战<br/>1场 BO5"]
Champion["冠军"]
RunnerUp["亚军"]
Third["季军"]
Fourth["殿军"]
end
E1["淘汰"]
E2["淘汰"]
E3["淘汰"]
E4["淘汰"]
Note -.-> R1
R1 -->|"胜者 8队"| W1
R1 -->|"败者 8队"| L1_1
W1 -->|"胜者 4队"| W2
W1 -->|"败者 4队"| L1_2
L1_1 -->|"胜者 4队"| L1_2
L1_1 -->|"败者"| E1
L1_2 -->|"胜者 4队"| L2_1
L1_2 -->|"败者"| E2
W2 -->|"胜者 2队"| SF
W2 -->|"败者 2队"| L2_2
L2_1 -->|"胜者 2队"| L2_2
L2_1 -->|"败者"| E3
L2_2 -->|"胜者 2队"| SF
L2_2 -->|"败者"| E4
SF -->|"胜者 2队"| Final
SF -->|"败者 2队"| Bronze
Bronze -->|"胜者"| Third
Bronze -->|"败者"| Fourth
Final -->|"胜者"| Champion
Final -->|"败者"| RunnerUp
classDef stage fill:#e3f2fd,stroke:#1565c0,color:#000;
classDef finalStage fill:#fff8e1,stroke:#f9a825,color:#000;
classDef win fill:#e8f5e9,stroke:#2e7d32,color:#000;
classDef lose fill:#ffebee,stroke:#c62828,color:#000;
classDef note fill:#f5f5f5,stroke:#999,color:#000;
class R1,W1,L1_1,L1_2,W2,L2_1,L2_2 stage;
class SF,Bronze,Final finalStage;
class Champion,RunnerUp,Third,Fourth win;
class E1,E2,E3,E4 lose;
class Note note;
```
:::note[赛制边界]
前两个阶段为原稿所述的双败阶段,四强起改为单败阶段。跨轮重排、回避重复对阵等未在原稿中明确,请等待正式对阵表。
@@ -90,7 +145,7 @@ import TournamentFlow from '../../../../components/TournamentFlow.astro';
排名指标依次为:
1. **主要指标:** 冠军 > 亚军 > 季军 > 殿军 > 8 强 > 16 强。
1. **主要指标:** $\text{冠军}>\text{亚军}>\text{季军}>\text{殿军}>8\text{强}>16\text{强}$。
2. **次要指标:** 队伍总造成伤害数。
:::caution[开源审查影响奖项分配]
@@ -119,4 +174,3 @@ A 类作品最高获得一等奖,B 类最高获得二等奖,C 类最高获
:::note[内容待发布]
原稿仅包含赛事标题,尚无参赛条件、赛制与评分规则。本页不补设规则。
:::
@@ -4,6 +4,7 @@ description: 作品报告、现场答辩、再设计分类与获奖限制。
sidebar:
order: 3
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
:::caution[预览版]
@@ -95,7 +96,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
## 分类优先级与获奖上限
满足某类的一条即可认定为该类,按最高分类,优先级为 **A > B > C**。例如满足 A 类 1 条、B 类 2 条,认定为 A 类。
满足某类的一条即可认定为该类,按最高分类,优先级为 $A>B>C$。例如满足 A 类 1 条、B 类 2 条,认定为 A 类。
| 类别 | 再设计程度 | 获奖上限 |
| --- | --- | --- |
@@ -104,4 +105,3 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
| C | 无效再设计 | 三等奖 |
若比赛结果对应奖项超出类别上限,按[奖项评定规则](/zh-cn/competition/matches/#奖项评定)调整奖项位次。
@@ -50,12 +50,12 @@ sidebar:
- 按参赛流程拆分章节,增加站内索引和跳转。
- 将关键数值集中到表格,使用提示栏突出禁止事项与缺失信息。
- 修正“陈宗座机器人”等明显笔误和重复编号,统一单位排版。
- 将 Mermaid 赛程图整理为阶段示意与完整晋级关系表。
- 直接使用原稿的 Mermaid 源码绘制赛程图,并恢复美元符号包裹的数学公式。
- 保留原稿的赛事日期、人数、费用、评分、数值限制及奖励表述。
## 对照原始附件
<a href="/downloads/rmic-2026-original-draft.md" download="比赛规则草稿.md">下载《比赛规则草稿》原始 Markdown</a>
[下载《比赛规则草稿》原始 Markdown](/downloads/rmic-2026-original-draft.md)
原始附件未改写;包含完整原文及 Mermaid 源码。后续规则更新建议同时记录发布日期、修改条款和生效范围。
@@ -4,7 +4,6 @@ description: 报名、规则测评、完整形态考察与晋级资格。
sidebar:
order: 2
---
import { Steps } from '@astrojs/starlight/components';
:::caution[预览版]
本章来自赛事规则草稿。道路宽度、旋转半径等未给出的判定参数,见[待确认事项](/zh-cn/competition/pending/)。
@@ -14,14 +13,10 @@ import { Steps } from '@astrojs/starlight/components';
报名时间为 **2026 年 9 月 23 日至 10 月 9 日**。每队 3 人,每人仅可参加一队,报名费为 50 元 / 队。
<Steps>
1. **联系队友并确认资格。** 所有选手均须为黑龙江大学本科生。
2. **加入赛事官方 QQ 群。** 后续通知将第一时间在群内发布。
3. **共同填写报名信息。** QQ 群二维码与报名链接待组委会补充。
</Steps>
## 规则测评
| 项目 | 规定 |
@@ -51,7 +46,7 @@ import { Steps } from '@astrojs/starlight/components';
| 底盘 | 全向移动 | 不旋转车体,相对地面完成前、后、左、右平移 | 15 |
| 云台 | 枪口俯仰 | 使用任意方法,使水弹发射机构绕某一与地面平行的轴转动超过 30° | 15 |
| 云台 | 发射水弹 | 以不大于 1 s 的发射间隔连续发射 10 s,不卡弹 | 15 |
| 云台 | 定点击打 | 30 s 内,命中 1 m 外面积为 100 cm² 的固定靶 5 次以上 | 15 |
| 云台 | 定点击打 | 30 s 内,命中 1 m 外面积为 $100cm^2$ 的固定靶 5 次以上 | 15 |
| 其他 | 有助于对战的功能 | 内容不限 | 10 |
:::note[评分细则待补充]
@@ -71,4 +66,3 @@ import { Steps } from '@astrojs/starlight/components';
## 同日开源审查
作品报告必须在完整形态考察前提交;考察通过后,当天接受实物审查。材料清单与获奖限制详见[开源审查](/zh-cn/competition/open-source/)。
@@ -14,8 +14,8 @@ sidebar:
| --- | --- |
| 运动控制 | 能通过遥控装置或裁判系统控制运动 |
| 发射器数量 | **有且仅有 1 个**水弹发射器 |
| 初始尺寸(包覆盒) | **小于 350 × 350 × 350 mm** |
| 伸展尺寸 | **小于 400 × 400 × 400 mm** |
| 初始尺寸(包覆盒) | **小于 $350\times350\times350(mm)$** |
| 伸展尺寸 | **小于 $400\times400\times400(mm)$** |
| 裁判系统安装位 | 4 个装甲板模块和 1 个图传模块;平衡车构型例外见下文 |
**初始尺寸**指机器人至少有一个状态小于规定尺寸;**伸展尺寸**指机器人在任何状态下都必须小于规定尺寸。
@@ -64,11 +64,11 @@ sidebar:
1. 线缆应整齐且不外露;无法避免的外露线材应使用束线管、理线器等保护。
2. 避免使用明显影响美观的材料,如塑料袋、床单、快递气垫膜。
3. 禁止刻意设计或使用尖锐结构,以免破坏场地或伤害人员。
4. 禁止出现面积大于 **30 × 30 mm²** 的接近纯红色或纯蓝色外观涂装。
4. 禁止出现面积大于 **$30\times30mm^2$** 的接近纯红色或纯蓝色外观涂装。
5. 禁止其他违背赛事精神的外观设计。
:::note[涂装面积口径待确认]
“30 × 30 mm²”沿用原稿写法。面积阈值、计算方式及“接近纯红 / 纯蓝”的判定需组委会明确。
“$30\times30mm^2$”沿用原稿写法。面积阈值、计算方式及“接近纯红 / 纯蓝”的判定需组委会明确。
:::
## 发射机构
@@ -88,26 +88,26 @@ sidebar:
### 机体坐标系
采用标准 **X、Y、Z 笛卡尔坐标系**:
采用标准 **$X,Y,Z$ 笛卡尔坐标系**:
- 原点:机器人质量中心。
- X 轴:底盘构型最大效率方向;存在多个方向时可任选其一。
- Z 轴:指向地心。
- $X$ 轴:底盘构型最大效率方向;存在多个方向时可任选其一。
- $Z$ 轴:指向地心。
- 机器人运动学方程也需建立在此坐标系下。
### 安装角度与方向
1. 装甲模块与支撑架稳固连接,支撑架底部连接面与 XY 平面平行。
2. 受力面所在平面的法向量所在直线,与 Z 轴负方向所在直线的锐角为 **75°**。
3. 装甲模块不含侧灯的两条边,与 XY 平面的夹角 **小于 5°**。
4. 取受击面法向量中与 Z 轴负方向成锐角的一支,其在 XY 平面上的投影为装甲模块的**方向向量**。
5. 四块装甲的方向向量分别对应 **+X、−X、+Y、−Y**,与对应坐标轴的角度误差 **不超过 5°**。
1. 装甲模块与支撑架稳固连接,支撑架底部连接面与 $XY$ 平面平行。
2. 受力面所在平面的法向量所在直线,与 $Z$ 轴负方向所在直线的锐角为 **$75°$**。
3. 装甲模块不含侧灯的两条边,与 $XY$ 平面的夹角 **小于 $5°$**。
4. 取受击面法向量中与 $Z$ 轴负方向成锐角的一支,其在 $XY$ 平面上的投影为装甲模块的**方向向量**。
5. 四块装甲的方向向量分别对应 $+X,-X,+Y,-Y$,与对应坐标轴的角度误差 **不超过 $5°$**。
### 参考坐标与位置
- 装甲安装方式应与机器人的结构特性或运动学特性共享同一参考坐标系。
- X 轴上两块装甲的几何中心连线,与 Y 轴上两块装甲的几何中心连线互相垂直。
- 装甲模块相对于机器人几何中心的偏移量,在 X 轴或 Y 轴上的分量 **不得超过 30 mm**。
- $X$ 轴上两块装甲的几何中心连线,与 $Y$ 轴上两块装甲的几何中心连线互相垂直。
- 装甲模块相对于机器人几何中心的偏移量,在 $X$ 轴或 $Y$ 轴上的分量 **不得超过 $30mm$**。
:::note[偏移量的测量对象待确认]
上述偏移限制保留原稿表述。具体是指单块装甲、成对装甲中心还是安装轴线,应结合组委会补充图示确认后制作。
@@ -117,7 +117,7 @@ sidebar:
支撑架可采用官方设计或自制,安装后的装甲模块、支撑架必须与底盘刚性连接;比赛中不可与底盘发生相对移动。
**判定方法:** 在装甲模块下边缘中点施加竖直向上的 **20 N** 力,受击面角度 α 的变化 **不得大于 5°**。
**判定方法:** 在装甲模块下边缘中点施加竖直向上的 **$20N$** 力,受击面角度 $\alpha$ 的变化 **不得大于 $5°$**。
:::note[示意图待补充]
原稿提及刚性连接示意图,但附件未包含图片。本章保留文字定义,不补绘可能影响判定的尺寸图。
@@ -125,15 +125,15 @@ sidebar:
### 平衡车构型例外
**90% 的时间仅有两轮接地**的底盘定义为平衡车构型,只需安装 **+X 与 −X** 方向的装甲板模块。
**90% 的时间仅有两轮接地**的底盘定义为平衡车构型,只需安装 $+X$ 与 $-X$ 方向的装甲板模块。
## 变形约束
| 项目 | 约束 |
| --- | --- |
| 装甲运动 | 不可相对底盘连续、往复快速移动;快速移动定义为速度超过 **0.5 m/s** |
| 下边缘高度差 | 任意两块装甲板下边缘高度差 **不超过 50 mm** |
| 离地高度 | 比赛中任意装甲板下边缘必须保持在 **30—200 mm(含端点)** |
| 装甲运动 | 不可相对底盘连续、往复快速移动;快速移动定义为速度超过 **$0.5m/s$** |
| 下边缘高度差 | 任意两块装甲板下边缘高度差 **不超过 $50mm$** |
| 离地高度 | 比赛中任意装甲板下边缘必须保持在 **$[30,200]mm$(含端点)** |
| 安装孔位 | 设计时考虑避免装甲板受撞击 |
:::caution[装甲板破损不能通过检录]
+98 -32
View File
@@ -1,32 +1,19 @@
---
title: 文档共建指南
description: 用 Markdown 与 Starlight 组件记录工程经验。
description: 使用 Markdown、组件、数学公式和 Mermaid 记录工程经验。
sidebar:
order: 2
---
import { Tabs, TabItem, Steps } from '@astrojs/starlight/components';
import { Tabs, TabItem } from '@astrojs/starlight/components';
:::note[协作规范示例]
本页是一份可修改的文档写作模板。审核人、分支策略和发布流程需按战队实际约定补充。
:::
## 一篇文档回答什么
## 使用 Markdown 编写
| 部分 | 要回答的问题 |
| --- | --- |
| 目标 | 读者要解决什么问题? |
| 前提 | 适用的硬件、软件版本和基础知识是什么? |
| 步骤 | 如何复现?关键参数为什么这样选? |
| 验证 | 用什么现象或数据证明完成? |
| 排错 | 常见失败有哪些?如何定位? |
| 参考 | 来源、许可证和相关文档在哪里? |
## 选择页面格式
<Tabs>
<TabItem label="Markdown">
普通文章使用 `.md`,适合标题、表格、代码块和提示栏。
在对应分类目录中新增 `.md` 或 `.mdx` 文件即可。首页与普通文章使用相同的 Starlight 文档框架;纯文字内容可使用 Markdown,需要卡片、步骤、标签页或自定义组件时使用 MDX。两种格式都支持提示栏、数学公式与 Mermaid。
```md
---
@@ -40,24 +27,45 @@ sidebar:
写清楚这次要验证的行为。
## 操作步骤
1. 记录环境。
2. 执行操作。
3. 核对结果。
```
## 按内容选择组件
可以使用任意 Starlight 组件和项目内的 Astro 组件;需要 React、Vue 等框架组件时,先为项目配置对应的 Astro 集成。在 `.mdx` 文件的 frontmatter 后导入组件,再与 Markdown 正文一起使用。本页的标签页就是一个示例:
<Tabs>
<TabItem label="普通 Markdown">
适合笔记、规则条款、表格和参考链接。保存为 `.md` 即可,不需要组件导入。
```md
## 调试记录
1. 记录环境与接线。
2. 完成实验并保存结果。
:::tip[复现提示]
注明固件版本与接线方式。
注明固件版本与关键参数。
:::
```
</TabItem>
<TabItem label="MDX">
<TabItem label="MDX 与组件">
需要卡片、步骤和标签页时使用 `.mdx`。组件从 Starlight 导入:
保存为 `.mdx`,即可将组件与 Markdown 混排。例如用 `Steps` 展示顺序操作:
```mdx
import { Steps } from '@astrojs/starlight/components';
<Steps>
1. 记录环境。
2. 执行操作。
3. 核对结果。
1. 记录环境与接线。
2. 完成实验并保存结果。
</Steps>
```
@@ -65,7 +73,70 @@ import { Steps } from '@astrojs/starlight/components';
</TabItem>
</Tabs>
## 提示栏如何选
组件示例可参考[首页卡片](/zh-cn/)、[入门步骤](/zh-cn/guides/getting-started/)和[开源审查分类](/zh-cn/competition/open-source/)。完整用法见 [Starlight 组件文档](https://starlight.astro.build/zh-cn/components/using-components/)。
## 一篇文档回答什么
| 部分 | 要回答的问题 |
| --- | --- |
| 目标 | 读者要解决什么问题? |
| 前提 | 适用的硬件、软件版本和基础知识是什么? |
| 步骤 | 如何复现?关键参数为什么这样选? |
| 验证 | 用什么现象或数据证明完成? |
| 排错 | 常见失败有哪些?如何定位? |
| 参考 | 来源、许可证和相关文档在哪里? |
## 数学公式
行内公式使用 `$…$`,独立公式使用单独成行的 `$$` 包裹。延续原始规则草稿的 LaTeX 写法:
```tex
初始尺寸小于 $350\times350\times350(mm)$。
$$
v = \frac{\Delta x}{\Delta t}
$$
```
显示效果:初始尺寸小于 $350\times350\times350(mm)$。
$$
v = \frac{\Delta x}{\Delta t}
$$
正文、导航、代码与图表标签统一采用无衬线字体,数学公式保留 KaTeX 数学字体。
## Mermaid 流程图
使用标记为 `mermaid` 的围栏代码块,直接维护图的源码。
````md
```mermaid
flowchart LR
A[记录问题] --> B[复现实验]
B --> C[核对结果]
```
````
显示效果:
```mermaid
flowchart LR
A[记录问题] --> B[复现实验]
B --> C[核对结果]
```
流程图随 Starlight 深浅主题切换。宽图默认适应正文宽度,可点击“放大查看”后滚动阅读细节;没有 JavaScript 时保留可读源码。[比赛赛程](/zh-cn/competition/matches/#晋级流程)直接使用原始附件中的 Mermaid 定义。
## 提示栏
保留 Starlight 的提示栏语法,不需要组件导入:
```md
:::tip[复现提示]
注明固件版本与接线方式。
:::
```
:::note[补充背景]
说明适用范围、版本或尚未确认的内容。
@@ -85,14 +156,9 @@ import { Steps } from '@astrojs/starlight/components';
## 发布前检查
<Steps>
1. **核实内容。** 区分正式规则、经验建议、示例与待确认项。
2. **检查链接。** 使用完整站内路径,如 `/zh-cn/competition/`。
3. **构建预览。** 执行 `npm run build`;开发预览使用 `npm run dev -- --background`。
4. **人工复核。** 检查手机排版、表格、提示栏及引用来源。
</Steps>
代码位于 [Simba 文档仓库](https://git.simba-robotics.com/PRAM/simba_docs)。各分类由目录自动生成,首页入口在 `src/data/home.ts` 中维护。
4. **人工复核。** 检查手机排版、表格、数学公式、流程图与提示栏。
代码位于 [Simba 文档仓库](https://git.simba-robotics.com/PRAM/simba_docs)。各分类按目录自动生成,首页内容直接在 `src/content/docs/zh-cn/index.mdx` 中维护。
@@ -4,7 +4,8 @@ description: 认识 ΣDOCS,选择一个方向,完成第一次工程实践。
sidebar:
order: 1
---
import { Steps, CardGrid, LinkCard } from '@astrojs/starlight/components';
import { Steps } from '@astrojs/starlight/components';
欢迎来到 **ΣDOCS**。这里整理 Simba 战队在机械、电控、视觉与团队协作中的知识,也收录校内赛参赛手册。
@@ -13,11 +14,8 @@ import { Steps, CardGrid, LinkCard } from '@astrojs/starlight/components';
:::
## 先找到你的入口
<CardGrid>
<LinkCard title="准备参加校内赛" description="先读参赛资格、赛事日程和机器人制作规范。" href="/zh-cn/competition/" />
<LinkCard title="准备贡献文档" description="了解页面结构、提示栏和发布前检查。" href="/zh-cn/guides/contributing/" />
</CardGrid>
- [准备参加校内赛](/zh-cn/competition/):先读参赛资格、赛事日程和机器人制作规范。
- [准备贡献文档](/zh-cn/guides/contributing/):了解页面结构、提示栏和发布前检查。
## 一次入门实践
@@ -44,4 +42,3 @@ import { Steps, CardGrid, LinkCard } from '@astrojs/starlight/components';
:::tip[先完成一个小闭环]
“跑起来”只是第一步。能够解释为什么、说明适用条件,并让别人复现,才是一份有用的工程记录。
:::
+30 -5
View File
@@ -1,7 +1,32 @@
---
title: ΣDOCS · Simba 战队知识库
description: 黑龙江大学 Simba Robotics 战队的开放知识库,汇集机械、电控、视觉、团队协作与 2026 RoboMaster 校内赛手册。
template: splash
hero:
title: BUILD. LEARN. ITERATE.
title: ΣDOCS 文档站
description: 黑龙江大学 Simba 机器人战队的技术文档、学习笔记与校内赛参赛手册。
---
import { CardGrid, LinkCard } from '@astrojs/starlight/components';
欢迎来到 **ΣDOCS**,黑龙江大学 602 创新实验室 / Simba 机器人战队的文档站。这里记录机械、电控、视觉与团队协作中的知识,供队员学习、查阅和共同完善。
[Simba 战队主站](https://simba-robotics.com) · [文档仓库](https://git.simba-robotics.com/PRAM/simba_docs)
## 从这里开始
<CardGrid>
<LinkCard title="2026 校内赛参赛手册" description="日程、考核、机器人制作规范与对抗赛规则。" href="/zh-cn/competition/" />
<LinkCard title="新队员入门" description="认识知识库,选择方向,完成第一次工程实践。" href="/zh-cn/guides/getting-started/" />
<LinkCard title="一起完善文档" description="Markdown、组件、数学公式和流程图的写作示例。" href="/zh-cn/guides/contributing/" />
</CardGrid>
## 文档目录
| 方向 | 内容入口 |
| --- | --- |
| 机械架构 · MEST | [从草图到装配](/zh-cn/mest/getting-started/) |
| 电传测控 · ELCT | [电控开发的第一个闭环](/zh-cn/elct/getting-started/) |
| 视觉算法 · VSAG | [视觉组导论](/zh-cn/vsag/intro/)、[视觉任务链路](/zh-cn/vsag/pipeline/) |
| 宣传筹划 · PRAM | [把工程故事记录下来](/zh-cn/pram/getting-started/) |
| 2026 校内赛 · RMIC | [赛事概览与日程](/zh-cn/competition/)、[机器人制作规范](/zh-cn/competition/robot-spec/) |
:::note[内容建设中]
新增技术示例已在各页标注,后续可替换为经过验证的实际内容。校内赛手册仍为规则预览版,缺失信息集中列于[待确认事项](/zh-cn/competition/pending/)。
:::
-13
View File
@@ -1,13 +0,0 @@
// 首页示例入口集中在这里维护;文章正文位于 src/content/docs/。
export const disciplines = [
{ code: 'MEST', title: '机械架构', en: 'Mechanical engineering', description: '从第一张草图,到能上场的机器人。', enDescription: 'From the first sketch to a robot in the arena.', tags: 'CAD / 结构设计 / 加工装配', href: '/zh-cn/mest/getting-started/', icon: 'mest' },
{ code: 'ELCT', title: '电传测控', en: 'Electronics & control', description: '连接电路与代码,让每一次运动可控。', enDescription: 'Connect circuits and code. Make every motion count.', tags: 'STM32 / 嵌入式 / 运动控制', href: '/zh-cn/elct/getting-started/', icon: 'elct' },
{ code: 'VSAG', title: '视觉算法', en: 'Vision & algorithms', description: '感知赛场,理解目标,做出下一步决策。', enDescription: 'Perceive the field. Understand the next move.', tags: 'OpenCV / 目标检测 / 自主决策', href: '/zh-cn/vsag/intro/', icon: 'vsag' },
{ code: 'PRAM', title: '宣传筹划', en: 'Operations & media', description: '记录每一次迭代,让工程故事被看见。', enDescription: 'Document every iteration. Share the engineering story.', tags: '视觉设计 / 内容创作 / 团队协作', href: '/zh-cn/pram/getting-started/', icon: 'pram' },
];
export const reading = [
{ code: 'START HERE', title: '新队员,从这里开始', en: 'Your first steps with Simba', description: '认识知识库,选择方向,完成第一次实践。', enDescription: 'Find your discipline and start a first project.', href: '/zh-cn/guides/getting-started/', label: '入门指南', enLabel: 'GETTING STARTED' },
{ code: 'BUILD TOGETHER', title: '把经验写成下一份文档', en: 'Turn experience into documentation', description: '使用统一的结构,记录问题、过程与验证结果。', enDescription: 'Capture the problem, process and verification.', href: '/zh-cn/guides/contributing/', label: '协作规范 · 示例', enLabel: 'CONTRIBUTING · SAMPLE' },
{ code: 'FIELD NOTES', title: '一次视觉任务的完整链路', en: 'Inside a vision pipeline', description: '从图像输入到控制输出,拆解模块与接口。', enDescription: 'Trace a frame from camera input to control output.', href: '/zh-cn/vsag/pipeline/', label: '技术笔记 · 示例', enLabel: 'TECHNICAL NOTE · SAMPLE' },
];
+31
View File
@@ -0,0 +1,31 @@
/** Render standard fenced Mermaid blocks without requiring MDX components. */
export default function remarkMermaid() {
return (tree) => {
const visit = (parent) => {
if (!parent.children) return;
parent.children = parent.children.map((node) => {
if (node.type === 'code' && node.lang === 'mermaid') {
// HAST data works in both Markdown and MDX, without injecting raw HTML.
// Text nodes safely preserve the source as the no-JavaScript fallback.
return {
type: 'paragraph',
children: [],
data: {
hName: 'div',
hProperties: { className: ['mermaid-diagram'], 'data-pagefind-ignore': true },
hChildren: [{
type: 'element',
tagName: 'pre',
properties: { className: ['mermaid-source'] },
children: [{ type: 'text', value: node.value }],
}],
},
};
}
visit(node);
return node;
});
};
visit(tree);
};
}
+113
View File
@@ -0,0 +1,113 @@
// Only diagram pages load Mermaid. Authors use ordinary fenced code blocks.
const sources = new WeakMap<HTMLElement, string>();
let running = false;
let pending = false;
let sequence = 0;
async function renderDiagrams() {
if (running) {
pending = true;
return;
}
const diagrams = [...document.querySelectorAll<HTMLElement>('.mermaid-diagram')];
if (!diagrams.length) return;
running = true;
try {
const { default: mermaid } = await import('mermaid');
const dark = document.documentElement.dataset.theme === 'dark';
mermaid.initialize({
startOnLoad: false,
securityLevel: 'strict',
theme: 'base',
themeVariables: {
darkMode: dark,
background: dark ? '#1a1a1a' : '#ffffff',
primaryColor: dark ? '#401820' : '#ffeaed',
primaryTextColor: dark ? '#eeeeee' : '#292929',
primaryBorderColor: dark ? '#d65a70' : '#c21932',
lineColor: dark ? '#c4c4c4' : '#5c5c5c',
secondaryColor: dark ? '#303030' : '#f4f4f4',
tertiaryColor: dark ? '#242424' : '#fafafa',
clusterBkg: dark ? '#242424' : '#fafafa',
clusterBorder: dark ? '#5c5c5c' : '#b8b8b8',
edgeLabelBackground: dark ? '#242424' : '#ffffff',
},
fontFamily: getComputedStyle(document.documentElement).getPropertyValue('--sl-font').trim(),
flowchart: { htmlLabels: false, useMaxWidth: false },
suppressErrorRendering: true,
});
for (const diagram of diagrams) {
if (!diagram.isConnected) continue;
const source = sources.get(diagram) ?? diagram.querySelector('.mermaid-source')?.textContent;
if (!source) continue;
sources.set(diagram, source);
try {
const { svg } = await mermaid.render(`mermaid-diagram-${++sequence}`, source);
if (!diagram.isConnected) continue;
const previousCanvas = diagram.querySelector('.mermaid-canvas');
const position = { left: previousCanvas?.scrollLeft ?? 0, top: previousCanvas?.scrollTop ?? 0 };
const chinese = document.documentElement.lang.startsWith('zh');
const canvas = document.createElement('div');
canvas.className = 'mermaid-canvas';
canvas.innerHTML = svg;
canvas.setAttribute('role', 'region');
canvas.setAttribute('aria-label', chinese ? 'Mermaid 流程图,可滚动查看' : 'Mermaid diagram, scroll to explore');
canvas.tabIndex = 0;
const width = canvas.querySelector('svg')?.viewBox.baseVal.width;
if (width) canvas.style.setProperty('--mermaid-width', `${width}px`);
const zoom = document.createElement('button');
zoom.type = 'button';
zoom.className = 'mermaid-zoom';
const updateButton = () => {
const expanded = diagram.dataset.zoomed === 'true';
zoom.textContent = chinese ? (expanded ? '适应宽度' : '放大查看') : (expanded ? 'Fit to width' : 'Enlarge diagram');
zoom.setAttribute('aria-pressed', String(expanded));
};
updateButton();
zoom.addEventListener('click', () => {
diagram.dataset.zoomed = String(diagram.dataset.zoomed !== 'true');
updateButton();
canvas.scrollTop = 0;
canvas.scrollLeft = 0;
if (diagram.dataset.zoomed === 'true') {
// Start at the topmost node, even when a wide bracket is asymmetric.
const firstNode = [...canvas.querySelectorAll('.node')]
.map((node) => node.getBoundingClientRect())
.sort((a, b) => a.top - b.top || a.left - b.left)[0];
canvas.scrollLeft = firstNode
? firstNode.left + firstNode.width / 2 - canvas.getBoundingClientRect().left - canvas.clientWidth / 2
: (canvas.scrollWidth - canvas.clientWidth) / 2;
}
});
diagram.replaceChildren(zoom, canvas);
canvas.scrollLeft = position.left;
canvas.scrollTop = position.top;
diagram.dataset.rendered = 'true';
} catch (error) {
// Preserve the original text if a contributor's diagram cannot be parsed.
const fallback = document.createElement('pre');
fallback.className = 'mermaid-source';
fallback.textContent = source;
diagram.replaceChildren(fallback);
diagram.dataset.rendered = 'error';
console.error('Unable to render Mermaid diagram:', error);
}
}
} catch (error) {
console.error('Unable to load Mermaid:', error);
} finally {
running = false;
if (pending) {
pending = false;
void renderDiagrams();
}
}
}
void renderDiagrams();
document.addEventListener('astro:page-load', renderDiagrams);
new MutationObserver(() => void renderDiagrams()).observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme'],
});
+52 -13
View File
@@ -1,24 +1,63 @@
:root {
--sl-font: 'Segoe UI', 'Microsoft YaHei', system-ui, sans-serif;
--sl-font-mono: 'Cascadia Code', Consolas, monospace;
--sl-font: 'Segoe UI', 'Microsoft YaHei', 'Noto Sans', Arial, sans-serif;
--sl-font-mono: var(--sl-font);
--sl-font-system-mono: var(--sl-font);
--sl-color-accent-low: #401820;
--sl-color-accent: #d91c3a;
--sl-color-accent-high: #ffb3bd;
}
:root[data-theme='dark'], [data-theme='dark'] ::backdrop {
--sl-color-white: #fafafa;
--sl-color-gray-1: #eeeeee;
--sl-color-gray-2: #c4c4c4;
--sl-color-gray-3: #929292;
--sl-color-gray-4: #5c5c5c;
--sl-color-gray-5: #383838;
--sl-color-gray-6: #242424;
--sl-color-black: #1a1a1a;
--sl-color-bg: #1a1a1a;
--sl-color-bg-nav: #222222;
--sl-color-bg-sidebar: #202020;
--sl-color-text-accent: #ff8fa1;
--sl-color-backdrop-overlay: rgb(18 18 18 / 66%);
}
:root[data-theme='light'] {
--sl-color-accent-low: #ffeaed;
--sl-color-accent: #c21932;
--sl-color-accent-high: #891328;
}
.docs-brand { display: inline-flex; align-items: center; gap: 11px; color: var(--sl-color-white); text-decoration: none; white-space: nowrap; }
.brand-icon { background: #090a0c; padding: 5px; display: flex; border-radius: 2px; }
.brand-name { font-size: 25px; line-height: 1.1; font-weight: 800; letter-spacing: -.04em; }
.brand-name small { display: block; margin-top: 5px; font: 8px/1.2 var(--sl-font-mono); letter-spacing: .14em; color: var(--sl-color-gray-2); }
:focus-visible { outline: 2px solid var(--sl-color-text-accent); outline-offset: 5px; }
.sl-markdown-content :is(h2, h3) { scroll-margin-top: 1rem; }
.sl-markdown-content table { font-size: .9rem; }
.sl-markdown-content details { padding: 1rem 1.2rem; border: 1px solid var(--sl-color-hairline); border-radius: 4px; }
.sl-markdown-content summary { cursor: pointer; font-weight: 600; }
.starlight-aside { border-radius: 0 4px 4px 0; }
@media print { .docs-brand { color: black; } }
/* Includes navigation, form controls, code, and diagram labels. KaTeX keeps its math fonts. */
body, button, input, select, textarea, code, pre, kbd, samp {
font-family: var(--sl-font);
}
.site-title img {
padding: .25rem;
border-radius: .25rem;
background: #222222;
}
:root[data-theme='dark'] .sidebar-pane a[aria-current='page'] {
color: #ffffff;
background-color: #b91e36;
}
.katex-display { overflow-x: auto; overflow-y: hidden; padding-block: .5rem; }
.mermaid-diagram {
max-width: 100%;
margin-block: 1.5rem;
padding: 1rem;
border: 1px solid var(--sl-color-hairline);
border-radius: .25rem;
}
.mermaid-canvas { max-height: 75vh; overflow: auto; margin-top: .75rem; }
.mermaid-diagram svg { display: block; width: 100%; height: auto; margin-inline: auto; }
.mermaid-diagram[data-zoomed='true'] svg { width: var(--mermaid-width); max-width: none; }
.mermaid-zoom { padding: .35rem .75rem; border: 1px solid var(--sl-color-gray-5); border-radius: .25rem; color: var(--sl-color-text); background: var(--sl-color-bg); cursor: pointer; }
.mermaid-zoom:hover { border-color: var(--sl-color-text-accent); }
.mermaid-diagram svg :is(text, tspan, foreignObject, span, p) { font-family: var(--sl-font) !important; }
.mermaid-source { white-space: pre; }
@media print {
.mermaid-diagram { overflow: visible; padding: 0; border: 0; }
.mermaid-zoom { display: none; }
.mermaid-canvas { max-height: none; overflow: visible; }
.mermaid-diagram svg, .mermaid-diagram[data-zoomed='true'] svg { width: 100%; height: auto; }
}
-179
View File
@@ -1,179 +0,0 @@
/* Only splash pages use the main site's fixed dark palette. Articles keep both themes. */
:root:has(.docs-home) {
color-scheme: dark;
--sl-color-bg: #090a0c; --sl-color-bg-nav: #090a0c;
--sl-color-white: #f4f1ea; --sl-color-black: #090a0c;
--sl-color-gray-1: #e6e3df; --sl-color-gray-2: #c2c2c3;
--sl-color-gray-3: #96979c; --sl-color-gray-4: #565a60;
--sl-color-gray-5: #292c31; --sl-color-gray-6: #15171b; --sl-color-gray-7: #101216;
--sl-color-accent: #ff3047; --sl-color-accent-low: #401820; --sl-color-accent-high: #ffb3bd;
--sl-color-text: #c2c2c3; --sl-color-text-accent: #ff8998;
--sl-color-hairline: #ffffff1c; --sl-color-hairline-shade: #ffffff1c;
--sl-color-bg-inline-code: #181b20; --sl-nav-height: 5rem;
}
:root:has(.docs-home) .content-panel { padding: 0; }
:root:has(.docs-home) .sl-container { max-width: none; }
:root:has(.docs-home) .sl-container > * + * { margin-top: 0; }
:root:has(.docs-home) main { padding: 0; }
:root:has(.docs-home) .header { border-bottom: 1px solid #ffffff1c; }
.home-header { display: flex; align-items: center; justify-content: space-between; height: 100%; gap: 24px; max-width: 1440px; margin: auto; }
.home-header nav { display: flex; align-items: stretch; height: calc(var(--sl-nav-height) - 1px); }
.home-header nav a { display: flex; align-items: center; gap: 8px; padding: 0 19px; color: #c2c2c3; text-decoration: none; font-size: 13px; border-bottom: 2px solid transparent; }
.home-header nav a span { color: #ff5a6d; font: 10px var(--sl-font-mono); }
.home-header nav a:hover, .home-header nav a.active { background: #ffffff04; color: #fff; border-color: #ff3047; }
.home-tools { display: flex; align-items: center; gap: 18px; }
.home-tools site-search button[data-open-modal] { width: 40px; height: 40px; justify-content: center; background: transparent; border: 1px solid #ffffff22; padding: 0; }
.home-tools site-search button[data-open-modal] > :not(svg) { display: none; }
.docs-home { --red: #ff3047; --paper: #f4f1ea; --muted: #96979c; --line: #ffffff1c; color: var(--paper); background: #090a0c; font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif; }
.docs-home a { text-decoration: none; }
.docs-home a:focus-visible { outline: 2px solid #ff8998; outline-offset: 5px; }
.home-hero { position: relative; overflow: hidden; border-bottom: 1px solid var(--line); }
.hero-backdrop { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 65% center; opacity: .55; }
.home-hero::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, #090a0cf5 5%, #090a0ccc 35%, #090a0c15 75%), linear-gradient(0deg, #090a0c 2%, transparent 45%); pointer-events: none; }
.hero-grid { position: absolute; inset: 0; background-image: linear-gradient(#ffffff05 1px, transparent 1px), linear-gradient(90deg, #ffffff05 1px, transparent 1px); background-size: 80px 80px; }
.hero-shell { position: relative; z-index: 1; max-width: 1320px; margin: auto; padding: 64px 48px 50px; }
.eyebrow { display: flex; align-items: center; gap: 13px; font: 10px var(--sl-font-mono); letter-spacing: .1em; }
.eyebrow > span { background: var(--red); color: white; padding: 7px 10px; }
.eyebrow b { font-weight: 500; color: #c2c2c3; }
.home-hero h1 { font-family: 'Arial Black', 'Segoe UI', sans-serif; font-size: clamp(64px, 7.8vw, 108px); letter-spacing: -.065em; line-height: .97; font-weight: 900; margin: 30px 0 24px; }
.home-hero h1 > span { display: block; }
.home-hero .outline { -webkit-text-stroke: 1px #a4a4a7; color: transparent; margin-left: .58em; }
.red { color: var(--red); }
.hero-copy h2 { font-size: clamp(19px, 2vw, 25px); letter-spacing: .04em; font-weight: 650; }
.hero-copy p { font-size: 13px; color: #b6b7bc; line-height: 1.9; margin-top: 12px; }
.hero-actions { display: flex; gap: 12px; margin-top: 27px; flex-wrap: wrap; }
.home-button { display: inline-flex; min-height: 48px; align-items: center; justify-content: space-between; gap: 40px; padding: 0 22px; border: 1px solid #ffffff38; color: var(--paper); font-size: 13px; font-weight: 600; transition: background .2s, border-color .2s; }
.home-button span { font-size: 20px; font-weight: 400; }
.home-button.primary { background: var(--red); border-color: var(--red); color: white; }
.home-button:hover { border-color: var(--red); background: #ff304720; }
.home-button.primary:hover { background: #da1b34; }
.image-caption { position: absolute; right: 48px; bottom: 55px; padding: 14px 16px; border: 1px solid #ffffff26; background: #090a0cbb; font: 9px/2 var(--sl-font-mono); letter-spacing: .08em; color: #c2c2c3; }
.image-caption > span:last-child { color: #878a90; padding-left: 13px; }
.signal { display: inline-block; width: 5px; height: 5px; background: #66e6a4; margin-right: 6px; vertical-align: middle; }
.hero-bottom { position: relative; z-index: 1; max-width: 1224px; padding: 23px 0; margin: auto; border-top: 1px solid var(--line); display: flex; align-items: center; gap: 36px; }
.hero-bottom > div { display: flex; align-items: baseline; gap: 10px; }
.hero-bottom strong { font: 600 27px/1 var(--sl-font-mono); }
.hero-bottom span { font-size: 11px; color: var(--muted); }
.hero-bottom .hero-motto { color: #858991; font: 9px var(--sl-font-mono); letter-spacing: .09em; margin-left: auto; }
.hero-bottom > a { display: flex; align-items: center; gap: 20px; font-size: 10px; color: #c2c2c3; }
.hero-bottom > a span { color: var(--red); font-size: 21px; }
.home-inner { max-width: 1320px; padding: 0 48px; margin: auto; }
.competition-notice { margin-top: 32px; display: flex; align-items: center; gap: 24px; background: linear-gradient(100deg, #ff304710, #111316 70%); border: 1px solid #ff304738; border-left: 3px solid var(--red); padding: 22px 26px; color: var(--paper); }
.notice-tag { font: 11px var(--sl-font-mono); color: #ff7a8b; letter-spacing: .04em; white-space: nowrap; }
.notice-copy { display: flex; flex-direction: column; gap: 6px; }
.notice-copy strong { font-size: 14px; font-weight: 600; }
.notice-copy > span { color: var(--muted); font-size: 11px; }
.notice-link { display: flex; align-items: center; gap: 24px; margin-left: auto; font-size: 11px; white-space: nowrap; }
.notice-link b { font-size: 20px; font-weight: 400; color: var(--red); }
.competition-notice:hover { border-color: var(--red); }
.knowledge-section { padding-top: 78px; scroll-margin-top: 7rem; }
.section-eyebrow { display: flex; align-items: center; gap: 12px; color: #989ca4; font: 10px/1.5 var(--sl-font-mono); letter-spacing: .13em; }
.section-eyebrow > span { color: var(--red); }
.section-eyebrow i { width: 60px; height: 1px; background: var(--line); }
.section-heading { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin: 16px 0 30px; }
.section-heading h2 { font-size: clamp(24px, 2.6vw, 33px); letter-spacing: -.04em; font-weight: 650; }
.section-heading p { color: var(--muted); font-size: 12px; line-height: 1.9; }
.discipline-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.discipline-card { color: var(--paper); background: #101215; border: 1px solid var(--line); padding: 26px 22px 18px; min-width: 0; transition: background .2s, border-color .2s; }
.discipline-card + .discipline-card { border-left: 0; }
.card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; }
.card-top span { font: 10px var(--sl-font-mono); color: #a7aab0; }
.card-top img { opacity: .9; }
.discipline-card h3 { font-size: 21px; font-weight: 650; }
.discipline-card p { color: var(--muted); font-size: 12px; line-height: 1.9; margin-top: 13px; min-height: 46px; }
.card-bottom { display: flex; align-items: center; justify-content: space-between; border-top: 1px solid var(--line); padding-top: 20px; margin-top: 25px; gap: 6px; }
.card-bottom span { font-size: 9px; color: #b0b1b7; }
.card-bottom b { color: var(--red); font-size: 20px; font-weight: 400; }
.discipline-card:hover { background: #19171c; box-shadow: inset 0 2px var(--red); }
.reading-section { padding-top: 76px; }
.text-link { color: #dddde0; font-size: 12px; white-space: nowrap; }
.text-link span { color: var(--red); margin-left: 14px; }
.reading-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.reading-card { border-top: 1px solid #ffffff35; padding: 24px 0; color: var(--paper); }
.reading-index { display: flex; gap: 18px; font: 11px var(--sl-font-mono); color: var(--red); }
.reading-index b { font-size: 9px; color: #878b93; font-weight: 400; letter-spacing: .08em; }
.reading-card h3 { font-size: 17px; margin-top: 20px; font-weight: 600; }
.reading-card p { color: var(--muted); font-size: 12px; margin-top: 11px; line-height: 1.9; }
.reading-card > div { display: flex; align-items: center; justify-content: space-between; margin-top: 26px; color: #a3a6af; font-size: 10px; }
.reading-card > div > b { color: var(--red); font-size: 21px; font-weight: 400; }
.reading-card:hover { border-color: var(--red); }
.contribute-panel { display: flex; justify-content: space-between; align-items: center; gap: 30px; border: 1px solid var(--line); background: #101215; padding: 38px; margin: 45px 0 72px; }
.contribute-panel .section-eyebrow { color: #ff7a8b; font-size: 9px; }
.contribute-panel h2 { font-size: 23px; margin-top: 13px; font-weight: 600; }
.contribute-panel p { font-size: 12px; color: var(--muted); margin-top: 12px; line-height: 1.8; }
.contribute-panel .home-button { flex-shrink: 0; }
.home-ticker { border-block: 1px solid var(--line); padding: 15px 24px; overflow: hidden; white-space: nowrap; color: #b4b6bd; font: 10px var(--sl-font-mono); letter-spacing: .17em; text-align: center; }
.home-ticker span { color: var(--red); margin: 0 28px; }
.home-footer { max-width: 1320px; padding: 48px 48px 22px; margin: auto; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 36px; }
.home-footer img { object-fit: contain; object-position: left; }
.home-footer p { font-size: 11px; color: var(--muted); line-height: 1.9; margin-top: 16px; }
.footer-links { display: flex; gap: 35px; }
.footer-links a { color: #c2c2c3; font-size: 11px; }
.footer-links a:hover { color: #ff7a8b; }
.footer-bottom { width: 100%; border-top: 1px solid var(--line); padding-top: 22px; display: flex; justify-content: space-between; gap: 16px; color: #8c9098; font: 8px var(--sl-font-mono); letter-spacing: .06em; flex-wrap: wrap; }
@media (min-width: 1440px) { .hero-backdrop { object-position: center 43%; } }
@media (max-width: 1100px) {
.home-header nav a { padding-inline: 12px; }
.home-tools { gap: 10px; }
.hero-bottom { margin-inline: 48px; }
.hero-bottom .hero-motto { display: none; }
.hero-bottom > a { margin-left: auto; }
.image-caption { display: none; }
.discipline-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.discipline-card + .discipline-card { border-left: 1px solid var(--line); }
}
@media (max-width: 760px) {
:root:has(.docs-home) { --sl-nav-height: 4.5rem; }
.home-header { gap: 12px; }
.home-header nav { display: none; }
.home-tools { margin-left: auto; }
.hero-shell { padding: 45px 24px 35px; }
.home-hero h1 { font-size: clamp(60px, 13vw, 92px); }
.hero-backdrop { object-position: 66% center; opacity: .3; }
.home-hero::after { background: linear-gradient(90deg, #090a0cd9, #090a0c33), linear-gradient(0deg, #090a0c, transparent); }
.eyebrow { font-size: 8px; gap: 9px; }
.hero-bottom { margin-inline: 24px; gap: 24px; }
.hero-bottom > a { font-size: 0; gap: 0; }
.hero-bottom strong { font-size: 23px; }
.home-inner { padding-inline: 24px; }
.competition-notice { flex-wrap: wrap; gap: 12px; padding: 20px; }
.notice-tag { width: 100%; }
.notice-copy strong { font-size: 13px; }
.notice-link { margin: 5px 0 0; }
.knowledge-section, .reading-section { padding-top: 54px; }
.section-heading { align-items: start; flex-direction: column; gap: 13px; }
.section-heading p br { display: none; }
.discipline-card { padding: 22px 17px 16px; }
.card-top { margin-bottom: 22px; gap: 6px; }
.card-top img { width: 32px; height: 32px; }
.card-top span { font-size: 9px; }
.discipline-card h3 { font-size: 18px; }
.card-bottom { margin-top: 20px; gap: 10px; }
.card-bottom span { line-height: 1.8; }
.reading-grid { grid-template-columns: 1fr; gap: 8px; }
.reading-card { padding-block: 22px; }
.reading-card h3 { margin-top: 15px; }
.reading-card > div { margin-top: 15px; }
.contribute-panel { flex-direction: column; align-items: start; padding: 26px; margin: 30px 0 50px; }
.contribute-panel h2 { font-size: 21px; }
.home-footer { padding: 36px 24px 22px; }
.footer-links { gap: 24px; flex-wrap: wrap; }
}
@media (max-width: 380px) {
.discipline-grid { grid-template-columns: 1fr; }
.home-tools { gap: 4px; }
.brand-name { font-size: 22px; }
.brand-name small { font-size: 7px; }
.docs-brand { gap: 7px; }
.hero-bottom { gap: 16px; }
}
@media (prefers-reduced-motion: reduce) { .docs-home * { transition: none; } }
@media print {
.docs-home { --paper: #111; --muted: #555; --line: #ddd; background: white; color: black; }
.hero-backdrop, .hero-grid, .home-hero::after, .home-ticker, .image-caption { display: none; }
.home-hero .outline { color: black; -webkit-text-stroke: 0; }
.hero-shell { padding: 20px; }
.home-hero h1 { font-size: 45px; }
}