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

summaryrefslogtreecommitdiffhomepage
path: root/frontend
diff options
context:
space:
mode:
authorLeitwolf112026-10-18 09:00:14 +0300
committerLeitwolf112026-10-18 09:00:14 +0300
commit47ffd40c8b61aa9dd131e567bfb2ce78ec7f354c (patch)
tree4760813c7550a29ee25160f70cf91b2f5bd552cd /frontend
parentc2eb3d208b37826167496cfdf657ffca33fef703 (diff)
downloadwebsite-design/docs-layout.tar.gz
Lay out the documentation like kotlinlang.org/docsdesign/docs-layout
The three documentation pages each drew their own sidebar. The two hand-built pages listed different topics: Getting started had no link to Syntax. Each page also opened with a capitalized section kicker. DocShell now frames every documentation page: - On the left, the topics of the site, with the current one marked. On a narrow screen they fold into a Contents button above the page. - Above the page, a breadcrumb: site / Documentation / topic. - The page in a column of at most 720 px. - On the right, "On this page". It is read from the h2 headings of the rendered page, and each heading gets an id from its words in any script. It is hidden below 1100 px. - Under the page, previous and next topic cards and an "Edit this page" link to the file the page is written in. DocPage, OverviewPage and GettingStartedPage use it and drop their own sidebars and kickers. The styles of the old layout are removed. The labels are in all four languages.
Diffstat (limited to 'frontend')
-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;
+ }
+}