Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLeitwolf2026-10-18 09:57:50 +0300
committerGitHub2026-10-18 09:57:50 +0300
commit5877c2ec7f0f58eb4128c83e20d93fd74c90a47d (patch)
tree4760813c7550a29ee25160f70cf91b2f5bd552cd
parentc2eb3d208b37826167496cfdf657ffca33fef703 (diff)
parent47ffd40c8b61aa9dd131e567bfb2ce78ec7f354c (diff)
downloadwebsite-5877c2ec7f0f58eb4128c83e20d93fd74c90a47d.tar.gz
Merge pull request #41 from Progmasoft/design/docs-layout
Lay out the documentation like kotlinlang.org/docs
-rw-r--r--frontend/src/components/DocShell.vue161
-rw-r--r--frontend/src/pages/DocPage.vue76
-rw-r--r--frontend/src/pages/GettingStartedPage.vue116
-rw-r--r--frontend/src/pages/OverviewPage.vue114
-rw-r--r--frontend/src/styles/site.css203
5 files changed, 454 insertions, 216 deletions
diff --git a/frontend/src/components/DocShell.vue b/frontend/src/components/DocShell.vue
new file mode 100644
index 0000000..ac9ef67
--- /dev/null
+++ b/frontend/src/components/DocShell.vue
@@ -0,0 +1,161 @@
+<!-- SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> -->
+<!-- SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 -->
+
+<script setup lang="ts">
+import { computed, nextTick, onMounted, ref, watch } from "vue";
+import { RouterLink } from "vue-router";
+import { sidebarFor } from "../content/routes";
+import { locale } from "../preferences";
+import { site } from "../site";
+
+/**
+ * The frame of every documentation page: the topics of the site on the left, the page in a readable column, the
+ * headings of the page on the right, and the previous and next topics under it. The headings are read from the
+ * rendered page, so a page only has to write its h2 elements.
+ */
+const props = defineProps<{ path: string; editPath: string }>();
+
+const labels = {
+ "en-US": {
+ contents: "Contents",
+ onPage: "On this page",
+ previous: "Previous",
+ next: "Next",
+ edit: "Edit this page",
+ docs: "Documentation",
+ },
+ "de-DE": {
+ contents: "Inhalt",
+ onPage: "Auf dieser Seite",
+ previous: "Zurück",
+ next: "Weiter",
+ edit: "Diese Seite bearbeiten",
+ docs: "Dokumentation",
+ },
+ "ru-RU": {
+ contents: "Содержание",
+ onPage: "На этой странице",
+ previous: "Назад",
+ next: "Далее",
+ edit: "Изменить страницу",
+ docs: "Документация",
+ },
+ "he-IL": {
+ contents: "תוכן",
+ onPage: "בעמוד הזה",
+ previous: "הקודם",
+ next: "הבא",
+ edit: "עריכת העמוד",
+ docs: "תיעוד",
+ },
+} as const;
+const copy = computed(() => labels[locale.value]);
+const brand = { language: "Tala", talac: "Talac", tazel: "Tazel" }[site];
+
+const sidebar = computed(() => sidebarFor(site, locale.value));
+const position = computed(() => sidebar.value.findIndex((entry) => entry.path === props.path));
+const current = computed(() => sidebar.value[position.value]);
+const previous = computed(() =>
+ position.value > 0 ? sidebar.value[position.value - 1] : undefined,
+);
+const next = computed(() =>
+ position.value >= 0 && position.value < sidebar.value.length - 1
+ ? sidebar.value[position.value + 1]
+ : undefined,
+);
+const editUrl = computed(
+ () => `https://github.com/Progmasoft/website/blob/main/frontend/${props.editPath}`,
+);
+
+const article = ref<HTMLElement>();
+const contents = ref<HTMLDetailsElement>();
+const headings = ref<{ id: string; text: string }[]>([]);
+
+/** A fragment for a heading: its words, in any script, joined by hyphens. */
+function slug(text: string): string {
+ return text
+ .toLowerCase()
+ .replace(/[^\p{L}\p{N}]+/gu, "-")
+ .replace(/^-+|-+$/g, "");
+}
+
+async function collectHeadings() {
+ await nextTick();
+ const found: { id: string; text: string }[] = [];
+ for (const heading of article.value?.querySelectorAll("h2") ?? []) {
+ const text = heading.textContent?.trim() ?? "";
+ if (!text) continue;
+ let id = slug(text) || `section-${found.length + 1}`;
+ while (found.some((entry) => entry.id === id)) id = `${id}-${found.length + 1}`;
+ heading.id = id;
+ found.push({ id, text });
+ }
+ headings.value = found;
+}
+
+onMounted(() => {
+ // On a narrow screen the topics fold away above the page; on a wide one they stay open beside it.
+ if (contents.value && window.matchMedia("(max-width: 760px)").matches)
+ contents.value.open = false;
+ collectHeadings();
+});
+watch([locale, () => props.path], collectHeadings);
+</script>
+
+<template>
+ <div class="docs">
+ <aside class="docs-nav">
+ <details ref="contents" class="docs-nav-toggle" open>
+ <summary>{{ copy.contents }}</summary>
+ <nav :aria-label="copy.docs">
+ <p class="docs-nav-site">{{ brand }}</p>
+ <RouterLink
+ v-for="entry in sidebar"
+ :key="entry.path"
+ :to="entry.path"
+ :aria-current="entry.path === path ? 'page' : undefined"
+ >{{ entry.label }}</RouterLink
+ >
+ <a v-if="site === 'language'" href="https://github.com/Progmasoft/tala/tree/main/Spec"
+ >Specification ↗</a
+ >
+ </nav>
+ </details>
+ </aside>
+
+ <div class="docs-main">
+ <nav class="docs-crumbs" aria-label="Breadcrumb">
+ <RouterLink to="/">{{ brand }}</RouterLink>
+ <span aria-hidden="true">/</span>
+ <span>{{ copy.docs }}</span>
+ <template v-if="current">
+ <span aria-hidden="true">/</span>
+ <span aria-current="page">{{ current.label }}</span>
+ </template>
+ </nav>
+ <article ref="article" class="doc-content">
+ <slot />
+ </article>
+ <nav class="docs-pager" :aria-label="`${copy.previous} / ${copy.next}`">
+ <RouterLink v-if="previous" class="docs-pager-previous" :to="previous.path">
+ <span>{{ copy.previous }}</span>
+ <strong>{{ previous.label }}</strong>
+ </RouterLink>
+ <RouterLink v-if="next" class="docs-pager-next" :to="next.path">
+ <span>{{ copy.next }}</span>
+ <strong>{{ next.label }}</strong>
+ </RouterLink>
+ </nav>
+ <p class="docs-edit">
+ <a :href="editUrl" target="_blank" rel="noopener noreferrer">{{ copy.edit }} ↗</a>
+ </p>
+ </div>
+
+ <aside v-if="headings.length > 1" class="docs-toc">
+ <p>{{ copy.onPage }}</p>
+ <a v-for="heading in headings" :key="heading.id" :href="`#${heading.id}`">{{
+ heading.text
+ }}</a>
+ </aside>
+ </div>
+</template>
diff --git a/frontend/src/pages/DocPage.vue b/frontend/src/pages/DocPage.vue
index 061acb4..7b7ec07 100644
--- a/frontend/src/pages/DocPage.vue
+++ b/frontend/src/pages/DocPage.vue
@@ -3,58 +3,46 @@
<script setup lang="ts">
import { computed } from "vue";
-import { RouterLink } from "vue-router";
-import { sidebarFor } from "../content/routes";
+import DocShell from "../components/DocShell.vue";
import type { DocTopic } from "../content/types";
import { locale } from "../preferences";
import { site } from "../site";
const props = defineProps<{ topic: DocTopic; path: string }>();
const page = computed(() => props.topic[locale.value]);
-const sidebar = computed(() => sidebarFor(site, locale.value));
-const kicker = { language: "TALA", talac: "TALAC", tazel: "TAZEL" }[site];
+// The file a page of each site is written in, for its "Edit this page" link.
+const source = {
+ language: "src/content/syntax.ts",
+ talac: "src/content/talac.ts",
+ tazel: "src/content/tazel.ts",
+}[site];
</script>
<template>
- <div class="doc-layout section-wrap">
- <aside class="doc-sidebar">
- <span class="kicker">{{ kicker }}</span
- ><RouterLink
- v-for="entry in sidebar"
- :key="entry.path"
- :to="entry.path"
- :aria-current="entry.path === path ? 'page' : undefined"
- >{{ entry.label }}</RouterLink
- ><a v-if="site === 'language'" href="https://github.com/Progmasoft/tala/tree/main/Spec"
- >Specification ↗</a
- >
- </aside>
- <article class="doc-content">
- <span class="kicker">{{ page.section }}</span>
- <h1>{{ page.heading }}</h1>
- <p class="doc-lead">{{ page.lead }}</p>
- <template v-for="(block, index) in page.blocks" :key="index">
- <h2 v-if="block.kind === 'heading'">{{ block.text }}</h2>
- <h3 v-else-if="block.kind === 'subheading'">{{ block.text }}</h3>
- <p v-else-if="block.kind === 'text'">{{ block.text }}</p>
- <pre
- v-else-if="block.kind === 'code'"
- class="doc-code"
- dir="ltr"
- ><code>{{ block.code }}</code></pre>
- <dl v-else-if="block.kind === 'terms'" class="doc-boundaries">
- <div v-for="item in block.items" :key="item.term">
- <dt dir="ltr">
- <code>{{ item.term }}</code>
- </dt>
- <dd>{{ item.detail }}</dd>
- </div>
- </dl>
- <div v-else-if="block.kind === 'note'" class="doc-note">
- <h3>{{ block.title }}</h3>
- <p>{{ block.text }}</p>
+ <DocShell :path="path" :edit-path="source">
+ <h1>{{ page.heading }}</h1>
+ <p class="doc-lead">{{ page.lead }}</p>
+ <template v-for="(block, index) in page.blocks" :key="index">
+ <h2 v-if="block.kind === 'heading'">{{ block.text }}</h2>
+ <h3 v-else-if="block.kind === 'subheading'">{{ block.text }}</h3>
+ <p v-else-if="block.kind === 'text'">{{ block.text }}</p>
+ <pre
+ v-else-if="block.kind === 'code'"
+ class="doc-code"
+ dir="ltr"
+ ><code>{{ block.code }}</code></pre>
+ <dl v-else-if="block.kind === 'terms'" class="doc-boundaries">
+ <div v-for="item in block.items" :key="item.term">
+ <dt dir="ltr">
+ <code>{{ item.term }}</code>
+ </dt>
+ <dd>{{ item.detail }}</dd>
</div>
- </template>
- </article>
- </div>
+ </dl>
+ <div v-else-if="block.kind === 'note'" class="doc-note">
+ <h3>{{ block.title }}</h3>
+ <p>{{ block.text }}</p>
+ </div>
+ </template>
+ </DocShell>
</template>
diff --git a/frontend/src/pages/GettingStartedPage.vue b/frontend/src/pages/GettingStartedPage.vue
index e526aff..d5794e7 100644
--- a/frontend/src/pages/GettingStartedPage.vue
+++ b/frontend/src/pages/GettingStartedPage.vue
@@ -2,6 +2,7 @@
<!-- SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 -->
<script setup lang="ts">
+import DocShell from "../components/DocShell.vue";
import { computed } from "vue";
import { RouterLink } from "vue-router";
import { arrow, locale } from "../preferences";
@@ -256,69 +257,60 @@ public class HelloWorld {
</script>
<template>
- <div class="doc-layout section-wrap">
- <aside class="doc-sidebar">
- <span class="kicker">TALA</span
- ><RouterLink to="/docs/overview">{{ c.navOverview }}</RouterLink
- ><RouterLink to="/docs/getting-started" aria-current="page">{{ c.navStart }}</RouterLink
- ><a href="https://github.com/Progmasoft/tala/tree/main/Spec">Specification ↗</a>
- </aside>
- <article class="doc-content">
- <span class="kicker">{{ c.section }}</span>
- <h1>{{ c.title }}</h1>
- <p class="doc-lead">{{ c.lead }}</p>
- <h2>{{ c.step1 }}</h2>
- <p>{{ c.step1Text }}</p>
- <pre
- class="doc-code"
- ><code>git clone --recurse-submodules https://github.com/Progmasoft/tala.git</code></pre>
- <h2>{{ c.step2 }}</h2>
- <p>{{ c.step2Text }}</p>
- <p>{{ c.platform }}</p>
- <pre class="doc-code"><code>go run ./helpers/cmd/develop doctor</code></pre>
- <h3>{{ c.bootstrap }}</h3>
- <p>{{ c.toolchainHelp }}</p>
- <pre class="doc-code"><code>go run ./helpers/cmd/prebuild check
+ <DocShell path="/docs/getting-started" edit-path="src/pages/GettingStartedPage.vue">
+ <h1>{{ c.title }}</h1>
+ <p class="doc-lead">{{ c.lead }}</p>
+ <h2>{{ c.step1 }}</h2>
+ <p>{{ c.step1Text }}</p>
+ <pre
+ class="doc-code"
+ ><code>git clone --recurse-submodules https://github.com/Progmasoft/tala.git</code></pre>
+ <h2>{{ c.step2 }}</h2>
+ <p>{{ c.step2Text }}</p>
+ <p>{{ c.platform }}</p>
+ <pre class="doc-code"><code>go run ./helpers/cmd/develop doctor</code></pre>
+ <h3>{{ c.bootstrap }}</h3>
+ <p>{{ c.toolchainHelp }}</p>
+ <pre class="doc-code"><code>go run ./helpers/cmd/prebuild check
go run ./helpers/cmd/prebuild install</code></pre>
- <h2>{{ c.step3 }}</h2>
- <p>{{ c.step3Text }}</p>
- <pre class="doc-code"><code>go run ./helpers/cmd/develop build
+ <h2>{{ c.step3 }}</h2>
+ <p>{{ c.step3Text }}</p>
+ <pre class="doc-code"><code>go run ./helpers/cmd/develop build
go run ./helpers/cmd/develop test</code></pre>
- <h2>{{ c.step4 }}</h2>
- <p>{{ c.step4Text }}</p>
- <pre class="doc-code"><code>{{ hello }}</code></pre>
- <h3>{{ c.fileCheck }}</h3>
- <pre
- class="doc-code"
- ><code>talac Examples/HelloWorld/HelloWorld.tala --emit=metadata</code></pre>
- <h3>{{ c.fileBuild }}</h3>
- <pre
- class="doc-code"
- ><code>talac Examples/HelloWorld/HelloWorld.tala --entry=Examples.HelloWorld.HelloWorld</code></pre>
- <p>{{ c.subset }}</p>
- <h2>{{ c.step5 }}</h2>
- <p>{{ c.step5Text }}</p>
- <pre class="doc-code"><code>talac --help
+ <h2>{{ c.step4 }}</h2>
+ <p>{{ c.step4Text }}</p>
+ <pre class="doc-code"><code>{{ hello }}</code></pre>
+ <h3>{{ c.fileCheck }}</h3>
+ <pre
+ class="doc-code"
+ ><code>talac Examples/HelloWorld/HelloWorld.tala --emit=metadata</code></pre>
+ <h3>{{ c.fileBuild }}</h3>
+ <pre
+ class="doc-code"
+ ><code>talac Examples/HelloWorld/HelloWorld.tala --entry=Examples.HelloWorld.HelloWorld</code></pre>
+ <p>{{ c.subset }}</p>
+ <h2>{{ c.step5 }}</h2>
+ <p>{{ c.step5Text }}</p>
+ <pre class="doc-code"><code>talac --help
tazel help</code></pre>
- <div class="doc-resource-list">
- <a v-for="link in c.links" :key="link.href" :href="link.href">
- <strong>{{ link.title }} <span aria-hidden="true">↗</span></strong>
- <span>{{ link.detail }}</span>
- </a>
- </div>
- <div class="doc-note">
- <h3>{{ c.note }}</h3>
- <p>{{ c.noteText }}</p>
- </div>
- <div class="doc-actions">
- <RouterLink class="button button-primary" to="/docs/overview"
- >{{ c.more }} {{ arrow }}</RouterLink
- ><a class="inline-link" href="https://github.com/Progmasoft/tala/tree/main/Spec"
- >{{ c.spec }} ↗</a
- ><a class="inline-link" href="https://github.com/Progmasoft/tala/tree/main/Examples"
- >{{ c.examples }} ↗</a
- >
- </div>
- </article>
- </div>
+ <div class="doc-resource-list">
+ <a v-for="link in c.links" :key="link.href" :href="link.href">
+ <strong>{{ link.title }} <span aria-hidden="true">↗</span></strong>
+ <span>{{ link.detail }}</span>
+ </a>
+ </div>
+ <div class="doc-note">
+ <h3>{{ c.note }}</h3>
+ <p>{{ c.noteText }}</p>
+ </div>
+ <div class="doc-actions">
+ <RouterLink class="button button-primary" to="/docs/overview"
+ >{{ c.more }} {{ arrow }}</RouterLink
+ ><a class="inline-link" href="https://github.com/Progmasoft/tala/tree/main/Spec"
+ >{{ c.spec }} ↗</a
+ ><a class="inline-link" href="https://github.com/Progmasoft/tala/tree/main/Examples"
+ >{{ c.examples }} ↗</a
+ >
+ </div>
+ </DocShell>
</template>
diff --git a/frontend/src/pages/OverviewPage.vue b/frontend/src/pages/OverviewPage.vue
index 2c4ccf0..4463135 100644
--- a/frontend/src/pages/OverviewPage.vue
+++ b/frontend/src/pages/OverviewPage.vue
@@ -2,6 +2,7 @@
<!-- SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 -->
<script setup lang="ts">
+import DocShell from "../components/DocShell.vue";
import { computed } from "vue";
import { RouterLink } from "vue-router";
import { arrow, locale } from "../preferences";
@@ -474,67 +475,58 @@ const c = computed(() => text[locale.value]);
</script>
<template>
- <div class="doc-layout section-wrap">
- <aside class="doc-sidebar">
- <span class="kicker">TALA</span
- ><RouterLink to="/docs/overview" aria-current="page">{{ c.navOverview }}</RouterLink
- ><RouterLink to="/docs/getting-started">{{ c.navStart }}</RouterLink
- ><a href="https://github.com/Progmasoft/tala/tree/main/Spec">Specification ↗</a>
- </aside>
- <article class="doc-content">
- <span class="kicker">{{ c.section }}</span>
- <h1>{{ c.title }}</h1>
- <p class="doc-lead">{{ c.lead }}</p>
- <h2>{{ c.goals }}</h2>
- <div class="doc-points">
- <section v-for="item in c.items" :key="item.title">
- <h3>{{ item.title }}</h3>
- <p>{{ item.body }}</p>
- </section>
+ <DocShell path="/docs/overview" edit-path="src/pages/OverviewPage.vue">
+ <h1>{{ c.title }}</h1>
+ <p class="doc-lead">{{ c.lead }}</p>
+ <h2>{{ c.goals }}</h2>
+ <div class="doc-points">
+ <section v-for="item in c.items" :key="item.title">
+ <h3>{{ item.title }}</h3>
+ <p>{{ item.body }}</p>
+ </section>
+ </div>
+ <h2>{{ c.modelHeading }}</h2>
+ <p>{{ c.modelIntro }}</p>
+ <div class="doc-points">
+ <section v-for="item in c.model" :key="item.title">
+ <h3>{{ item.title }}</h3>
+ <p>{{ item.body }}</p>
+ </section>
+ </div>
+ <h2>{{ c.pipelineHeading }}</h2>
+ <p>{{ c.pipelineIntro }}</p>
+ <ol class="doc-pipeline">
+ <li v-for="step in c.pipeline" :key="step.title">
+ <h3>{{ step.title }}</h3>
+ <p>{{ step.body }}</p>
+ </li>
+ </ol>
+ <h2>{{ c.boundariesHeading }}</h2>
+ <dl class="doc-boundaries">
+ <div v-for="boundary in c.boundaries" :key="boundary.label">
+ <dt>{{ boundary.label }}</dt>
+ <dd>{{ boundary.value }}</dd>
</div>
- <h2>{{ c.modelHeading }}</h2>
- <p>{{ c.modelIntro }}</p>
- <div class="doc-points">
- <section v-for="item in c.model" :key="item.title">
- <h3>{{ item.title }}</h3>
- <p>{{ item.body }}</p>
- </section>
+ </dl>
+ <h2>{{ c.not }}</h2>
+ <p>{{ c.notText }}</p>
+ <h2>{{ c.questionHeading }}</h2>
+ <div class="doc-points">
+ <section v-for="question in c.questions" :key="question.q">
+ <h3>{{ question.q }}</h3>
+ <p>{{ question.a }}</p>
+ </section>
+ </div>
+ <div class="doc-next">
+ <h2>{{ c.next }}</h2>
+ <p>{{ c.nextText }}</p>
+ <div class="doc-actions">
+ <RouterLink class="button button-primary" to="/docs/getting-started"
+ >{{ c.start }} {{ arrow }}</RouterLink
+ ><a class="button button-quiet" href="https://github.com/Progmasoft/tala/tree/main/Spec"
+ >{{ c.spec }} ↗</a
+ ><a class="inline-link" href="https://github.com/Progmasoft/tala">{{ c.source }} ↗</a>
</div>
- <h2>{{ c.pipelineHeading }}</h2>
- <p>{{ c.pipelineIntro }}</p>
- <ol class="doc-pipeline">
- <li v-for="step in c.pipeline" :key="step.title">
- <h3>{{ step.title }}</h3>
- <p>{{ step.body }}</p>
- </li>
- </ol>
- <h2>{{ c.boundariesHeading }}</h2>
- <dl class="doc-boundaries">
- <div v-for="boundary in c.boundaries" :key="boundary.label">
- <dt>{{ boundary.label }}</dt>
- <dd>{{ boundary.value }}</dd>
- </div>
- </dl>
- <h2>{{ c.not }}</h2>
- <p>{{ c.notText }}</p>
- <h2>{{ c.questionHeading }}</h2>
- <div class="doc-points">
- <section v-for="question in c.questions" :key="question.q">
- <h3>{{ question.q }}</h3>
- <p>{{ question.a }}</p>
- </section>
- </div>
- <div class="doc-next">
- <h2>{{ c.next }}</h2>
- <p>{{ c.nextText }}</p>
- <div class="doc-actions">
- <RouterLink class="button button-primary" to="/docs/getting-started"
- >{{ c.start }} {{ arrow }}</RouterLink
- ><a class="button button-quiet" href="https://github.com/Progmasoft/tala/tree/main/Spec"
- >{{ c.spec }} ↗</a
- ><a class="inline-link" href="https://github.com/Progmasoft/tala">{{ c.source }} ↗</a>
- </div>
- </div>
- </article>
- </div>
+ </div>
+ </DocShell>
</template>
diff --git a/frontend/src/styles/site.css b/frontend/src/styles/site.css
index 7695a64..0133939 100644
--- a/frontend/src/styles/site.css
+++ b/frontend/src/styles/site.css
@@ -105,10 +105,6 @@ p {
.skip-link:focus {
top: 8px;
}
-.section-wrap {
- width: min(100% - 48px, 1050px);
- margin: 0 auto;
-}
.site-header {
display: flex;
@@ -185,15 +181,6 @@ p {
.inline-link:hover {
text-decoration: underline;
}
-.kicker {
- color: var(--accent);
- font:
- 600 11px/1.5 ui-monospace,
- Consolas,
- monospace;
- letter-spacing: 0.08em;
- text-transform: uppercase;
-}
.doc-actions {
display: flex;
align-items: center;
@@ -243,33 +230,6 @@ p {
Consolas,
monospace;
}
-
-.doc-layout {
- display: grid;
- grid-template-columns: 200px minmax(0, 760px);
- gap: 60px;
- padding-top: 65px;
- padding-bottom: 100px;
-}
-.doc-sidebar {
- display: flex;
- flex-direction: column;
- align-self: start;
- gap: 16px;
- position: sticky;
- top: 25px;
- font-size: 13px;
-}
-.doc-sidebar .kicker {
- margin-bottom: 8px;
-}
-.doc-sidebar a {
- color: var(--muted);
-}
-.doc-sidebar a[aria-current="page"],
-.doc-sidebar a:hover {
- color: var(--accent);
-}
.doc-content h1 {
margin: 13px 0 21px;
font-size: clamp(34px, 4vw, 48px);
@@ -422,15 +382,6 @@ p {
.header-tools {
margin-left: auto;
}
- .doc-layout {
- grid-template-columns: minmax(0, 1fr);
- gap: 27px;
- }
- .doc-sidebar {
- position: static;
- flex-direction: row;
- flex-wrap: wrap;
- }
.doc-boundaries div {
grid-template-columns: 1fr;
gap: 4px;
@@ -611,3 +562,157 @@ p {
display: none;
}
}
+
+/* Documentation: the topics, the page in a readable column, and its headings. */
+.docs {
+ display: grid;
+ grid-template-columns: 210px minmax(0, 720px) 190px;
+ justify-content: center;
+ gap: 48px;
+ width: min(100% - 48px, 1240px);
+ margin: 0 auto;
+ padding: 36px 0 72px;
+}
+.docs-nav-toggle > summary {
+ display: none;
+}
+.docs-nav nav {
+ position: sticky;
+ top: 24px;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+}
+.docs-nav-site {
+ margin-bottom: 8px;
+ color: var(--text);
+ font-weight: 600;
+}
+.docs-nav a {
+ padding: 6px 10px;
+ border-radius: 7px;
+ color: var(--muted);
+ font-size: 14px;
+}
+.docs-nav a:hover {
+ background: var(--panel);
+ color: var(--text);
+}
+.docs-nav a[aria-current="page"] {
+ background: var(--panel);
+ color: var(--accent);
+ font-weight: 600;
+}
+.docs-crumbs {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 18px;
+ color: var(--quiet);
+ font-size: 13px;
+}
+.docs-crumbs a:hover {
+ color: var(--accent);
+}
+.docs-main .doc-content h1 {
+ margin-bottom: 14px;
+ font-size: clamp(30px, 4vw, 40px);
+ line-height: 1.15;
+}
+.docs-main .doc-content h2 {
+ scroll-margin-top: 20px;
+}
+.docs-pager {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 16px;
+ margin-top: 48px;
+ padding-top: 24px;
+ border-top: 1px solid var(--border);
+}
+.docs-pager a {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ padding: 14px 16px;
+ border: 1px solid var(--border);
+ border-radius: 10px;
+}
+.docs-pager a:hover {
+ border-color: var(--accent);
+}
+.docs-pager span {
+ color: var(--quiet);
+ font-size: 13px;
+}
+.docs-pager-next {
+ grid-column: 2;
+ text-align: end;
+}
+.docs-edit {
+ margin-top: 18px;
+ font-size: 13px;
+}
+.docs-edit a {
+ color: var(--quiet);
+}
+.docs-edit a:hover {
+ color: var(--accent);
+}
+.docs-toc {
+ position: sticky;
+ top: 24px;
+ align-self: start;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ font-size: 13px;
+}
+.docs-toc p {
+ margin-bottom: 4px;
+ color: var(--text);
+ font-weight: 600;
+}
+.docs-toc a {
+ color: var(--muted);
+ line-height: 1.4;
+}
+.docs-toc a:hover {
+ color: var(--accent);
+}
+@media (max-width: 1100px) {
+ .docs {
+ grid-template-columns: 200px minmax(0, 1fr);
+ }
+ .docs-toc {
+ display: none;
+ }
+}
+@media (max-width: 760px) {
+ .docs {
+ grid-template-columns: minmax(0, 1fr);
+ gap: 20px;
+ width: calc(100% - 32px);
+ padding-top: 20px;
+ }
+ .docs-nav-toggle {
+ border: 1px solid var(--border);
+ border-radius: 10px;
+ }
+ .docs-nav-toggle > summary {
+ display: block;
+ padding: 10px 14px;
+ cursor: pointer;
+ font-weight: 600;
+ }
+ .docs-nav nav {
+ position: static;
+ padding: 0 8px 10px;
+ }
+ .docs-pager {
+ grid-template-columns: 1fr;
+ }
+ .docs-pager-next {
+ grid-column: 1;
+ }
+}